Webhooks de chat en vivo

Los webhooks permiten que onWebChat envíe eventos a tu propio servidor en tiempo real. Cada vez que ocurre algo (se inicia un chat, se envía un mensaje, se cierra o se valora un chat, o un visitante deja un mensaje fuera de línea), enviamos una petición HTTP POST con un cuerpo JSON a la URL que elijas.

Es la forma más sencilla de sincronizar las transcripciones de los chats con tu CRM o CMS, enviar correos de seguimiento, crear informes personalizados o avisar a otro sistema, sin necesidad de hacer consultas periódicas (polling).

Los webhooks están disponibles en todos los planes de pago y durante la prueba gratuita de 14 días. Cada entrega está firmada para que puedas verificar que realmente procede de onWebChat.



POST https://your-server.com/onwebchat-webhook
Content-Type: application/json
User-Agent: onWebChat-Webhooks/1.0
X-OWC-Event: chat.closed
X-OWC-Delivery: 9381
X-OWC-Signature: sha256=4f1c...c2a9

{ "event": "chat.closed", "siteid": 1234, ... }

Configurar webhooks

Inicia sesión en tu panel como administrador y ve a Configuración → Webhooks. Haz clic en «Agregar endpoint», pega la URL que debe recibir los eventos, elige los eventos que quieras (o selecciona «Todos los eventos», que también incluye los que añadamos más adelante) y guarda.

Al crear un endpoint, generamos para él un secreto de firma (empieza por whsec_). Usarás este secreto para verificar las solicitudes entrantes (consulta Verificar firmas más abajo). Puedes regenerar el secreto en cualquier momento; el anterior deja de funcionar de inmediato.

Puedes añadir varios endpoints por sitio web y revisar las entregas recientes, con el estado HTTP, el número de intentos y cualquier error, directamente en el panel.



/* Dashboard → Settings → Webhooks */

URL      : https://your-server.com/onwebchat-webhook
Events   : chat.closed, message.created
Secret   : whsec_3f9a...   (used to verify requests)
Status   : Enabled

Tipos de evento

Suscríbete a cualquier combinación de los eventos siguientes. Cada mensaje lleva un campo "author": visitor, agent o ai (y trigger, para los mensajes de disparadores en la transcripción de chat.closed), así que el mismo evento message.created cubre las conversaciones atendidas por tu equipo y por el chatbot de IA.

Evento Se envía cuando
chat.createdSe inicia un chat nuevo (diálogo). El campo source indica cómo: visitor, trigger o agent.
chat.assignedUn agente se hace cargo de un chat: lo recoge, lo toma de otro agente o del chatbot de IA, o acepta una transferencia. El campo source es pickup, reassign, ai_takeover o transfer.
message.createdSe envía un mensaje nuevo en un chat. Incluye los mensajes del visitante, de un agente y del chatbot de IA.
chat.closedUn chat termina. El payload incluye la transcripción completa, los datos del visitante y las etiquetas.
chat.ratedUn visitante valora un chat (de 1 a 5 estrellas).
offline_message.createdUn visitante envía el formulario fuera de línea o de contacto mientras no hay ningún agente disponible.
visitor.updatedUn agente actualiza el nombre, el correo electrónico, el teléfono o las notas del visitante desde el panel de chat.
visitor.bannedUn agente bloquea a un visitante desde el panel de chat.
visitor.unbannedUn agente desbloquea a un visitante bloqueado anteriormente desde el panel de chat.

Formato del payload

Cada webhook es un objeto JSON con el mismo sobre: el nombre del evento, tu siteid, una marca de tiempo ISO-8601 y un objeto de datos cuya forma depende del evento.

El ejemplo muestra un payload de chat.closed, que contiene la conversación completa. Los eventos más pequeños, como message.created o chat.rated, incluyen solo los campos pertinentes.


