WhatsApp · Runbook

Runbook — WhatsApp incidents

Sesión de una empresa cae (status=logged_out)

  1. php yii whatsapp/status <empresa_id> para confirmar estado
  2. El admin debe entrar a /configuracion/canales/whatsapp y re-escanear QR
  3. Si el cliente reporta no haber recibido email: verificar views/mail/whatsapp/session-disconnected.php y empresas.admin_email

Webhook genérico devolviendo 401

  • Verificar que whatsapp_sessions.webhook_secret coincida con el secret en la URL del cliente
  • Si rotaron secret: el cliente debe actualizar la URL en su integración

Queue Bull stuck

redis-cli LLEN bull:whatsapp-sends:wait      # jobs pendientes
redis-cli LLEN bull:whatsapp-sends:failed    # jobs fallidos
pm2 logs excucha-wa                          # ver errores recientes

Si el Node está caído: pm2 restart excucha-wa.

Número baneado por WhatsApp

Síntomas: connection.update con statusCode=403 o 405. Mitigación:

  • Reducir daily_cap de la empresa (UPDATE whatsapp_sessions SET daily_cap=100 WHERE empresa_id=X)
  • Documentar al cliente que pruebe con otro número
  • Largo plazo: considerar migrar al WhatsApp Business API oficial (out of scope actual)

Restart limpio del Node

pm2 stop excucha-wa
pm2 start ecosystem.config.js
pm2 logs excucha-wa --lines 50

Las sesiones se re-hidratan automáticamente en boot (sessionManager.rehydrateAll).

Auth state corrupto en una empresa

UPDATE whatsapp_sessions SET auth_state = NULL, status = 'disconnected' WHERE empresa_id = X;

Luego pedir al admin re-escanear QR.

Smoke test E2E (post-deploy)

  1. Iniciar Node service
    cd whatsapp-service && cp .env.example .env  # editar valores reales
    npm install
    npm run dev
    
  2. Verificar health: curl http://localhost:3001/health{ok:true, sessions_active:0}
  3. Conectar empresa de test:
    • Login como admin de empresa #1
    • Ir a /configuracion/canales/whatsapp
    • Click "Conectar" → escanear QR con un WhatsApp de prueba
    • Verificar status → connected
  4. Envío manual:
    • POST /api/v1/envios/whatsapp con {telefono: "+57...", encuesta_id: 1}
    • Verificar que llega el WhatsApp al teléfono
    • Verificar whatsapp_envios.status evoluciona: queued → sent → delivered → read
  5. Webhook trigger:
    • Copiar webhook URL del panel
    • cURL POST con envio_id_externo: "smoke-1" → debe responder 202
    • Reintento mismo envio_id_externo → 202 con duplicate:true
  6. Auto-reply: responder al WhatsApp recibido → verificar fila en whatsapp_inbound_log con auto_replied=1 y mensaje guía recibido
  7. Reconexión: desde el teléfono cerrar WhatsApp Web → verificar status logged_out + email recibido
  8. PM2 production: pm2 start ecosystem.config.js && pm2 save