Un webhook que «no funciona» son en Bitrix24 (Alaio) dos fallos muy distintos bajo una misma palabra, y la solución de uno no sirve para el otro: o un evento saliente nunca llega a tu handler, o una llamada entrante devuelve un error en lugar de datos. Una sincronización muerta, un bot que dejó de escribir, un sistema contable sin las oportunidades de ayer: cada síntoma es uno de esos dos casos disfrazado. Primero determina cuál tienes y luego recorre las comprobaciones en orden.

¿Saliente o entrante: qué mitad está rota?

Un webhook entrante es una URL con una clave con la que tu servicio llama al portal; uno saliente es lo contrario, el portal te llama cuando ocurre un evento. Si tus registros muestran una petición que sale y una cadena de error que vuelve, el problema es entrante y el propio error lo nombra. Si no muestran nada, el problema es saliente, y no hay error en ninguna parte: eso es justo lo que vuelve lenta la diagnosis. Cómo se crean ambos tipos está en la guía de webhooks; esta página trata de qué hacer cuando callan.

¿Por qué el webhook saliente nunca llega a mi handler?

Los eventos no viajan del portal directamente a tu URL. Se encolan en un servidor de entrega aparte, y es ese servidor el que envía el POST. Tres propiedades suyas explican la mayor parte del silencio. El handler tiene que ser alcanzable desde la internet pública: una dirección en localhost o dentro de una red privada no recibe nada, y un cortafuegos que solo admite socios conocidos produce el mismo efecto. Tiene que responder rápido: la cola vigila el tiempo de respuesta y llama menos a los handlers lentos, estirando el intervalo entre intentos, de modo que un handler pesado se vuelve poco fiable sin fallar nunca de forma visible. Y la carga útil es deliberadamente escasa, básicamente el identificador de la entidad y el nombre del evento, así que el código que espera valores de campo completos lee una estructura vacía. Los campos se piden con una llamada REST aparte.

¿Es de verdad el evento al que te suscribiste?

La segunda causa más frecuente es una suscripción sana al evento equivocado. Los eventos de actualización se disparan con cualquier cambio de la entidad, incluidos los que hace tu propia automatización: eso parece entregas duplicadas y a veces se convierte en un bucle. Los handlers registrados en la sección de recursos para desarrolladores y los registrados por una aplicación mediante event.bind viven en listas distintas, así que la suscripción que estás mirando puede no ser la que se ejecuta, y los enlaces de una aplicación desaparecen cuando esta se elimina o se actualiza. La comprobación cuesta un minuto: lanza la acción a mano y mira en tu registro de acceso si llega un POST.

Mi handler estaba caído: ¿puedo recuperar el evento?

No, y esta es la propiedad que la mayoría de las integraciones pasa por alto. Si tu servidor no responde o devuelve un error, el servidor de la cola anota el fallo y no reenvía el evento. No hay reintentos ni cola de mensajes muertos: diez segundos de despliegue cuestan en silencio todos los eventos de esa ventana.

Hay dos respuestas. Para la dirección entrante, vincula la suscripción como evento offline: el portal guarda los eventos en una cola que tu servicio recoge a su propio ritmo con event.offline.get, de modo que una caída retrasa la entrega en lugar de destruirla. Para las llamadas que empiezan dentro del portal, envíalas desde un flujo de trabajo: Webhook tolerante a fallos reintenta los envíos fallidos en el intervalo que fijes, permite declarar qué códigos de estado cuentan como éxito, informa del número de intentos y avisa a los empleados elegidos si la entrega finalmente no se logra.

¿Por qué el webhook entrante devuelve un error?

Aquí tienes un código: léelo a él, no la frase de al lado. Un error de permisos significa que la clave se creó sin el alcance que el método necesita, y los alcances se fijan al crearla: hay que reemitirla. Un error de acceso suele significar que la clave está bien pero su propietario no: el webhook actúa con los derechos del empleado que lo creó, así que un propietario dado de baja, o uno que no ve el embudo, falla con un token perfectamente válido. QUERY_LIMIT_EXCEEDED es el limitador de frecuencia, no una clave rota: las operaciones masivas se empaquetan en llamadas batch y se reintentan con retardo creciente. Una llamada por HTTP simple en lugar de HTTPS se rechaza de inmediato.

¿Cómo probar un webhook en vez de adivinar?

Registra el cuerpo crudo de la petición antes de analizarlo: la mitad de los casos de «el webhook está roto» resultan ser un handler que recibió el POST y se cayó en su propio análisis. Comprueba también al remitente: con las llamadas de evento llega un token de aplicación, y compararlo con el valor guardado es a la vez la comprobación de seguridad y una respuesta rápida a si ese POST vino realmente del portal.

La dirección contraria se prueba desde dentro del portal: pon Petición HTTP GET/POST en un flujo — envía una petición a tu endpoint y devuelve el cuerpo de la respuesta, el código de estado y una marca Y/N, así que sabrás si tu endpoint responde siquiera a la red del portal; Extraer valor de JSON por ruta saca un campo para una línea de registro legible. Si el flujo que debía enviar la petición nunca arrancó, el rastro pasa a las reglas de automatización que no se ejecutan.

Qué sigue

Silencio significa saliente; una cadena de error, entrante: solo esa división ahorra la mayor parte del tiempo. Después diseña con la restricción y no contra ella: los eventos nunca se reenvían, así que todo lo que no se puede perder entra por una suscripción offline y sale por el webhook tolerante a fallos, ambos bloques corrientes de las reglas de automatización en Bitrix24. Los demás están en el catálogo de Roboteka; si falta el que necesitas, describe la tarea: lo construimos gratis y lo añadimos a la biblioteca común.