طلبات webhook في n8n لا تعمل؟ اضبط WEBHOOK_URL وHTTPS والوكيل العكسي بشكل صحيح

كثيرًا ما تعمل نسخة n8n المستضافة ذاتيًا بلا مشكلات داخل المحرر، ثم يفشل أول طلب webhook حقيقي. يظهر الرابط بصيغة http://localhost:5678، أو ترفض خدمة خارجية تسجيله، أو يظل المحرر يعرض رسالة "Connection lost". تأتي هذه المشكلات غالبًا من ثلاثة مواضع: رابط webhook الذي يظن n8n أنه يملكه، وHTTPS، والوكيل العكسي (reverse proxy) الموضوع أمام n8n. يمر هذا الدليل على كل منها، مع الإعداد الذي يعمل ورسائل الخطأ التي تدل على كل خطأ.
رابط الاختبار مقابل رابط الإنتاج
لكل عقدة Webhook رابطان، والخلط بينهما هو السبب الأكثر شيوعًا لخطأ 404.
رابط الاختبار (
/webhook-test/your-path): يعمل فقط أثناء استماع المحرر، بعد أن تضغط زر الاستماع لحدث اختباري. يستقبل طلبًا واحدًا، وتظهر بياناته على اللوحة.رابط الإنتاج (
/webhook/your-path): يعمل فقط عندما يكون مسار العمل مفعّلًا. لا تظهر الطلبات على اللوحة، بل تجدها في قائمة التنفيذات (Executions).
إذا استدعيت رابطًا لا يستمع، يرد n8n بخطأ 404 ورسالة مثل The requested webhook "POST your-path" is not registered.، وغالبًا مع تلميح بتفعيل مسار العمل أو بدء الاستماع في المحرر. وإذا كان المسار موجودًا لكن طريقة HTTP خاطئة، تحصل على This webhook is not registered for GET requests. Did you mean to make a POST request?. تحقّق من الطريقة المحددة في عقدة Webhook أولًا.
اختبر من خارج الخادم باستخدام curl لترى بالضبط ما تراه الخدمة الخارجية:
curl -i -X POST https://n8n.example.com/webhook/your-path \
-H "Content-Type: application/json" \
-d '{"ping": true}'
اضبط WEBHOOK_URL
يبني n8n روابط webhook التي يعرضها في المحرر ويرسلها إلى الخدمات الخارجية من إعداداته الخاصة. ودون توجيه منك يستخدم N8N_PROTOCOL وN8N_HOST وN8N_PORT، وهو ما ينتج خلف الوكيل رابطًا مثل http://localhost:5678/webhook/...، وهذا الرابط لا قيمة له لأي جهة خارج الخادم.
حدّد العنوان العام صراحة:
N8N_HOST=n8n.example.com
N8N_PROTOCOL=https
N8N_PORT=5678
WEBHOOK_URL=https://n8n.example.com/
N8N_PROXY_HOPS=1
أهم هذه المتغيرات هو WEBHOOK_URL. يجب أن يكون العنوان العام بـHTTPS، مع الشرطة المائلة في النهاية، ودون /webhook في آخره، لأن n8n يضيف المسار بنفسه. وإذا كان n8n يعمل تحت مسار فرعي فأضفه، مثل https://example.com/n8n/، واضبط أيضًا N8N_PATH=/n8n/.
في Docker Compose ضع هذه القيم تحت environment في خدمة n8n، ثم أعد إنشاء الحاوية بالأمر docker compose up -d، فإعادة التشغيل العادية لا تقرأ التغييرات في ملف compose.
وهناك خطوة يسهل نسيانها: عقد التشغيل (trigger) الخاصة بخدمات مثل Telegram وStripe وGitHub تسجّل رابط webhook لدى الخدمة عند تفعيل مسار العمل. بعد تغيير WEBHOOK_URL، عطّل هذه المسارات ثم فعّلها من جديد حتى تتلقى الخدمة العنوان الجديد.
لماذا يهم N8N_PROXY_HOPS؟
خلف الوكيل العكسي، يصل كل طلب إلى n8n من عنوان الوكيل، بينما ينتقل عنوان IP الحقيقي للعميل في الترويسة X-Forwarded-For. ولا يثق n8n بهذه الترويسة إلا إذا أخبرته بعدد الوكلاء الموجودين أمامه. ودون هذا الإعداد تمتلئ السجلات بالخطأ:
ValidationError: The 'X-Forwarded-For' header is set but the Express 'trust proxy' setting is false (default).
اضبط N8N_PROXY_HOPS على عدد الوكلاء في المسار. خادم Nginx أو Caddy واحد على الخادم نفسه يعني القيمة 1، وإذا كانت هناك شبكة توزيع محتوى (CDN) أو موازن أحمال أمامه فاحسبه أيضًا. هذا يصحّح عناوين العملاء في السجلات ويجعل تحديد معدل الطلبات يعمل على المستخدمين الحقيقيين لا على الوكيل.
HTTPS ليس خيارًا إضافيًا
معظم الخدمات التي ترسل طلبات webhook لا تقبل إلا روابط HTTPS بشهادة صالحة. كما يضبط n8n ملف تعريف الارتباط الخاص بتسجيل الدخول كملف آمن افتراضيًا، فإذا فتحت المحرر عبر HTTP العادي ستظهر الرسالة:
Your n8n server is configured to use a secure cookie, however you are either visiting this via an insecure URL, or using Safari.
الحل هو وضع HTTPS أمام n8n، لا تعطيل ملفات تعريف الارتباط الآمنة. استخدام N8N_SECURE_COOKIE=false مقبول فقط لاختبار محلي قصير.
إعداد Nginx يعمل
اترك n8n يستمع على 127.0.0.1:5678 ودع Nginx يتولى TLS. يستخدم المحرر اتصال WebSocket للتحديثات المباشرة، لذا يجب أن يمرّر الوكيل الترويستين Upgrade وConnection. ودونهما تظهر رسالة "Connection lost" ولا تتحدّث التنفيذات في المحرر، حتى لو استمرت طلبات webhook في العمل.
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name n8n.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name n8n.example.com;
ssl_certificate /etc/letsencrypt/live/n8n.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/n8n.example.com/privkey.pem;
client_max_body_size 16m;
location / {
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_read_timeout 300s;
}
}
احصل على الشهادة باستخدام Certbot، ثم اختبر الإعداد وأعد تحميل Nginx:
sudo certbot certonly --nginx -d n8n.example.com
sudo nginx -t && sudo systemctl reload nginx
إذا أصدرت الشهادة قبل وجود كتلة HTTPS، فعلّق كتلة المنفذ 443 أولًا، أو دع Certbot يعدّل الإعداد بنفسه عبر sudo certbot --nginx.
ثلاثة أسطر في هذا الملف تحل أخطاء محددة:
client_max_body_size: يسمح Nginx افتراضيًا بـ1 ميجابايت فقط، فتفشل طلبات webhook الأكبر بالخطأ413 Request Entity Too Largeقبل أن تصل إلى n8n. وقيمة 16 ميجابايت تطابق الحد الافتراضي لحجم الطلب في n8n (N8N_PAYLOAD_SIZE_MAX).proxy_read_timeout: إذا انتظر webhook انتهاء مسار العمل قبل الرد، فقد يتجاوز مسار طويل المهلة الافتراضية البالغة 60 ثانية ويعود بالخطأ504 Gateway Timeout.X-Forwarded-Proto: يخبر n8n بأن الطلب الأصلي كان عبر HTTPS.
البديل: Caddy
يحصل Caddy على الشهادات ويجدّدها تلقائيًا، ويمرّر ترويسات WebSocket والتوجيه افتراضيًا. الإعداد كله هو:
n8n.example.com {
reverse_proxy 127.0.0.1:5678
}
طلبات webhook الطويلة
إذا كانت خدمة خارجية تستدعي رابطك وتنتظر الرد، فاجعل الرد سريعًا. كثير من المرسلين يتوقفون بعد ثوانٍ قليلة ويعيدون المحاولة، وقد يؤدي ذلك إلى تشغيل مسار العمل مرتين. اضبط عقدة Webhook لترد فورًا، أو أضف عقدة Respond to Webhook في بداية المسار ونفّذ العمل الثقيل بعدها. وإذا كانت شبكة توزيع محتوى أمام خادمك، فتذكّر أن لها مهلة خاصة بها لا تغيّرها إعدادات Nginx.
قائمة فحص سريعة
مسار العمل مفعّل، وأنت تستدعي رابط
/webhook/لا/webhook-test/.طريقة HTTP في عقدة Webhook تطابق ما يرسله الطرف الآخر.
قيمة
WEBHOOK_URLهي العنوان العام بـHTTPS مع شرطة مائلة في النهاية، وأُعيد إنشاء الحاوية.عُطّلت مسارات التشغيل الخاصة بالخدمات الخارجية ثم فُعّلت من جديد بعد تغيير الرابط.
سجلات DNS تشير إلى الخادم، والمنفذان 80 و443 مفتوحان في الجدار الناري.
الوكيل يمرّر ترويسات
UpgradeوConnectionوX-Forwarded-*، وقيمةN8N_PROXY_HOPSتطابق عدد الوكلاء.الأمر
curl -iمن خارج الخادم يعيد 200 لا 404 أو 413 أو 504.
شغّله على IM HOST
تأتي استضافة n8n من IM HOST مع n8n مثبّتًا مسبقًا مع HTTPS وPostgreSQL، فيكون الوكيل والشهادة جاهزين من البداية. تحصل على عدد غير محدود من مسارات العمل والتنفيذات، وصلاحيات root كاملة إن أردت تعديل الإعدادات أعلاه. وإذا فضّلت إعداد كل شيء بنفسك، فخادم Linux VPS يمنحك صلاحيات root كاملة على KVM مع عنوان IPv4 مخصّص، بدءًا من 5 دولارات شهريًا. ومهندسونا متاحون على مدار الساعة إذا ظل أحد طلبات webhook يرفض العمل.
المزيد من مدونتنا
اكتشف المزيد من الأدلة العملية ورؤى الخدمات من فريق IM Host.
عرض كل المقالات