وصف المشكلة/الخطأ/السؤال:
حاولت الرد على موضوع مغلق يناقش نفس المشكلة بالضبط، لكن نظراً لأنه مقفول، أنشئ موضوعاً جديداً.
أنا غير قادر على التحقق من عنوان URL الخاص بي Meta WhatsApp Cloud API Webhook في n8n Cloud. Meta يستمر في فشل التحقق من Callback URL.
ما هي رسالة الخطأ (إن وجدت)؟
يعرض Meta Developer Console خطأ تحقق عام للـ callback عند النقر على “Verify and Save”.
يرجى مشاركة سير العمل الخاص بك:
- Webhook trigger (GET/POST)
- If node checks: hub.mode == subscribe AND hub.verify_token == n8n_property_bot_verify_token
- Respond to Webhook node: يُرجع raw hub.challenge كنص عادي (HTTP Status 200).
شارك الناتج الذي يُرجعه آخر عقدة:
نص عادي يحتوي على قيمة hub.challenge مع رأس HTTP 200.
معلومات إعداد n8n الخاص بك:
- n8n version: Latest Cloud
- Database: Cloud Default
- Running n8n via: n8n cloud (aboanada67.app.n8n.cloud)
- Operating system: Cloud Hosted
مرحباً @Abo_Anad_Abo_Anad أهلاً وسهلاً!
تُرسل Meta التحقق كـ GET وتسليمات الرسائل كـ POST، والعقدة Webhook تسجل طريقة واحدة في كل مرة، لذا فإن العقدة الموجودة على POST ترجع 404 لطلب التحقق وتعرض Meta فقط فشل رد النداء العام الخاص بها. افتح إعدادات العقدة وقم بتشغيل السماح بطرق HTTP متعددة، ثم احتفظ بـ GET و POST في حقل HTTP Methods. تحصل العقدة بعد ذلك على مخرج واحد لكل طريقة، لذا وجّه مخرج GET إلى عقدة If الخاصة بك وعقدة Respond to Webhook، واستخدم مخرج POST للتعامل مع الرسائل.
انقر فوق Verify وحفظ مع نشر سير العمل بواسطة عنوان URL الإنتاج المُلصق في Meta، فعنوان URL الاختبار يستمع فقط لمدة 120 ثانية.
مرحبا @Abo_Anad_Abo_Anad
من المؤكد تقريباً أن الفشل ناجم عن أحد ثلاثة أشياء: استخدام عنوان URL للاختبار بدلاً من عنوان URL الإنتاج، أو مسار JSON غير صحيح في التعبير الخاص بك (معاملات الاستعلام متداخلة)، أو إرسال الاستجابة كـ application/json بدلاً من text/plain.
عند النقر على “التحقق والحفظ” في وحدة تحكم Meta Developer، ترسل Meta طلب GET في الوقت الفعلي إلى عنوان URL الخاص بك.
- عدم استخدام عنوان URL للاختبار (الذي ينتهي بـ
/test). يعمل عنوان URL للاختبار فقط عندما تكون محرر n8n مفتوحاً وقمت بالنقر يدويًا على “تنفيذ سير العمل”. سيؤدي طلب Meta إلى مستقبِل مغلق وسيفشل.
- استخدم عنوان URL الإنتاج (الذي بدون
/test).
- ملاحظة: يجب عليك الحفظ وتفعيل سير العمل لكي يكون عنوان URL الإنتاج نشطاً.
للتصرف في عملية المصافحة الخاصة بـ Meta، يجب تكوين العُقد الخاصة بك بالضبط كما يلي:
- طريقة HTTP:
GET (ملاحظة: لاستقبال الرسائل الفعلي، ستحتاج لاحقاً إلى إضافة POST، لذا عيّن هذا على GET و POST).
- المسار: (المسار الذي اخترته، مثلاً
whatsapp-webhook)
- الرد:
Using 'Respond to Webhook' node (هذا إلزامي).
ترسل Meta المعاملات في سلسلة الاستعلام، وليس في النص. يجب أن تتحقق العقدة “If” من كائن query.
- الشرط 1 (نص):
{{ $json.query['hub.mode'] }} يساوي subscribe
- الشرط 2 (نص):
{{ $json.query['hub.verify_token'] }} يساوي your_token_here
هنا يفشل معظم المستخدمين. تتوقع Meta النص الخام، وليس كائن JSON.
- الرد بـ:
Text
- نص الاستجابة:
{{ $json.query['hub.challenge'] }} (استخدم تعبيراً)
- رمز حالة HTTP:
200
- رؤوس الاستجابة (اختياري لكن موصى به):
- الاسم:
Content-Type
- القيمة:
text/plain
عندما تصل Meta إلى عنوان URL الخاص بك، تبدو بنية البيانات كما يلي:
{
"query": {
"hub.mode": "subscribe",
"hub.verify_token": "n8n_property_bot_verify_token",
"hub.challenge": "123456789"
}
}
يجب أن يستخرج سير العمل الخاص بك 123456789 وإرجاعه كـ نص عادي، وليس {"challenge": "123456789"}.
هل هذا يساعد؟
متابعة للنقاش من Meta Whats-app Web hook Verification failing on n8n Cloud (GET hub.challenge response issue):
هذا يكاد يكون دائماً واحداً من أمرين، وكلاهما سهل الإغفال عنه.
أولاً، صيغة الاستجابة. استدعاء التحقق من Meta هو GET يحتوي على ثلاث معاملات استعلام: hub.mode و hub.verify_token و hub.challenge. يتوقع الحصول على hub.challenge كنص عادي خام مع 200. الاستجابة الافتراضية لـ webhook في n8n هي JSON، لذا يتلقى Meta شيئاً مثل {“challenge”:“123”} بدلاً من مجرد 123، ويرفضها.
الحل:
- على عقدة Web hook، اضبط Respond على “Using Respond to Web hook node”
- أضف عقدة Respond to Web hook
- اضبط Respond With = Text
- Response Body = {{ $json.query[‘hub.challenge’] }}
نص، وليس JSON. هذا الإعداد الوحيد هو عادة المشكلة بأكملها.
ثانياً، وهذا يمسك الكثيرين على Cloud: تأكد من أنك أعطيت Meta عنوان URL الإنتاج وليس عنوان URL الاختبار، وأن سير العمل نشط فعلاً. عنوان URL الاختبار يستمع فقط لاستدعاء واحد بعد أن تنقر على “Listen for test event” ويصبح معطلاً بعد ذلك، لذلك يفشل التحقق بصمت حتى وإن بدا كل شيء صحيحاً في المحرر.
شيء واحد آخر سيوفر عليك لاحقاً: Meta تستخدم GET للتحقق و POST للرسائل الواردة الفعلية، على نفس عنوان URL. إذا لم تفصل بينهما، فستعمل منطق معالجة الرسائل الخاص بك على استدعاء التحقق أيضاً. أضف Switch أو IF مباشرة بعد webhook تتحقق من {{ $json.headers[‘x-forwarded-method’] }} أو وجود $json.query[‘hub.mode’]، وأرسل المسارين بشكل منفصل.
من الجدير التحقق من أن hub.verify_token يطابق ما حددته في لوحة تحكم Meta قبل الرد، بدلاً من إرسال الـ challenge بشكل غير مشروط.