Saltar al contenido
Wbiztool

Guías del producto

Webhooks de mensajes entrantes (oyentes)

Un oyente (listener) conecta uno de tus números de WhatsApp con Unibox y puede enviar un webhook de mensajes entrantes a tu servidor. En el panel, los oyentes se gestionan en la página Disparadores Entrantes. Cuando un número es oyente, sus chats se sincronizan con la bandeja de entrada de Unibox y, si agregas una URL de webhook, Wbiztool envía cada mensaje nuevo a tu servidor. Usa los webhooks para registrar conversaciones en un CRM, avisar a tu equipo o crear una respuesta automática.

Antes de empezar#

  • El complemento Unibox. Cuesta $20/mes o $200/año por número de WhatsApp, y la cantidad de oyentes que puedes tener es igual a la cantidad del complemento. Cómpralo en Complementos Disponibles de Facturación y Planes dentro del panel. Sin él, la página Disparadores Entrantes se abre igualmente, pero al hacer clic en Agregar Nuevo Oyente aparece Unibox Add-on Required (se requiere el complemento Unibox) con un botón Subscribe to Unibox Add-on (suscribirse al complemento Unibox).
  • Un número de WhatsApp conectado en la configuración de WhatsApp. Solo se pueden agregar números conectados que todavía no sean oyentes.
  • Debes ser propietario o editor del espacio de trabajo.
  • Para los webhooks: una URL pública (usa https) de 100 caracteres o menos que acepte solicitudes POST con un cuerpo JSON.

Agregar un oyente#

  1. Abre Disparadores Entrantes

    En la barra lateral, abre Unibox y haz clic en Disparadores Entrantes, o ve a Disparadores Entrantes.

  2. Empieza un nuevo oyente

    Haz clic en la tarjeta Agregar Nuevo Oyente.

  3. Elige el número

    Elígelo en Select WhatsApp Number (seleccionar número de WhatsApp). Si la lista dice No available WhatsApp numbers (no hay números de WhatsApp disponibles), todos los números conectados ya son oyentes o no hay ninguno conectado.

  4. Agrega un webhook (opcional)

    Ingresa tu URL del Webhook (Opcional). Cuando escribes una URL, aparece Webhook Events (eventos del webhook): deja marcado Incoming Messages (mensajes entrantes), Outgoing Messages (mensajes salientes) o ambos. Puedes agregar o cambiar la URL más tarde.

  5. Guarda

    Haz clic en Agregar Oyente. El oyente aparece como una tarjeta con el estado Active (activo). Si ingresaste una URL, se crea un secreto de webhook para ella.

Gestionar oyentes#

Cada tarjeta muestra el número, su estado, la URL del Webhook: (o No configurado), la Última Actividad: (cuándo se revisó por última vez si el número tenía mensajes, o Nunca) y el Secreto del Webhook:, oculto hasta que haces clic en el botón del ojo.

Abre el menú de una tarjeta para:

AcciónQué ocurre
EditarCambia la URL del webhook, los eventos del webhook o el secreto. El número no se puede cambiar.
Deshabilitar / HabilitarAl deshabilitarlo, el oyente pasa a Inactive (inactivo): el número deja de sincronizarse con la bandeja de entrada y no se envían webhooks. Al habilitarlo vuelve a estar Active.
EliminarQuita el oyente después de que confirmes. Las conversaciones que ya están en la bandeja de entrada se conservan. Si más adelante vuelves a agregar el mismo número, se restaura el oyente. Si ingresas una URL de webhook al volver a agregarlo, el oyente conserva su secreto de webhook anterior, si tenía uno, en lugar de recibir uno nuevo.

Estados del oyente#

EstadoSignificado
Active (activo)Los mensajes se sincronizan y se envían webhooks mientras el número está conectado.
Pending (pendiente)El número no estaba conectado cuando se creó el oyente, por ejemplo desde Zapier. Haz clic en Habilitar cuando el número esté conectado.
Inactive (inactivo)Deshabilitado. No se sincroniza nada y no se envían webhooks.

Estadísticas#

TarjetaQué muestra
Oyentes ActivosTodos los oyentes de la página, incluidos los deshabilitados.
Números DisponiblesLos números conectados que todavía no son oyentes. Los números cuyo oyente eliminaste siguen contando como usados aquí, así que puede mostrar menos números de los que realmente puedes agregar.
Límite TotalCuántos oyentes permite tu complemento Unibox.
Mensajes HoyTodavía no se contabiliza; siempre muestra 0.

