Vérification du Webhook Meta WhatsApp échouant sur n8n Cloud (problème de réponse hub.challenge GET)

Décrivez le problème/l’erreur/la question :
J’ai tenté de répondre à un sujet fermé qui discutait exactement du même problème, mais comme il est verrouillé, je crée un nouveau fil de discussion.
Je ne parviens pas à vérifier l’URL de mon webhook Meta WhatsApp Cloud API dans n8n Cloud. Meta ne cesse d’échouer à valider l’URL de rappel.

Quel est le message d’erreur (le cas échéant) ?
La console des développeurs Meta affiche une erreur générale de vérification de rappel lors du clic sur « Vérifier et enregistrer ».

Veuillez partager votre workflow :

  • Déclencheur de webhook (GET/POST)
  • Nœud If : hub.mode == subscribe ET hub.verify_token == n8n_property_bot_verify_token
  • Nœud Respond to Webhook : retourne le hub.challenge brut en tant que texte brut (statut HTTP 200).

Partagez la sortie retournée par le dernier nœud :
Texte brut contenant la valeur hub.challenge avec l’en-tête HTTP 200.

Informations sur votre configuration n8n :

  • Version n8n : dernière version Cloud
  • Base de données : Cloud Default
  • Exécution de n8n via : n8n cloud (aboanada67.app.n8n.cloud)
  • Système d’exploitation : hébergé dans le Cloud

Salut @Abo_Anad_Abo_Anad Bienvenue !
Meta envoie la vérification en GET et les livraisons de messages en POST, et le nœud Webhook enregistre une méthode à la fois, donc un nœud sur POST renvoie 404 à la demande de vérification et Meta n’affiche que son erreur de rappel générique. Ouvrez les paramètres du nœud et activez Autoriser plusieurs méthodes HTTP, puis conservez GET et POST dans le champ Méthodes HTTP. Le nœud a alors une sortie par méthode, donc connectez la sortie GET à votre nœud If et au nœud Répondre à Webhook, et utilisez la sortie POST pour la gestion des messages.
Cliquez sur Vérifier et enregistrez avec le workflow publié et l’URL de production collée dans Meta, l’URL de test n’écoute que pendant 120 secondes.

Salut @Abo_Anad_Abo_Anad

L’erreur est presque certainement causée par l’une de ces trois choses : utiliser l’URL de test au lieu de l’URL de production, un chemin JSON incorrect dans votre expression (les paramètres de requête sont imbriqués), ou la réponse envoyée en tant que application/json au lieu de text/plain.

Quand vous cliquez sur « Vérifier et enregistrer » dans la console Meta Developer, Meta envoie une requête GET en temps réel à votre URL.

  • N’utilisez PAS l’URL de test (celle se terminant par /test). L’URL de test ne fonctionne que lorsque vous avez l’éditeur n8n ouvert et que vous avez cliqué manuellement sur « Exécuter le flux de travail ». La requête de Meta frappera un écouteur fermé et échouera.
  • Utilisez l’URL de production (celle sans /test).
  • Remarque : Vous devez Enregistrer et Activer le flux de travail pour que l’URL de production soit active.

Pour réussir la poignée de main de Meta, vos nœuds doivent être configurés exactement comme ceci :

  • Méthode HTTP : GET (Remarque : Pour la réception réelle de messages, vous devrez ajouter POST plus tard, alors définissez ceci sur GET et POST).
  • Chemin : (Votre chemin choisi, par exemple whatsapp-webhook)
  • Répondre : Using 'Respond to Webhook' node (Ceci est obligatoire).

Meta envoie les paramètres dans la Chaîne de requête, pas dans le corps. Votre nœud « If » doit vérifier l’objet query.

  • Condition 1 (Chaîne): {{ $json.query['hub.mode'] }} Égal à subscribe
  • Condition 2 (Chaîne): {{ $json.query['hub.verify_token'] }} Égal à your_token_here

C’est là que la plupart des utilisateurs échouent. Meta s’attend à une chaîne brute, pas à un objet JSON.

  • Répondre avec : Text
  • Corps de la réponse : {{ $json.query['hub.challenge'] }} (Utilisez une expression)
  • Code de statut HTTP : 200
  • En-têtes de réponse (Facultatif mais recommandé) :
    • Nom : Content-Type
    • Valeur : text/plain

Quand Meta frappe votre URL, la structure des données ressemble à ceci :

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

Votre flux de travail doit extraire 123456789 et le retourner en tant que chaîne de texte brute, pas {"challenge": "123456789"}.

Cela vous aide-t-il ?

Continuation de la discussion sur Meta Whats-app Web hook Verification failing on n8n Cloud (GET hub.challenge response issue):

C’est presque toujours l’une de ces deux choses, et les deux sont faciles à manquer.

D’abord, le format de la réponse. L’appel de vérification de Meta est un GET avec trois paramètres de requête : hub.mode, hub.verify_token et hub.challenge. Il s’attend à recevoir hub.challenge en tant que texte brut avec un statut 200. La réponse webhook par défaut de n8n est du JSON, donc Meta reçoit quelque chose comme {“challenge”:“123”} au lieu de simplement 123, et rejette la demande.

Solution :

  1. Sur le nœud Web hook, définissez Respond sur « Using Respond to Web hook node »
  2. Ajoutez un nœud Respond to Web hook
  3. Définissez Respond With = Text
  4. Response Body = {{ $json.query[‘hub.challenge’] }}

Texte, pas JSON. Ce seul paramètre est généralement tout le problème.

Deuxièmement, et c’est ce qui piège beaucoup de gens sur Cloud : assurez-vous d’avoir donné à Meta l’URL de production, et non l’URL de test, et que le workflow est réellement actif. L’URL de test n’écoute qu’un seul appel après que vous ayez cliqué sur « Listen for test event » et cesse de fonctionner après cela, donc la vérification échoue silencieusement même si tout semble correct dans l’éditeur.

Une autre chose qui vous sera utile plus tard : Meta utilise GET pour la vérification et POST pour les messages entrants réels, sur la même URL. Si vous ne les séparez pas, votre logique de traitement des messages s’exécutera également sur l’appel de vérification. Ajoutez un Switch ou IF juste après le webhook en vérifiant {{ $json.headers[‘x-forwarded-method’] }} ou la présence de $json.query[‘hub.mode’], et acheminez les deux chemins séparément.

Il est judicieux de vérifier que hub.verify_token correspond à ce que vous avez défini dans le tableau de bord Meta avant de répondre, plutôt que de renvoyer le challenge inconditionnellement.