العودة إلى المدونة

استضافة بوت واتساب 24 ساعة: تشغيل البوت على سيرفر خاص

فريق تحرير IM Host14 أكتوبر 20267 دقائق قراءة
استضافة بوت واتساب 24 ساعة: تشغيل البوت على سيرفر خاص

لتشغيل بوت واتساب 24 ساعة استخدم منصة WhatsApp Business الرسمية (Cloud API)، وشغّل خادم Webhook صغيرًا على سيرفر VPS يعمل باستمرار وله عنوان HTTPS عام. ترسل Meta كل رسالة واردة إلى الـ Webhook، فيؤكد سيرفرك الاستلام فورًا، ثم يعالج الرسالة في الخلفية ويرد عبر الـ API. شغّل العملية تحت systemd أو Docker مع إعادة تشغيل تلقائية، وخزّن المحادثات في PostgreSQL، وأضف طبقة ذكاء اصطناعي للردود إذا احتجت إليها.

الـ Cloud API الرسمي أم المكتبات غير الرسمية؟

هناك طريقان لبناء بوت واتساب:

  • منصة WhatsApp Business (Cloud API): الواجهة الرسمية من Meta. تسجّل رقم هاتف تجاريًا عبر تطبيق مطوّر في Meta، وتستقبل الرسائل عبر Webhook، وترسلها بطلبات HTTPS موثّقة. وتُحتسب الرسائل وفق قواعد التسعير لدى Meta.

  • مكتبات غير رسمية تتحكم في WhatsApp Web آليًا أو تقلّد تطبيق الهاتف. مغرية لأنها تعمل برقم عادي، لكن أتمتة واتساب بهذه الطريقة مخالفة لشروط واتساب، وقد يُحظر الرقم دون إنذار، وأي تغيير من جهة واتساب قد يوقف البوت بين ليلة وضحاها.

لأي خدمة يعتمد عليها عملاؤك استخدم المنصة الرسمية، وبقية الدليل مبنية على الـ Cloud API. تغيّر Meta تفاصيل مثل التسعير والحدود وإصدارات الـ API من وقت لآخر، لذلك تأكد من التفاصيل في وثائق المطورين الحالية لدى Meta.

ما المطلوب من خادم الـ Webhook؟

1. أن يكون متاحًا عبر HTTPS عام

لا ترسل Meta الـ Webhooks إلا إلى رابط HTTPS صالح. الإعداد المعتاد على الـ VPS هو دومين فرعي مثل bot.example.com يشير إلى السيرفر، وNginx كـ Reverse Proxy، وشهادة Let's Encrypt مجانية. يستمع البوت على منفذ محلي مثل 3000، ويحوّل Nginx حركة HTTPS إليه.

2. أن يجتاز مصافحة التحقق

عند تسجيل رابط الـ Webhook في لوحة التطبيق تحدد أيضًا Verify Token، وهو نص سري تختاره أنت. بعدها ترسل Meta طلب GET يحمل hub.mode=subscribe وhub.verify_token وhub.challenge. إذا طابق الرمز ما لديك فأرجع الحالة 200 وقيمة الـ challenge في جسم الرد، وإلا فأرجع 403.

3. أن يؤكد الاستلام بسرعة

الرسائل الواردة وتحديثات حالة التسليم تصل كطلبات POST بجسم JSON. أرجع 200 بأسرع ما يمكن، ثم نفّذ العمل البطيء (الكتابة في قاعدة البيانات، واستدعاء الذكاء الاصطناعي، والطلبات الصادرة) بشكل غير متزامن. إذا كان الـ Endpoint بطيئًا أو يرجع أخطاء، تعيد Meta محاولة الإرسال، فتعالج الرسالة نفسها مرتين ما لم تمنع التكرار بمعرّف الرسالة.

4. أن يتحقق من التوقيع

توقّع Meta محتوى الـ Webhook بالـ App Secret الخاص بتطبيقك وترسل النتيجة في الترويسة X-Hub-Signature-256. احسب HMAC-SHA256 لجسم الطلب الخام وقارنه قبل أن تثق في المحتوى، حتى لا يستطيع أحد إرسال رسائل مزيفة إلى الـ Endpoint.

Webhook مبسّط بـ Node.js