Cambiar la URL o los eventos del webhook#

  1. Abre el oyente

    Haz clic en en la tarjeta y luego en Editar.

  2. Actualiza la configuración

    Cambia la Webhook URL (Optional) (URL del webhook, opcional) y los Webhook Events. Borra la URL para dejar de enviar webhooks de este número: también se elimina su secreto, y se crea uno nuevo si vuelves a agregar una URL.

  3. Guarda

    Haz clic en Update Listener (actualizar oyente).

Regenerar el secreto#

En Edit Listener (editar oyente), haz clic en el botón de actualizar junto a Webhook Secret (secreto del webhook) y confirma. El nuevo secreto se guarda de inmediato, aunque después cierres el cuadro de diálogo sin hacer clic en Update Listener, y a partir de ese momento las solicitudes se firman con él. Actualiza tu servidor con el nuevo secreto de inmediato.

Cómo se entregan los webhooks#

Wbiztool envía una solicitud POST a tu URL por cada mensaje nuevo encontrado cuando se sincroniza el número, algo que ocurre cada pocos minutos mientras el número está conectado y no está ocupado enviando mensajes.

  • Eventos: message_received para los mensajes que te envían a tu número, y message_sent para los mensajes enviados desde él (desde el teléfono, campañas o la API). Solo se envían los eventos marcados en Webhook Events.
  • Las respuestas desde la bandeja de entrada de Unibox normalmente no generan message_sent, porque la bandeja de entrada ya las tiene cuando se ejecuta la sincronización.
  • Respuesta: responde con HTTP 200 en menos de 8 segundos. Cualquier otra respuesta o un tiempo de espera agotado cuenta como entrega fallida.
  • Sin reintentos: cada mensaje se envía una sola vez. Si tu servidor está caído, ese webhook se pierde.
  • Orden: las solicitudes se envían de forma independiente y pueden llegar desordenadas. Ordena por message.timestamp si el orden importa.

Encabezados#

EncabezadoValor
Content-Typeapplication/json
X-Wbiztool-Eventmessage_received o message_sent
X-Wbiztool-TimestampCuándo se envió el webhook, en ISO 8601 UTC. Igual que timestamp en el cuerpo.
X-Wbiztool-Webhook-IdEl ID del oyente. Igual que webhook_id en el cuerpo.
X-Wbiztool-Signaturesha256= seguido de la firma. Se envía siempre que el oyente tiene un secreto, lo que ocurre siempre que hay una URL configurada.

Payload#

Ejemplos de cuerpos de webhook
{
  "event": "message_received",
  "timestamp": "2026-09-16T10:31:12.482913+00:00",
  "webhook_id": 42,
  "whatsapp_client_id": "678",
  "whatsapp_phone": "919812345678",
  "message": {
    "id": "[email protected]_3EB0C1A2B3D4E5F60718",
    "type": "chat",
    "content": "Hi, is my order #4821 out for delivery?",
    "from": "919876543210",
    "from_name": "Aman",
    "to": "919812345678",
    "timestamp": "2026-09-16T10:29:58+00:00",
    "whatsapp_timestamp": 1789554598,
    "direction": "incoming",
    "status": "pending",
    "is_forwarded": false,
    "forwarding_score": 0
  },
  "contact": {
    "whatsapp_id": "[email protected]",
    "phone": "919876543210",
    "name": "Aman",
    "is_group": false,
    "is_business": false
  },
  "organisation": {
    "id": "10314",
    "name": "Acme Stores"
  }
}

Los números, ID y nombres anteriores son ejemplos.

Campos de primer nivel#

CampoTipoDescripción
eventstringmessage_received o message_sent.
timestampstringCuándo se envió el webhook (ISO 8601, UTC).
webhook_idintegerEl ID del oyente.
whatsapp_client_idstringEl ID de tu número de WhatsApp, tal como aparece en la configuración de WhatsApp.
whatsapp_phonestringTu número de WhatsApp.
messageobjectEl mensaje. Consulta más abajo.
contactobjectLa persona o el grupo con quien es la conversación. Consulta más abajo.
organisationobjectid (string) y name de tu espacio de trabajo.
groupobjectSolo en chats de grupo: name, el nombre del grupo.

Campos de message#

