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

Промокод

Есть два способа отправить виджет:

  • Готовый шаблон — одна строка в Калькуляторе. Макет и функциональность уже реализованы.
  • Пользовательский виджет — напишите свой собственный 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

Отображает список вопросов. Клиенты могут нажать на вопрос, чтобы развернуть ответ.

Виджет 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-виджет.

Пользовательский виджет: рейтинг звездами

Как это работает

  1. Создайте виджет как один HTML-файл, содержащий его стили и JavaScript.
  2. Сохраните код как файл .txt в разделе Файлы проекта и скопируйте URL файла. Система хранения не принимает файлы .html.
  3. Блок бота отправляет виджет, используя URL, и передает его начальные данные.
  4. Когда клиент взаимодействует с виджетом, бот получает callback, содержащий текст, определенный в коде виджета.
  5. Блок-обработчик вычисляет новые данные и отправляет их обратно в виджет, который обновляет свой интерфейс.

Отправка пользовательского виджета

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>. Внешние скрипты, таблицы стилей, шрифты и изображения загружать нельзя. Изображения должны быть встроены с помощью URL data: или 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, например, из окна тестирования бота