Un widget es un componente interactivo integrado directamente en un mensaje del bot: un código promocional con un botón de copiar, un temporizador de cuenta regresiva, un rastreador de estado de pedido, un cuestionario o un calendario para seleccionar fecha y hora. Cuando un cliente interactúa con un widget, el bot actualiza el mismo mensaje en su lugar, sin enviar nuevos mensajes ni mostrar una etiqueta de "editado".

Código promocional

Hay dos formas de enviar un widget:

  • Plantilla lista para usar — una sola línea en la Calculadora. El diseño y la funcionalidad ya están implementados.
  • Widget personalizado — escribe tu propio código HTML (o pide a Mavi que lo cree) y procesa las interacciones usando bloques de flujo del bot.

Dónde funcionan los widgets

Mensajero Solo Telegram
Tipo de chat Solo chats privados entre un cliente y un bot
No compatible Grupos, canales, Telegram Business
Aplicación de Telegram Requiere una versión reciente de Telegram. Las versiones anteriores muestran un aviso de "Mensaje no compatible" y el subtítulo
Reenvío Los widgets no se pueden reenviar ni copiar

Los widgets no admiten campos de entrada de texto ni teclados. Los clientes solo pueden interactuar tocando. Si necesitas que los clientes ingresen texto, usa una pregunta normal del bot o una Web App.

Los widgets no se muestran en la ventana de prueba del bot en el panel de control porque no es Telegram. Prueba los widgets directamente en Telegram enviando un mensaje a tu bot.


Plantillas listas para usar

Todas las plantillas se envían usando una sola función:

tg_send_widget(platform_id, template, params, caption)
Parámetro Descripción
platform_id ID del destinatario. Para el cliente actual, usa la variable platform_id
template Nombre de la plantilla: promo, timer, order_status, faq, quiz, calendar
params Diccionario que contiene la configuración de la plantilla
caption Texto que se muestra debajo del widget. Los clientes también lo ven en su lista de chats, notificaciones y versiones anteriores de Telegram, por lo que debe ser significativo por sí solo

La función devuelve la respuesta de la API de Telegram. El ID del mensaje enviado está disponible en response['result']['message_id']. Guárdalo si planeas actualizar el widget más tarde.

Si la función devuelve texto en lugar de una respuesta de Telegram, ha ocurrido un error: una plantilla desconocida, un parámetro no válido o faltante, o un widget que excede el límite de tamaño. El texto del error explica qué salió mal.

Cómo construir parámetros

Crea un diccionario y asigna cada parámetro en una línea separada:

p = {}
p["code"] = "WIDGET10"
p["title"] = "Tu código promocional"
p["note"] = "10% de descuento en cualquier pedido"
w = tg_send_widget(platform_id, "promo", p, "Tu código promocional WIDGET10 — 10% de descuento")

Ingresa el código en el campo Calculadora del bloque. La captura de pantalla muestra un bloque de Condición de inicio que envía un widget de estado de pedido cuando el cliente envía la frase "widget de pedido".

Widget en el constructor de bots

En el bloque que envía el widget, normalmente establecerías el campo de respuesta a #{none}. El bloque no envía un mensaje de texto separado porque el subtítulo del widget sirve como texto del mensaje.

Idioma

Las plantillas incluyen texto de interfaz integrado, como etiquetas de botones, nombres de meses y días de la semana, "Se acabó el tiempo" y otros mensajes.

El idioma predeterminado en Mavibot es inglés (en).

Para usar otro idioma, especifica el parámetro lang:

p["lang"] = "es"

Idiomas compatibles:

ru, en, de, es, fr, pt, tr, uk, kk, ms, th, ar.

Los textos que proporciones tú mismo — títulos, preguntas, pasos y subtítulos — se muestran exactamente como se ingresan y no se traducen automáticamente.


Código promocional — promo

Muestra un código promocional con un botón que lo copia con un toque.

Código promocional

Parámetro Descripción
code Código promocional. Obligatorio
title Texto que se muestra encima del código
note Texto que se muestra debajo del código, como una fecha de vencimiento
button Etiqueta del botón. Predeterminado: "Copiar código promocional"
used_text Texto que se muestra cuando el código se marca como usado
p = {}
p["code"] = "WIDGET10"
p["title"] = "Tu código promocional"
p["note"] = "10% de descuento en cualquier pedido"
p["button"] = "Copiar código"
w = tg_send_widget(platform_id, "promo", p, "Tu código promocional WIDGET10 — 10% de descuento")
client.promo_widget_id = w['result']['message_id']