{
  "event": "chat.closed",
  "siteid": 1234,
  "created_at": "2026-06-22T07:40:52.322Z",
  "data": {
    "chat_id": 1206836,
    "started_at": "22-06-2026 10:40",
    "closed_at": "2026-06-22T07:40:52.322Z",
    "visitor": {
      "name": "Sarah Chen",
      "email": "sarah@example.com",
      "phone": "",
      "notes": "",
      "country_code": "us",
      "country": "United States",
      "os": "Windows 10",
      "browser": "Chrome 149.0"
    },
    "agents": ["Alex"],
    "labels": [{ "name": "sales", "color": "#4caf50" }],
    "messages": [
      { "author": "visitor", "agent_name": "", "text": "pricing info please", "time": "10:40", "date": "22-06-2026" },
      { "author": "ai", "agent_name": "", "text": "Here is a quick overview...", "time": "10:40", "date": "22-06-2026" },
      { "author": "agent", "agent_name": "Alex", "text": "Hi Sarah, I can help with a quote.", "time": "10:41", "date": "22-06-2026" }
    ]
  }
}

Verificar firmas

Cada solicitud incluye una cabecera X-OWC-Signature con un hash HMAC-SHA256 del cuerpo exacto de la solicitud sin procesar, calculado con el secreto de firma de tu endpoint.

Para verificar una solicitud, calcula el HMAC-SHA256 del cuerpo sin procesar con tu secreto y compáralo con el valor de la cabecera (la parte después de "sha256="). Usa una comparación en tiempo constante y aplica el hash siempre sobre el cuerpo sin procesar.

También recibes X-OWC-Event (el nombre del evento) y X-OWC-Delivery (un ID de entrega único que se mantiene igual en los reintentos, así que puedes usarlo para eliminar duplicados). Las solicitudes se envían con el User-Agent onWebChat-Webhooks/1.0.


// Node.js / Express
const crypto = require('crypto');

app.post('/onwebchat-webhook',
  express.raw({ type: '*/*' }), (req, res) => {

  const secret = 'whsec_your_secret';
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(req.body)              // raw Buffer
    .digest('hex');

  const got = req.headers['x-owc-signature'] || '';

  // constant-time compare; guard length first (timingSafeEqual throws on mismatch)
  const a = Buffer.from(got), b = Buffer.from(expected);
  if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) return res.status(401).end();

  const payload = JSON.parse(req.body.toString());
  // ... handle payload.event ...
  res.sendStatus(200);
});

Verificar en PHP

La misma comprobación en PHP: lee el cuerpo sin procesar, recalcula el HMAC con tu secreto y compara con hash_equals().


<?php
$secret  = 'whsec_your_secret';
$payload = file_get_contents('php://input');
$got     = $_SERVER['HTTP_X_OWC_SIGNATURE'] ?? '';
$expected = 'sha256=' . hash_hmac('sha256', $payload, $secret);

if (!hash_equals($expected, $got)) {
    http_response_code(401);
    exit;
}

$event = json_decode($payload, true);
// ... handle $event['event'] ...
http_response_code(200);

Reintentos y desactivación automática

Tu endpoint debe responder con un estado 2xx lo antes posible y, como máximo, en 10 segundos. Cualquier respuesta que no sea 2xx, un tiempo de espera agotado o un error de conexión cuenta como intento fallido.

Las entregas fallidas se reintentan con un intervalo creciente: al cabo de 1 minuto, 5 minutos, 20 minutos, 1 hora y 2 horas (6 intentos en total).

Si 5 entregas seguidas siguen fallando después de todos sus reintentos, el endpoint se desactiva automáticamente y el propietario de la cuenta recibe un correo electrónico. Reactívalo desde el panel cuando hayas resuelto el problema. Si devuelves HTTP 410 (Gone), el endpoint se desactiva de inmediato.



    Attempt 1  → immediately
    Attempt 2  → after  1 minute
    Attempt 3  → after  5 minutes
    Attempt 4  → after 20 minutes
    Attempt 5  → after  1 hour
    Attempt 6  → after  2 hours

    5 failed deliveries in a row → endpoint disabled

Buenas prácticas

  • Verifica siempre la cabecera X-OWC-Signature antes de confiar en un payload.
  • Responde rápido con un 2xx y haz el trabajo pesado de forma asíncrona (en una cola) para no agotar el tiempo de espera.
  • Usa X-OWC-Delivery para eliminar duplicados, ya que la misma entrega puede reintentarse tras un fallo temporal.
  • Sirve tu endpoint mediante HTTPS.
  • Ignora los tipos de eventos desconocidos para que los eventos que añadamos más adelante no rompan tu integración.

¿Listo para empezar? Ver planes o abre Configuración → Webhooks en tu panel.

Usamos cookies para mejorar nuestro sitio web. No se capturan datos personales ni campos de formulario.