La forma de un bot escalable
plataforma --> ingreso (verificar, encolar, 200 OK) --> cola --> workers --> cola de salida --> emisor (con límite) --> API de la plataforma
- El ingreso verifica la firma, registra el ID del evento, lo encola y devuelve 200 en milisegundos. Las plataformas tienen tiempos de espera cortos (por ejemplo, unos 3 segundos para interacciones de Discord y eventos de Slack).
- Los workers ejecutan tu lógica y pueden llamar a bases de datos, LLMs y otras APIs.
- El emisor es el único componente que habla con los endpoints de envío, así puede aplicar los límites de tasa de forma centralizada.
Elegir una cola
| Opción | Notas |
|---|---|
Tabla de base de datos con SKIP LOCKED |
Sencilla y transaccional; suficiente para volúmenes moderados en PostgreSQL |
| Streams o listas de Redis (BullMQ, RQ, Celery con Redis) | Popular y rápida; requiere configurar la persistencia |
| RabbitMQ, NATS, Kafka | Más rendimiento y enrutado, más que operar |
| Colas gestionadas (de tu proveedor cloud, Cloudflare Queues) | Menos operación, límites propios del proveedor |
Elijas lo que elijas: la entrega al menos una vez implica duplicados, así que los handlers deben ser idempotentes. Configura reintentos con backoff y una cola de fallidos para los mensajes que fallan una y otra vez.
Orden
Los usuarios esperan respuestas en orden. Particiona el trabajo por ID de chat (una clave por chat en Kafka, grupos por chat en BullMQ o un bloqueo por chat) para que los eventos de un chat se procesen en secuencia mientras los distintos chats van en paralelo.
Difusiones
Enviar un mensaje a muchas personas es una tarea por lotes: crea una tarea por destinatario, limita al máximo de la plataforma con margen, registra el estado por destinatario, omite a quien bloqueó el bot (Telegram devuelve 403) y hazla reanudable. Estima la duración con el comparador de límites de tasa.
Bots con gateway
Los bots de Discord con gateway deben usar sharding al alcanzar el umbral de servidores (actualmente 2.500 servidores por shard); los bots grandes reparten los shards entre procesos o máquinas. Los bots de Telegram con polling no escalan añadiendo más consultores; cambia a webhooks tras un balanceador.
Qué medir
- Latencia: tiempo desde el evento hasta la respuesta enviada (p50, p95, p99).
- Errores: excepciones en handlers y llamadas fallidas, por tipo.
- Profundidad de la cola y antigüedad del mensaje más viejo.
- Respuestas 429 y número de reintentos, por ruta.
- Señales de negocio: chats activos, comandos usados, flujos completados, tokens y coste de LLM.
Logs y trazas
- Registra JSON con un ID de correlación por update, el ID de chat (o un hash), el handler y la duración. Oculta tokens y contenido de mensajes; la biblioteca de regex tiene un patrón para prefijos comunes de secretos.
- Usa trazas de OpenTelemetry entre ingreso, worker y emisor para ver dónde se va el tiempo.
Salud y alertas
- Expón
/healthz(proceso vivo) y/readyz(dependencias accesibles). - En webhooks de Telegram,
getWebhookInfoinforma depending_update_countylast_error_message. Consúltalo y alerta cuando se acumulen updates. - Alerta por síntomas que notan los usuarios (latencia, tasa de errores, antigüedad de la cola), no por cada excepción. Cada alerta debe decir qué revisar primero.
- Ejecuta una comprobación sintética: una cuenta de prueba envía un comando cada pocos minutos y espera respuesta.