هذا المثال بـ Express يوضح المصافحة والتحقق من التوقيع ونمط «أكّد الاستلام أولًا ثم اعمل». في الإنتاج ضع المهام في طابور (Redis أو جدول مهام في PostgreSQL) بدل تنفيذها داخل نفس العملية.

const express = require('express');
const crypto = require('crypto');
const app = express();

app.use(express.json({ verify: (req, res, buf) => { req.rawBody = buf; } }));

app.get('/webhook', (req, res) => {
  const ok = req.query['hub.mode'] === 'subscribe' &&
             req.query['hub.verify_token'] === process.env.VERIFY_TOKEN;
  return ok ? res.status(200).send(req.query['hub.challenge']) : res.sendStatus(403);
});

app.post('/webhook', (req, res) => {
  const sig = req.get('X-Hub-Signature-256') || '';
  const expected = 'sha256=' + crypto.createHmac('sha256', process.env.APP_SECRET)
    .update(req.rawBody).digest('hex');
  if (sig.length !== expected.length ||
      !crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
    return res.sendStatus(401);
  }
  res.sendStatus(200);                          // تأكيد الاستلام فورًا
  setImmediate(() => handleEvent(req.body));   // استبدله بطابور حقيقي
});

app.listen(3000, '127.0.0.1');

الردود تُرسل بطلب POST إلى /PHONE_NUMBER_ID/messages في Graph API مع Access Token. للبوت الذي يعمل على سيرفر استخدم توكن System User طويل الأمد بدل التوكن المؤقت الظاهر في اللوحة، واحفظه في ملف متغيرات بيئة لا داخل الكود.

القوالب ونافذة خدمة العملاء 24 ساعة

يفرّق واتساب بين المحادثة التي يبدأها العميل والرسالة التي تبدأها الشركة:

  • عندما يراسلك العميل تُفتح نافذة خدمة عملاء مدتها 24 ساعة، يستطيع البوت خلالها إرسال ردود حرة: نصوص ووسائط وأزرار وقوائم.

  • خارج هذه النافذة لا يمكنك التواصل مع العميل إلا عبر قالب رسالة (Message Template) قُدِّم واعتُمد مسبقًا، مثل تحديث طلب أو تذكير بموعد أو رمز تحقق لمرة واحدة.

  • كل رسالة جديدة من العميل تبدأ النافذة من جديد.

صمّم البوت على هذا الأساس: احفظ وقت آخر رسالة من كل عميل، وقبل الإرسال تحقق هل ما زلت داخل النافذة، وإن لم تكن فانتقل إلى قالب معتمد. فئات القوالب وقواعد اعتمادها وتسعيرها تتغير مع الوقت، لذلك راجع وثائق Meta قبل التخطيط للإشعارات أو الحملات.

التشغيل 24 ساعة دون انقطاع

بوت الـ Webhook بلا فائدة إذا توقفت العملية. هناك خياران موثوقان على سيرفر لينكس:

systemd يشغّل البوت مع إقلاع السيرفر ويعيد تشغيله إذا تعطل. احفظ الملف التالي باسم /etc/systemd/system/whatsapp-bot.service وفعّله بالأمر sudo systemctl enable --now whatsapp-bot:

[Unit]
Description=WhatsApp bot
Wants=network-online.target
After=network-online.target

[Service]
User=bot
WorkingDirectory=/opt/whatsapp-bot
EnvironmentFile=/opt/whatsapp-bot/.env
ExecStart=/usr/bin/node server.js
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Docker: شغّل البوت وقاعدة بياناته عبر Docker Compose مع restart: unless-stopped، فتعود الحاويات للعمل بعد أي تعطل أو إعادة تشغيل. وإذا كنت تشغّل تطبيقات Node.js عبر PM2، فدليل استضافة Node.js على VPS مع PM2 وNginx يشرح هذا الطريق بما فيه الـ Reverse Proxy وشهادة SSL.

وأضف مراقبة أساسية: فحص توافر خارجي على Endpoint للصحة، وتنبيه عندما يبدأ الـ Webhook في إرجاع أخطاء.

تخزين المحادثات في PostgreSQL

احتفظ بسجل لكل رسالة واردة وصادرة. ستحتاجه كسياق لردود الذكاء الاصطناعي، ولمنطق نافذة الـ 24 ساعة، وللموظف الذي يتسلّم المحادثة، ولتتبع الأخطاء.

