Voltar ao Portfolio
Optimus PlatformMessaging Infrastructure

WhatsApp Integration

Serviço enterprise para WhatsApp com Message Aggregator inteligente, Redis isolado, graceful degradation e integração bidirecional com Evolution API.

Message Aggregator5s DebounceEvolution APIRedis IsoladoGraceful DegradationWebSocket

O Problema: "Split Messages" do WhatsApp

❌ Comportamento Natural dos Usuários

[14:32:01] "Oi"
[14:32:03] "tudo bem?"
[14:32:07] "queria agendar"
[14:32:12] "uma consulta"
[14:32:15] "pra amanhã às 10h"

Usuários enviam pensamentos fragmentados em múltiplas mensagens rápidas. Isso é comportamento normal no WhatsApp.

Sem Agregação (caos):

  • ⚠️5 chamadas à API de IA para UMA intenção
  • ⚠️5 respostas confusas ("Oi!", "Bem!", "Agendar o quê?"...)
  • ⚠️Custo de tokens 5x maior
  • ⚠️UX horrível para o cliente

✅ Message Aggregator (5s Debounce)

// Mensagens recebidas em 14s...
// Agregadas em UMA mensagem:
"Oi, tudo bem? Queria agendar uma consulta pra amanhã às 10h"

O Message Aggregator espera 5 segundos após cada mensagem. estende o timeout.

Com Agregação (elegante):

  • 1 chamada à API de IA com contexto completo
  • 1 resposta precisa ("Perfeito! Agendei para amanhã 10h.")
  • Custo de tokens 5x menor
  • UX natural e fluida

📊 Fluxo do Message Aggregator

┌─────────────────────────────────────────────────────────────────────────┐
│                    Message Aggregator Timeline                           │
└─────────────────────────────────────────────────────────────────────────┘

  Mensagem 1        Mensagem 2        Mensagem 3        Timeout
      │                 │                 │                 │
      ▼                 ▼                 ▼                 ▼
   ┌──────┐          ┌──────┐          ┌──────┐          ┌──────┐
   │ "Oi" │          │"bem?"│          │"10h" │          │ENVIAR│
   └──┬───┘          └──┬───┘          └──┬───┘          └──┬───┘
      │                 │                 │                 │
      │    5s timer     │    RESET!       │    RESET!       │
      │────────────────▶│────────────────▶│────────────────▶│
      │                 │                 │                 │
      │         Timer estendido     Timer estendido    Timer expirou
      │                 │                 │                 │
      └─────────────────┴─────────────────┴─────────────────┘
                                                           │
                              ┌─────────────────────────────┘
                              │
                              ▼
                   ┌─────────────────────┐
                   │ Mensagem Agregada:  │
                   │ "Oi bem? 10h"       │
                   │                     │
                   │ → Backend Orch.     │
                   │ → AI Engine         │
                   └─────────────────────┘

┌─────────────────────────────────────────────────────────────────────────┐
│  CONFIG: MESSAGE_DEBOUNCE_SECONDS=5                                     │
│          AGGREGATOR_MAX_TIMEOUT_SECONDS=30                              │
│          AGGREGATOR_MAX_MESSAGES_PER_AGGREGATION=10                     │
└─────────────────────────────────────────────────────────────────────────┘

🔄 Typing Detection: O Segredo da Fluidez

O WhatsApp envia eventos de "digitando..." via webhook. O Message Aggregator estender o timeout inteligentemente.

Cenário Real:

  1. t=0Usuário envia "Oi" → timer 5s inicia
  2. t=3Webhook: "usuário digitando" → timer pausado
  3. t=8Usuário envia "quero agendar" → timer 5s reinicia
  4. t=13Sem typing, timer expira → mensagem agregada enviada

Resultado: O usuário pode digitar no seu ritmo natural. O sistema "espera" inteligentemente até ele terminar o pensamento completo. O usuário pode digitar no seu ritmo natural. O sistema "espera" inteligentemente até ele terminar o pensamento completo.

Limites de Segurança

Max Timeout Total30 seconds
Max Mensagens por Agregação10 messages
Debounce Base5 seconds

Esses limites previnem DoS e garantem que mensagens não fiquem "presas" indefinidamente se o usuário ficar digitando sem parar.

🔒 Redis Isolado: Separação de Tráfego

WhatsApp gera <strong class="text-green-400">muito tráfego de webhook</strong> - muito tráfego de webhook Misturar isso com o Redis principal é receita para disaster.

┌─────────────────────────────────────────────────────────────────┐
│                   REDIS ISOLATED ARCHITECTURE                    │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  🔴 Redis Principal (Porta 6379/6380)                           │
│  ├─ AI Engine ✅ Cache de conversas                    │
│  ├─ Backend Orchestrator ✅ Rate limiting, cache                │
│  ├─ Memory Engine ✅ Hot/Warm storage                      │
│  ├─ Rules Engine ✅ Cache de regras                       │
│  └─ Celery Workers ✅ Task queues                           │
│                                                                 │
│  🟢 Redis WhatsApp (Porta 6382) - ISOLADO                       │
│  └─ WhatsApp Integration ONLY                                   │
│      ├─ Message buffers (agregação)                             │
│      ├─ Typing state tracking                                │
│      ├─ Webhook deduplication                              │
│      ├─ Instance → Tenant mapping                            │
│      └─ Delivery status cache                              │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

⚡ Benefícios:
   • WhatsApp broadcast não afeta cache de conversas
   • Falha no Redis WhatsApp não derruba sistema principal
   • Métricas separadas para debugging
   • Escala independente se necessário
🛡️

Isolamento de Falhas

Se Redis WhatsApp cair ou ficar lento, o sistema principal (AI, Memory, Rules) continua funcionando normalmente.