Para marcar el código como usado, lo que tacha el código y elimina el botón:

p = {}
p["used"] = 1
t = tg_edit_widget_data(platform_id, client.promo_widget_id, p)

Temporizador de cuenta regresiva — timer

Muestra una cuenta regresiva hasta una fecha y hora especificadas.

La cuenta regresiva se ejecuta en el dispositivo del cliente. El bot no participa en la actualización del temporizador.

Temporizador de cuenta regresiva

Parámetro Descripción
until Fecha y hora objetivo en formato "DD.MM.YYYY HH:MM", usando la zona horaria del proyecto
seconds Alternativamente, el número de segundos desde el momento en que se envía el widget
title Encabezado del temporizador. Predeterminado: "La oferta termina en"
done Texto que se muestra cuando la cuenta regresiva termina
text Texto que se muestra debajo de la cuenta regresiva
button, url Etiqueta del botón y URL de destino (solo https://)
hide_button Establecer a 1 para ocultar el botón cuando la cuenta regresiva termina

Debes proporcionar until o seconds.

p = {}
p["seconds"] = 7200
p["title"] = "La oferta termina en"
p["button"] = "Visitar sitio web"
p["url"] = "https://salebot.pro"
w = tg_send_widget(platform_id, "timer", p, "La oferta termina en 2 horas")

Cuando la cuenta regresiva llega a cero, no se envía ningún mensaje ni callback al bot. Si el bot necesita realizar una acción cuando la oferta expira, usa una conexión de temporizador regular en el flujo del bot.


Estado del pedido — order_status

Muestra una lista de etapas del pedido con la etapa actual resaltada.

El bot puede actualizar la etapa en su lugar, por lo que el cliente siempre ve el mismo mensaje.

Estado del pedido: primera etapa

Parámetro Descripción
title Título del widget
steps Lista de etapas, de 1 a 12. Predeterminado: aceptado, preparando, entregado al mensajero, en camino, entregado
step Número de etapa actual, comenzando desde 1
text Texto que se muestra debajo de las etapas

Envío del widget:

p = {}
p["title"] = "Estado del pedido"
p["steps"] = ["Aceptado", "Preparando", "Entregado"]
p["step"] = 1
p["text"] = "Tu pedido ha sido aceptado y se está preparando"
w = tg_send_widget(platform_id, "order_status", p, "Tu pedido")
client.order_widget_id = w['result']['message_id']

Avanzar a la siguiente etapa desde cualquier otro bloque, como cuando cambia la etapa de un trato, un gerente envía un comando o un temporizador se activa:

p = {}
p["step"] = 2
p["text"] = "Tu pedido se está preparando y pronto será entregado al mensajero"
t = tg_edit_widget_data(platform_id, client.order_widget_id, p)

Estado del pedido: segunda etapa

El subtítulo debajo del widget no cambia cuando se actualiza la etapa. Usa un subtítulo neutral como "Tu pedido" en lugar de "Estado: Aceptado".


Preguntas frecuentes — faq

Muestra una lista de preguntas. Los clientes pueden tocar una pregunta para expandir su respuesta.

Widget de preguntas frecuentes

Parámetro Descripción
title Título del widget
items Lista de pares de preguntas y respuestas. Obligatorio
p = {}
p["title"] = "Preguntas frecuentes"
p["items"] = [["¿Cómo puedo pagar?", "Puedes pagar con tarjeta. Se enviará un enlace de pago a este chat."], ["¿Cuánto tarda la entrega?", "La entrega suele tardar 1–2 días localmente y 3–7 días a nivel nacional."], ["¿Puedo devolver un artículo?", "Sí, dentro de 14 días."]]
w = tg_send_widget(platform_id, "faq", p, "Respuestas a preguntas frecuentes")

El texto se muestra como texto plano. Las etiquetas HTML y otros marcados no se procesan.


Cuestionario y encuesta — quiz

Muestra preguntas con respuestas de opción múltiple, una pregunta a la vez.

Si se especifican respuestas correctas, el widget actúa como un cuestionario y calcula una puntuación. Sin respuestas correctas, funciona como una encuesta.

Pregunta de cuestionario

Parámetro Descripción
title Encabezado que se muestra encima de las preguntas
questions Lista de preguntas. Obligatorio
retry Establecer a 1 para mostrar un botón "Intentar de nuevo" al final
callback Texto de callback personalizado en lugar de widget_quiz_finished

Cada pregunta es un diccionario que contiene:

  • q — texto de la pregunta
  • options — opciones de respuesta
  • correct — respuesta correcta, especificada por su índice basado en 1 o texto exacto
p = {}
p["title"] = "Cuestionario: Pon a prueba tus conocimientos"
p["retry"] = 1
p["questions"] = [{"q": "¿Cuánto es 2 + 2?", "options": ["3", "4", "5"], "correct": 2}, {"q": "¿Cuál es la capital de Francia?", "options": ["Londres", "París", "Berlín"], "correct": "París"}]
w = tg_send_widget(platform_id, "quiz", p, "¡Haz este cuestionario de dos preguntas!")

Para crear una encuesta sin puntuación, omite correct en cada pregunta.

Las respuestas correctas son verificadas por la plataforma y no se envían al dispositivo del cliente.

Lo que recibe el flujo del bot

Las respuestas individuales a las preguntas no se envían a la conversación.

Cuando el cliente responde la última pregunta, el bot recibe el callback widget_quiz_finished y se completan las siguientes variables:

Variable Valor
widget_quiz_score Número de respuestas correctas; vacío para encuestas
widget_quiz_total Número total de preguntas
widget_quiz_answers Índices de las opciones seleccionadas, como [2,2]

Para procesar el resultado, crea una conexión desde el bloque que envió el cuestionario o usa un bloque de Condición de inicio con la condición widget_quiz_finished.

Ejemplo de respuesta:

Tu resultado: #{widget_quiz_score} de #{widget_quiz_total} respuestas correctas

Resultado del cuestionario y respuesta del bot


Calendario — calendar

Muestra un calendario mensual donde los clientes pueden seleccionar una fecha y luego una franja horaria.

Reemplaza múltiples páginas de botones de fecha y hora, incluida la navegación "Atrás" y "Siguiente".

Calendario: selección de fecha y hora

El calendario admite tres modos.

Fechas y horas personalizadas

Las horas disponibles siempre se pasan a través del parámetro slots.

Mismas franjas horarias todos los días — proporciona una lista de horas y un rango de fechas:

p = {}
p["title"] = "Selecciona una fecha y hora"
p["name"] = "Consulta"
p["days"] = 10
p["slots"] = ["10:00", "12:00", "15:00"]
w = tg_send_widget(platform_id, "calendar", p, "Elige una fecha y hora")

Diferentes franjas horarias para fechas específicas — proporciona un diccionario que asigne fechas a listas de horas. Las fechas disponibles se toman de las claves del diccionario:

p = {}
p["slots"] = {"20.11.2026": ["10:00", "12:00"], "21.11.2026": ["15:00"]}
w = tg_send_widget(platform_id, "calendar", p, "Elige una fecha y hora")
Parámetro Descripción
slots Horas disponibles, como una lista o un diccionario agrupado por fecha
days Número de días disponibles a partir de hoy
date_from, date_to Alternativamente, límites del rango de fechas en formato "DD.MM.YYYY"
dates Alternativamente, una lista de fechas específicas
weekdays_off Días de la semana no disponibles: 1 = lunes hasta 7 = domingo
title Sugerencia que se muestra debajo de la cuadrícula del calendario
name Nombre del artículo o servicio que se reserva; se muestra después de la selección
change Establecer a 1 para mostrar un botón "Elegir otra hora" después de la selección
callback Texto de callback personalizado en lugar de widget_calendar_selected

Solo fecha

No pase slots si el cliente solo necesita seleccionar una fecha.

p = {}
p["days"] = 45
p["weekdays_off"] = [7]
w = tg_send_widget(platform_id, "calendar", p, "Choose a date")

Reserva en línea

Proporcione una sucursal y un servicio, y el calendario recuperará automáticamente las fechas y franjas horarias disponibles del módulo Servicios.

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)
Parámetro Descripción
company_id Identificador de la sucursal
service_ids Servicio o lista de servicios
employee_id Identificador del empleado; si se omite, se utiliza cualquier empleado disponible
days_limit Número de días hacia adelante para buscar disponibilidad. Predeterminado: 14
people_count Número de plazas necesarias para un servicio grupal
auto_booking Establecer en 1 para que la plataforma cree la reserva automáticamente

