Skip to main content
Los webhooks te avisan cuando ocurren eventos: nuevos mensajes, leads capturados, cambios de estado.

Configurar un webhook

  1. Andá a SettingsWebhooks
  2. Click en “Nuevo Webhook”
  3. Ingresá la URL de tu endpoint
  4. Seleccioná los eventos
  5. Guardá

Eventos disponibles

EventoCuándo se dispara
conversation.createdNueva conversación
conversation.message.createdNuevo mensaje
conversation.status.changedCambio de estado
lead.capturedLead capturado

Formato del payload

{
  "id": "evt_abc123",
  "type": "conversation.message.created",
  "timestamp": "2024-01-21T15:30:00Z",
  "data": {
    "conversationId": "conv_abc123",
    "messageId": "msg_xyz789",
    "role": "user",
    "content": "Hola, necesito ayuda",
    "contact": {
      "email": "cliente@ejemplo.com"
    }
  }
}

Ejemplos

Nuevo mensaje

{
  "type": "conversation.message.created",
  "data": {
    "conversationId": "conv_abc123",
    "content": "Hola, necesito ayuda",
    "role": "user"
  }
}

Lead capturado

{
  "type": "lead.captured",
  "data": {
    "conversationId": "conv_abc123",
    "contact": {
      "email": "lead@ejemplo.com",
      "firstName": "María",
      "phoneNumber": "+5491123456789"
    }
  }
}

Verificar firma

Cada webhook incluye una firma en X-Horneross-Signature:
const crypto = require('crypto');

function verificarWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(payload))
    .digest('hex');

  return signature === expected;
}

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

  if (!verificarWebhook(req.body, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Firma inválida');
  }

  // Procesar evento
  console.log('Evento:', req.body.type);

  res.status(200).send('OK');
});

Reintentos

Si tu endpoint no responde 200, reintentamos:
IntentoDelay
1Inmediato
21 minuto
35 minutos
430 minutos
52 horas

Ejemplo: Notificar a Slack

app.post('/webhook', async (req, res) => {
  const { type, data } = req.body;

  if (type === 'lead.captured') {
    await fetch(process.env.SLACK_WEBHOOK, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        text: `🎯 Nuevo lead: ${data.contact.email}`
      })
    });
  }

  res.status(200).send('OK');
});

Ejemplo: Sincronizar con CRM

app.post('/webhook', async (req, res) => {
  const { type, data } = req.body;

  if (type === 'conversation.status.changed' && data.newStatus === 'resolved') {
    await crm.closeTicket(data.conversationId);
  }

  res.status(200).send('OK');
});
Usá webhook.site para testear sin necesidad de un servidor.