📊

Métricas Separadas

Monitoring independente: latência do Redis WhatsApp não polui métricas do sistema core. Debug mais fácil.

📈

Escala Independente

Alta demanda de WhatsApp? Escala só o Redis WhatsApp. Não precisa mexer na infra principal.

⚡ Graceful Degradation: Sistema que não cai

Sob alta carga, o sistema degrada features não-essenciais para manter o core funcionando. Níveis configuráveis de degradação.

NORMAL

Usuários &lt; 500

  • ✅ Full aggregation (5s)
  • ✅ Typing detection ativo
  • ✅ WebSocket real-time
  • ✅ Todas as features
DEGRADED_LOW

500-2000 usuários

  • ⚠️ Aggregation reduzido (3s)
  • ⚠️ Typing detection limitado
  • ✅ WebSocket ativo
  • ⚠️ Métricas reduzidas
DEGRADED_HIGH

&gt; 2000 usuários

  • ❌ Aggregation mínimo (1s)
  • ❌ Typing detection off
  • ⚠️ WebSocket pooled
  • ❌ Só métricas críticas

Thresholds Configuráveis

DEGRADATION_PENDING_USERS_THRESHOLD_LOW=500
DEGRADATION_PENDING_USERS_THRESHOLD_HIGH=2000
DEGRADATION_REDIS_LATENCY_THRESHOLD_LOW_MS=50
DEGRADATION_REDIS_LATENCY_THRESHOLD_HIGH_MS=150

Degradação baseada em:

  • Número de usuários pendentes
  • Latência do Redis
  • Taxa de erros de webhook
  • Tamanho da fila de mensagens

🎯 1 Conversa por Telefone (Deterministic ID)

No WhatsApp, cada telefone = uma conversa. Não importa qual header chega, sempre calcula o mesmo UUID Isso elimina sessões paralelas e cross-user pollution.

Cálculo Determinístico

conversation_id = UUID5(
    namespace=OPTIMUS_NAMESPACE,
    name=f"{tenant_id}:{normalized_phone}"
)

# Exemplo:
# tenant: "clinica_abc"
# phone: "+5511999999999"
# → UUID: "a1b2c3d4-e5f6-5a7b-8c9d-0e1f2a3b4c5d"

# SEMPRE o mesmo UUID para mesmos inputs
# Ignora headers externos completamente

Headers de X-Conversation-ID são <strong class="text-red-400">ignorados</strong>. ignorados. Previne que um cliente malicioso "pule" para conversa de outro usuário.

Normalização de Telefone

// Todos viram o MESMO UUID:
"+5511999999999"     → UUID_X
"5511999999999"      → UUID_X
"+55 11 999-999-999" → UUID_X
"+55 (11) 99999-9999" → UUID_X

// Phone é normalizado antes do hash:
// 1. Remove espaços, hífens, parênteses
// 2. Remove "+" prefix
// 3. Garante formato numérico puro

Não importa como o telefone chega (WhatsApp, Evolution, manual), a normalização garante consistência.

👥 Integração com Handover

Quando um atendente humano assume a conversa, o comportamento do suportar interação em tempo real.

Durante Handover:

  • ⏸️
    Aggregation Pausado
    Mensagens do cliente vão direto pro operador, sem delay de 5s.
  • Immediate Delivery
    Respostas do operador são enviadas instantaneamente.
  • 🔄
    WebSocket Real-time
    Frontend do operador recebe mensagens em tempo real.

Configuração Handover

HANDOVER_PAUSE_AGGREGATIONtrue
HANDOVER_IMMEDIATE_DELIVERYtrue
HANDOVER_WEBSOCKET_ENABLEDtrue
HANDOVER_AUTO_RESUME_MINUTES30

🚀 Evolution API Integration

Multi-tenant Instances

Cada tenant pode ter múltiplas instâncias WhatsApp. O sistema resolve automaticamente qual tenant "dono" de cada instância via cache O(1).

// Instance → Tenant mapping
{
  "clinica_sp": "Local - SP",
  "clinica_rj": "Local - RJ",
  "clinica_demo": "Local - Dev"
}

// Lookup O(1) via Redis:
// GET instance:tenant:{instance_name}

Webhook Security

API keys são validadas via HMAC com secret dedicado. Hash do API key (não a key em si) é cacheada para lookups rápidos.

// API Key validation flow:
1. Webhook chega com X-API-Key header
2. HMAC(apikey, EVOLUTION_SECRET) → hash
3. Redis lookup: apikeyhash:tenant:
4. Se match → autorizado
5. Se não → schema scan (fallback)

🎤 Audio Message Support

🎙️
Voice Notes
Cliente envia áudio → Audio Processor transcreve → Texto vai pro AI Engine
🔊
Audio Reply
Resposta do AI → TTS (Text-to-Speech) → Áudio enviado ao cliente
📁
MinIO Storage
Arquivos de áudio armazenados no MinIO para processamento assíncrono

Resultados em Produção

~80%
Redução de Chamadas IA
Via message aggregation
&lt;100ms
Latência Webhook
P95 end-to-end
100%
Isolamento Redis
Zero cross-pollution
2000+
Usuários Simultâneos
Antes de degradation

Stack Técnico

Framework

FastAPI + Uvicorn

Storage

Redis 8.2 (isolated) + MinIO

Real-time

WebSocket (25 concurrent)

WhatsApp API

Evolution API

Audio

Audio Processor (STT/TTS)

Observability

OpenTelemetry + Prometheus

Rate Limiting

60 req/min configurable

HTTP Client

HTTPX (30s timeout, 3 retries)

Interessado em integrações WhatsApp?

Message aggregation, webhooks, multi-tenant instances - tenho experiência prática com os desafios reais.