CampoTipoDescripción
idstringEl ID de WhatsApp del mensaje. Úsalo para ignorar duplicados.
typestringchat para texto. En los demás casos, el tipo de WhatsApp, como image, video, audio, ptt (nota de voz), document, sticker o location.
contentstringEl texto en los mensajes chat. En los archivos multimedia, una etiqueta: 📸 Image, 🎥 Video, 🎵 Audio, 🎤 Voice Message, 😊 Sticker, Document: seguido del texto del documento (Document cuando no hay texto), o el nombre del tipo con la inicial en mayúscula en cualquier otro caso, como Location. No se incluyen los pies de foto.
fromstringSiempre el número del contacto (o el ID del grupo), en ambas direcciones.
from_namestringEl nombre del contacto o del grupo. Puede estar vacío.
tostringSiempre tu número de WhatsApp, en ambas direcciones.
timestampstringCuándo se envió el mensaje en WhatsApp (ISO 8601, UTC).
whatsapp_timestampintegerLa misma hora como marca de tiempo Unix en segundos.
directionstringincoming o outgoing. Usa este campo, no from y to, para saber la dirección.
statusstringActualmente siempre es pending. No lo uses para saber el estado de entrega o de lectura.
is_forwardedbooleanSi el mensaje fue reenviado.
forwarding_scoreintegerCuántas veces fue reenviado.
mediaobjectEn mensajes multimedia, cuando hay detalles disponibles: filename, mimetype y size en bytes. El archivo en sí no se incluye.
quoted_message_idstringSolo cuando el mensaje responde a otro mensaje.

Campos de contact#

CampoTipoDescripción
whatsapp_idstringEl ID de WhatsApp, como [email protected] para una persona o …@g.us para un grupo.
phonestringEl número sin +, o el ID del grupo en el caso de los grupos.
namestringEl nombre que Wbiztool tiene para el contacto, o el nombre del grupo. Puede estar vacío.
is_groupbooleantrue en los chats de grupo.
is_businessbooleantrue en las cuentas de WhatsApp Business, cuando se sabe.

Verificar la firma#

Cada solicitud se firma con el secreto de tu oyente usando HMAC-SHA256. La firma se calcula sobre el cuerpo sin procesar de la solicitud, exactamente como se recibe, y se envía como sha256= más el resumen hexadecimal en minúsculas en X-Wbiztool-Signature.

Calcula siempre la firma a partir de los bytes sin procesar antes de analizar el JSON. Analizar y volver a codificar el cuerpo lo modifica (por ejemplo, los caracteres no ingleses y los emojis llegan escapados como \uXXXX), y la firma no coincidirá.

// Express: keep the raw body for this route
import crypto from "node:crypto";
import express from "express";

const app = express();
const SECRET = process.env.WBIZTOOL_WEBHOOK_SECRET;

app.post("/wbiztool/webhook", express.raw({ type: "application/json" }), (req, res) => {
  const expected = "sha256=" + crypto.createHmac("sha256", SECRET).update(req.body).digest("hex");
  const received = req.get("X-Wbiztool-Signature") || "";

  const valid =
    received.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
  if (!valid) return res.status(401).send("Invalid signature");

  const data = JSON.parse(req.body.toString("utf8"));
  if (data.event === "message_received") {
    console.log(`New message from ${data.contact.phone}: ${data.message.content}`);
  }
  res.sendStatus(200); // reply quickly; do slow work in the background
});

app.listen(3000);

La firma no cubre el encabezado de la marca de tiempo, así que no protege contra la repetición de una solicitud. Si eso te importa, guarda cada message.id que hayas procesado e ignora las repeticiones.

Solución de problemas#

Mensaje o problemaQué hacer
Unibox Add-on Required al hacer clic en Agregar Nuevo OyenteTu espacio de trabajo no tiene el complemento Unibox. Cómpralo en Complementos Disponibles de Facturación y Planes dentro del panel.
You have reached your unibox numbers limitElimina un oyente que ya no necesites o aumenta la cantidad del complemento.
No available WhatsApp numbersConecta otro número, o ese número ya es un oyente.
This WhatsApp number is already a listenerEdita la tarjeta existente.
Invalid WhatsApp clientEl número se desconectó. Vuelve a conectarlo en la configuración de WhatsApp y recarga la página.
Error que menciona value too long al guardarLa URL del webhook tiene más de 100 caracteres. Usa una URL más corta.
No llega ningún webhookComprueba que el oyente esté Active, que el número esté conectado, que el tipo de evento esté marcado y que tu URL sea pública, con https y un certificado válido. Los mensajes solo se envían después de la siguiente sincronización, unos minutos más tarde.
Faltan algunos webhooksTu servidor devolvió algo distinto de 200, tardó más de 8 segundos o no estaba disponible. Las entregas fallidas no se reintentan.
La firma no coincideUsa el cuerpo sin procesar, no JSON recodificado, y el secreto actual. Regenerar el secreto, o conectar Zapier, lo reemplaza.
Última Actividad: dice NuncaEl número todavía no se ha revisado. Debe estar conectado y no estar ocupado enviando mensajes.

Relacionado#