👂 Bot Listener
Archivo: agentes/supervisores/bot-listener.ts · Plist: com.rifai.bot-listener (solo cargado en ~/Library/LaunchAgents, no versionado en cron/) · Horario: cada 30 s (StartInterval 30) + RunAtLoad
Qué hace
Es el cerebro conversacional de los bots especializados de Telegram. Cada 30 s consulta los mensajes nuevos del CEO en los 8 bots de área (Maya/Meta, Sergio/SEO, Sofía/Social, Cristina/CS, Mario/Creative, Fernando/Finanzas, Oscar/Ops, Iván/Intel) y responde con la persona de cada uno, inyectando datos reales (Shopify/Meta/GLS/Notion) y contexto del Brain. Cada bot solo contesta de su área y deriva el resto. El bot CEOSEC (Sec) NO se gestiona aquí — lo lleva en exclusiva bot-telegram.ts/router-central para no pisar el getUpdates del mismo token.
Cómo funciona
1. Carga estado (data/bot-listener-state.json) con offsets de getUpdates e historial.
2. Por cada bot con token: hace getUpdates(offset); ignora mensajes que no sean del TELEGRAM_CHAT_ID del CEO; responde a /start con un saludo de la persona.
3. Detecta qué datos en tiempo real necesita el mensaje con tools/realtime-data.ts (detectDataNeeded + fetchAllNeeded), filtrando por un allowlist por bot (finance/meta/ops solo ven sus propios fetches).
4. Construye contexto del Brain (brain/tools/brain.ts: getCorporateIdentity + getContext por dominio).
5. Empaqueta los datos como bloque [DATOS REALES TIEMPO REAL] y llama al modelo local tools/gemini-cli (--model haiku) con el system-prompt de la persona.
6. Envía la respuesta por la API de Telegram con el token del bot correspondiente y guarda el historial (máx 500).
7. Caso Sec (domain==='secretary', no activo en la lista actual de BOTS): detecta intención secretarial, deriva a otra área sin gastar tokens, o consulta/crea tareas Notion + eventos Google Calendar vía tools/secretary-data.ts.
Datos/APIs
- Telegram:
getUpdates/sendMessagedirectos por token. Vars.env:TELEGRAM_META_TOKEN,TELEGRAM_SEO_TOKEN,TELEGRAM_SOCIAL_TOKEN,TELEGRAM_CS_TOKEN,TELEGRAM_CREATIVE_TOKEN,TELEGRAM_FINANCE_TOKEN,TELEGRAM_OPS_TOKEN,TELEGRAM_INTEL_TOKEN,TELEGRAM_CHAT_ID. - LLM local: binario
tools/gemini-cli(modelo haiku) víaspawnSync. - Datos reales:
tools/realtime-data.ts→ Shopify, Meta, GLS según el área.tools/secretary-data.ts→ Notion + Google Calendar (para el caso Sec). - Brain:
brain/tools/brain.ts(identidad corporativa + retrieval por dominio).
Cómo probarlo
cd /Users/user/rifai-agents && npx tsx agentes/supervisores/bot-listener.ts
Esperar: 👂 Bot Listener … y 📊 N respuestas enviadas en este ciclo. ⚠️ Lee getUpdates real: si lo ejecutas a mano consumes los mensajes pendientes (avanzas el offset) para el daemon. Hazlo solo si el cron está parado, para no pisar offsets.
Si se rompe / recuperar
launchctl unload ~/Library/LaunchAgents/com.rifai.bot-listener.plist && launchctl load ~/Library/LaunchAgents/com.rifai.bot-listener.plist
Logs: /Users/user/rifai-agents/logs/bot-listener.log (+ .out.log/.err.log).
INVARIANTE crítica: un único consumidor de getUpdates por token. Si este listener leyera el token ceosec (TELEGRAM_BOT_TOKEN) a la vez que bot-telegram.ts, Sec dejaría de responder a ratos. Verificar tokens antes de tocar.
Cómo replicarlo
Tabla de personas (token + persona + role + domain), loop de getUpdates con offsets persistidos, filtro por chat_id del CEO, detección de datos por dominio con allowlist, fetch en paralelo de datos reales, construcción de contexto Brain, generación con LLM local haiku y envío con el token de cada bot. Estado en JSON. Mantener Sec FUERA de este loop.