Estos parámetros son los mismos que utilizan get_dates_for_booking y get_slots_for_booking.

Lo que recibe el flujo del bot

Las selecciones de fecha individuales no se envían a la conversación.

Cuando el cliente selecciona una franja horaria, o una fecha si el calendario no tiene franjas horarias, el bot recibe la devolución de llamada widget_calendar_selected y se completan las siguientes variables:

Variable Valor
widget_date Fecha seleccionada en formato DD.MM.YYYY
widget_time Hora seleccionada en formato HH:MM; vacío para calendarios de solo fecha
widget_message_id ID del mensaje que contiene el widget

Calendario: selección completada

Los formatos de fecha y hora son los mismos que aceptan create_booking y modify_booking_time.


Reserva en línea con calendario: ejemplo completo

El widget maneja la selección de fecha, las franjas horarias y la navegación, reduciendo el número de bloques de bot necesarios.

Bloque 1. Selección de servicio

Use un bloque de Condición de inicio con la condición "reservar una cita".

Respuesta: "Elija un servicio:"

Establezca el campo de botones en #{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']

Bloque 2. Calendario

Respuesta: #{none}.

Conecte el Bloque 1 al Bloque 2 usando la condición #{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)

Bloque 3. Crear reserva

Respuesta: #{none}.

