Verificación de Webhook de Meta WhatsApp fallando en n8n Cloud (problema con respuesta hub.challenge GET)

Describe el problema/error/pregunta:
Intentć responder a un tema cerrado que discutía exactamente el mismo problema, pero como está bloqueado, estoy creando un nuevo hilo.
No puedo verificar mi URL de Webhook de Meta WhatsApp Cloud API en n8n Cloud. Meta sigue fallando al validar la URL de Callback.

¿Cuál es el mensaje de error (si la hay)?
La consola de Meta Developer muestra un error general de verificación de callback cuando se hace clic en “Verify and Save”.

Por favor, comparte tu workflow:

  • Disparador Webhook (GET/POST)
  • Nodo If: hub.mode == subscribe AND hub.verify_token == n8n_property_bot_verify_token
  • Nodo Respond to Webhook: Devuelve el hub.challenge sin procesar como texto plano (HTTP Status 200).

Comparte la salida devuelta por el último nodo:
Texto sin procesar que contiene el valor hub.challenge con encabezado HTTP 200.

Información sobre tu configuración de n8n:

  • versión de n8n: Latest Cloud
  • Base de datos: Cloud Default
  • Ejecutando n8n a través de: n8n cloud (aboanada67.app.n8n.cloud)
  • Sistema operativo: Cloud Hosted

¡Hola @Abo_Anad_Abo_Anad Bienvenido!
Meta envía la verificación como GET y los envíos de mensajes como POST, y el nodo Webhook registra un método a la vez, por lo que un nodo en POST devuelve 404 a la solicitud de verificación y Meta muestra solo su fallo de callback genérico. Abre la configuración del nodo y activa Allow Multiple HTTP Methods (Permitir múltiples métodos HTTP), luego mantén GET y POST en el campo HTTP Methods (Métodos HTTP). El nodo tendrá entonces una salida por método, así que conecta la salida GET a tu nodo If y al nodo Respond to Webhook, y usa la salida POST para el manejo de mensajes.
Haz clic en Verify (Verificar) y guarda con el flujo de trabajo publicado y la URL de producción pegada en Meta, la URL de prueba solo escucha durante 120 segundos.

Hola @Abo_Anad_Abo_Anad

El error casi seguramente es causado por una de tres cosas: usar la URL de prueba en lugar de la URL de producción, una ruta JSON incorrecta en tu expresión (los parámetros de consulta están anidados), o la respuesta se envía como application/json en lugar de text/plain.

Cuando haces clic en “Verify and Save” en la Meta Developer Console, Meta envía una solicitud GET en tiempo real a tu URL.

  • NO uses la URL de prueba (la que termina en /test). La URL de prueba solo funciona cuando tienes el editor de n8n abierto y has hecho clic manualmente en “Execute Workflow”. La solicitud de Meta golpeará un listener cerrado y fallará.
  • SÍ usa la URL de producción (la que no tiene /test).
  • Nota: Debes guardar y activar el flujo de trabajo para que la URL de producción esté en vivo.

Para pasar el apretón de manos de Meta, tus nodos deben estar configurados exactamente así:

  • HTTP Method: GET (Nota: Para recibir mensajes reales, más tarde necesitarás agregar POST, así que configura esto en GET y POST).
  • Path: (Tu ruta elegida, por ejemplo, whatsapp-webhook)
  • Respond: Using 'Respond to Webhook' node (Esto es obligatorio).

Meta envía parámetros en la Query String, no en el Body. Tu nodo “If” debe verificar el objeto query.

  • Condition 1 (String): {{ $json.query['hub.mode'] }} Equal subscribe
  • Condition 2 (String): {{ $json.query['hub.verify_token'] }} Equal your_token_here

Este es el punto donde la mayoría de los usuarios fallan. Meta espera la cadena sin procesar, no un objeto JSON.

  • Respond With: Text
  • Response Body: {{ $json.query['hub.challenge'] }} (Usa una expresión)
  • HTTP Status Code: 200
  • Response Headers (Opcional pero recomendado):
    • Name: Content-Type
    • Value: text/plain

Cuando Meta accede a tu URL, la estructura de datos se ve así:

{
  "query": {
    "hub.mode": "subscribe",
    "hub.verify_token": "n8n_property_bot_verify_token",
    "hub.challenge": "123456789"
  }
}

Tu flujo de trabajo debe extraer 123456789 y devolverlo como una cadena de texto sin procesar, no {"challenge": "123456789"}.

¿Te ayuda esto?

Continuando la discusión desde Meta Whats-app Web hook Verification failing on n8n Cloud (GET hub.challenge response issue):

Esto casi siempre es una de dos cosas, y ambas son fáciles de pasar por alto.

Primero, el formato de la respuesta. La llamada de verificación de Meta es un GET con tres parámetros de consulta: hub.mode, hub.verify_token y hub.challenge. Espera que hub.challenge vuelva como texto sin formato con un 200. La respuesta de web hook predeterminada de n8n es JSON, así que Meta recibe algo como {“challenge”:“123”} en lugar de solo 123, y lo rechaza.

Solución:

  1. En el nodo Web hook, establece Respond to en “Using Respond to Web hook node”
  2. Agrega un nodo Respond to Web hook
  3. Establece Respond With = Text
  4. Response Body = {{ $json.query[‘hub.challenge’] }}

Text, no JSON. Esa única configuración suele ser todo el problema.

Segundo, y esto atrapa a mucha gente en Cloud: asegúrate de que le diste a Meta la URL de producción, no la URL de prueba, y que el flujo de trabajo esté realmente activo. La URL de prueba solo escucha una llamada después de que haces clic en “Listen for test event” y deja de funcionar después de eso, así que la verificación falla silenciosamente aunque todo se vea bien en el editor.

Una cosa más que te ahorrará problemas después: Meta usa GET para la verificación y POST para los mensajes entrantes reales, en la misma URL. Si no separas esos, tu lógica de manejo de mensajes se ejecutará también en la llamada de verificación. Agrega un Switch o IF justo después del web hook verificando {{ $json.headers[‘x-forwarded-method’] }} o la presencia de $json.query[‘hub.mode’], y enruta los dos caminos por separado.

Vale la pena verificar que hub.verify_token coincida con lo que estableciste en el panel de Meta antes de responder, en lugar de devolver el challenge incondicionalmente.