Appearance
Arquitectura — Visión general
Impulse es una suite multi-servicio que integra WhatsApp Cloud API con un CRM operativo para ISPs. Cinco sistemas cooperan sin acoplarse fuertemente: cada uno es dueño de su dominio, se comunican por eventos Kafka (asincrónico) y HTTP + PASETO (sincrónico cuando hace falta respuesta inmediata).
Diagrama global
Rol de cada servicio
1. whatsapp-gateway (Go · Fiber · puerto 3400)
Único punto de contacto con Meta Cloud API. Responsabilidades:
- Recibir webhooks de WhatsApp (mensajes entrantes, status de entrega, reacciones).
- Enviar mensajes salientes (texto, media, templates) consumiendo
whatsapp-outbound-jobs. - Persistir todo en Mongo (
whatsapp_messages,whatsapp_conversations). - Publicar eventos de timeline a Redis para SSE en el CRM.
- Emitir el mirror a Chatwoot vía
whatsapp-crm-outbound-mirrorcuando un agente CRM responde.
Aislado por diseño: no conoce billing ni tickets. Lo único que sabe es "hay un mensaje, guárdalo y retransmítelo".
2. crm-backend/api (Go · Fiber · puerto 3000)
Núcleo operativo del ISP. Contiene:
- Dominio de contactos, contratos, alertas, comentarios, workflows.
- Worker horario de cobranza (dunning) que consulta billing y encola mensajes WhatsApp.
- Endpoint
/v1/alerts/revenue-impactque calcula pérdida económica cruzando contratos ↔ subscripciones de billing. - Handler
ChatwootBridgeque recibe webhooks de Chatwoot cuando un agente responde desde esa UI.
Es el único servicio que tiene contexto de "quién es el cliente" — los demás lo conocen por identificadores opacos (contact_id, external_contract_id, wa_id).
3. impulse-support-agents (Go · dos binarios)
Equipo de dos procesos que viven juntos:
integration-api: consume eventos de WhatsApp, los traduce a conversaciones Chatwoot, y viceversa. Provisiona agentes Chatwoot on-the-fly cuando un agente CRM envía su primer mensaje.orchestrator: agente IA (OpenAI + herramientas) que responde automáticamente si la empresa tiene el AgentBot "Asistente IA" activo. Publica respuestas a Kafka para que el integration-api las entregue.
4. Chatwoot (Rails · fork Impulse)
UI de soporte omnicanal. No se modificó el core — se usa:
- API Channel inbox per tenant (account_id=2 para Semtec).
- Platform API para crear agentes programáticamente.
- AgentBot "Asistente IA" con token propio que identifica los mensajes del orchestrator.
- Webhooks que apuntan al
ChatwootBridgedel CRM para sincronizar outbound desde Chatwoot → Meta.
5. impulse-billing (Go · Fiber · puerto 3030)
Servicio de facturación. Relevante para esta integración:
- Expone
/subscriptions/by-contract/:external_id?status=active— lo consume el CRM para calcular MRC. - Normaliza frecuencias (monthly/weekly×52/12, yearly/12, daily×365/12) → devuelve
monthly_centsuniforme. - Dunning futuro: cuando el billing detecte mora, emitirá eventos que el CRM/support-agents consumirán (hoy el worker horario del CRM hace polling).
Canales de comunicación
| Origen → Destino | Mecanismo | Propósito |
|---|---|---|
| Gateway → CRM | Kafka whatsapp-inbound-events | Mensajes entrantes para persistir en timeline |
| CRM → Gateway | Kafka whatsapp-outbound-jobs | "Envía este mensaje al cliente" |
| Gateway → IntAPI | Kafka whatsapp-crm-outbound-mirror | Reflejar outbound del CRM en Chatwoot |
| IntAPI → Orchestrator | Kafka impulse.support.messages.inbound | Delegar procesamiento IA |
| Orchestrator → IntAPI | Kafka impulse.support.messages.outbound | Respuesta IA a entregar |
| CRM ↔ Billing/Telemetry | HTTP + PASETO v2 | Consultas síncronas de datos |
| Chatwoot ↔ IntAPI | Webhooks HMAC | Bidireccional de mensajes |
| Frontend ↔ API | REST + SSE (Redis) | UI en vivo |
Por qué Kafka en el medio
Tres razones operativas:
- Back-pressure: cuando Meta throttlea, los jobs se acumulan sin perder nada ni tumbar el API.
- Fan-out: un inbound del cliente llega al CRM (para timeline) y al integration-api (para Chatwoot) leyendo el mismo topic.
- Loop prevention: los mirrors van por topics separados con
content_attributes.sourcetageado, evitando ciclos infinitos gateway↔chatwoot.
Siguiente: Componentes detallados — stack, puertos, env, DB por servicio.