Interfaz de Bot de Telegram (UI)
Habilidad portátil e independiente del SDK para el ciclo de vida completo de la interfaz de usuario de un bot de Telegram: auditoría → mapa de pantallas/estados → diseño de texto, botones y navegación → implementación → migración → pruebas → documentación.
Un bot de Telegram no tiene CSS ni motor de diseño. Toda su interfaz se compone de cinco elementos: texto del mensaje, formato, teclados, el "chrome" del chat (comandos, botón de menú, enlaces profundos) y las transiciones entre estados. Esta habilidad trata los cinco como una única superficie de diseño.
Propósito
Ayudar a un agente a hacer que la interfaz de un bot sea clara, coherente y segura de modificar: elegir lo que dice una pantalla y cómo lo dice; etiquetar, agrupar, ordenar, colorear y distribuir los botones; diseñar la navegación entre pantallas y estados; mantener cada pantalla coherente con el resto del bot; mantener la localización intacta; y renderizar los cuerpos de los mensajes con el formato más enriquecido que sea adecuado, en cualquier idioma y con cualquier SDK de Telegram, sin romper los manejadores existentes ni la lógica de negocio.
Cuándo usarla
- Trabajo de interfaz: "mejorar la UX/UI del bot", "rediseñar este menú", "el teclado está sobrecargado", "los usuarios no entienden esta pantalla", "añadir un botón de retroceso", "agrupar estas acciones", "hacer que la acción principal destaque".
- Botones y teclados: teclados en línea, teclados de respuesta, etiquetas de botones, orden y distribución de botones, colores
style,icon_custom_emoji_idemoji personalizado, botones de Web App / URL / copiar texto / cambiar a inline,ForceReply, eliminación de teclado, paginación y navegación de retroceso. - Texto y microcopia: reescribir mensajes del bot, títulos, pies de foto, avisos, confirmaciones, estados de error y vacío, tono y longitud, uso de emojis.
- Chrome del chat: lista de
/commandsy ámbitos, botón de menú,/starty enlaces profundos, experiencia de primer uso. - Comentarios dinámicos: respuestas de IA en streaming (
sendMessageDraft,sendRichMessageDraft,<tg-thinking>), barras de progreso, estados "escribiendo", cargadores de botones, "el bot se siente congelado mientras trabaja". - Personalización y enlaces: saludar a los usuarios por su nombre de forma segura, pistas de configuración regional, botones de URL frente a enlaces en línea, vistas previas de enlaces, enlaces profundos, menciones.
- Coherencia: la misma acción nombrada de tres maneras diferentes, botones de retroceso que solo existen en algunas pantallas, estados no coincidentes después de una edición.
- Renderizado de mensajes: HTML / MarkdownV2 /
MessageEntity, emoji personalizado en texto, pies de foto, tablas y Mensajes Enriquecidos, opciones de vista previa de enlace / silencioso / protegido, división de mensajes largos, borradores en streaming, edición, publicaciones de canal, localización y RTL,can't parse entities, mensajes rotos o de gran tamaño.
Cuándo NO usarla
Lógica del bot que no se manifiesta en la interfaz: infraestructura de webhook, procesamiento de pagos, autorización, bases de datos y migraciones, lógica de administración y moderación de grupos, scraping, canalizaciones de análisis, internos de Mini App (su propia UI HTML/CSS es trabajo de front-end web normal — esta habilidad cubre solo la superficie del lado de Telegram: el botón o menú que la abre). Tampoco para archivos .rtf de Microsoft.
Terminología — no confundir estos términos
- Teclado en línea ≠ teclado de respuesta.
InlineKeyboardMarkupestá asociado a un mensaje específico y envíacallback_query/ abre URLs.ReplyKeyboardMarkupreemplaza el teclado de letras del usuario y envía texto como un mensaje normal. Diferentes clases de botones, diferente UX. styleno es un valor de color. Es uno de exactamenteprimary,success,danger. Telegram no tiene colores de botón HEX/RGB/CSS.icon_custom_emoji_idno es unfile_id, no es un nombre de paquete de emojis, no es un enlace y no es un emoji Unicode. Es el ID de un emoji personalizado específico.- Texto enriquecido de Telegram NO es RTF de Microsoft. Nunca llames "RTF" a los Mensajes Enriquecidos.
- Markdown enriquecido ≠ MarkdownV2. MarkdownV2 es un
parse_modepara mensajes normales con escape estricto. Markdown enriquecido es la sintaxis de documento para Mensajes Enriquecidos. - HTML enriquecido ≠ HTML de navegador arbitrario. Solo el conjunto de etiquetas admitido por Telegram.
- Editar un teclado ≠ reenviar una pantalla.
editMessageReplyMarkupyeditMessageTextactualizan en el lugar; enviar un nuevo mensaje apila pantallas.
Política de fuente de verdad
Confiar en este orden:
- Documentación oficial actual de Telegram (API de Bot, Funciones de Bot, páginas de formato, blog oficial).
- Registro de cambios oficial de la API de Bot.
- Documentación del SDK realmente instalado en el proyecto.
- Código fuente del SDK.
- Rastreador de incidencias del SDK.
- Artículos de terceros: solo contexto complementario.
Verificar nuevamente la documentación oficial antes de actuar cuando: la tarea toca nuevas API; hoy es posterior a la fecha de "última verificación" en references/official-sources.md; se desconoce la versión de la API de Bot del proyecto; la documentación del SDK contradice la API de Bot; te encuentras con un tipo/campo desconocido; o el usuario solicita "las últimas capacidades".
Esta habilidad no está congelada en la API de Bot 10.2 — si Telegram lanzó una versión más nueva, úsala. Compuertas de versión relevantes para la UI: references/ui-changelog.md.
Flujo de trabajo principal (auditar antes de rediseñar)
- Leer las instrucciones del proyecto (
AGENTS.md/CLAUDE.md/ README / docs). - Detectar idioma, framework, SDK de Telegram y versiones exactas.
- Determinar la versión de la API de Bot que el SDK realmente soporta — esto decide si
styleeicon_custom_emoji_idson alcanzables. - Construir un mapa de pantallas/estados: cada mensaje que el usuario puede ver, cada teclado, cada
callback_data, cada comando, cada transición (references/navigation-and-flows.md). - Clasificar cada pantalla: entrada / menú / paso de formulario / confirmación / resultado / error / vacía / notificación.
- Identificar los defectos UX reales (no inventar trabajo): etiquetas ambiguas, teclados sobrecargados, callejones sin salida sin forma de retroceder, nombres inconsistentes, acciones destructivas a un solo toque, cadenas sin localizar, cuerpos ilegibles.
- Diseñar la corrección: texto primero, luego estructura, luego distribución, luego color/emoji — en ese orden. El color es la última capa, nunca la solución para una mala etiqueta.
- Verificar la compatibilidad del SDK para cada campo que planeas usar (
references/sdk-compatibility.md). - Implementar en el estilo y utilidades existentes del proyecto (no duplicar sus constructores de teclado).
- Preservar
callback_data, URLs, enlaces profundos, enrutamiento de manejadores y claves de localización a menos que el usuario solicite explícitamente cambiarlos. - Añadir una ruta de reserva y mantener los clientes antiguos utilizables (
references/errors-and-fallbacks.md). - Añadir pruebas con la infraestructura de pruebas existente del proyecto (
references/testing-playbook.md). - Ejecutar el linteo / verificación de tipos / pruebas / comprobaciones de humo aplicables del proyecto.
- Informar: mapa de pantallas, qué cambió y por qué, qué se dejó deliberadamente intacto, límites y evidencia de verificación.
No escribir código de implementación antes de que los pasos 1–6 estén completos.
Las cinco capas de UI (diseñar en este orden)
| # | Capa | Pregunta que responde | Referencia |
|---|---|---|---|
| 1 | Palabras | ¿El usuario entiende qué es esto y qué sucederá después? | references/microcopy-and-labels.md |
| 2 | Estructura | ¿Qué acciones existen, cómo se agrupan y ordenan? | references/inline-keyboards.md, references/reply-keyboards.md |
| 3 | Navegación | ¿Cómo llego aquí, hacia atrás y salgo? ¿En qué estado estoy? | references/navigation-and-flows.md |
| 4 | Renderizado del cuerpo | ¿El contenido es legible — tabla, lista, encabezados, plano? | references/format-selection.md, references/tables.md |
| 5 | Énfasis | ¿Cuál es la acción aquí? ¿Qué es peligroso? | references/buttons-and-styles.md, references/custom-emoji.md |
Una pantalla que falla en la capa 1 no puede ser rescatada por las capas 4–5. Nunca empezar con color.
Elementos esenciales de los botones (reglas completas en references/buttons-and-styles.md)
Exactamente una acción por botón en línea. Según la API de Bot, InlineKeyboardButton requiere exactamente uno de los campos distintos de text, icon_custom_emoji_id y style (url, callback_data, web_app, login_url, switch_inline_query*, copy_text, callback_game, pay). KeyboardButton permite como máximo uno de sus campos que no sean text/icon/style.
style (API de Bot 9.4) — opcional, exactamente uno de:
style | Color | Significado | Etiquetas típicas |
|---|---|---|---|
primary | azul | La acción principal hacia adelante de la pantalla | Continuar, Iniciar, Abrir, Siguiente, Elegir |
success | verde | Comprometer / confirmar / completar positivamente | Guardar, Confirmar, Publicar, Enviar, Finalizar |
danger | rojo | Destructivo o irreversible | Eliminar, Restablecer, Cancelar suscripción, Salir, Cancelar plan |
| omitido | predeterminado de la app | Todo lo demás | Atrás, Configuración, Ayuda, opciones secundarias |
Si se omite style, se utiliza un estilo específico de la aplicación. Como máximo un primary por pantalla. danger solo para acciones genuinamente destructivas, emparejado con un paso de confirmación. Las acciones secundarias como "Atrás" normalmente permanecen sin estilo.
icon_custom_emoji_id (API de Bot 9.4) — muestra un emoji personalizado antes del texto del botón. Utilizable solo por bots que compraron nombres de usuario adicionales en Fragment, o en mensajes enviados directamente por el bot a chats privados, grupales y supergrupos cuando el propietario del bot tiene Telegram Premium. Nunca inventes un ID — obténlo (references/custom-emoji.md) o pídele al usuario que lo proporcione.
Ambos campos son decoración sobre un botón funcional: la etiqueta debe seguir teniendo sentido sin color ni icono.
Cuerpo del mensaje: el formato más enriquecido que ayude
| Necesidad | Usar |
|---|---|
| Filas/columnas o datos etiqueta→valor | Tabla — references/tables.md |
| Documento estructurado: informe, respuesta de IA, comparación, lista de verificación | Markdown enriquecido |
| Contenido generado por plantillas del servidor, control preciso de etiquetas | HTML enriquecido |
| Generación tipificada desde datos / CMS / AST | Bloques InputRichBlock |
| Una pantalla con teclado: aviso corto + opciones | HTML normal, corto |
Control exacto de desplazamiento, sin parse_mode | MessageEntity |
| Sin necesidad de estilo genuinamente | Texto plano |
Regla: los datos estructurados se convierten en una tabla real, nunca en una cuadrícula monoespaciada — pero una pantalla de menú es un aviso corto más botones, no un ensayo. Matriz completa: references/format-selection.md.
Comentarios mientras el bot trabaja
Esperar sin señal es el fallo de UX más común en los bots. Elegir según la forma de la operación (reglas completas: references/dynamic-feedback-and-streaming.md):
| Situación | Mecanismo |
|---|---|
| Botón en línea tocado | answerCallbackQuery primero, luego hacer el trabajo |
| Operación de 2–5 s | sendChatAction (typing, upload_photo, …) — máximo 5 s |
| Texto de IA generándose (chat privado) | sendMessageDraft — mismo draft_id, finalizar con sendMessage |
| Respuesta de IA con estructura | sendRichMessageDraft + <tg-thinking> → sendRichMessage |
| Etapas reales y nombrables | editMessageText, limitado |
| Progreso no medible | Etapas nombradas — nunca un porcentaje falso |
| Proceso interactivo | Mini App (BottomButton.showProgress(), WebApp.ready()) |
Nunca editar por token: actualizar cada ~800–1500 ms, ~30–80 caracteres nuevos, una oración terminada o un cambio de etapa real — y respetar retry_after. Un draft_id / message_id / operation_id por operación, finalizado exactamente una vez.
Qué referencia leer (dirigido por tarea — no leerlas todas)
UI / UX
- Etiquetas de botones, redacción de mensajes, tono, emoji en texto →
references/microcopy-and-labels.md - Colores
style, énfasis, diseño y agrupación de botones →references/buttons-and-styles.md - Teclados en línea,
callback_data, paginación, edición en el lugar →references/inline-keyboards.md - Teclados de respuesta,
ForceReply, eliminación de teclado, marcadores de posición →references/reply-keyboards.md - Pantallas, estados, atrás/inicio, comandos, botón de menú, enlaces profundos →
references/navigation-and-flows.md - Emoji personalizado en botones y texto, obtención de IDs, elegibilidad →
references/custom-emoji.md - Respuestas en streaming, bloques de pensamiento, barras de progreso, cargadores, acciones de chat →
references/dynamic-feedback-and-streaming.md - Personalización con datos de usuario, enlaces, vistas previas, enlaces profundos →
references/personalization-and-links.md - Coherencia entre pantallas + lista de verificación previa a la finalización →
references/consistency-and-review.md - Historial de la API de Bot relevante para UI y compuertas de versión →
references/ui-changelog.md - Escenarios de antes/después trabajados →
references/examples-before-after.md
Renderizado de contenido
- Tablas →
references/tables.md - Mensajes enriquecidos / bloques / matriz de capacidades →
references/telegram-capabilities.md - HTML / MarkdownV2 / entidades / pies de foto / vistas previas →
references/regular-formatting.md - Elegir un formato →
references/format-selection.md - Multimedia →
references/rich-media.md - Límites y división →
references/limits-and-splitting.md - Borradores en streaming y edición →
references/streaming-and-editing.md - Canales, notificaciones, transmisiones →
references/channels-and-broadcasting.md
Ingeniería
- Investigar un proyecto desconocido →
references/project-adaptation.md - Escape / inyección / contenido de usuario o IA →
references/security-and-escaping.md - Localización, RTL, longitud de etiquetas de botones →
references/localization-and-rtl.md - Errores, alternativas, clientes antiguos →
references/errors-and-fallbacks.md - Brechas del SDK / cargas útiles sin procesar de la API de Bot →
references/sdk-compatibility.md - Pruebas →
references/testing-playbook.md - Fuentes y fechas de última verificación →
references/official-sources.md
Validadores locales: scripts/validate_skill.py, scripts/validate_references.py, scripts/validate_keyboard.py (reglas JSON de teclado — sin conexión, sin token). Escenarios de activación: evals/activation-evals.md.
Reglas no negociables
- Preservar el comportamiento. Mantener los
callback_data, URLs, enlaces profundos, cargas útiles y enrutamiento de manejadores existentes. Un rediseño visual no debe reescribir manejadores. Si un cambio encallback_dataes inevitable, decirlo y actualizar cada manejador/ruta en el mismo cambio. - Palabras antes que píxeles. Corregir la etiqueta antes de añadir un color o un emoji.
- Sin color decorativo. Asignar
stylesegún el significado de la acción. No colorear todos los botones; un teclado completamente coloreado no tiene jerarquía. styledefine el color, no la posición. No usarstylepara indicar disposición (por ejemplo,primaryno significa "a la izquierda").dangerrequiere confirmación. Tocar un botóndangernunca debe ejecutar la acción destructiva inmediatamente; debe abrir un paso de confirmación.urlrequiere confirmación perceptible. Si el usuario es redirigido a una URL externa, el botón debe indicarlo claramente (por ejemplo, sufijo "↗" o "Abrir sitio web").callback_dataes opaco para el botón. El texto decallback_datano es legible por el usuario; la etiqueta del botón es la comunicación al usuario. Mantenercallback_dataestable a menos que se necesite migración.- Un botón, una acción. No enviar
callback_datayurlsimultáneamente; no adjuntarswitch_inline_querya un botónurl. - Cuerpos breves para pantallas con teclado. Una pantalla con teclado nunca debe contener más de 3–4 oraciones de texto de mensaje (incluyendo la descripción del estado actual). Las explicaciones largas van antes del teclado o en un mensaje separado.
- Colores de la API de Bot, no de la marca del sistema. El azul de Telegram (
primary) es el azul oficial de la marca Telegram, no "azul de enlace". No sustituirstylepor colores HEX/RGB arbitrarios. icon_custom_emoji_idsolo donde está disponible. No insertar sintaxis de emoji personalizado en mensajes enviados a canales o grupos públicos a menos que el bot tenga un nombre de usuario fragment y el contexto lo permita. Siempre comprobar primero la elegibilidad (references/custom-emoji.md).
Referencias
Todas las referencias y guías detalladas se proporcionan en el directorio references/. Los archivos correspondientes se mencionan a lo largo de este documento. Además, los validadores locales y scripts de prueba están disponibles en los directorios scripts/ y evals/. Esta habilidad se verifica para ser coherente con la API de Bot 10.2 y versiones posteriores; consulta references/ui-changelog.md para conocer las compuertas de versión específicas de UI.