El canal de webhook es el punto de entrada genérico para conectar cualquier sistema capaz de hacer un POST HTTP. Es la opción a elegir cuando no existe un canal dedicado para tu fuente.
Cuándo usarlo
- Conectar una herramienta interna (ERP, aplicación de negocio, pasarela de pago).
- Recibir eventos de una plataforma de terceros que ofrece webhooks genéricos.
- Disparar un pipeline desde un cron externo o una CI.
Configuración
- En el editor del modelo, configura el nodo Start con un receptor Webhook entrante.
- betool genera una URL pública (
https://platform.betool.ai/entries/webhook/<token>). - (Recomendado) Define un secreto HMAC en la configuración del receptor.
Cuando hay un secreto configurado, tu sistema debe firmar el cuerpo bruto de cada petición — HMAC-SHA256(secret, body), en hexadecimal — y pasar la firma en la cabecera X-Webhook-Signature, con la forma sha256=<hex> o <hex> solo. El nombre de la cabecera y el algoritmo (sha256, sha384, sha512) son configurables, por ejemplo para seguir la convención X-Hub-Signature-256 de GitHub. Toda petición sin una firma válida se rechaza entonces (401).
Solo se verifica este formato: un HMAC hexadecimal del cuerpo bruto. Una firma con marca de tiempo (t=…,v1=…) o codificada en base64 no será reconocida.
Formato de la carga útil
Envías cualquier JSON. betool no restringe la estructura. La carga útil se expone al pipeline bajo webhook.payload (con sus subclaves); las cabeceras, el método y la query string también están disponibles bajo webhook.headers, webhook.method y webhook.query.
El cuerpo se lee según su Content-Type: JSON analizado, formulario (application/x-www-form-urlencoded) como diccionario, XML y text/* como texto bruto, multipart/form-data como campos + archivos adjuntos (webhook.payload._files), y cualquier otro tipo (PDF, imagen, archivo comprimido…) se guarda como archivo. Un cuerpo comprimido en gzip se descomprime. Tamaño máximo: 50 MB (413 por encima).
Ejemplo:
curl -X POST https://platform.betool.ai/entries/webhook/abc123 \
-H "Content-Type: application/json" \
-H "X-Webhook-Signature: sha256=$SIGNATURE" \
-d '{
"type": "order.created",
"order_id": "ord_42",
"amount_cents": 9900,
"customer_email": "client@exemple.com"
}'
El pipeline puede entonces conectar un agente que lea webhook.payload.customer_email y webhook.payload.amount_cents directamente.
Respuesta
Dos modos de respuesta (response_mode): sync (por defecto) se bloquea hasta el resultado del pipeline y lo devuelve en la respuesta; ack devuelve de inmediato un 202 Accepted tras poner el evento en una cola duradera (el pipeline se ejecuta después, con reintentos) — elígelo para los proveedores que agotan el tiempo de espera pronto.
Llamadas GET (opción)
Por defecto, solo se acepta POST: un GET recibe 405. Para un socio que impone una consulta en GET ?action=…, marca Aceptar también GET (allow_get). La query string pasa entonces a ser webhook.payload, con la misma forma que un POST de formulario: el pipeline no necesita saber qué método se ha usado. Un GET no lleva body (rechazado con 400) y no es compatible con la firma HMAC (rechazado con 405 mientras haya un secreto definido). Un identificador pasado en la query aparece en los registros de acceso: prefiere POST cuando el socio lo permita.
Seguridad
- Firma tus peticiones (HMAC) en cuanto el endpoint procese algo más que pruebas.
- El secreto se puede cambiar en cualquier momento en la configuración del receptor (rotación). Una vez guardado, nunca se vuelve a mostrar: el campo indica « •••••• guardado — escribe para reemplazar », y Quitar lo borra (la firma deja entonces de verificarse).
- Las cargas útiles se almacenan en texto plano en el historial de ejecuciones — no envíes datos que solo deban estar cifrados en tránsito.