Guía 02

Cómo crear un bot de Telegram: tokens, webhooks, teclados y límites

Telegram tiene la plataforma de bots más amable: API HTTP gratuita, sin proceso de revisión y funciones que van de simples comandos a aplicaciones web completas.

Guía4 min de lecturaActualizado

Crear el bot

  1. Abre un chat con @BotFather (comprueba la marca azul de verificación).
  2. Envía /newbot, elige un nombre visible y un nombre de usuario que termine en bot.
  3. BotFather responde con un token del tipo 123456789:AA.... Trátalo como una contraseña.
  4. Opcional pero recomendable: /setdescription, /setabouttext, /setuserpic y /setcommands para que la gente entienda qué hace el bot.

Prueba el token con el constructor de la API de Telegram usando el método getMe, o así:

curl -s "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/getMe"

Cómo funciona la Bot API

Cada llamada es una petición HTTPS a https://api.telegram.org/bot<token>/<método>. Las respuestas son JSON con ok y, o bien result, o bien error_code con description. Los eventos entrantes son updates: cada uno tiene un update_id creciente y un contenido como message, edited_message, callback_query, inline_query o my_chat_member.

Recibir actualizaciones: polling o webhook

El long polling con getUpdates es perfecto para desarrollar. Pasa offset como el último update_id + 1 para confirmar las anteriores, y timeout (por ejemplo 30) para que la petición espere nuevos eventos.

Los webhooks son mejores para producción. Registra una URL HTTPS una sola vez:

curl -s "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/setWebhook" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://bot.example.com/telegram","secret_token":"'"$TG_WEBHOOK_SECRET"'","allowed_updates":["message","callback_query"],"drop_pending_updates":true}'
  • Telegram envía el secret_token en la cabecera X-Telegram-Bot-Api-Secret-Token. Rechaza cualquier petición que no traiga el valor exacto.
  • Los puertos admitidos son 443, 80, 88 y 8443, con un certificado TLS válido.
  • Devuelve 200 rápido. Si respondes con error o tardas demasiado, Telegram reintenta y se acumulan actualizaciones pendientes. Revísalas con getWebhookInfo, que también muestra last_error_message.
  • No puedes usar getUpdates mientras haya un webhook configurado.

Un bot mínimo con grammY

import { Bot, InlineKeyboard } from "grammy";

const bot = new Bot(process.env.TELEGRAM_BOT_TOKEN!);

bot.command("start", (ctx) =>
  ctx.reply("¡Hola! Puedo recordarte cosas. Prueba /remind 10m estirar", {
    reply_markup: new InlineKeyboard().text("Cómo funciona", "help"),
  })
);

bot.callbackQuery("help", async (ctx) => {
  await ctx.answerCallbackQuery();             // responde siempre o el botón se queda girando
  await ctx.reply("Envía /remind <minutos>m <texto>. Usa /stop para borrar tus datos.");
});

bot.on("message:text", (ctx) => ctx.reply("Comando desconocido. Prueba /help."));
bot.catch((err) => console.error("error en manejador", err.error));
bot.start();                                   // long polling para desarrollo

La misma biblioteca funciona como webhook en Node.js, Deno o Cloudflare Workers.

Comandos, teclados y formato

  • Los comandos empiezan por /. En grupos pueden llegar como /start@tu_bot; cuando sea posible, interprétalos con la entidad bot_command en lugar de una regex.
  • Los teclados de respuesta sustituyen el teclado del usuario por botones que envían texto. Los teclados inline se adjuntan a un mensaje: los botones url abren enlaces y los callback_data (hasta 64 bytes) envían un callback_query que debes contestar con answerCallbackQuery.
  • Formato: usa parse_mode HTML o MarkdownV2. MarkdownV2 obliga a escapar caracteres como _ * [ ] ( ) ~ > # + - = | { } . !. HTML suele ser más sencillo: escapa <, > y &. El constructor de la API incluye un escapador.
  • Los mensajes admiten 4096 caracteres; los pies de foto, 1024.

Grupos, modo privacidad y permisos de administrador

Por defecto los bots tienen el modo privacidad activado en grupos: solo ven comandos, respuestas a sus propios mensajes y menciones. Es el valor correcto. Desactívalo en BotFather solo si el bot debe leer todos los mensajes (por ejemplo, para moderar) y dilo en su descripción. Comprueba permisos con getChatMember antes de ejecutar comandos de administración y autoriza por ID numérico, nunca por nombre de usuario.

Archivos, pagos y Mini Apps

  • Descarga archivos con getFile y luego https://api.telegram.org/file/bot<token>/<file_path>. Por la API en la nube los bots pueden descargar archivos de hasta 20 MB.
  • Los bienes digitales vendidos dentro de Telegram usan Telegram Stars; los físicos pueden usar proveedores de pago compatibles.
  • Las Mini Apps son páginas web que se abren dentro de Telegram. Valida siempre initData en tu servidor: calcula secret_key = HMAC_SHA256(key="WebAppData", data=bot_token), compara HMAC_SHA256(secret_key, data_check_string) con el campo hash y comprueba que auth_date sea reciente.

Límites que respetar

Telegram publica límites orientativos: evita enviar más de un mensaje por segundo al mismo chat, unos 20 mensajes por minuto al mismo grupo y alrededor de 30 mensajes por segundo en total en difusiones. Si los superas recibirás 429 Too Many Requests con parameters.retry_after; espera esos segundos. Para boletines, encola los mensajes y envíalos a ritmo constante. Consulta fiabilidad y límites de tasa.

Buen comportamiento

  • Escribe solo a usuarios que iniciaron el bot. Respeta /stop: cuando alguien bloquea el bot recibes un my_chat_member con estado kicked; borra sus datos.
  • No pidas teléfonos ni ubicaciones salvo que la función lo necesite, y explica por qué.
  • Lee los términos para desarrolladores de bots de Telegram y enlaza una política de privacidad en la descripción del bot.

Comprueba lo aprendido

1. ¿Qué cabecera lleva el secret_token del webhook de Telegram?
2. ¿Qué debes hacer tras recibir un callback_query?