Виджет — это интерактивный компонент, встроенный непосредственно в сообщение бота: промокод с кнопкой копирования, таймер обратного отсчета, трекер статуса заказа, викторина или календарь для выбора даты и времени. Когда клиент взаимодействует с виджетом, бот обновляет то же самое сообщение на месте — без отправки новых сообщений и без отображения пометки «изменено».

Есть два способа отправить виджет:
- Готовый шаблон — одна строка в Калькуляторе. Макет и функциональность уже реализованы.
- Пользовательский виджет — напишите свой собственный HTML-код (или попросите Mavi создать его) и обрабатывайте взаимодействия с помощью блоков потока бота.
Где работают виджеты
| Мессенджер | Только Telegram |
| Тип чата | Только личные чаты между клиентом и ботом |
| Не поддерживается | Группы, каналы, Telegram Business |
| Приложение Telegram | Требуется последняя версия Telegram. В более старых версиях отображается уведомление «Неподдерживаемое сообщение» и подпись |
| Пересылка | Виджеты нельзя пересылать или копировать |
Виджеты не поддерживают текстовые поля ввода или клавиатуры. Клиенты могут взаимодействовать только касанием. Если вам нужно, чтобы клиенты вводили текст, используйте обычный вопрос бота или Web App.
Виджеты не отображаются в окне тестирования бота в панели управления, потому что это не Telegram. Тестируйте виджеты непосредственно в Telegram, отправив сообщение своему боту.
Готовые шаблоны
Все шаблоны отправляются с помощью одной функции:
tg_send_widget(platform_id, template, params, caption)
| Параметр | Описание |
|---|---|
platform_id |
ID получателя. Для текущего клиента используйте переменную platform_id
|
template |
Имя шаблона: promo, timer, order_status, faq, quiz, calendar
|
params |
Словарь, содержащий настройки шаблона |
caption |
Текст, отображаемый под виджетом. Клиенты также видят его в списке чатов, в уведомлениях и в старых версиях Telegram, поэтому он должен быть осмысленным сам по себе |
Функция возвращает ответ Telegram API. ID отправленного сообщения доступен в response['result']['message_id']. Сохраните его, если планируете обновлять виджет позже.
Если функция возвращает текст вместо ответа Telegram, произошла ошибка: неизвестный шаблон, недопустимый или отсутствующий параметр, или виджет превышает ограничение по размеру. Текст ошибки объясняет, что пошло не так.
Как составить параметры
Создайте словарь и присвойте каждый параметр в отдельной строке:
p = {}
p["code"] = "WIDGET10"
p["title"] = "Ваш промокод"
p["note"] = "Скидка 10% на любой заказ"
w = tg_send_widget(platform_id, "promo", p, "Ваш промокод WIDGET10 — скидка 10%")
Введите код в поле Калькулятор блока. На скриншоте показан блок Стартовое условие, который отправляет виджет статуса заказа, когда клиент отправляет фразу «виджет заказа».

В блоке, который отправляет виджет, обычно устанавливается поле ответа в #{none}. Блок не отправляет отдельное текстовое сообщение, потому что подпись виджета служит текстом сообщения.
Язык
Шаблоны включают встроенный текст интерфейса, такой как подписи кнопок, названия месяцев и дней недели, «Время вышло» и другие сообщения.
Язык по умолчанию в Mavibot — английский (en).
Чтобы использовать другой язык, укажите параметр lang:
p["lang"] = "de"
Поддерживаемые языки:
ru, en, de, es, fr, pt, tr, uk, kk, ms, th, ar.
Тексты, которые вы предоставляете сами — заголовки, вопросы, шаги и подписи — отображаются точно так, как введены, и не переводятся автоматически.
Промокод — promo
Отображает промокод с кнопкой, которая копирует его одним касанием.