Conecte el Bloque 2 al Bloque 3 usando la condición widget_calendar_selected con Coincidencia exacta.

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']

Bloque 4. Reserva confirmada

Conecte el Bloque 3 al Bloque 4 usando la condición de variable booking_ok == True con un retraso de un segundo.

Respuesta:

Su cita está confirmada: #{serv_title}, #{booking_date} a las #{booking_time}. ¡Hasta pronto!

Bloque 5. Franja horaria ya no disponible

Respuesta: #{none}.

Conecte el Bloque 3 al Bloque 5 usando la condición de variable booking_ok != True con un retraso de un segundo.

Este bloque restablece el calendario existente, permitiendo al cliente seleccionar otra hora y mostrando un mensaje de error.

fix = {}
fix["reset"] = 1
fix["error"] = "Esta franja horaria acaba de ser reservada. Por favor, elija otra."
t = tg_edit_widget_data(platform_id, widget_message_id, fix)

Añada otra conexión del Bloque 5 al Bloque 3 con la condición widget_calendar_selected.

El cliente ahora puede seleccionar otra hora en el mismo calendario.

Opción más simple: reserva automática

Añada el siguiente parámetro a la configuración del calendario:

cal["auto_booking"] = 1

La plataforma creará la reserva inmediatamente cuando el cliente seleccione una hora.

Si la franja horaria seleccionada no está disponible, el widget muestra un error directamente.

La devolución de llamada widget_calendar_selected se envía solo después de una reserva exitosa, junto con la variable widget_booking_id.

Con este enfoque, los Bloques 3 y 5 no son necesarios.

Use la reserva a través del flujo del bot (el primer enfoque) si necesita prepago o comprobaciones personalizadas antes de confirmar una cita.


Actualización de un widget enviado

Use la siguiente función para actualizar los datos del widget:

tg_edit_widget_data(platform_id, message_id, data)
Parámetro Descripción
message_id ID del mensaje del widget, guardado al enviarlo u obtenido de widget_message_id después de una interacción
data Diccionario que contiene los nuevos valores

Solo se pueden actualizar los datos del widget. No puede cambiar el diseño de un widget ya enviado. Para usar un diseño diferente, envíe un nuevo widget.

Cómo se aplican las actualizaciones:

  • Código promocional, temporizador, estado del pedido, FAQ: los nuevos datos reemplazan completamente la actualización anterior. Los campos faltantes vuelven a los valores originales proporcionados al enviar el widget. Por lo tanto, incluya cada campo que deba diferir de los datos iniciales, como tanto step como text.
  • Cuestionario y calendario: los nuevos datos se aplican sobre el estado actual del widget.

Parámetros de actualización especiales:

Plantilla Datos Resultado
promo {"used": 1} Marca el código promocional como usado
timer {"seconds": 600} o {"until": "…"} Reinicia la cuenta regresiva
calendar {"reset": 1, "error": "message"} Limpia la selección, reabre el calendario y muestra un mensaje

Widgets personalizados

