Skip to main content

O que são Webhooks?

Webhooks são “callbacks HTTP” - quando um evento acontece (mensagem recebida, entrega confirmada), o EnviaAI envia os dados para uma URL que você define.

Setup Rápido

1

Criar endpoint

Crie um endpoint POST no seu servidor
2

Expor na internet

Use ngrok para desenvolvimento ou deploy em produção
3

Registrar webhook

Configure a URL no EnviaAI
4

Testar

Envie um evento de teste

1. Criar o Endpoint

Express.js (Node.js)

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

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

const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;

// Verificar assinatura
function verifySignature(payload, signature) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', WEBHOOK_SECRET)
    .update(JSON.stringify(payload))
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature || ''),
    Buffer.from(expected)
  );
}

app.post('/webhooks/enviaai', (req, res) => {
  // Verificar assinatura
  const signature = req.headers['x-enviaai-signature'];
  if (!verifySignature(req.body, signature)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  // Responder imediatamente
  res.status(200).json({ received: true });

  // Processar em background
  handleWebhook(req.body);
});

async function handleWebhook({ event, data, timestamp }) {
  console.log(`[${timestamp}] ${event}:`, data);

  switch (event) {
    case 'message.received':
      await onMessageReceived(data);
      break;
    case 'message.sent':
      await onMessageSent(data);
      break;
    case 'message.delivered':
      await onMessageDelivered(data);
      break;
    case 'message.read':
      await onMessageRead(data);
      break;
    case 'message.failed':
      await onMessageFailed(data);
      break;
    case 'instance.connected':
      await onInstanceConnected(data);
      break;
    case 'instance.disconnected':
      await onInstanceDisconnected(data);
      break;
  }
}

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

FastAPI (Python)

from fastapi import FastAPI, Request, HTTPException, BackgroundTasks
import hmac
import hashlib
import os

app = FastAPI()
WEBHOOK_SECRET = os.environ.get('WEBHOOK_SECRET')

def verify_signature(payload: bytes, signature: str) -> bool:
    expected = 'sha256=' + hmac.new(
        WEBHOOK_SECRET.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature or '', expected)

@app.post('/webhooks/enviaai')
async def webhook(request: Request, bg: BackgroundTasks):
    body = await request.body()
    signature = request.headers.get('x-enviaai-signature')

    if not verify_signature(body, signature):
        raise HTTPException(401, 'Invalid signature')

    data = await request.json()
    bg.add_task(handle_webhook, data)

    return {'received': True}

async def handle_webhook(data: dict):
    event = data.get('event')
    payload = data.get('data')

    print(f"Event: {event}")

    if event == 'message.received':
        await on_message_received(payload)
    elif event == 'message.delivered':
        await on_message_delivered(payload)
    # ... outros eventos

2. Expor na Internet

Desenvolvimento (ngrok)

# Instalar
npm install -g ngrok

# Autenticar (opcional, para URLs fixas)
ngrok authtoken seu_token

# Expor porta 3000
ngrok http 3000
Saída:
Forwarding: https://abc123.ngrok.io -> http://localhost:3000

Produção

Deploy em qualquer plataforma:
  • Vercel: vercel deploy
  • Railway: railway up
  • Render: Push para GitHub
  • AWS Lambda: Serverless

3. Registrar o Webhook

Via API

const webhook = await client.webhooks.create({
  url: 'https://abc123.ngrok.io/webhooks/enviaai',
  instanceId: 'inst_abc123',
  events: [
    'message.received',
    'message.sent',
    'message.delivered',
    'message.read',
    'message.failed',
    'instance.connected',
    'instance.disconnected'
  ],
  secret: 'seu-secret-seguro-aqui'
});

console.log('Webhook criado:', webhook.id);

Via Developer Portal

  1. Acesse dev.enviaai.app/webhooks
  2. Clique em “Criar Webhook”
  3. Preencha a URL e selecione eventos
  4. Copie o secret gerado

4. Testar

Via API

await client.webhooks.test(webhook.id);
// Envia um evento de teste para sua URL

Via cURL

# Simular um webhook localmente
curl -X POST http://localhost:3000/webhooks/enviaai \
  -H "Content-Type: application/json" \
  -H "X-EnviaAI-Signature: sha256=..." \
  -d '{
    "event": "message.received",
    "timestamp": "2026-02-03T12:00:00Z",
    "data": {
      "messageId": "msg_test",
      "from": "5511999999999",
      "content": "Teste"
    }
  }'

Eventos Disponíveis

Mensagens

EventoQuando
message.receivedNova mensagem recebida
message.sentMensagem enviada ao WhatsApp
message.deliveredMensagem entregue ao destinatário
message.readDestinatário leu a mensagem
message.failedFalha no envio

Instância

EventoQuando
instance.connectedInstância conectou
instance.disconnectedInstância desconectou
instance.qr_updatedNovo QR Code gerado

Payloads de Exemplo

{
  "event": "message.received",
  "timestamp": "2026-02-03T12:00:00.000Z",
  "data": {
    "messageId": "msg_abc123",
    "instanceId": "inst_xyz789",
    "chatId": "chat_def456",
    "from": "5511999999999",
    "type": "text",
    "content": "Olá!",
    "contactName": "João Silva",
    "isGroup": false
  }
}
{
  "event": "message.delivered",
  "timestamp": "2026-02-03T12:00:05.000Z",
  "data": {
    "messageId": "msg_abc123",
    "instanceId": "inst_xyz789",
    "to": "5511999999999",
    "deliveredAt": "2026-02-03T12:00:05.000Z"
  }
}
{
  "event": "instance.disconnected",
  "timestamp": "2026-02-03T12:00:00.000Z",
  "data": {
    "instanceId": "inst_xyz789",
    "reason": "logged_out"
  }
}

Boas Práticas

Responda rápido

Retorne 200 em menos de 5 segundos

Processe async

Use filas para processamento pesado

Verifique assinatura

Sempre valide em produção

Seja idempotente

Use messageId para evitar duplicatas

Retry e Falhas

Se seu endpoint falhar:
TentativaDelay
1Imediato
230s
32min
410min
51h
66h
Após 6 tentativas, o evento é descartado.

Logs e Debug

Veja os logs de entrega no Developer Portal ou via API:
const logs = await client.webhooks.getLogs(webhook.id, {
  limit: 50
});

logs.forEach(log => {
  console.log(`${log.timestamp} - ${log.event}: ${log.status}`);
});