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".

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".

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.

| 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.

| 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.

| 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)

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.

| 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.

| 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

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".

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 |

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
stepcomotext. - 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.

Cómo funciona
- Cree un widget como un único archivo HTML que contenga sus estilos y JavaScript.
- Guarde el código como un archivo
.txten la sección Archivos del proyecto y copie la URL del archivo. El sistema de almacenamiento no acepta archivos.html. - Un bloque de bot envía el widget usando la URL y pasa sus datos iniciales.
- 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.
- 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 URLsdata: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,textareayformse eliminan. Solo se admiten elementos<button>como controles interactivos. -
Sin solicitudes de red:
fetchy APIs similares no funcionan. La única forma de comunicarse con el bot es a través deTelegramWidget.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.chatDatay vuelva a dibujar el widget cuando ocurra el eventochatDataChanged. -
Solicitudes: llame a
requestdirectamente 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_querydeben 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 |