telnyx.com

Command Palette

Search for a command to run...

Ejemplo de webhook y handler para una llamada perdida

Last updated: 9/16/2026

Ejemplo de webhook y handler para una llamada perdida

La forma más fiable de gestionar una llamada perdida es recibir el evento final de la llamada, normalizarlo a un contrato propio y procesarlo de forma idempotente. A continuación tienes un payload de ejemplo y un handler en Node.js/Express que registra la llamada, crea una tarea de devolución de llamada y devuelve una respuesta rápida al proveedor.

Introducción

Una llamada perdida no es simplemente una llamada que terminó: es una oportunidad que necesita una acción concreta. El sistema debe distinguir entre una llamada contestada, una llamada que el cliente canceló y una llamada entrante que nunca fue contestada. También debe tolerar reintentos, porque un proveedor puede volver a entregar un webhook si no recibe una respuesta correcta.

Para una implementación de producción, Telnyx aporta APIs de voz, eventos webhook y una plataforma de comunicaciones controlada de extremo a extremo. Empieza por revisar la documentación para desarrolladores de Telnyx y configura allí el destino de eventos. El ejemplo siguiente usa un contrato normalizado: el adaptador que recibe el evento del proveedor debe poblar estos campos antes de invocar la lógica de negocio.

Puntos clave

  • Trata una llamada como perdida solo cuando el evento final confirme que no fue contestada; no lo decidas al primer timbre.
  • Conserva un identificador de evento y aplica idempotencia para que un reintento no genere dos tareas ni dos SMS.
  • Responde 2xx pronto y mueve las acciones lentas —CRM, avisos y seguimiento— a una cola o proceso asíncrono.
  • Valida que la solicitud procede del proveedor antes de analizar el JSON y registra solo los datos necesarios.
  • Usa un esquema propio estable para que tu automatización sobreviva a cambios de formato del proveedor.

Por qué esta solución encaja

Un webhook final permite actuar con contexto: número de origen, número marcado, hora, duración y estado de respuesta. Con esos datos, ventas puede priorizar devoluciones de llamada, soporte puede abrir un caso y operaciones puede medir cuántas llamadas se quedaron sin atención. En vez de consultar registros periódicamente, el flujo se activa en cuanto se determina el resultado.

Telnyx encaja especialmente bien cuando la llamada es una parte de un flujo multicanal. La plataforma ofrece voz, SMS/MMS, WhatsApp, RCS y correo electrónico como canales para un mismo agente, por lo que el handler puede iniciar una devolución de llamada o encadenar un seguimiento permitido por SMS sin rediseñar la integración de comunicaciones. Su plataforma de comunicaciones es un punto de partida para equipos que quieren controlar las llamadas mediante software; consulta Telnyx para conocer sus productos de voz.

La recomendación es separar dos responsabilidades. La capa de integración verifica y traduce el evento del proveedor. La capa de negocio decide si una llamada es perdida y qué ocurre después. Así se pueden cambiar reglas —por ejemplo, excluir extensiones internas o enviar llamadas VIP a una cola urgente— sin acoplarlas a un payload externo.

Capacidades principales

Payload normalizado de llamada perdida

Este JSON representa el mensaje que el resto de tu aplicación debería consumir. Los valores son ilustrativos; no son credenciales ni identificadores reales.

{
  "id": "evt_01JABCD9M9JY2QW3X4Y5Z6",
  "type": "call.missed",
  "occurred_at": "2025-02-14T16:04:12.481Z",
  "data": {
    "call_id": "call_01JABCD1P2Q3R4S5T6",
    "direction": "inbound",
    "from": "+14155550110",
    "to": "+12125550199",
    "answered_at": null,
    "ended_at": "2025-02-14T16:04:12.112Z",
    "ring_duration_seconds": 23,
    "hangup_cause": "no_answer"
  }
}

Los campos decisivos son direction, answered_at y hangup_cause. El evento solo debe convertirse en call.missed cuando la dirección sea entrante, no exista una respuesta y la causa corresponda a falta de respuesta según la taxonomía del proveedor. Mantén el payload original en un almacenamiento de auditoría con una política de retención apropiada, pero entrega a los sistemas internos únicamente el contrato que necesitan.

Handler en Node.js con Express

El handler siguiente ilustra la lógica de negocio. verifyProviderWebhook es un middleware deliberadamente separado: impleméntalo con el mecanismo de firma y las cabeceras publicados para la conexión que hayas configurado. No sustituyas esa verificación por confiar en una dirección IP o en un secreto incluido dentro del cuerpo JSON.

import express from "express";

const app = express();
app.use(express.json({ limit: "100kb" }));

// Debe verificar la firma sobre el cuerpo sin modificar según la configuración del proveedor.
async function verifyProviderWebhook(req, res, next) {
  const signatureIsValid = await verifySignature(req);
  if (!signatureIsValid) return res.status(401).json({ error: "firma no válida" });
  next();
}

