← Blog

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:

  1. Acesse zapixo.com.br e faça login.
  2. Vá em Painel → Instâncias e abra a instância desejada.
  3. No campo Webhook URL, insira o endpoint público da sua aplicação.
  4. 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.