Webhooks
Los webhooks le permiten recibir notificaciones en tiempo real cuando ocurren eventos en su widget de chat. Cuando un visitante inicia un chat, envía un formulario o envía un mensaje, Chatim envía una solicitud HTTP POST a su URL con los datos del evento.
Descripcion general
Con los webhooks puede:
- Enviar nuevos leads a su CRM automaticamente
- Activar flujos de trabajo en Zapier, Make o aplicaciones personalizadas
- Registrar eventos de chat en su plataforma de analisis
- Notificar a su equipo en Slack u otras herramientas
- Sincronizar datos de visitantes con su base de datos
Acceder a Webhooks
- Inicie sesion en su panel de Chatim
- Seleccione su proyecto desde la barra lateral
- Haga clic en Webhooks en el menu de navegacion
Crear un Webhook
- Haga clic en Crear Webhook
- Ingrese un Nombre opcional (ej., "Integracion CRM")
- Ingrese la URL donde se deben enviar los eventos
- Seleccione uno o mas Eventos que desea recibir
- Haga clic en Crear
Despues de la creacion, vera un Secreto del Webhook - copielo y guardelo inmediatamente. Este secreto se usa para verificar que las solicitudes entrantes provienen de Chatim. Solo se muestra una vez.
Eventos compatibles
| Evento | Se activa cuando |
|---|---|
chat.started | Un visitante abre el widget de chat y comienza una nueva sesion |
chat.message.received | Un visitante envia un mensaje de texto |
chat.form.submitted | Un visitante envia un formulario en el flujo del chatbot |
chat.closed | Se cierra una sesion de chat |
chat.assigned | Un agente de soporte se une a la conversacion |
chat.handoff | El chatbot hace la transicion del modo bot al chat en vivo |
Carga del Webhook
Cada entrega de webhook es una solicitud HTTP POST con un cuerpo JSON.
Campos comunes
{
"event": "chat.started",
"eventId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": "2025-01-15T10:30:00.000Z",
"projectUuid": "your-project-uuid",
"chatUuid": "visitor-chat-uuid",
"data": { }
}chat.started
Incluye informacion del visitante, URL de la pagina, ubicacion y agente de usuario.
{
"event": "chat.started",
"data": {
"visitor": {
"uuid": "visitor-uuid",
"name": "John Doe",
"email": "[email protected]",
"phone": "+1234567890"
},
"page": {
"url": "https://example.com/pricing",
"title": "Pricing - Example"
},
"location": { "country": "US", "city": "Los Angeles" },
"userAgent": { "browser": "Chrome", "os": "Windows", "device": "Desktop" }
}
}chat.message.received
{
"event": "chat.message.received",
"data": {
"messageUuid": "message-uuid",
"message": "Hi, I have a question about your pricing.",
"visitor": { "uuid": "visitor-uuid", "name": "John Doe" }
}
}chat.form.submitted
{
"event": "chat.form.submitted",
"data": {
"formNodeId": "node-id",
"formName": "Contact Form",
"fields": {
"name": "John Doe",
"email": "[email protected]",
"phone": "+1234567890",
"message": "I'd like a product demo."
},
"visitor": { "uuid": "visitor-uuid", "name": "John Doe" }
}
}chat.closed
Incluye quien cerro el chat (agent, visitor, system o timeout), duracion en segundos, cantidad de mensajes y transcripcion.
{
"event": "chat.closed",
"data": {
"closedBy": "agent",
"status": "closed",
"duration": 345,
"messageCount": 12,
"visitor": { "uuid": "visitor-uuid", "name": "John Doe" }
}
}chat.assigned
Se envia cuando un agente de soporte se une a la conversacion.
{
"event": "chat.assigned",
"data": {
"assignedTo": { "uuid": "agent-uuid", "name": "Jane Smith" },
"visitor": { "uuid": "visitor-uuid", "name": "John Doe" }
}
}chat.handoff
Se envia cuando el chatbot hace la transicion al modo de chat en vivo.
{
"event": "chat.handoff",
"data": {
"reason": "Visitor requested human support",
"fromNode": "node-id",
"visitor": { "uuid": "visitor-uuid", "name": "John Doe" }
}
}Seguridad
Verificacion de firma
Cada solicitud de webhook incluye una firma para que pueda verificar que proviene de Chatim. La firma se calcula como HMAC-SHA256(secret, timestamp + "." + payload) y se envia en el encabezado X-Chatim-Signature.
Encabezados de solicitud
| Encabezado | Descripcion |
|---|---|
X-Chatim-Signature | Firma HMAC-SHA256 de la carga |
X-Chatim-Timestamp | Marca de tiempo Unix de cuando se envio la solicitud |
X-Chatim-Event | El tipo de evento |
X-Chatim-Delivery-Id | Identificador unico de entrega |
Ejemplo de verificacion en Node.js
const crypto = require('crypto');
function verifyWebhook(req, secret) {
const signature = req.headers['x-chatim-signature'];
const timestamp = req.headers['x-chatim-timestamp'];
const body = JSON.stringify(req.body);
// Reject requests older than 5 minutes
const age = Math.floor(Date.now() / 1000) - parseInt(timestamp);
if (age > 300) return false;
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(timestamp + '.' + body)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}Ejemplo de verificacion en Python
import hmac, hashlib, time
def verify_webhook(headers, body, secret):
signature = headers.get('X-Chatim-Signature', '')
timestamp = headers.get('X-Chatim-Timestamp', '')
if abs(time.time() - int(timestamp)) > 300:
return False
expected = 'sha256=' + hmac.new(
secret.encode(),
f'{timestamp}.{body}'.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)Logica de reintentos
Si su endpoint no esta disponible o devuelve un error, Chatim reintenta automaticamente.
| Intento | Retraso |
|---|---|
| 1er reintento | 1 minuto |
| 2do reintento | 5 minutos |
| 3er reintento | 30 minutos |
| 4to reintento | 2 horas |
| 5to reintento | 24 horas |
Despues de 5 reintentos fallidos, la entrega se marca como fallida. Las respuestas 2xx se tratan como exito, 4xx como fallos permanentes (sin reintento), 5xx y tiempos de espera (30s) activan reintentos.
Si un webhook acumula 10 fallos consecutivos, se desactiva automaticamente. Puede reactivarlo desde el panel despues de solucionar el problema.
Administrar Webhooks
Pruebas
Haga clic en Probar en cualquier webhook para enviar un evento de ejemplo chat.started a su URL. Esto le permite verificar su endpoint antes de ponerlo en produccion.
Historial de entregas
Haga clic en un webhook para ver las entregas recientes con tipo de evento, marca de tiempo, codigo de estado HTTP y mensajes de error. El historial se conserva durante 30 dias.
Regenerar un secreto
Si su secreto de webhook se ve comprometido, haga clic en Regenerar secreto, guarde el nuevo secreto y actualice su endpoint. El secreto anterior se invalida inmediatamente.
Casos de uso
Integracion CRM
Suscribase a chat.form.submitted y chat.started para crear automaticamente contactos y leads en su CRM.
Notificaciones de Slack
Suscribase a chat.assigned y chat.handoff para alertar a su equipo cuando un visitante necesita soporte en vivo.
Analisis
Suscribase a todos los eventos para obtener una imagen completa del compromiso del chat, tasas de conversion de formularios y tiempos de respuesta del soporte.
Automatizacion de email
Suscribase a chat.form.submitted para activar emails de bienvenida, secuencias de seguimiento o mensajes de confirmacion.
Mejores practicas
- Devuelva una respuesta 2xx rapidamente - procese los datos de forma asincrona
- Use HTTPS para la URL de su endpoint
- Siempre verifique la firma del webhook antes de procesar
- Implemente idempotencia usando el
eventIdpara manejar entregas duplicadas - Almacene su secreto de webhook de forma segura (variable de entorno, gestor de secretos)
- Valide la marca de tiempo para prevenir ataques de repeticion (rechace solicitudes de mas de 5 minutos)
Solucion de problemas
El Webhook no recibe eventos
- Verifique que el webhook este Activo (no desactivado)
- Verifique que la URL sea correcta y accesible publicamente
- Use el boton de Probar para enviar un evento de ejemplo
- Revise los registros de su servidor en busca de solicitudes entrantes
- Asegurese de que su endpoint devuelva un codigo de estado 2xx
Webhook desactivado automaticamente
- Verifique la razon de desactivacion en el panel
- Solucione el problema subyacente (endpoint caido, devolviendo errores)
- Haga clic en Activar para reactivar
- Use Probar para verificar antes de reactivar
La verificacion de firma falla
- Asegurese de estar usando el secreto correcto
- Verifique que este firmando
timestamp + "." + raw_body(no JSON parseado) - Use comparacion segura en tiempo para prevenir ataques de tiempo