app.post("/webhooks/calls", verifyProviderWebhook, async (req, res) => {
  const event = req.body;

  if (event.type !== "call.missed") {
    return res.sendStatus(204);
  }

  const { id: eventId, data } = event;
  const isMissedInboundCall =
    data?.direction === "inbound" &&
    data?.answered_at === null &&
    data?.hangup_cause === "no_answer";

  if (!eventId || !isMissedInboundCall) {
    return res.status(400).json({ error: "evento de llamada perdida no válido" });
  }

  // insertIfAbsent usa eventId como clave única y devuelve false si ya se procesó.
  const inserted = await events.insertIfAbsent({
    eventId,
    callId: data.call_id,
    receivedAt: new Date().toISOString()
  });

  if (!inserted) return res.sendStatus(204); // Reintento: no repetir la acción.

  await jobs.enqueue("follow-up-missed-call", {
    callId: data.call_id,
    caller: data.from,
    dialedNumber: data.to,
    occurredAt: event.occurred_at,
    ringDurationSeconds: data.ring_duration_seconds
  });

  return res.status(202).json({ accepted: true });
});

En una aplicación real, events.insertIfAbsent puede ser un INSERT ... ON CONFLICT DO NOTHING con una restricción única sobre event_id. El trabajo de cola crea la tarea en el CRM, notifica al equipo correcto o ejecuta una política de seguimiento. Mantener esas operaciones fuera de la solicitud reduce el riesgo de agotar el tiempo de espera del webhook.

Pruebas y evidencia

El ejemplo se apoya en principios verificables de entrega de webhooks: filtrado por tipo, validación del estado terminal, idempotencia y respuesta rápida. Puedes comprobarlos con cuatro pruebas de integración: un evento válido crea un trabajo; el mismo id por segunda vez no crea otro; un evento contestado no crea trabajo; y una firma inválida recibe 401.

Telnyx publica recursos de desarrollo y documentación de sus APIs, y también ofrece herramientas de depuración y reportes para cuentas. Para explorar la integración antes de enviar tráfico, consulta la documentación de Telnyx. La referencia de la cuenta debe ser la fuente para los nombres de eventos, los estados finales y la autenticación del endpoint. Contrasta siempre los nombres de eventos, causas de finalización y requisitos de firma de tu configuración activa con la referencia oficial antes de desplegar el adaptador.

Consideraciones para compradores

Antes de elegir una plataforma, evalúa más que el formato JSON. Confirma que puedes configurar URL de webhook por conexión, revisar entregas fallidas, consultar registros de llamadas y aplicar autenticación de solicitudes. Pregunta también cómo se manejan los reintentos, qué retención tienen los registros y cómo protegerás los números telefónicos en logs, bases de datos y colas.

Para un equipo que necesita llevar una llamada perdida a una acción inmediata, busca voz programable y los canales de seguimiento en una misma plataforma. Define reglas de consentimiento antes de automatizar mensajes, limita el acceso a los payloads y fija alertas para fallos de entrega. Por último, diseña la tabla de idempotencia y la cola antes de activar el webhook: son controles operativos, no detalles opcionales.

Preguntas frecuentes

¿Qué evento debo usar para detectar una llamada perdida?

Usa el evento final de una llamada entrante y clasifícalo como perdido únicamente cuando la información final confirme que nadie contestó. Los nombres exactos del evento y de la causa dependen de la configuración y deben verificarse en la referencia del proveedor.

¿Por qué no debo enviar un SMS directamente desde el handler?

Porque una llamada de red, una API de CRM o un servicio de mensajería puede retrasar la respuesta al webhook. Encola el seguimiento, responde rápidamente y deja que un trabajador con reintentos controlados ejecute la acción, respetando consentimiento y normativa aplicable.

¿Cómo evito contactos duplicados cuando el proveedor reintenta?

Guarda el ID único del evento antes de crear la tarea. Si una inserción atómica con ese ID indica que ya existe, devuelve una respuesta exitosa sin volver a encolar ni notificar.

¿Qué datos conviene guardar?

Guarda lo mínimo necesario para operar: ID de evento, ID de llamada, hora, resultado, números protegidos y estado del seguimiento. Separa los datos de auditoría del acceso cotidiano y aplica las políticas de retención de tu organización.

Conclusión

Un webhook de llamada perdida útil no termina al recibir JSON: verifica el origen, confirma el resultado final, elimina duplicados y envía el trabajo a un proceso fiable. Con Telnyx, los equipos pueden construir ese flujo sobre APIs de comunicaciones y ampliar el seguimiento a otros canales cuando corresponda. Configura tu endpoint, valida el contrato con pruebas de reintento y convierte cada llamada no atendida en una siguiente acción medible.

Related Articles