Webhook WhatsApp: como receber mensagens na sua aplicação
Enviar mensagens programaticamente é apenas metade da equação. Para construir chatbots, sistemas de atendimento, confirmações interativas ou integrações bidirecionais com CRMs, você precisa receber o que o usuário responde — e fazer isso em tempo real, sem polling.
É exatamente para isso que existem webhooks: a API notifica sua aplicação sempre que algo acontece na instância WhatsApp. Neste artigo, explicamos como funcionam os webhooks na prática, como configurá-los no Zapixo e como processar os eventos no seu backend com segurança e confiabilidade.
O que é um webhook de WhatsApp?
Um webhook é uma URL pública no seu servidor que recebe requisições HTTP POST sempre que um evento ocorre. Em vez de sua aplicação perguntar repetidamente "chegou mensagem nova?", a API empurra os dados para você no momento em que o evento acontece.
No ecossistema Evolution API v2 — que o Zapixo gerencia por baixo dos panos — os eventos mais comuns incluem:
- MESSAGES_UPSERT: nova mensagem recebida ou enviada.
- MESSAGES_UPDATE: atualização de status (entregue, lida).
- CONNECTION_UPDATE: mudança no estado da conexão (conectado, desconectado).
- QRCODE_UPDATED: novo QR code gerado para reconexão.
Com o Zapixo, você configura a URL do webhook diretamente no painel da instância, sem precisar chamar endpoints de configuração manualmente.
Configurando o webhook no Zapixo
O fluxo é simples:
- Acesse zapixo.com.br e faça login.
- Vá em Painel → Instâncias e abra a instância desejada.
- No campo Webhook URL, insira o endpoint público da sua aplicação.
- Salve. O Zapixo registra automaticamente os eventos na Evolution API.
Exemplo de URL válida:
https://api.seudominio.com.br/webhooks/zapixo
Requisitos importantes:
- A URL deve ser HTTPS (certificado SSL válido).
- O endpoint precisa responder com status 200 em até alguns segundos.
- Para desenvolvimento local, use ferramentas como ngrok, Cloudflare Tunnel ou localtunnel para expor sua máquina.
Estrutura típica de um evento MESSAGES_UPSERT
Quando alguém envia "Olá" para o seu número conectado, o webhook recebe um payload JSON semelhante a este (estrutura simplificada):
{
"event": "messages.upsert",
"instance": "minha-loja",
"data": {
"key": {
"remoteJid": "5511999999999@s.whatsapp.net",
"fromMe": false,
"id": "3EB0123456789ABCDEF"
},
"message": {
"conversation": "Olá, gostaria de saber o status do meu pedido"
},
"messageTimestamp": 1717536000,
"pushName": "Maria Silva"
}
}
Campos que você vai usar com mais frequência:
| Campo | Descrição |
|-------|-----------|
| remoteJid | Identificador do chat (extraia o número antes do @) |
| fromMe | false = mensagem do cliente; true = mensagem sua |
| conversation | Texto da mensagem (mensagens simples) |
| pushName | Nome exibido no WhatsApp do remetente |
Para mensagens com mídia, o campo message terá estruturas diferentes (imageMessage, documentMessage, etc.).
Implementando o endpoint (Node.js + Express)
import express from "express";
const app = express();
app.use(express.json());
app.post("/webhooks/zapixo", (req, res) => {
const { event, data } = req.body;
// Responda rápido — processe depois se necessário
res.sendStatus(200);
if (event !== "messages.upsert") return;
const msg = data?.message;
const fromMe = data?.key?.fromMe;
if (fromMe) return; // ignore mensagens enviadas por você
const texto = msg?.conversation ?? msg?.extendedTextMessage?.text ?? "";
const jid = data?.key?.remoteJid ?? "";
const numero = jid.replace("@s.whatsapp.net", "");
console.log(`Mensagem de ${numero}: ${texto}`);
// Aqui: lógica do bot, encaminhar para CRM, etc.
});
app.listen(3000, () => console.log("Webhook rodando na porta 3000"));
Implementando o endpoint (Python + FastAPI)
from fastapi import FastAPI, Request, BackgroundTasks
app = FastAPI()
def processar_mensagem(payload: dict):
data = payload.get("data", {})
if data.get("key", {}).get("fromMe"):
return
jid = data.get("key", {}).get("remoteJid", "")
numero = jid.split("@")[0]
msg = data.get("message", {})
texto = msg.get("conversation") or msg.get("extendedTextMessage", {}).get("text", "")
print(f"Mensagem de {numero}: {texto}")
# Disparar resposta via API do Zapixo, salvar no banco, etc.
@app.post("/webhooks/zapixo")
async def webhook(request: Request, background_tasks: BackgroundTasks):
payload = await request.json()
background_tasks.add_task(processar_mensagem, payload)
return {"ok": True}
O padrão de responder 200 imediatamente e processar em background é fundamental. Webhooks que demoram muito podem ser reenviados ou marcados como falha.
Respondendo mensagens automaticamente
Ao receber uma mensagem, você provavelmente quer responder. Use a API de envio do Zapixo no mesmo fluxo:
import requests
def responder(numero: str, texto: str):
requests.post(
"https://zapixo.com.br/api/v1/messages/text",
headers={"Authorization": "Bearer SUA_CHAVE"},
json={
"instance": "minha-loja",
"number": numero,
"text": texto,
},
timeout=30,
)
Monte um fluxo básico de atendimento: recebe webhook → identifica intenção → consulta banco de dados → envia resposta personalizada.
Tratando eventos de conexão
O evento CONNECTION_UPDATE avisa quando a instância desconecta — algo que acontece se o celular perder internet, a sessão expirar ou o WhatsApp solicitar nova autenticação.
Monitore esse evento para:
- Alertar sua equipe via e-mail ou Slack.
- Pausar campanhas automáticas até reconexão.
- Registrar métricas de uptime da instância.
{
"event": "connection.update",
"data": {
"state": "close"
}
}
Quando state for close ou disconnected, acesse o painel do Zapixo e escaneie o novo QR code.
Boas práticas de segurança
Webhooks expõem um endpoint público. Siga estas recomendações:
Valide a origem — em produção, restrinja IPs ou use um token secreto na URL (/webhooks/zapixo?token=seu_segredo).
Idempotência — o mesmo evento pode ser entregue mais de uma vez. Use o messageId (data.key.id) como chave única no banco para evitar processamento duplicado.
Não exponha dados sensíveis em logs — registre IDs e timestamps, não o conteúdo completo de conversas.
HTTPS obrigatório — nunca aceite webhooks em HTTP puro.
Timeout curto — responda em menos de 5 segundos; delegue processamento pesado para filas.
Debugando webhooks em desenvolvimento
Durante o desenvolvimento local, sua máquina não é acessível pela internet. Soluções:
# ngrok
ngrok http 3000
# Use a URL gerada (ex: https://abc123.ngrok.io/webhooks/zapixo) no painel Zapixo
Ferramentas como webhook.site também ajudam a inspecionar payloads brutos antes de implementar o handler definitivo.
Webhook vs. polling: quando usar cada um
| Abordagem | Vantagem | Desvantagem | |-----------|----------|-------------| | Webhook | Tempo real, eficiente | Exige URL pública | | Polling | Simples em dev | Lento, desperdiça requisições |
Para qualquer aplicação de atendimento ou bot, webhook é a escolha correta.
Integrando com outras ferramentas
O payload do webhook pode ser encaminhado para:
- n8n / Make: automações visuais sem código.
- Chatwoot: central de atendimento omnichannel.
- Banco de dados: persistir histórico de conversas.
- Filas (SQS, RabbitMQ): desacoplar recebimento do processamento.
O Zapixo atua como ponte confiável entre o WhatsApp e sua stack — você foca na lógica de negócio.
Conclusão
Webhooks transformam sua integração WhatsApp de unidirecional para conversacional. Configurar no Zapixo leva segundos no painel; o trabalho real está em construir um handler robusto, idempotente e rápido no seu backend.
Comece expondo um endpoint simples que loga os eventos, valide o formato dos payloads e só então adicione lógica de resposta automática. Com a instância conectada e o webhook ativo em zapixo.com.br, sua aplicação estará pronta para conversar com clientes em tempo real.