| Параметр | Описание |
|---|---|
code |
Промокод. Обязательный |
title |
Текст, отображаемый над кодом |
note |
Текст, отображаемый под кодом, например, срок действия |
button |
Подпись кнопки. По умолчанию: «Скопировать промокод» |
used_text |
Текст, отображаемый, когда код отмечен как использованный |
p = {}
p["code"] = "WIDGET10"
p["title"] = "Ваш промокод"
p["note"] = "Скидка 10% на любой заказ"
p["button"] = "Скопировать код"
w = tg_send_widget(platform_id, "promo", p, "Ваш промокод WIDGET10 — скидка 10%")
client.promo_widget_id = w['result']['message_id']
Чтобы отметить код как использованный, что зачеркивает код и удаляет кнопку:
p = {}
p["used"] = 1
t = tg_edit_widget_data(platform_id, client.promo_widget_id, p)
Таймер обратного отсчета — timer
Отображает обратный отсчет до указанной даты и времени.
Обратный отсчет запускается на устройстве клиента. Бот не участвует в обновлении таймера.

| Параметр | Описание |
|---|---|
until |
Целевая дата и время в формате "ДД.ММ.ГГГГ ЧЧ:ММ", с использованием часового пояса проекта |
seconds |
Альтернативно, количество секунд с момента отправки виджета |
title |
Заголовок таймера. По умолчанию: «Предложение заканчивается через» |
done |
Текст, отображаемый, когда обратный отсчет заканчивается |
text |
Текст, отображаемый под обратным отсчетом |
button, url
|
Подпись кнопки и URL назначения (только https://) |
hide_button |
Установите 1, чтобы скрыть кнопку, когда обратный отсчет заканчивается |
Вы должны указать либо until, либо seconds.
p = {}
p["seconds"] = 7200
p["title"] = "Предложение заканчивается через"
p["button"] = "Посетить сайт"
p["url"] = "https://salebot.pro"
w = tg_send_widget(platform_id, "timer", p, "Предложение заканчивается через 2 часа")
Когда обратный отсчет достигает нуля, боту не отправляется ни сообщение, ни обратный вызов. Если боту нужно выполнить действие по истечении предложения, используйте обычное таймерное соединение в потоке бота.
Статус заказа — order_status
Отображает список этапов заказа с выделением текущего этапа.
Бот может обновлять этап на месте, поэтому клиент всегда видит одно и то же сообщение.

| Параметр | Описание |
|---|---|
title |
Заголовок виджета |
steps |
Список этапов, от 1 до 12. По умолчанию: принят, готовится, передан курьеру, в пути, доставлен |
step |
Номер текущего этапа, начиная с 1 |
text |
Текст, отображаемый под этапами |
Отправка виджета:
p = {}
p["title"] = "Статус заказа"
p["steps"] = ["Принят", "Готовится", "Доставлен"]
p["step"] = 1
p["text"] = "Ваш заказ принят и готовится"
w = tg_send_widget(platform_id, "order_status", p, "Ваш заказ")
client.order_widget_id = w['result']['message_id']
Переход к следующему этапу из любого другого блока, например, при изменении этапа сделки, отправке команды менеджером или срабатывании таймера:
p = {}
p["step"] = 2
p["text"] = "Ваш заказ готовится и скоро будет передан курьеру"
t = tg_edit_widget_data(platform_id, client.order_widget_id, p)

Подпись под виджетом не меняется при обновлении этапа. Используйте нейтральную подпись, например «Ваш заказ», вместо «Статус: Принят».
Часто задаваемые вопросы — faq
Отображает список вопросов. Клиенты могут нажать на вопрос, чтобы развернуть ответ.

| Параметр | Описание |
|---|---|
title |
Заголовок виджета |
items |
Список пар вопрос-ответ. Обязательный |
p = {}
p["title"] = "Часто задаваемые вопросы"
p["items"] = [["Как я могу оплатить?", "Вы можете оплатить картой. Ссылка для оплаты будет отправлена в этот чат."], ["Сколько времени занимает доставка?", "Доставка обычно занимает 1–2 дня по городу и 3–7 дней по стране."], ["Могу ли я вернуть товар?", "Да, в течение 14 дней."]]
w = tg_send_widget(platform_id, "faq", p, "Ответы на часто задаваемые вопросы")
Текст отображается как обычный текст. HTML-теги и другая разметка не обрабатываются.
Викторина и опрос — quiz
Отображает вопросы с вариантами ответов, по одному вопросу за раз.
Если указаны правильные ответы, виджет действует как викторина и подсчитывает баллы. Без правильных ответов он работает как опрос.

| Параметр | Описание |
|---|---|
title |
Заголовок, отображаемый над вопросами |
questions |
Список вопросов. Обязательный |
retry |
Установите 1, чтобы отображать кнопку «Попробовать снова» в конце |
callback |
Пользовательский текст обратного вызова вместо widget_quiz_finished
|
Каждый вопрос — это словарь, содержащий:
-
q— текст вопроса -
options— варианты ответов -
correct— правильный ответ, указанный по индексу (начиная с 1) или точному тексту
p = {}
p["title"] = "Викторина: Проверьте свои знания"
p["retry"] = 1
p["questions"] = [{"q": "Сколько будет 2 + 2?", "options": ["3", "4", "5"], "correct": 2}, {"q": "Какая столица Франции?", "options": ["Лондон", "Париж", "Берлин"], "correct": "Париж"}]
w = tg_send_widget(platform_id, "quiz", p, "Пройдите викторину из двух вопросов!")
Чтобы создать опрос без подсчета баллов, опустите correct в каждом вопросе.
Правильные ответы проверяются платформой и не отправляются на устройство клиента.
Что получает поток бота
Ответы на отдельные вопросы не отправляются в диалог.
Когда клиент отвечает на последний вопрос, бот получает обратный вызов widget_quiz_finished, и заполняются следующие переменные:
| Переменная | Значение |
|---|---|
widget_quiz_score |
Количество правильных ответов; пусто для опросов |
widget_quiz_total |
Общее количество вопросов |
widget_quiz_answers |
Индексы выбранных вариантов, например [2,2]
|
Чтобы обработать результат, создайте соединение из блока, отправившего викторину, или используйте блок Стартовое условие с условием widget_quiz_finished.
Пример ответа:
Ваш результат: #{widget_quiz_score} из #{widget_quiz_total} правильных ответов

Календарь — calendar
Отображает ежемесячный календарь, в котором клиенты могут выбрать дату, а затем временной слот.
Он заменяет несколько страниц кнопок даты и времени, включая навигацию «Назад» и «Далее».

Календарь поддерживает три режима.
Пользовательские даты и время
Доступное время всегда передается через параметр slots.
Одинаковые временные слоты каждый день — укажите список времени и диапазон дат:
p = {}
p["title"] = "Выберите дату и время"
p["name"] = "Консультация"
p["days"] = 10
p["slots"] = ["10:00", "12:00", "15:00"]
w = tg_send_widget(platform_id, "calendar", p, "Выберите дату и время")
Разные временные слоты для конкретных дат — укажите словарь, сопоставляющий даты со списками времени. Доступные даты берутся из ключей словаря:
p = {}
p["slots"] = {"20.11.2026": ["10:00", "12:00"], "21.11.2026": ["15:00"]}
w = tg_send_widget(platform_id, "calendar", p, "Выберите дату и время")
| Параметр | Описание |
|---|---|
slots |
Доступное время, как список или словарь, сгруппированный по датам |
days |
Количество доступных дней, начиная с сегодняшнего |
date_from, date_to
|
Альтернативно, границы диапазона дат в формате "ДД.ММ.ГГГГ"
|
dates |
Альтернативно, список конкретных дат |
weekdays_off |
Недоступные дни недели: 1 = понедельник, 7 = воскресенье |
title |
Подсказка, отображаемая под сеткой календаря |
name |
Название услуги или товара, который бронируется; отображается после выбора |
change |
Установите 1, чтобы отображать кнопку «Выбрать другое время» после выбора |
callback |
Пользовательский текст обратного вызова вместо widget_calendar_selected
|
Только дата
Не передавайте slots, если клиенту нужно выбрать только дату.
p = {}
p["days"] = 45
p["weekdays_off"] = [7]
w = tg_send_widget(platform_id, "calendar", p, "Choose a date")
Онлайн-бронирование
Укажите филиал и услугу — календарь автоматически получит доступные даты и временные слоты из модуля Услуги.
cal = {}
cal["company_id"] = comp_id
cal["service_ids"] = serv_id
cal["days_limit"] = 30
cal["name"] = serv_title
w = tg_send_widget(platform_id, "calendar", cal, serv_title)
| Параметр | Описание |
|---|---|
company_id |
Идентификатор филиала |
service_ids |
Услуга или список услуг |
employee_id |
Идентификатор сотрудника; если не указан, используется любой доступный сотрудник |
days_limit |
Количество дней вперед для поиска доступности. По умолчанию: 14 |
people_count |
Количество мест, необходимых для групповой услуги |
auto_booking |
Установите 1, чтобы платформа создавала бронирование автоматически |
Эти параметры совпадают с параметрами, используемыми в get_dates_for_booking и get_slots_for_booking.
Что получает бот-сценарий
Отдельные выборы дат не отправляются в диалог.
Когда клиент выбирает временной слот или дату (если в календаре нет временных слотов), бот получает callback widget_calendar_selected, и заполняются следующие переменные:
| Переменная | Значение |
|---|---|
widget_date |
Выбранная дата в формате ДД.ММ.ГГГГ
|
widget_time |
Выбранное время в формате ЧЧ:ММ; пусто для календарей только с датой |
widget_message_id |
ID сообщения, содержащего виджет |

Форматы даты и времени совпадают с теми, которые принимают create_booking и modify_booking_time.
Онлайн-бронирование с календарем: полный пример
Виджет обрабатывает выбор даты, временные слоты и навигацию, сокращая количество необходимых блоков бота.
Блок 1. Выбор услуги
Используйте блок Стартовое условие с условием «записаться на прием».
Ответ: «Выберите услугу:»
Установите поле кнопок в #{srv_buttons}.
comp_id = 8
srv_data = get_services_for_booking(comp_id)
srv_kb = tools_make_button_str_checker(srv_data, 'title', 1)
srv_buttons = srv_kb['buttons']
srv_checker = srv_kb['checker']
Блок 2. Календарь
Ответ: #{none}.
Соедините Блок 1 с Блоком 2, используя условие #{srv_checker}.
serv_id = tools_check_user_input(srv_data, question, 'title', 'id')
serv_title = tools_check_user_input(srv_data, question, 'title', 'title')
cal = {}
cal["company_id"] = comp_id
cal["service_ids"] = serv_id
cal["days_limit"] = 30
cal["name"] = serv_title
cal_sent = tg_send_widget(platform_id, "calendar", cal, serv_title)
Блок 3. Создание бронирования
Ответ: #{none}.
Соедините Блок 2 с Блоком 3, используя условие widget_calendar_selected с Точным совпадением.
booking_date = widget_date
booking_time = widget_time
booking_result = create_booking(comp_id, serv_id, booking_date, booking_time, '')
booking_ok = booking_result['status']
Блок 4. Бронирование подтверждено
Соедините Блок 3 с Блоком 4, используя условие по переменной booking_ok == True с задержкой в одну секунду.
Ответ:
Ваша запись подтверждена: #{serv_title}, #{booking_date} в #{booking_time}. До встречи!
Блок 5. Временной слот больше не доступен
Ответ: #{none}.
Соедините Блок 3 с Блоком 5, используя условие по переменной booking_ok != True с задержкой в одну секунду.
Этот блок сбрасывает существующий календарь, позволяя клиенту выбрать другое время и отображая сообщение об ошибке.
fix = {}
fix["reset"] = 1
fix["error"] = "Этот временной слот только что забронировали. Пожалуйста, выберите другой."
t = tg_edit_widget_data(platform_id, widget_message_id, fix)
Добавьте еще одно соединение от Блока 5 к Блоку 3 с условием widget_calendar_selected.
Теперь клиент может выбрать другое время в том же календаре.
Более простой вариант: автоматическое бронирование
Добавьте следующий параметр в настройки календаря:
cal["auto_booking"] = 1
Платформа создаст бронирование сразу после выбора клиентом времени.
Если выбранный временной слот станет недоступен, виджет отобразит ошибку напрямую.
Callback widget_calendar_selected отправляется только после успешного бронирования, вместе с переменной widget_booking_id.
При таком подходе блоки 3 и 5 не требуются.
Используйте бронирование через бот-сценарий (первый подход), если вам нужна предоплата или дополнительные проверки перед подтверждением записи.
Обновление отправленного виджета
Используйте следующую функцию для обновления данных виджета:
tg_edit_widget_data(platform_id, message_id, data)
| Параметр | Описание |
|---|---|
message_id |
ID сообщения с виджетом, сохраненный при отправке или полученный из widget_message_id после взаимодействия |
data |
Словарь, содержащий новые значения |
Можно обновлять только данные виджета. Нельзя изменить макет уже отправленного виджета. Чтобы использовать другой макет, отправьте новый виджет.
Как применяются обновления:
-
Промокод, таймер, статус заказа, FAQ: новые данные полностью заменяют предыдущее обновление. Отсутствующие поля возвращаются к исходным значениям, указанным при отправке виджета. Поэтому включайте каждое поле, которое должно отличаться от исходных данных, например, и
step, иtext. - Викторина и календарь: новые данные применяются поверх текущего состояния виджета.
Специальные параметры обновления:
| Шаблон | Данные | Результат |
|---|---|---|
promo |
{"used": 1} |
Помечает промокод как использованный |
timer |
{"seconds": 600} или {"until": "…"}
|
Перезапускает обратный отсчет |
calendar |
{"reset": 1, "error": "message"} |
Очищает выбор, открывает календарь заново и отображает сообщение |
Пользовательские виджеты
Когда готовых шаблонов недостаточно — например, если нужен каталог товаров с корзиной, рейтинг звездами или калькулятор цен — вы можете создать собственный HTML-виджет.

Как это работает
- Создайте виджет как один HTML-файл, содержащий его стили и JavaScript.
- Сохраните код как файл
.txtв разделе Файлы проекта и скопируйте URL файла. Система хранения не принимает файлы.html. - Блок бота отправляет виджет, используя URL, и передает его начальные данные.
- Когда клиент взаимодействует с виджетом, бот получает callback, содержащий текст, определенный в коде виджета.
- Блок-обработчик вычисляет новые данные и отправляет их обратно в виджет, который обновляет свой интерфейс.
Отправка пользовательского виджета
tg_send_widget_file(platform_id, url, data, caption)
Пример:
st = {}
st["rating"] = 0
w = tg_send_widget_file(platform_id, "https://files.mavibot.ai/…/rating.txt", st, "Оцените ваш заказ — нажмите на звезду")
Параметр data — это словарь, содержащий начальное состояние, используемое для отрисовки виджета.
Обработка взаимодействий
Когда клиент взаимодействует с пользовательским виджетом, бот получает callback.
Также заполняются следующие переменные:
| Переменная | Значение |
|---|---|
widget_data |
Текст запроса, отправленный виджетом, например rate:4
|
widget_message_id |
ID сообщения, в котором произошло взаимодействие |
widget_query_id |
Идентификатор запроса |
Создайте обработчик с помощью блока Триггер и включите настройку Триггер только на Callback.
Условие должно соответствовать тексту запроса виджета.
Такой тип блока работает независимо от текущей позиции клиента в бот-сценарии и не перемещает его с текущего шага.
Важно: Не используйте блок Стартовое условие для обработки взаимодействий с пользовательским виджетом. Виджет остается в чате, и клиент может взаимодействовать с ним в любое время — даже во время заполнения анкеты, бронирования или оплаты. Блок Стартовое условие перенаправит клиента в обработчик и прервет его текущий шаг.
Пример обработчика рейтинга:
Условие (регулярное выражение):
^rate:[1-5]$
Калькулятор:
local a = splitter(widget_data, ":")
client.widget_rating = a[1]
st = {}
st["rating"] = client.widget_rating
t = tg_edit_widget_data(platform_id, widget_message_id, st)
Данные пользовательского виджета заменяются полностью при обновлениях. Всегда отправляйте полное состояние, а не только измененное поле.
Лимит размера данных — 1024 байта.
Храните большие статические наборы данных (например, каталоги товаров) внутри кода виджета и отправляйте только изменяющиеся значения через данные виджета.
Ответ на запрос виджета
По умолчанию виджет немедленно получает пустой ответ, а обновленные данные приходят через отдельное обновление виджета.
Если виджету нужно получать данные непосредственно в ответ на свой запрос, текст запроса должен начинаться с ?, например:
?price
В этом случае блок-обработчик должен вызвать следующую функцию в течение 15 секунд:
tg_answer_widget_query(data)
В противном случае виджет отобразит ошибку тайм-аута.
Лимит размера ответа — 1024 байта.
Требования к коду
-
Один файл: включайте стили внутри
<style>, а JavaScript внутри<script>. Внешние скрипты, таблицы стилей, шрифты и изображения загружать нельзя. Изображения должны быть встроены с помощью URLdata:или SVG. - Лимиты размера: максимум 32 КБ до сжатия и 4 КБ после сжатия.
-
Нет полей ввода: элементы
input,select,textareaиformудаляются. В качестве интерактивных элементов управления поддерживаются только элементы<button>. -
Нет сетевых запросов:
fetchи подобные API не работают. Единственный способ связаться с ботом — черезTelegramWidget.request("text"), с размером запроса от 1 до 64 байт. - Нет внутренней прокрутки: максимальная высота виджета — 600 пикселей. Все, что выходит за эти пределы, обрезается. Чтобы создать карусель, перемещайте ряд карточек, а не используйте прокрутку.
-
Доступ к элементам: используйте
document.getElementById. Доступ к элементам как к глобальным переменным на основе их ID не работает. -
Тема Telegram: используйте переменные темы Telegram, такие как
var(--tg-theme-text-color), чтобы виджет корректно отображался в светлой и темной темах. -
Данные виджета: читайте данные из
TelegramWidget.chatDataи перерисовывайте виджет при возникновении событияchatDataChanged. -
Запросы: вызывайте
requestнепосредственно внутри обработчика взаимодействия с пользователем. Разрешен только один запрос на взаимодействие.
Виджет не отображает ошибки кодирования. Неподдерживаемые элементы молча удаляются, а ошибка JavaScript может привести к пустому виджету. Всегда тестируйте виджет в Telegram после внесения изменений.
Минимальный пример пользовательского виджета
Пример ниже отображает товар, кнопку, отправляющую запрос боту, и счетчик корзины на основе данных виджета.
<style>
body{margin:0;padding:14px}
.h{color:var(--tg-theme-hint-color);font-size:.85em}
button{width:100%;margin-top:8px}
</style>
<b>Маргарита · $10</b>
<div class="h" id="c"></div>
<button id="add">В корзину</button>
<div class="h" id="e"></div>
<script>
var W=window.TelegramWidget,$=function(i){return document.getElementById(i)},busy=0;
function draw(){
var s={};
try{s=JSON.parse(W.chatData)||{}}catch(e){}
$('c').textContent='В корзине: '+(s.count||0)
}
$('add').onclick=function(){
if(busy)return;
busy=1;
$('e').textContent='';
W.request('cart_add').then(
function(){busy=0},
function(x){
busy=0;
$('e').textContent='Ошибка: '+x.code
}
)
};
W.onEvent('chatDataChanged',draw);
draw();
</script>
Mavi и виджеты
Mavi может автоматически создавать полные боты с виджетами.
Просто опишите, что вам нужно, на простом языке.
Например:
- «Когда клиент отправляет "order", покажите виджет статуса заказа с тремя этапами. Когда он отправляет "ready", переместите заказ на второй этап.»
- «Создайте сценарий бронирования услуг: клиенты выбирают услугу с помощью кнопок, затем выбирают дату и время с помощью виджета календаря.»
- «Создайте виджет рейтинга звезд для заказов и сохраните выбранный рейтинг в переменную клиента.»
Mavi автоматически настраивает готовые шаблоны.
Для пользовательских виджетов Mavi пишет и проверяет код, сохраняет файл виджета в проект и создает блоки, необходимые для отправки виджета и обработки взаимодействий с клиентом.
Справочник
Функции
| Функция | Описание |
|---|---|
tg_send_widget(platform_id, template, params, caption) |
Отправляет готовый шаблон виджета |
tg_send_widget_file(platform_id, url, data, caption) |
Отправляет пользовательский виджет из файла |
tg_edit_widget_data(platform_id, message_id, data) |
Обновляет данные в существующем виджете |
tg_answer_widget_query(data) |
Отвечает на запрос пользовательского виджета, начинающийся с ?
|
Обратные вызовы и переменные
| Событие | Обратный вызов | Переменные |
|---|---|---|
| Викторина завершена | widget_quiz_finished |
widget_quiz_score, widget_quiz_total, widget_quiz_answers
|
| Дата и время выбраны в календаре | widget_calendar_selected |
widget_date, widget_time; также widget_booking_id, если включен auto_booking
|
| Взаимодействие с пользовательским виджетом | Текст запроса, определенный в коде виджета |
widget_data, widget_message_id, widget_query_id
|
Если ваш бот содержит несколько викторин или календарей, назначьте уникальный обратный вызов каждому виджету с помощью параметра callback, чтобы различать их в условиях вашего бота.
Ограничения
- Виджеты работают только в личных чатах Telegram между клиентом и ботом.
- Для каждого клиента сохраняются только пять последних викторин и календарей. Более старые перестают реагировать на взаимодействия.
- Очистка всех переменных клиента в боте отключает ранее отправленные викторины и календари.
- Данные виджета ограничены 1024 байтами.
- Запросы от пользовательских виджетов ограничены 64 байтами.
- На запросы пользовательских виджетов, требующие
tg_answer_widget_query, необходимо ответить в течение 15 секунд.
Устранение неполадок
| Проблема | Причина / Решение |
|---|---|
Виджет не отправлен, и переменная содержит Unknown parameter…
|
Шаблон получил неподдерживаемый параметр. В сообщении об ошибке перечислены допустимые параметры |
| Календарь останавливается после выбора даты, не показывая временные слоты | Параметр slots не был предоставлен |
| После взаимодействия с виджетом бот перестает реагировать на кнопки на текущем шаге | Обработчик взаимодействия использует блок Start Condition. Замените его на Non-State Block с Condition |
| Пользовательский виджет отображается пустым | В коде виджета есть ошибка. Частая причина — обращение к элементу по его ID без использования document.getElementById
|
| Telegram отображает «Unsupported message» | Клиент использует устаревшую версию Telegram |
Bad Request: chat not found |
Виджет был отправлен вне Telegram, например, из окна тестирования бота |