Skip to main content

Configurando Webhooks

Webhooks permitem que sua aplicação receba notificações em tempo real quando eventos acontecem no WhatsApp (mensagens recebidas, status de entrega, etc.).

Como Funciona

WhatsApp → Wapizap API → Seu Webhook → Sua Aplicação
  1. Um evento acontece (ex: mensagem recebida)
  2. A Wapizap API envia um POST para sua URL de webhook
  3. Sua aplicação processa o evento

Criar um Webhook

curl -X POST https://api.wapizap.com/api/v2/webhooks \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer SEU_TOKEN" \
  -d '{
    "instanceId": "sua-instancia",
    "url": "https://seu-servidor.com/webhook/wapizap",
    "events": ["message", "message.ack", "connection.update"],
    "secret": "seu_secret_para_validacao"
  }'

Eventos Disponíveis

EventoDescrição
messageNova mensagem recebida
message.ackAtualização de status (enviado, entregue, lido)
message.revokedMensagem apagada pelo remetente
connection.updateStatus da conexão mudou
presence.updateStatus de presença (online, digitando)
groups.upsertGrupo criado ou atualizado
groups.updateConfigurações do grupo alteradas
group-participants.updateParticipantes adicionados/removidos
chats.upsertNovo chat iniciado
chats.updateChat atualizado
contacts.upsertNovo contato detectado
Use ["*"] para receber todos os eventos (não recomendado em produção).

Recebendo Webhooks

Estrutura do Payload

{
  "event": "message",
  "instanceId": "sua-instancia",
  "timestamp": 1705233000,
  "data": {
    "key": {
      "remoteJid": "[email protected]",
      "fromMe": false,
      "id": "3EB0XXXXX"
    },
    "message": {
      "conversation": "Olá, preciso de ajuda!"
    },
    "messageTimestamp": 1705233000,
    "pushName": "João Silva"
  }
}

Exemplo de Servidor (Node.js/Express)

const express = require('express');
const crypto = require('crypto');

const app = express();
app.use(express.json());

const WEBHOOK_SECRET = 'seu_secret_para_validacao';

// Validar assinatura do webhook
function validateSignature(payload, signature) {
  const hash = crypto
    .createHmac('sha256', WEBHOOK_SECRET)
    .update(JSON.stringify(payload))
    .digest('hex');
  return hash === signature;
}

app.post('/webhook/wapizap', (req, res) => {
  const signature = req.headers['x-webhook-signature'];

  // Validar assinatura (recomendado)
  if (!validateSignature(req.body, signature)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  const { event, instanceId, data } = req.body;

  switch (event) {
    case 'message':
      console.log('Nova mensagem de:', data.pushName);
      console.log('Conteúdo:', data.message?.conversation);
      // Processar mensagem...
      break;

    case 'message.ack':
      console.log('Status atualizado:', data.status);
      // 1=enviado, 2=entregue, 3=lido
      break;

    case 'connection.update':
      console.log('Conexão:', data.state);
      // 'open', 'close', 'connecting'
      break;

    default:
      console.log('Evento:', event);
  }

  // Sempre responda com 200 rapidamente
  res.status(200).json({ received: true });
});

app.listen(3000, () => {
  console.log('Webhook server running on port 3000');
});

Exemplo de Servidor (Python/Flask)

from flask import Flask, request, jsonify
import hmac
import hashlib

app = Flask(__name__)
WEBHOOK_SECRET = 'seu_secret_para_validacao'

def validate_signature(payload, signature):
    hash = hmac.new(
        WEBHOOK_SECRET.encode(),
        payload.encode(),
        hashlib.sha256
    ).hexdigest()
    return hash == signature

@app.route('/webhook/wapizap', methods=['POST'])
def webhook():
    signature = request.headers.get('X-Webhook-Signature')

    # Validar assinatura (recomendado)
    if not validate_signature(request.get_data(as_text=True), signature):
        return jsonify({'error': 'Invalid signature'}), 401

    data = request.json
    event = data.get('event')

    if event == 'message':
        message_data = data.get('data', {})
        print(f"Nova mensagem de: {message_data.get('pushName')}")
        print(f"Conteúdo: {message_data.get('message', {}).get('conversation')}")

    elif event == 'message.ack':
        print(f"Status atualizado: {data.get('data', {}).get('status')}")

    elif event == 'connection.update':
        print(f"Conexão: {data.get('data', {}).get('state')}")

    return jsonify({'received': True}), 200

if __name__ == '__main__':
    app.run(port=3000)

Validação de Assinatura

Para garantir que os webhooks vêm realmente da Wapizap, valide a assinatura:
  1. O header X-Webhook-Signature contém um HMAC-SHA256
  2. É calculado usando o secret que você definiu ao criar o webhook
  3. O payload é o corpo JSON da requisição
Sempre valide a assinatura em produção para evitar que terceiros enviem requisições falsas para seu endpoint.

Testar Webhook

Teste se seu endpoint está recebendo corretamente:
curl -X POST "https://api.wapizap.com/api/v2/webhooks/{webhookId}/test" \
  -H "Authorization: Bearer SEU_TOKEN" \
  -d '{
    "instanceId": "sua-instancia"
  }'

Atualizar Webhook

curl -X PATCH "https://api.wapizap.com/api/v2/webhooks/{webhookId}" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer SEU_TOKEN" \
  -d '{
    "instanceId": "sua-instancia",
    "url": "https://novo-servidor.com/webhook",
    "events": ["message", "message.ack"]
  }'

Listar Webhooks

curl -X GET "https://api.wapizap.com/api/v2/webhooks?instanceId=sua-instancia" \
  -H "Authorization: Bearer SEU_TOKEN"

Deletar Webhook

curl -X DELETE "https://api.wapizap.com/api/v2/webhooks/{webhookId}?instanceId=sua-instancia" \
  -H "Authorization: Bearer SEU_TOKEN"

Melhores Práticas

Responda Rápido

Sempre responda com HTTP 200 em menos de 5 segundos. Processe dados de forma assíncrona.

Valide Assinaturas

Use o secret para validar que a requisição vem da Wapizap.

Use HTTPS

Sua URL de webhook deve usar HTTPS em produção.

Seja Idempotente

Webhooks podem ser reenviados. Use o messageId para detectar duplicatas.

Tratamento de Falhas

Se seu servidor não responder com 2xx:
  • 1ª tentativa: Imediata
  • 2ª tentativa: Após 1 minuto
  • 3ª tentativa: Após 5 minutos
  • 4ª tentativa: Após 30 minutos
  • Após 4 falhas, o webhook é marcado como inativo

Desenvolvimento Local

Para testar webhooks em desenvolvimento local, use um túnel:

ngrok

# Instalar ngrok
npm install -g ngrok

# Criar túnel
ngrok http 3000

# Use a URL gerada (ex: https://abc123.ngrok.io)

Cloudflare Tunnel

# Instalar cloudflared
brew install cloudflared

# Criar túnel
cloudflared tunnel --url http://localhost:3000

Debugging

Verificar Logs

No dashboard, você pode ver o histórico de webhooks enviados:
  • Status de entrega
  • Payload enviado
  • Resposta recebida
  • Tempo de resposta

Problemas Comuns

ProblemaSolução
Webhook não chegaVerifique se a URL é acessível publicamente
TimeoutProcesse de forma assíncrona, responda em < 5s
Assinatura inválidaVerifique se o secret está correto
Eventos duplicadosUse messageId para deduplicação

Próximos Passos