|
| 1 | +# Implementación: Coordinador Bot-Chatwoot |
| 2 | + |
| 3 | +**Rama:** `coordinador-bot-chat` |
| 4 | +**Base:** `main` (tag `2.3.7`) |
| 5 | +**Fecha:** 2025-02-15 |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## Resumen |
| 10 | + |
| 11 | +Se implementó una capa de coordinación configurable entre los chatbots (Typebot, OpenAI, Dify, etc.) y Chatwoot en Evolution API. El objetivo es gestionar automáticamente el ciclo de vida de las conversaciones: cuándo el bot debe responder, cuándo debe pausarse, y cuándo debe resolver la conversación. |
| 12 | + |
| 13 | +--- |
| 14 | + |
| 15 | +## Commits (5) |
| 16 | + |
| 17 | +| # | Hash | Tipo | Descripción | |
| 18 | +|---|------|------|-------------| |
| 19 | +| 1 | `7ed6a67e` | fix(meta) | Normalizar orden de ejecución Chatwoot-first en Meta Business API + fix bug chatwootIds | |
| 20 | +| 2 | `fb601198` | feat(chatbot) | Coordination layer: ChatbotChatwootService, agent check, auto-pause, auto-resolve | |
| 21 | +| 3 | `9b38f47e` | feat(chatbot) | Endpoint REST `/chatbot/manage` (transfer_human, resolve_bot, pause_bot, resume_bot) | |
| 22 | +| 4 | `1cfeafcc` | feat(chatbot) | Coordinación configurable: env vars globales + override per-instance | |
| 23 | +| 5 | `197a3a45` | docs | Documentación completa de la coordinación y configuración | |
| 24 | + |
| 25 | +--- |
| 26 | + |
| 27 | +## Archivos creados (nuevos, no existen en upstream) |
| 28 | + |
| 29 | +| Archivo | Propósito | |
| 30 | +|---------|-----------| |
| 31 | +| `src/api/integrations/chatbot/chatbot-chatwoot.service.ts` | Servicio de coordinación. Métodos: `hasHumanAgentAssigned`, `getCoordinationConfig`, `pauseBotSessionsForJid`, `updateChatwootConversationStatus`, `transferToHuman`, `resolveBot`, `resumeBot`, `pauseBot` | |
| 32 | +| `src/api/integrations/chatbot/manage/dto/chatbot-manage.dto.ts` | DTO para acciones de gestión | |
| 33 | +| `src/api/integrations/chatbot/manage/controllers/chatbot-manage.controller.ts` | Controller REST para acciones de gestión | |
| 34 | +| `src/api/integrations/chatbot/manage/validate/chatbot-manage.schema.ts` | JSONSchema7 para validación de requests | |
| 35 | +| `src/api/integrations/chatbot/manage/routes/chatbot-manage.router.ts` | Router con POST `/action` y GET `/status` | |
| 36 | +| `prisma/postgresql-migrations/20250215120000_.../migration.sql` | Migración PostgreSQL: campo `coordinationSettings` | |
| 37 | +| `prisma/mysql-migrations/20250215120000_.../migration.sql` | Migración MySQL: campo `coordinationSettings` | |
| 38 | +| `docs/coordinacion-typebot-chatwoot.md` | Documentación técnica detallada | |
| 39 | +| `docs/cosas-pendietnes.md` | Lista de pendientes actualizada | |
| 40 | + |
| 41 | +--- |
| 42 | + |
| 43 | +## Archivos modificados (vs upstream) |
| 44 | + |
| 45 | +### 1. `src/api/integrations/channel/meta/whatsapp.business.service.ts` |
| 46 | +**Cambio:** Normalizar orden de ejecución para que Chatwoot procese antes que el bot (igual que Baileys). |
| 47 | +**Bug fix:** `chatwootInboxId` y `chatwootConversationId` usaban `.id` en vez de `.inbox_id` y `.conversation_id`. |
| 48 | +**Impacto:** El bot ahora tiene acceso al `chatwootConversationId` para verificar agentes. |
| 49 | + |
| 50 | +### 2. `src/api/integrations/chatbot/base-chatbot.controller.ts` |
| 51 | +**Cambio:** Capa de coordinación en `emit()`. |
| 52 | +- Lazy getter `getChatbotChatwootService()` via `require()` para evitar dependencia circular |
| 53 | +- Verifica si hay agente humano asignado antes de activar el bot (respeta `checkAgent` config) |
| 54 | +- Si hay agente → pausa la sesión del bot y retorna sin procesar |
| 55 | +- Debug logging extensivo en todo el flujo de `emit()` |
| 56 | +- Session lifecycle: sesiones cerradas se nullifican para crear nuevas conversaciones |
| 57 | + |
| 58 | +### 3. `src/api/integrations/chatbot/chatbot.controller.ts` |
| 59 | +**Cambio:** `chatbotChatwootService` agregado como propiedad pública y parámetro opcional del constructor. |
| 60 | + |
| 61 | +### 4. `src/api/integrations/chatbot/chatwoot/services/chatwoot.service.ts` |
| 62 | +**Cambio:** Auto-pausa de bot sessions en `receiveWebhook()`. |
| 63 | +- Cuando se detecta un mensaje outgoing (agente responde desde Chatwoot), se pausan todas las sessions activas del bot para ese `remoteJid` |
| 64 | +- Respeta `autoPause` config (global env var + per-instance override) |
| 65 | + |
| 66 | +### 5. `src/api/integrations/chatbot/typebot/services/typebot.service.ts` |
| 67 | +**Cambio:** Auto-resolución de conversación Chatwoot al terminar flujo. |
| 68 | +- Cuando `input === null` (flujo Typebot terminó), resuelve la conversación en Chatwoot |
| 69 | +- Nuevo método `resolveChatwootConversation()` que busca el conversationId en mensajes recientes |
| 70 | +- Respeta `autoResolve` config (global env var + per-instance override) |
| 71 | + |
| 72 | +### 6. `src/api/server.module.ts` |
| 73 | +**Cambio:** Registra `ChatbotChatwootService` y `ChatbotManageController`, los exporta para uso global. |
| 74 | + |
| 75 | +### 7. `src/api/integrations/chatbot/chatbot.router.ts` |
| 76 | +**Cambio:** Agrega ruta `/manage` con `ChatbotManageRouter`. |
| 77 | + |
| 78 | +### 8. `src/api/integrations/chatbot/chatbot.schema.ts` |
| 79 | +**Cambio:** Exporta `chatbotManageSchema`. |
| 80 | + |
| 81 | +### 9. `src/config/env.config.ts` |
| 82 | +**Cambio:** Agrega tipo `ChatbotCoordination` y sección `CHATBOT_COORDINATION` con 4 env vars. |
| 83 | + |
| 84 | +### 10. `prisma/postgresql-schema.prisma` y `prisma/mysql-schema.prisma` |
| 85 | +**Cambio:** Agrega campo `coordinationSettings Json?` al modelo `Chatwoot`. |
| 86 | + |
| 87 | +--- |
| 88 | + |
| 89 | +## Configuración |
| 90 | + |
| 91 | +### Variables de entorno (defaults globales) |
| 92 | + |
| 93 | +```bash |
| 94 | +# Todos los defaults son true (coordinación completa activada) |
| 95 | +CHATBOT_COORDINATION_CHECK_AGENT=true # Verificar agente antes de bot |
| 96 | +CHATBOT_COORDINATION_AUTO_PAUSE=true # Pausar bot cuando agente responde |
| 97 | +CHATBOT_COORDINATION_AUTO_RESOLVE=true # Resolver Chatwoot al terminar flujo |
| 98 | +CHATBOT_COORDINATION_MANAGE_ENABLED=true # Habilitar /chatbot/manage |
| 99 | +``` |
| 100 | + |
| 101 | +### Override per-instance (campo JSON en DB) |
| 102 | + |
| 103 | +```sql |
| 104 | +-- Desactivar checkAgent para una instancia |
| 105 | +UPDATE "Chatwoot" SET "coordinationSettings" = '{"checkAgent": false}' |
| 106 | +WHERE "instanceId" = 'id-de-la-instancia'; |
| 107 | +``` |
| 108 | + |
| 109 | +### Presets de escenarios |
| 110 | + |
| 111 | +| Escenario | checkAgent | autoPause | autoResolve | manageEnabled | |
| 112 | +|-----------|-----------|-----------|-------------|---------------| |
| 113 | +| **A: Coordinación completa** | `true` | `true` | `true` | `true` | |
| 114 | +| **B: Bot + derivación manual** | `false` | `true` | `false` | `true` | |
| 115 | +| **C: Sin coordinación** | `false` | `false` | `false` | `false` | |
| 116 | +| **D: Coexistencia** | `false` | `false` | `false` | `true` | |
| 117 | + |
| 118 | +--- |
| 119 | + |
| 120 | +## Endpoints nuevos |
| 121 | + |
| 122 | +### POST `/chatbot/manage/action/{instanceName}` |
| 123 | + |
| 124 | +```json |
| 125 | +{ |
| 126 | + "action": "transfer_human", |
| 127 | + "remoteJid": "5491155551234@s.whatsapp.net", |
| 128 | + "assigneeId": 42, |
| 129 | + "teamId": 5 |
| 130 | +} |
| 131 | +``` |
| 132 | + |
| 133 | +Acciones disponibles: `transfer_human`, `resolve_bot`, `pause_bot`, `resume_bot` |
| 134 | + |
| 135 | +### GET `/chatbot/manage/status/{instanceName}` |
| 136 | + |
| 137 | +Devuelve la configuración de coordinación actual (merge global + per-instance): |
| 138 | + |
| 139 | +```json |
| 140 | +{ |
| 141 | + "status": "ok", |
| 142 | + "integration": "chatbot-chatwoot-coordination", |
| 143 | + "instance": "mi-instancia", |
| 144 | + "coordination": { |
| 145 | + "checkAgent": true, |
| 146 | + "autoPause": true, |
| 147 | + "autoResolve": true, |
| 148 | + "manageEnabled": true |
| 149 | + } |
| 150 | +} |
| 151 | +``` |
| 152 | + |
| 153 | +--- |
| 154 | + |
| 155 | +## Flujo de coordinación |
| 156 | + |
| 157 | +``` |
| 158 | +Mensaje WhatsApp llega |
| 159 | + ↓ |
| 160 | +Canal (Baileys/Meta) procesa |
| 161 | + ↓ |
| 162 | +Chatwoot recibe mensaje (SIEMPRE, si habilitado) |
| 163 | + → Crea conversación / agrega mensaje |
| 164 | + → Devuelve chatwootConversationId |
| 165 | + ↓ |
| 166 | +Bot emit() se ejecuta |
| 167 | + → [checkAgent=true] Verifica agente en Chatwoot API |
| 168 | + → Si hay agente → pausa session → NO procesa |
| 169 | + → Si no hay agente → continúa |
| 170 | + → Bot procesa mensaje normalmente |
| 171 | + ↓ |
| 172 | +Si flujo bot termina (input=null): |
| 173 | + → [autoResolve=true] Resuelve conversación Chatwoot |
| 174 | + ↓ |
| 175 | +Si agente responde desde Chatwoot: |
| 176 | + → [autoPause=true] Pausa sessions activas del bot |
| 177 | + ↓ |
| 178 | +Typebot HTTP Request block puede llamar: |
| 179 | + → [manageEnabled=true] /chatbot/manage/action |
| 180 | + → transfer_human, resolve_bot, pause_bot, resume_bot |
| 181 | +``` |
| 182 | + |
| 183 | +--- |
| 184 | + |
| 185 | +## Requisitos para deploy |
| 186 | + |
| 187 | +1. **Migración DB:** |
| 188 | + ```sql |
| 189 | + -- PostgreSQL |
| 190 | + ALTER TABLE "Chatwoot" ADD COLUMN "coordinationSettings" JSONB; |
| 191 | + -- MySQL |
| 192 | + ALTER TABLE `Chatwoot` ADD COLUMN `coordinationSettings` JSON NULL; |
| 193 | + ``` |
| 194 | + |
| 195 | +2. **Build:** `npm run build` |
| 196 | + |
| 197 | +3. **Env vars:** Opcionales. Sin setear = coordinación completa (Escenario A). |
| 198 | + |
| 199 | +4. **Configuración recomendada de Chatwoot (instancia):** |
| 200 | + - `reopenConversation: false` |
| 201 | + - `conversationPending: true` |
| 202 | + |
| 203 | +5. **Configuración recomendada de Typebot (bot):** |
| 204 | + - `keepOpen: false` |
| 205 | + - `expire: 30` |
| 206 | + - `stopBotFromMe: true` |
0 commit comments