Los widgets en los mensajes de Telegram han obtenido un canal de comunicación inverso con el bot. En las versiones beta de Telegram para macOS 13.1.0 del 26 de octubre, el script del widget incorporó la llamada request(): al tocar, envía hasta 64 bytes al bot y espera una respuesta de hasta 1.024 bytes. Sin un toque, la solicitud se envía solo en el chat privado con el bot, si el bot ha permitido tales solicitudes, mientras el widget está en pantalla y no más de una vez cada cinco segundos. Allí mismo, el widget ahora sabe quién lo abrió — ID, nombre, nombre de usuario y si tiene Premium — y en qué tipo de chat se encuentra. Los widgets se han observado en las betas de iOS, macOS y Android, pero este mecanismo solo es visible por ahora en la versión para macOS; en el esquema público de la API y en la Bot API no hay widgets.
Qué cambió entre el 25 y el 26 de octubre
La beta de macOS se distribuye a través del feed de actualizaciones; cada versión es un archivo zip con la aplicación. Para la comparación, se tomaron las versiones 13.1.0.283381 del 25 de octubre y 13.1.0.283391 del 26 de octubre.
El script del widget se comunica con el cliente a través del objeto global TelegramWidget. Su código se encuentra en el paquete WidgetSandbox dentro de la aplicación, en el archivo sandbox-bundle.js. En la versión 283381, el objeto tenía pocas funciones: devolver el tema de diseño, suscribirse a eventos, abrir un enlace y activar la vibración. En la versión 283391, se añadieron las siguientes:
| Qué | Qué hace |
|---|---|
request(data) | envía una cadena de 1 a 64 bytes al bot y devuelve su respuesta |
viewer | ID, nombre, apellido, nombre de usuario y estado Premium de quien lo ve |
chatType | tipo de chat: privado, grupo, supergrupo o canal |
chatData | datos asociados al mensaje en este chat, hasta 1.024 bytes |
publicData | datos del propio mensaje, hasta 1.024 bytes |
watchPublicData() | suscripción a los cambios de publicData |
isForward y isPreview | si es una copia reenviada y si es una vista previa de un resultado inline aún no enviado |
copyText(text) | copia hasta 256 caracteres al portapapeles |
setResizeAnchor | el borde desde el cual el widget crece al cambiar de altura — superior o inferior |
A los tres eventos anteriores — cambio de tema, activación y desactivación — se añadieron chatDataChanged y publicDataChanged.
Al mismo tiempo, se eliminó todo el contenido de demostración del paquete HTMLBubbles: trece chats de demostración, mencionados en el artículo del 13 de octubre, la carpeta ported con las tarjetas portadas, el juego multijugador voxel-clash y la carpeta widget-sandbox con ejemplos. En el paquete solo quedó la biblioteca three.js.
Cuándo puede un widget escribir al bot
Las reglas están escritas en la misma sandbox, en el texto de los errores que recibe el script y en las cadenas de la aplicación:
- la solicitud se envía desde el controlador de un toque en el widget, una llamada por cada toque;
- sin un toque — solo en el chat privado con el bot, solo si el mensaje permite solicitudes en segundo plano (el flag
background_query), solo mientras el widget está en pantalla y no más de una vez cada cinco segundos; - mientras se espera la respuesta de una solicitud anterior, no se envía una nueva;
- la vista previa de un resultado inline que aún no ha sido enviado al chat no consulta al bot;
- las solicitudes están desactivadas si el bot no las ha permitido para ese mensaje — una copia reenviada tiene un permiso separado;
- la respuesta del bot es solo texto y no más larga de 1.024 bytes, de lo contrario el script recibe el error
INVALID_ANSWER; si no responde a tiempo —TIMEOUT.
En una copia reenviada, chatData está vacío, mientras que publicData permanece.
En las cadenas de la aplicación, junto al código del mensaje-burbuja HTML, apareció la frase «A tap may send data to the bot» — «un toque puede enviar datos al bot». La versión no muestra exactamente dónde la muestra el cliente.
Qué hacer
- Los widgets solo existen en las betas por ahora, y no se pueden enviar desde bots: la Bot API no tiene un método para enviar un widget.
- Al tocar un widget, tenga en cuenta que cada toque puede convertirse en una solicitud al bot. El script ve su ID, nombre, nombre de usuario y estado Premium, y el ID ocupa hasta 16 dígitos — cabe en una solicitud de 64 bytes.
- Por sí mismo, sin un toque, el widget escribe al bot solo en el chat privado con ese bot. Para grupos y canales, la sandbox no prevé solicitudes en segundo plano.
- El widget no tiene red:
fetch,XMLHttpRequest,WebSockety los workers en la sandbox han sido reemplazados por stubs que devuelven un error. Los datos se envían al exterior a través del bot o a través de un enlace que el widget abre (openLinksolo acepta https y no más de 256 caracteres) — esto ya era así en la versión del 25 de octubre.
Cómo el servidor entregará el widget
En el binario 283391 aparecieron nombres de tipos de esquema que no estaban en el 283381. En el esquema público de la capa 232 — ni en Telegram Desktop, ni en Telegram Web A — no hay widgets, ni tampoco en la documentación de la Bot API. La estructura se deduce por los nombres, por lo tanto, lo siguiente es una interpretación, no una descripción:
botInlineMessageWidget,inputBotInlineMessageWidgeteinputBotInlineMessageWidgetId— el bot, al parecer, entrega el widget como un resultado inline, completo o por ID;inputMediaWidgetId— el widget como un adjunto de mensaje por ID;updateBotWidgetQuery,updateInlineBotWidgetQueryyupdateBotWidgetCopyQuery— solicitudes al bot desde el widget en un mensaje normal, en uno enviado a través del modo inline y, a juzgar por el nombre, en una copia reenviada; la respuesta esbotWidgetQueryAnswer;updateMessageWidgetDataywidgetPublicData— el servidor envía nuevos datos de un widget ya enviado, y en la sandbox hay un eventopublicDataChangedpara esto;- los errores del servidor
WIDGET_QUERY_NOT_ALLOWEDyWIDGET_RESPONSE_TIMEOUTparecen ser la contraparte de los errores del scriptNOT_ALLOWEDyTIMEOUT.
Las cadenas del cliente también mencionan los flags de permisos: allow_queries para el mensaje, fwd_allow_queries para sus copias reenviadas y background_query para solicitudes sin un toque. La versión no muestra exactamente qué recibe el bot junto con la solicitud — si es el ID de quien tocó, como en los botones debajo del mensaje, o no.
Qué prueban los laboratorios en el código abierto
En el repositorio abierto del cliente, el motor de widgets está conectado como un submódulo twidget; al hacer clic en el enlace del submódulo, GitHub responde con un 404 — el repositorio está cerrado o eliminado. Cerca se encuentran los laboratorios de referencia, y en la carpeta tools/perflab/TwidgetLab/widgets/attack hay 28 widgets que intentan actuar sin un toque real. Dieciséis de ellos envían datos al bot: por temporizador cada 50 ms, con un clic sintético, con una llamada retrasada después de un clic, a través de una etiqueta de campo de formulario (label), arrastrando y soltando. Doce intentan abrir un enlace o salir de la página sin un toque — con un enlace sobre un botón, enviando un formulario, o con una actualización automática de la página. La carpeta apareció en el repositorio con el commit del 23 de octubre, tres días antes de la versión con request().
En estos laboratorios, el envío todavía se llama TelegramWidget.sendMessage. En la versión 283391 no existe tal llamada — hay request(), y el script recibe una llamada fuera de un toque como un error con la razón no-activation.
Qué más había en los ejemplos eliminados
En la carpeta widget-sandbox de la versión 283381, había dos conjuntos de 20 widgets — with-profile y without-profile. Los nombres de los archivos eran solicitudes: «show me a mortgage calculator», «make a bar chart of the top 6 programming…», «create a pomodoro timer», «create a flashcard widget for 8 Spanish…». El objeto TelegramWidget se menciona en 12 archivos del primer conjunto y en ninguno del segundo. Esto parece indicar widgets generados por un modelo a partir de las mismas solicitudes con y sin una descripción de las capacidades de la sandbox — esta es una inferencia basada en el contenido, la versión en sí no lo especifica. La palabra profile también está en el objeto TelegramWidget: la propiedad profile es igual a 1, y isProfileAtLeast() verifica el nivel.
El resto de la carpeta contenía pruebas de compatibilidad (Chart.js, D3, three.js, WebGL, formularios, arrastrar y soltar, localStorage), tarjetas para escaparates por temas como «compras», «trabajo», «vida», «viajes» y pruebas de estrés.
Dónde más hay widgets
Los widgets en los mensajes como formato de la próxima actualización 13.2 se describieron el 25 de octubre. Cómo el widget se comunica con el bot, qué ve sobre el espectador y dónde están los límites de las solicitudes, no se mencionaba en esa descripción.




