Wafly › Tutoriais › WhatsApp no CRM
Como integrar WhatsApp ao CRM usando webhooks
O webhook transforma uma conversa do WhatsApp em dados acionáveis: contato atualizado, atividade registrada, negócio movimentado e resposta enviada sem copiar e colar.
Arquitetura da integração
O receiver não deve conhecer todas as regras do CRM. Sua primeira responsabilidade é validar o evento, impedir duplicidade e colocá-lo num formato estável. Depois outro passo localiza o contato, registra a interação e decide se deve criar ou movimentar um negócio.
Quais dados enviar ao CRM
| Campo | Uso | Regra recomendada |
|---|---|---|
message_id | Idempotência e auditoria | Único; nunca processe duas vezes |
phone | Localizar o contato | Somente dígitos, com DDI |
text | Atividade e qualificação | Ausente para mídias sem legenda |
type | Texto, áudio, imagem ou documento | Não force tudo para texto |
instance | Empresa, unidade ou cliente | Obrigatório em multi-instância |
received_at | Linha do tempo | ISO 8601 em UTC |
Como cadastrar o webhook de recebimento
Crie primeiro uma rota pública, por exemplo https://automacao.suaempresa.com/webhooks/whatsapp. Ela deve aceitar POST e HTTPS. Depois configure na instância:
curl -X PUT "https://wafly.com.br/api-bridge-whats/instances/SUA_INSTANCIA/token/SEU_TOKEN/update-webhook-received" \
-H "Client-Token: SEU_CLIENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"value":"https://automacao.suaempresa.com/webhooks/whatsapp"}'
Você também pode configurar webhooks de entrega e desconexão. O guia geral de eventos está em Webhook de WhatsApp.
Receiver mínimo em Node.js
app.post('/webhooks/whatsapp', async (req, res) => {
const event = normalizeWafly(req.body);
if (!event.message_id || !event.phone) {
return res.status(400).json({ error: 'invalid_event' });
}
if (await processed.exists(event.message_id)) {
return res.status(200).json({ duplicate: true });
}
await queue.publish('whatsapp.received', event);
await processed.reserve(event.message_id);
return res.status(200).json({ accepted: true });
});
O exemplo responde depois de registrar o evento na fila. Se você chamar o CRM antes da resposta e ele demorar, o fornecedor pode interpretar como falha e reenviar. É por isso que idempotência não é opcional.
Como localizar contato e atualizar o negócio
- Normalize o telefone para DDI + DDD + número.
- Busque o contato pelo telefone; se não existir, crie com origem “WhatsApp”.
- Registre a mensagem como atividade com data, instância e ID externo.
- Procure um negócio aberto daquele contato antes de criar outro.
- Movimente etapa somente quando houver uma regra clara, como intenção de preço ou reunião confirmada.
- Salve o ID do contato e do negócio no seu banco de integração.
No n8n, isso vira: Webhook → Set/Edit Fields → Data Store ou banco → node do CRM/HTTP Request → decisão → Wafly. O tutorial de WhatsApp no n8n mostra a configuração da credencial.
Como responder usando o contexto do CRM
A regra de negócio retorna o telefone e a mensagem. O transporte faz a chamada:
curl -X POST "https://wafly.com.br/api-bridge-whats/instances/SUA_INSTANCIA/token/SEU_TOKEN/send-text" \
-H "Client-Token: SEU_CLIENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"phone":"5511999999999","message":"Recebi seu pedido. Posso ajudar com o plano?"}'
Persista o ID retornado pelo envio. Quando o webhook de status chegar, atualize aquela mesma atividade em vez de criar outra.
Checklist antes de colocar em produção
- URL HTTPS e resposta 200 em poucos segundos.
- Chave de idempotência baseada no ID da mensagem.
- Fila ou retry com limite para falhas do CRM.
- Dead-letter ou lista de eventos que falharam definitivamente.
- Telefone normalizado com DDI.
- Instância associada à empresa correta.
- Segredos somente no backend ou cofre do n8n.
- Logs sem tokens e sem payload pessoal completo desnecessário.
- Opt-in e base legal definidos para mensagens ativas.
- Alerta de desconexão e teste periódico de ponta a ponta.
Teste a integração com seu CRM
Use os 3 dias de trial para validar recebimento, criação do contato, resposta e status de entrega.
Criar instância grátisAbrir documentaçãoPerguntas frequentes
Funciona com qualquer CRM?
Sim, desde que o CRM tenha API ou automação para contatos, atividades e negócios. O contrato normalizado evita prender o fluxo a um fornecedor específico.
Como evitar mensagens duplicadas?
Use o ID da mensagem como chave única. Se o webhook for reenviado, responda 200 sem repetir a atualização.
Devo responder antes de chamar o CRM?
Quando o CRM puder demorar, registre o evento em fila e responda 200 rapidamente. O processamento continua em segundo plano.
Preciso usar n8n?
Não. O mesmo desenho funciona em Node.js, Python, Java ou qualquer backend que receba HTTP e chame a API do CRM.