CREATE TABLE wa_messages (
  id            bigserial PRIMARY KEY,
  wa_message_id text UNIQUE,     -- معرّف الرسالة من Meta لمنع التكرار
  phone         text NOT NULL,
  direction     text NOT NULL CHECK (direction IN ('in', 'out')),
  body          jsonb NOT NULL,
  created_at    timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX ON wa_messages (phone, created_at DESC);

قيد التفرد على معرّف الرسالة يجعل إعادة إرسال الـ Webhook غير مؤذية: أدخل الصف مع ON CONFLICT DO NOTHING وتجاهل المعالجة إذا لم يُضف صف جديد. المحادثات تحتوي بيانات شخصية، لذلك قيّد الوصول إلى قاعدة البيانات، وخذ منها نسخًا احتياطية، وحدد مدة الاحتفاظ بها.

إضافة ردود بالذكاء الاصطناعي

بعد أن تستقر حركة الرسائل، تصبح طبقة الذكاء الاصطناعي مجرد Worker يلتقط كل رسالة واردة ثم:

  1. يحمّل آخر رسائل هذا الرقم من PostgreSQL كسياق.

  2. يسترجع عند الحاجة فقرات مناسبة من الأسئلة الشائعة أو السياسات أو الكتالوج عبر pgvector.

  3. يستدعي API النموذج برسالة نظام تحدد النطاق والأسلوب ومتى يحوّل المحادثة إلى موظف.

  4. يرسل الرد عبر الـ Cloud API ويخزنه.

اترك دائمًا مخرجًا: كلمة أو زر يحوّل العميل إلى موظف، وعلامة توقف البوت مؤقتًا لهذا العميل أثناء تعامل الموظف معه. وضع مهلة على استدعاء النموذج حتى لا يبقى العميل منتظرًا بلا رد إذا تباطأ الـ API. ولأن النموذج يعمل لدى المزوّد فالبوت نفسه خفيف، وكما شرحنا في هل تحتاج GPU لتشغيل وكيل ذكاء اصطناعي فإن المعالج والذاكرة هما الأهم. وإذا كنت لم تحسم مكان التشغيل بعد، راجع أين تستضيف وكيل الذكاء الاصطناعي. والبنية قريبة جدًا من بوت تيليجرام الذي شرحناه في تشغيل بوت تيليجرام 24 ساعة على VPS.

أسئلة شائعة

هل يمكن تشغيل بوت واتساب على جهازي الشخصي؟

للتجربة نعم، عبر نفق يمنحك رابط HTTPS مؤقتًا. أما في الإنتاج فلا، لأن الـ Webhook يجب أن يكون متاحًا كل دقيقة من اليوم، وجهاز المنزل لا يضمن ذلك.

هل استخدام مكتبة واتساب غير رسمية آمن؟

ليس لنشاط تجاري. أتمتة واتساب خارج المنصة الرسمية مخالفة لشروط واتساب وقد تؤدي إلى حظر الرقم. استخدم منصة WhatsApp Business.

لماذا يستقبل الـ Webhook الرسالة نفسها مرتين؟

لأن Meta تعيد إرسال ما تعتبره تسليمًا فاشلًا، وكثيرًا ما يكون السبب بطء الرد. أرجع 200 فورًا وامنع التكرار بمعرّف الرسالة.

هل يستطيع البوت أن يبدأ المحادثة مع العميل؟

فقط عبر قالب رسالة معتمد إذا كنت خارج نافذة الـ 24 ساعة. داخل النافذة يُسمح بالردود الحرة.

استضافة بوت واتساب على IM HOST

سيرفرات استضافة وكلاء الذكاء الاصطناعي تأتي وعليها Docker وDocker Compose وNode.js وPython وPostgreSQL مع pgvector مثبتة مسبقًا، فيمكن تشغيل بوت واتساب ومخزن محادثاته وطبقة الردود الذكية معًا على سيرفر واحد يعمل باستمرار، مع نسخ احتياطي يومي مجاني. وإذا فضّلت بناء كل شيء بنفسك، فإن سيرفر VPS لينكس يمنحك سيرفر KVM غير مُدار على أقراص NVMe مع صلاحيات root كاملة.

المزيد من مدونتنا

اكتشف المزيد من الأدلة العملية ورؤى الخدمات من فريق IM Host.

عرض كل المقالات