Cuando las plantillas listas no son suficientes — por ejemplo, si necesita un catálogo de productos con carrito de compras, una calificación de estrellas o una calculadora de precios — puede crear un widget HTML personalizado.

Widget personalizado: calificación de estrellas

Cómo funciona

  1. Cree un widget como un único archivo HTML que contenga sus estilos y JavaScript.
  2. Guarde el código como un archivo .txt en la sección Archivos del proyecto y copie la URL del archivo. El sistema de almacenamiento no acepta archivos .html.
  3. Un bloque de bot envía el widget usando la URL y pasa sus datos iniciales.
  4. Cuando un cliente interactúa con el widget, el bot recibe una devolución de llamada que contiene el texto definido en el código del widget.
  5. Un bloque de manejo calcula los nuevos datos y los envía de vuelta al widget, que actualiza su propia interfaz.

Envío de un widget personalizado

tg_send_widget_file(platform_id, url, data, caption)

Ejemplo:

st = {}
st["rating"] = 0
w = tg_send_widget_file(platform_id, "https://files.mavibot.ai/…/rating.txt", st, "Califique su pedido — toque una estrella")

El parámetro data es un diccionario que contiene el estado inicial utilizado para renderizar el widget.

Manejo de interacciones

Cuando un cliente interactúa con un widget personalizado, el bot recibe una devolución de llamada.

También se completan las siguientes variables:

Variable Valor
widget_data Texto de solicitud enviado por el widget, como rate:4
widget_message_id ID del mensaje donde ocurrió la interacción
widget_query_id Identificador de la solicitud

Cree el manejador usando un bloque Disparador y active la configuración Disparador solo en devolución de llamada.

La condición debe coincidir con el texto de solicitud del widget.

Este tipo de bloque funciona independientemente de la posición actual del cliente en el flujo del bot y no lo mueve de su paso actual.

Importante: No use un bloque de Condición de inicio para manejar interacciones de widgets personalizados. Un widget permanece en el chat, y el cliente puede interactuar con él en cualquier momento — incluso mientras completa un cuestionario, reserva una cita o realiza un pago. Un bloque de Condición de inicio redirigiría al cliente al manejador e interrumpiría su paso actual.

Ejemplo de manejador de calificación:

Condición (expresión regular):

^rate:[1-5]$

Calculadora:

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)

Los datos del widget personalizado se reemplazan por completo durante las actualizaciones. Siempre envíe el estado completo en lugar de solo el campo cambiado.

El límite de tamaño de datos es de 1024 bytes.

Mantenga conjuntos de datos grandes y estáticos (como catálogos de productos) dentro del código del widget, y envíe solo los valores que cambian a través de los datos del widget.

Responder a una solicitud del widget

Por defecto, el widget recibe inmediatamente una respuesta vacía, y los datos actualizados llegan a través de una actualización separada del widget.

Si el widget necesita recibir datos directamente en respuesta a su solicitud, el texto de la solicitud debe comenzar con ?, por ejemplo:

?price

En este caso, el bloque manejador debe llamar a la siguiente función dentro de 15 segundos:

tg_answer_widget_query(data)

De lo contrario, el widget muestra un error de tiempo de espera.

El límite de tamaño de respuesta es de 1024 bytes.

Requisitos del código

  • Archivo único: incluya estilos dentro de <style> y JavaScript dentro de <script>. No se pueden cargar scripts externos, hojas de estilo, fuentes e imágenes. Las imágenes deben incrustarse usando URLs data: o SVG.
  • Límites de tamaño: máximo 32 KB antes de la compresión y 4 KB después de la compresión.
  • Sin campos de entrada: los elementos input, select, textarea y form se eliminan. Solo se admiten elementos <button> como controles interactivos.
  • Sin solicitudes de red: fetch y APIs similares no funcionan. La única forma de comunicarse con el bot es a través de TelegramWidget.request("text"), con un tamaño de solicitud de 1 a 64 bytes.
  • Sin desplazamiento interno: la altura máxima del widget es de 600 píxeles. Todo lo que supere eso se recorta. Para crear un carrusel, mueva una fila de tarjetas en lugar de usar desplazamiento.
  • Acceso a elementos: use document.getElementById. Acceder a elementos como variables globales basadas en sus IDs no funciona.
  • Tema de Telegram: use variables de tema de Telegram como var(--tg-theme-text-color) para que el widget se vea correcto tanto en temas claros como oscuros.
  • Datos del widget: lea los datos de TelegramWidget.chatData y vuelva a dibujar el widget cuando ocurra el evento chatDataChanged.
  • Solicitudes: llame a request directamente dentro de un manejador de interacción de usuario. Solo se permite una solicitud por interacción.

