4.5 KiB
Resolução: Falha no Recebimento de Webhooks Wuzapi
Contexto
Mensagens enviadas para o número WhatsApp não estavam chegando na caixa de entrada do Chatwoot no ambiente local, apesar de mensagens de saída funcionarem.
Diagnóstico
- Backend (Controller): O
Webhooks::WuzapiControllerexistia mas o métodoprocess_payloadestava vazio. Ele recebia o webhook, retornava 200 OK, mas não fazia nada. - Ambiente (Túnel): O comando
make runinicia apenas o servidor Rails/Sidekiq, sem o túnel Ngrok necessário para expor o localhost para a internet (Wuzapi). - Segurança: O ID da Inbox usado nos testes iniciais (3) era diferente do ID do canal para o qual o webhook estava sendo enviado, causando confusão inicial.
Solução Técnica
-
Implementação do Controller: Conectamos o controller ao serviço existente:
# app/controllers/webhooks/wuzapi_controller.rb def process_payload Whatsapp::IncomingMessageWuzapiService.new(inbox: @inbox, params: params.to_unsafe_hash).perform head :ok rescue StandardError => e Rails.logger.error e head :internal_server_error end -
Fluxo de Execução: Padronizado o uso de
make force_run_tunnelpara garantir que o Ngrok suba junto com a aplicação.
Validação
- Teste simulado via
curlconfirmou criação de mensagem no banco. - Teste real ("Teste 123") confirmado pelo usuário e validado nos logs com resposta automática do Agente ("Olá! Como posso ajudar...").
Arquivos Alterados
app/controllers/webhooks/wuzapi_controller.rbtask.md,walkthrough.md(Documentação)
Implementação de Presença Simulada (Typing Indicator) e Delay Humanizado
Contexto e Objetivo
O objetivo era implementar uma experiência de chat mais "humana", onde o bot exibe o status "digitando..." (typing) enquanto processa a resposta e durante um período de delay artificial (humanized delay), antes de enviar a mensagem final.
Mecanismo de Presença Simulada
O comportamento "humano" é alcançado mantendo o indicador de digitação ativo durante todo o ciclo de geração da resposta:
- Início do Processamento: O Job (
ResponseBuilderJob) ativa o statustyping_on. - Geração da IA: O LLM processa a resposta (indicador continua ativo).
- Delay Humanizado: Um delay calculado (baseado no tamanho da resposta) é executado.
- Crítico: O indicador deve permanecer ativo durante este
sleep.
- Crítico: O indicador deve permanecer ativo durante este
- Finalização: O status é alterado para
typing_offe a mensagem é enviada imediatamente em seguida.
Diagnóstico e Correções
Para que este fluxo funcionasse no Wuzapi, corrigimos os seguintes pontos:
-
Sincronia do Delay (Correção de UX):
- Problema: O código original desligava o indicador (
typing_off) antes de entrar nohumanized_delay. Isso causava um "silêncio visual" (sem indicador) de ~5 segundos antes da mensagem aparecer. - Solução: Movemos a chamada de
typing_offpara após a execução do delay.
- Problema: O código original desligava o indicador (
-
Incompatibilidade de Status ("Bug Raiz"):
- Problema: A aplicação enviava o status simplificado
'on', mas o adaptador do Wuzapi esperava estritamente a string'typing_on'. Isso fazia o código falhar silenciosamente e enviar'paused'. - Solução: O adaptador (
WuzapiService) foi atualizado para aceitar tanto'on'quanto'typing_on'.
- Problema: A aplicação enviava o status simplificado
-
Formato do JID (Protocolo WhatsApp):
- Problema: O envio de presença falhava se o número não tivesse o sufixo correto.
- Solução: Forçamos a formatação
<numero>@s.whatsapp.netno envio para a API do Wuzapi.
-
Crash na Validação de Webhook (Entrada):
- Problema: Webhooks de presença contendo IDs internos do WhatsApp (
@lid) quebravam a validação de telefone da aplicação. - Solução: O parser foi blindado para ignorar IDs inválidos sem travar o processamento.
- Problema: Webhooks de presença contendo IDs internos do WhatsApp (
Arquivos Chave Alterados
enterprise/app/jobs/captain/conversation/response_builder_job.rb: Ajuste na ordem dohumanized_delay.app/services/whatsapp/providers/wuzapi_service.rb: Suporte a status'on'e formatação JID.app/services/whatsapp/providers/wuzapi/payload_parser.rb: Tratamento de IDs inválidos.
Como Validar
- Envie uma mensagem para o bot.
- Observe que o status "digitando..." aparece quase imediatamente.
- Note que o status persiste por alguns segundos (durante o delay).
- A mensagem chega assim que o status some.