Conformidade com Diretrizes da Meta¶
Status: Documento de referencia, atualizado em 2026-06-02
Aplicacao: Sistema ChatBot Survey integrado com Meta WhatsApp Business Cloud API v22.0
Este documento descreve como o sistema se alinha com as regras da Meta para mensageria via WhatsApp Business API, e quais lacunas ainda precisam ser endereçadas.
Regras Fundamentais da Meta¶
1. Janela de Atendimento de 24h (Customer Service Window)¶
Quando um usuario envia mensagem para o numero comercial, abre uma janela de 24 horas durante a qual o negocio pode enviar mensagens de texto livres (nao templates).
- Dentro da janela: texto livre, audio, video, imagem, documento
- Fora da janela: apenas templates aprovados
2. Templates Aprovados (Business-Initiated)¶
Para iniciar conversas (sem ter recebido msg do cliente nas ultimas 24h), o negocio deve usar templates pre-aprovados.
Categorias: - MARKETING - promocional (exige opt-out) - UTILITY - transacional (confirmacao, lembrete) - AUTHENTICATION - 2FA
3. Quality Rating¶
A Meta atribui um quality rating ao numero comercial baseado em: - Volume de bloqueios pelos usuarios - Reports de spam - Frequencia de envio
Rating pode ser: GREEN, YELLOW, RED, FLAGGED, RESTRICTED.
Alinhamento Atual do Sistema¶
✅ Janela de 24h respeitada¶
Implementacao: backend/chat/services.py:ChatService._validate_can_send()
Cobertura: - Operador no chat livre: bloqueado se passou 24h sem msg IN do cliente - Bot durante pesquisa: regra C (in_progress expira em 24h) garante que o bot nao continue tentando responder fora da janela
✅ Templates para iniciar conversa¶
Implementacao: MetaGraphService.send_initial_survey_message() em backend/whatsapp/services/meta_graph_service.py
Survey configurada com:
| Python | |
|---|---|
O sistema so envia template para iniciar conversa. Apos o cliente responder SIM (entrando em in_progress), as proximas perguntas sao enviadas como mensagens regulares dentro da janela de 24h.
✅ Bloqueio de reenvio responsavel¶
Implementacao: backend/surveys/views.py:start_survey()
Antes de criar nova run, verifica se ha run ativa para o mesmo (survey, contact). Se houver e nao expirou, bloqueia o disparo com payload estruturado informando o tempo restante.
Isso evita: - Spam de templates para o mesmo contato - Duplicacao de execucoes - Custos desnecessarios (cada template envia paga)
✅ Opt-out via botao¶
Implementacao: backend/whatsapp/services/survey_service.py
Cliente pode recusar a pesquisa respondendo "NAO" no botao de confirmacao. A run e marcada como opt_out e nao recebe mais mensagens.
✅ Expiracao automatica = nao "esperar eternamente"¶
Implementacao: task expire_stale_runs (ver expiracao-pesquisas.md)
Apos as janelas configuradas (24h/72h/24h), runs sao automaticamente marcadas como expired, liberando o reenvio futuro.
⚠️ Gaps Conhecidos¶
Gap 1: HMAC do Webhook Pendente¶
Risco: MEDIO-ALTO
A Meta recomenda validar a assinatura HMAC-SHA256 do webhook usando o App Secret. Sem isso, terceiros podem enviar webhooks falsos para a aplicacao.
Status: aguardando META_APP_SECRET do cliente Highlas (vide memory project_hmac_pending.md).
Acao: implementar middleware/decorator que valida X-Hub-Signature-256 header antes de processar webhook.
| Python | |
|---|---|
Gap 2: Cooldown de Reenvio Apos Expiracao¶
Risco: MEDIO
Atualmente, assim que uma run expira (ou e cancelada manualmente), o operador pode disparar nova pesquisa imediatamente para o mesmo contato. Em volume, isso pode: - Degradar quality rating se cliente final marcar como spam - Gerar custos repetitivos - Irritar contatos que ja optaram por nao participar
Acao sugerida: adicionar campo cooldown_until ou usar completed_at + janela minima (ex: 7 dias). Validar em start_survey:
Gap 3: Opt-out por Palavra-Chave¶
Risco: BAIXO (mas critico se template for MARKETING)
Templates de categoria MARKETING exigem mecanismo de opt-out por texto. Hoje so capturamos opt-out via botao "NAO".
Acao sugerida: em survey_service.process_incoming_message(), detectar palavras como PARAR, STOP, CANCELAR, SAIR, DESCADASTRAR e marcar contato como opt-out global (impede futuros disparos para esse numero).
Gap 4: Janela 24h durante in_progress pode estourar silenciosamente¶
Risco: BAIXO
Cenario: 1. Cliente responde SIM ao template 2. Bot envia pergunta 1 3. Cliente leva > 24h para responder 4. Cliente responde 5. Bot tenta enviar pergunta 2 -> a Meta rejeita (fora da janela)
Hoje a rejeicao seria logada como failed no MessageLog, mas a run continua in_progress ate a regra C marcar como expired (mais 24h depois). Cliente final fica em limbo.
Acao sugerida: ao detectar erro 131047 da Meta (re-engagement message), marcar a run como expired imediatamente e logar o motivo.
Gap 5: Codigos de Erro Especificos Nao Tratados¶
Risco: BAIXO
A Meta retorna codigos de erro especificos que poderiam alimentar decisoes automaticas:
| Codigo | Significado | Acao sugerida |
|---|---|---|
131026 | Mensagem nao entregavel (numero invalido) | mark_as_expired() + flag no Contact |
131047 | Re-engagement needed (fora da janela 24h) | mark_as_expired() |
131056 | Rate limit do par (sender, recipient) hit | Aguardar e retry com backoff |
131051 | Tipo de mensagem nao suportado | Log e descarta |
Hoje todos os erros sao logados de forma generica em meta_graph_service.py mas nao geram acoes diferenciadas.
Gap 6: Quality Rating Nao Monitorado¶
Risco: BAIXO
A Meta envia webhooks com account_update e phone_number_quality_update. Hoje o sistema ignora silenciosamente esses webhooks (so processa messages e statuses).
Acao sugerida: criar handler para account_update. Se rating cair para RED, FLAGGED ou RESTRICTED, enviar email de alerta para o admin.
Auditoria e Logs¶
Toda mensagem trocada e registrada em MessageLog:
Permite reconstruir o historico completo de comunicacao com qualquer contato para fins de auditoria, disputa ou debugging.
Roadmap de Conformidade¶
Priorizacao sugerida (vide roadmap-gaps.md):
| Prioridade | Item |
|---|---|
| 🔴 ALTA | HMAC do webhook (assim que receber App Secret) |
| 🟡 MEDIA | Cooldown de reenvio (Gap 2) |
| 🟡 MEDIA | Tratamento de 131026 e 131047 (Gap 5 parcial) |
| 🟢 BAIXA | Opt-out por keyword (Gap 3) |
| 🟢 BAIXA | Quality rating monitoring (Gap 6) |