El widget no muestra errores de codificación. Los elementos no admitidos se eliminan silenciosamente, y un error de JavaScript puede resultar en un widget vacío. Siempre pruebe el widget en Telegram después de hacer cambios.

Ejemplo mínimo de widget personalizado

El ejemplo a continuación muestra un producto, un botón que envía una solicitud al bot y un contador de carrito basado en los datos del widget.

<style>
body{margin:0;padding:14px}
.h{color:var(--tg-theme-hint-color);font-size:.85em}
button{width:100%;margin-top:8px}
</style>

<b>Margherita · $10</b>
<div class="h" id="c"></div>
<button id="add">Add to cart</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='In cart: '+(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='Error: '+x.code
    }
  )
};

W.onEvent('chatDataChanged',draw);
draw();
</script>

Mavi y Widgets

Mavi puede crear flujos de bot completos con widgets automáticamente.

Simplemente describe lo que necesitas en lenguaje natural.

Por ejemplo:

  • "Cuando el cliente envíe 'order', muestra un widget de estado de pedido con tres etapas. Cuando envíe 'ready', mueve el pedido a la segunda etapa."
  • "Crea un flujo de reserva de servicios: los clientes eligen un servicio usando botones, luego seleccionan una fecha y hora usando un widget de calendario."
  • "Crea un widget de calificación con estrellas para pedidos y guarda la calificación seleccionada en una variable de cliente."

Mavi configura automáticamente plantillas listas para usar.

Para widgets personalizados, Mavi escribe y verifica el código, guarda el archivo del widget en el proyecto y crea los bloques necesarios para enviar el widget y manejar las interacciones del cliente.


Referencia

Funciones

Función Descripción
tg_send_widget(platform_id, template, params, caption) Envía una plantilla de widget lista para usar
tg_send_widget_file(platform_id, url, data, caption) Envía un widget personalizado desde un archivo
tg_edit_widget_data(platform_id, message_id, data) Actualiza datos en un widget existente
tg_answer_widget_query(data) Responde a una solicitud de widget personalizado que comienza con ?

Callbacks y Variables

Evento Callback Variables
Cuestionario completado widget_quiz_finished widget_quiz_score, widget_quiz_total, widget_quiz_answers
Fecha y hora seleccionadas en el calendario widget_calendar_selected widget_date, widget_time; también widget_booking_id cuando auto_booking está habilitado
Interacción con widget personalizado Texto de solicitud definido en el código del widget widget_data, widget_message_id, widget_query_id

Si tu bot contiene múltiples cuestionarios o calendarios, asigna un callback único a cada widget usando el parámetro callback para poder distinguirlos en las condiciones de tu flujo de bot.

Limitaciones

  • Los widgets funcionan solo en chats privados de Telegram entre un cliente y un bot.
  • Solo se conservan los cinco cuestionarios y calendarios más recientes para cada cliente. Los más antiguos dejan de responder a las interacciones.
  • Limpiar todas las variables de cliente en un flujo de bot desactiva cuestionarios y calendarios enviados previamente.
  • Los datos del widget están limitados a 1024 bytes.
  • Las solicitudes de widgets personalizados están limitadas a 64 bytes.
  • Las solicitudes de widgets personalizados que requieren tg_answer_widget_query deben responderse dentro de 15 segundos.

Solución de problemas

Problema Causa / Solución
El widget no se envía y la variable contiene Unknown parameter… La plantilla recibió un parámetro no soportado. El mensaje de error lista los parámetros permitidos
El calendario se detiene después de la selección de fecha sin mostrar franjas horarias El parámetro slots no fue proporcionado
Después de interactuar con un widget, el bot deja de responder a los botones en el paso actual El manejador de interacción usa un bloque de Condición de Inicio. Reemplázalo con un bloque No-Estado con Condición
El widget personalizado aparece vacío Hay un error en el código del widget. Una causa común es acceder a un elemento por su ID sin usar document.getElementById
Telegram muestra "Mensaje no soportado" El cliente está usando una versión desactualizada de Telegram
Bad Request: chat not found El widget fue enviado fuera de Telegram, por ejemplo desde la ventana de prueba del bot