Início › Tutoriais › Agente de IA e mensagens picotadas
Seu agente de IA responde 3 vezes porque o cliente mandou 3 mensagens
Padrões: janela de 8 segundos de silêncio, teto absoluto de 30 segundos e no máximo 10 mensagens por grupo.
O problema, com payload real
Cada mensagem do WhatsApp é um evento independente. Sem agrupamento, uma frase quebrada em três vira três chamadas ao seu webhook:
POST /seu-webhook { "phone": "5511...", "text": { "message": "oi" } }
POST /seu-webhook { "phone": "5511...", "text": { "message": "tudo bem?" } }
POST /seu-webhook { "phone": "5511...", "text": { "message": "queria saber o preço" } }
Se do outro lado tem um LLM, ele responde três vezes — e as duas primeiras respostas foram geradas sem conhecer o que a pessoa ainda ia escrever. É a reclamação mais comum de quem coloca agente de IA no WhatsApp, e a maioria das APIs empurra o problema para você resolver com fila e debounce do seu lado.
Ligando com uma chamada
curl -X PUT "https://wafly.com.br/api-bridge-whats/instances/SUA_INSTANCIA/token/SEU_TOKEN/inbound-config" \
-H "Client-Token: SEU_CLIENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "buffer": { "enabled": true } }'
Só isso. Os padrões já são sensatos: 8 segundos de silêncio, teto de 30 segundos, máximo de 10 mensagens por grupo.
O que muda no webhook
Uma chamada só, e o payload continua com exatamente a mesma estrutura:
POST /seu-webhook
{
"phone": "5511...",
"text": { "message": "oi\ntudo bem?\nqueria saber o preço" },
"buffered": { "count": 3, "messageIds": ["...","...","..."], "waitedMs": 8012 }
}
Seu código lê text.message como sempre leu. O campo buffered é informativo — ignore se não precisar. Quando só chega uma mensagem, o payload sai idêntico ao de antes, sem o campo extra, então nada no seu integrador precisa saber que o buffer existe.
Parâmetros
| Campo | Padrão | O que faz |
|---|---|---|
enabled | false | Liga o agrupamento. |
window_ms | 8000 | Janela de silêncio. Reinicia a cada mensagem nova — a entrega sai quando a pessoa para de digitar. Máx. 20000. |
max_wait_ms | 30000 | Teto absoluto desde a primeira mensagem, para quem digita sem parar não adiar a entrega para sempre. Máx. 30000. |
max_messages | 10 | Entrega na hora ao acumular N mensagens. |
mode | concat | concat junta os textos no campo de sempre. batch adiciona o array bufferedMessages — muda o formato, use só se quiser mesmo. |
include_groups | false | Estende para conversas de grupo. |
Valor fora do limite não é aceito em silêncio: ele é ajustado e a correção volta no campo notes da resposta.
Mídia, áudio e ordem da conversa
Mídia, reação e resposta de botão nunca são agrupadas. E tem um detalhe que importa mais do que parece: se houver texto esperando na janela quando um áudio chegar, o texto pendente é entregue antes. A ordem da conversa nunca se inverte.
O motivo de não agrupar é semântico, não preguiça: concatenar "olha isso" na legenda de uma imagem mudaria o significado do payload e quebraria o vínculo com o arquivo. Reação é metadado sobre outra mensagem, não conversa. E resposta de botão é uma ação esperando resposta imediata — segurar 8 segundos é o oposto do que ela pede.
Grupos
Desligado por padrão. Ao ligar com include_groups, o agrupamento é por participante: cinco pessoas falando ao mesmo tempo num grupo continuam gerando cinco conversas separadas. Agrupar por conversa juntaria falas de pessoas diferentes numa mensagem só — que é exatamente o erro que este recurso existe para evitar.
Teste com o seu agente hoje
Instância conectada por QR em ~2 minutos e o buffer liga com um curl. 3 dias grátis, sem cartão.
Perguntas frequentes
Preciso mudar meu código?
Não, no modo concat (o padrão). O payload chega na mesma estrutura, só com o texto junto. Foi projetado assim de propósito: recurso que exige refatoração do seu lado não é adotado.
E se a pessoa nunca parar de digitar?
max_wait_ms força a entrega. O teto é 30 segundos — é limite de segurança, não preferência: mensagem esperando vive em memória, e uma janela longa aumentaria a perda em caso de queda do processo.
Funciona com n8n, Dify, Flowise, LangChain?
Com qualquer coisa que receba webhook. O agrupamento acontece antes de sair da Wafly, então a ferramenta do outro lado nem sabe que existiu. Veja o tutorial de n8n.
Dá para ligar só em algumas instâncias?
Sim, a configuração é por instância. Sem configuração, a instância entrega uma chamada por mensagem, como sempre foi.
Como desligo?
DELETE no mesmo endpoint, ou PUT com enabled: false.
Continue
Encontrou algo impreciso? Fale com a gente que corrigimos.