Enviar alertas a un webhook

5 min de lectura174
Copiar para la IA:

Además del correo y Slack, una alerta puede llamar a una dirección de tu propio sistema. Así abres un ticket automáticamente, guardas el evento en tu base de datos o disparas un flujo en Zapier, Make o n8n — todos aceptan recibir un webhook, sin integración dedicada. El ejemplo de este artículo es la alerta "NPS crítico" de la encuesta posatención.

Cómo configurarlo

  1. En Alertas, haz clic en Nueva Alerta (o edita una existente). Solo el administrador de la cuenta configura alertas.
  2. Completa Nombre de la Alerta, Condición y Encuesta, como en cualquier alerta.
  3. En Métodos de Notificación, activa Webhook e informa la URL del endpoint.
  4. Guarda y abre la alerta otra vez en edición: aparece la Clave de firma (empieza con whsec_), con el botón Copiar. Guárdala en tu sistema — con ella confirmas que la llamada vino de nosotros.

Requisitos de la URL

  • Debe usar HTTPS y tener como máximo 255 caracteres.
  • Debe ser accesible desde internet. Las direcciones internas (localhost, 192.168.x.x, 10.x.x.x, dominios .local) se rechazan al guardar.
  • No respondas con redirección: la llamada va solo a la dirección informada, y una respuesta de redirección cuenta como falla.

Qué enviamos

Un POST con los encabezados Content-Type: application/json y Signature, y un cuerpo con este formato:

{ "event": "alert.triggered", "alert": { "id": "12", "name": "NPS crítico", "condition": "nps_below", "threshold": 30 }, "survey": { "id": "01J9Z3K8TQ4M2X7V5B6N0P1R2S", "title": "Posatención" }, "context": { "current_nps": "12", "threshold": "30", "window": "Últimos 30 días", "responses": "48" }, "triggered_at": "2026-07-27T15:34:56+00:00" }
  • event es siempre alert.triggered.
  • condition es un código estable, no un texto traducido: nps_below, nps_above, sentiment_negative, no_response, response_rate_below, new_feedback o question_average_below. Puedes usarlo en un switch.
  • alert.threshold es un número entero, o null en las condiciones sin valor.
  • survey trae la encuesta que disparó. En una alerta para todas las encuestas, es la primera que cumplió la condición.
  • triggered_at viene en ISO 8601 con el desplazamiento de zona horaria — lee el desplazamiento en lugar de suponer la hora.

Las claves de context

Todos los valores de context son texto (string). Las claves cambian según la condición:

  • nps_below y nps_above: current_nps, threshold, window, responses.
  • question_average_below: question (el texto de la pregunta), current_average (con un decimal, como "2.4"), threshold, window, responses.
  • sentiment_negative: count, latest_comment (hasta 180 caracteres), window.
  • no_response: last_response (fecha en formato AAAA-MM-DD), days_since (∞ si nunca hubo respuesta), threshold.
  • response_rate_below: current_rate y threshold (con el símbolo %, como "12.5%"), sent, responses.
  • new_feedback: comment (hasta 200 caracteres), score (nota y máximo de la escala, como "4/10"; no viene cuando la respuesta no tiene nota, como en un cuestionario sin pregunta que cuente en el NPS), when (fecha y hora, sin zona horaria).

Atención: condition y las claves de context son códigos estables, pero algunos valores salen como texto en el idioma del dueño de la cuenta — window, latest_comment cuando no hay comentario y last_response cuando la encuesta nunca recibió respuesta. No compares esos valores como si fueran códigos — para decidir, usa condition.

Verificando la firma

El encabezado Signature es el HMAC-SHA256, en hexadecimal, del cuerpo de la solicitud usando tu clave de firma. Calcúlalo sobre el cuerpo bruto, exactamente como llegó — si decodificas el JSON y lo vuelves a codificar, los acentos y las barras cambian de forma y la firma no coincide. Verifícala antes de actuar sobre el contenido: sin eso, quien descubra tu URL puede falsificar una alerta.

En PHP:

$cuerpoBruto = file_get_contents('php://input'); $esperado = hash_hmac('sha256', $cuerpoBruto, $tuClave); if (! hash_equals($esperado, $_SERVER['HTTP_SIGNATURE'] ?? '')) { http_response_code(403); exit; }

En Node.js (con el cuerpo bruto en rawBody):

const esperado = crypto.createHmac('sha256', tuClave).update(rawBody).digest('hex'); const recibido = req.get('Signature') || ''; const valido = recibido.length === esperado.length && crypto.timingSafeEqual(Buffer.from(recibido), Buffer.from(esperado));

Cuándo llega y reintentos

El webhook sigue el ritmo de cualquier alerta: las condiciones se verifican cada 30 minutos y, después de dispararse, la misma alerta espera 6 horas antes de llamar otra vez.

Cualquier respuesta 2xx cuenta como entregada. Cada llamada tiene un límite de 5 segundos; si tu endpoint tarda, da error o redirige, hacemos hasta 3 intentos en total, con esperas crecientes entre ellos. Responde rápido (un 200 inmediato) y procesa después, en segundo plano. Si los tres fallan, la tarjeta de la alerta muestra La última entrega falló; pasa el cursor sobre la marca para ver el destino y el motivo (por ejemplo, Webhook: HTTP 500). El aviso desaparece solo cuando una entrega siguiente al webhook funciona; una entrega exitosa en Slack no borra la falla del webhook, y viceversa.

No hay botón de envío de prueba. Para ver una llamada real, crea una alerta Sin respuesta por con valor 1 en una encuesta que no recibió respuestas en el último día: se dispara en la siguiente verificación.

Privacidad

El payload no identifica a quien respondió: el comentario y la nota van, el nombre y el correo no. En una encuesta anónima, es una promesa hecha al encuestado, y vale también aquí.

Cambiar la URL o quitarla

Cambiar la dirección mantiene la misma clave de firma, así que no necesitas reconfigurar la verificación del otro lado. Desactivar Webhook quita la URL y borra la clave — si lo vuelves a activar, se genera una clave nueva.

A dónde ir después

  • Alertas — las condiciones y con qué frecuencia avisa cada una.
  • Recibir alertas en Slack — el mismo aviso en el canal del equipo.

En resumen: activa Webhook en la alerta, informa una URL HTTPS pública, guarda la clave de firma y valida el encabezado Signature sobre el cuerpo bruto antes de actuar.

¿Te resultó útil este artículo?