1. كيف يعمل نظام الويبهوك؟
نظرة عامة على تدفق الرسائل والأحداث في الوقت الفعلي
عند تفعيل Webhook في حسابك، يقوم خادم WMAM بإرسال طلب HTTP POST فوري وبحمولة JSON إلى الرابط الخاص بك في كل مرة يحدث فيها نشاط على أي حساب واتساب متصل (استقبال رسالة، وسائط، موقع، تغير حالة الاتصال، إلخ).
استقبال الحدث
يصل إشعار من واتساب إلى أحد حساباتك المتصلة في النظام.
إرسال Webhook
يقوم WMAM ببث الحدث إلى رابطك مع توقيع HMAC وتحديد معرّف الحساب accountId.
الرد التلقائي (اختياري)
يمكن لخادمك الرد مباشرة بنص أو كائن JSON ليتم إرساله كـ Auto-Reply في الحال.
تسجيل رابط الويبهوك الخاص بك:
يمكنك تسجيل الويبهوك إما من لوحة التحكم (قسم Webhooks) أو عبر الـ API التالي:
POST /api/webhooks
Authorization: Bearer YOUR_JWT_OR_API_KEY
Content-Type: application/json
{
"name": "My External Automation & AI",
"url": "https://your-server.com/api/v1/whatsapp-webhook",
"events": [
"message_received",
"message_sent",
"connection_update",
"group_participants_update"
],
"secret": "my_super_secure_secret_key",
"enabled": true
}
2. بنية الاستماع الموحد (Multi-Account Architecture)
رابط ويبهوك واحد يستمع لجميع حساباتك مع التمييز الدقيق
ميزة الارتباط الموحد (Multiplexing)
لا تحتاج لإنشاء رابط ويبهوك لكل حساب على حدة! الويبهوك العام (Global Webhook) يستقبل أحداث كافة الحسابات التابعة لك، ويحتوي كل حدث دائماً على حقل accountId لمعرفة الحساب المصدر بدقة.
| نوع الخطة (Plan) | عدد الحسابات المسموحة | سلوك الويبهوك | الاستخدام الموصى به |
|---|---|---|---|
| Free (المجانية) | حساب واحد (1 Account) | يستمع لحسابك المجاني الوحيد | التجربة، البوتات الشخصية البسيطة |
| Pro (الاحترافية) | حسابات متعددة (3-10 حسابات) | ويبهوك واحد يستمع لجميع الحسابات ويوزعها حسب accountId |
المتاجر الإلكترونية، فرق المبيعات، والدعم الفني |
| Enterprise / Custom (الشركات) | حسابات غير محدودة (Unlimited) | استماع موحد لمئات الحسابات في مسار مركزي واحد مع دعم التكرار السريع | المنصات الكبرى (SaaS)، وكالات التسويق، أنظمة الذكاء الاصطناعي الضخمة |
3. نقاط ربط الحسابات (Account Onboarding API)
إنشاء الحساب والربط عبر QR Code أو كود الهاتف (Pairing Code)
يتيح لك النظام ربط حسابات واتساب برمجياً عبر الـ API بالكامل لإتاحة ربط الحسابات لمستخدميك داخل نظامك الخاص:
/api/accounts/create/:accountId
يقوم بتجهيز مسار بيانات الحساب وتجهيز جلسة Baileys للربط.
curl -X POST https://your-domain.com/api/accounts/create/acc_user_101 \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json"
/api/accounts/qr/:accountId
يعيد كود الـ QR كـ Data URL أو صورة لعرضها للمستخدم لمسحها عبر تطبيق واتساب.
{
"success": true,
"qr": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
"status": "scan_qr",
"accountId": "acc_user_101"
}
/api/accounts/pairing-code/:accountId
يولد كود ربط مكون من 8 أحرف وأرقام لربط الهاتف دون الحاجة لمسح الكاميرا (Link with phone number).
POST /api/accounts/pairing-code/acc_user_101
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json
{
"phoneNumber": "212612345678"
}
استجابة الخادم:
{
"success": true,
"pairingCode": "1234-ABCD",
"message": "أدخل هذا الكود في واتساب على هاتفك لتأكيد الربط"
}
/api/accounts/:accountId/status
يعيد ما إذا كان الحساب متصلاً حالياً ومعلومات الرقم المتصل.
{
"success": true,
"status": "connected",
"connected": true,
"user": {
"id": "212612345678:1@s.whatsapp.net",
"name": "My Business Support"
}
}
4. هل يدعم النظام إشعار "يكتب الآن..." (isTyping / Presence)؟
محاكاة الكتابة التفاعلية لإعطاء طابع بشري لبوتات الذكاء الاصطناعي
نعم، النظام يدعم محاكاة الكتابة بالكامل!
يمكنك تفعيل محاكاة الكتابة التلقائية (humanize: true) عند إرسال أي رسالة، أو عند إرجاع رد فوري من خلال الويبهوك. يقوم النظام بإرسال حالة composing (يكتب الآن...) للطرف الآخر لفترة زمنية طبيعية تتناسب مع طول الرد، ثم يرسل الرسالة ويحول الحالة إلى paused.
طريقة تفعيلها برمجياً:
1. عبر مسار الإرسال المباشر (API)
POST /api/messages/send/acc_101
{
"to": "212612345678",
"text": "مرحباً! جارٍ توليد الإجابة بواسطة الذكاء الاصطناعي...",
"humanize": true
}
2. عبر استجابة الويبهوك المباشرة (Auto-Reply)
// استجابة خادمك لطلب الويبهوك:
{
"reply": {
"text": "تم استلام استفسارك وسيتم الرد خلال لحظات.",
"humanize": true
}
}
5. الأحداث وهيكل البيانات (Event Payloads)
الشكل الكامل للبيانات التي يرسلها الويبهوك لخادمك
Event
message_received (استقبال رسالة جديدة)
يشمل جميع أنواع الرسائل: نصية، صور، فيديو، صوت، مستندات، موقع جغرافي، جهات اتصال، وملصقات مع استخراج رقم الهاتف ومعرف LID بدقة.
{
"event": "message_received",
"timestamp": "2026-08-20T15:30:00.000Z",
"accountId": "acc_sales_morocco",
"data": {
"messageId": "3EB0123456789ABCDEF",
"from": "212612345678@s.whatsapp.net",
"phoneNumber": "212612345678",
"phoneJid": "212612345678@s.whatsapp.net",
"lid": "123456789012345@lid",
"fromMe": false,
"to": "212600000000@s.whatsapp.net",
"chatId": "212612345678@s.whatsapp.net",
"isGroup": false,
"pushName": "Ahmed Mansour",
"message": {
"type": "text",
"text": "السلام عليكم، هل المنتج متوفر؟",
"hasMedia": false,
"media": null
},
"timestamp": "2026-08-20T15:30:00.000Z"
}
}
Media رسالة وسائط أو موقع جغرافي (Location)
{
"event": "message_received",
"accountId": "acc_sales_morocco",
"data": {
"messageId": "3EB0998877665544",
"from": "212612345678@s.whatsapp.net",
"isGroup": false,
"message": {
"type": "location",
"text": "Casablanca, Morocco",
"hasMedia": false,
"location": {
"latitude": 33.5731,
"longitude": -7.5898,
"name": "مقر الشركة",
"address": "شارع الجيش الملكي"
}
}
}
}
Event
status_changed (تغير دورة حياة واتصال الحساب)
يُرسل في الوقت الفعلي عند أي تحول في دورة حياة الجلسة مع منع التكرار الذكي (Deduping) والـ Throttling للحالات العابرة.
| الحالة (Status) | النوع | الوصف وسلوك النظام |
|---|---|---|
| connected | Terminal / Active | الجلسة متصلة وجاهزة للإرسال والاستقبال الفوري. يتم إرسالها فوراً دون قيود. |
| pending / connecting | Transient | جارٍ تهيئة السوكت أو محاولة الاتصال/المزامنة. تخضع لـ Throttling (مرة كل 15 دقيقة كحد أقصى). |
| disconnected | Transient / Error | انقطاع شبكة مؤقت؛ يقوم النظام بمحاولات إعادة الاتصال التلقائي بـ Exponential Backoff. |
| logged_out | Terminal / Error | تم تسجيل الخروج من الهاتف أو إلغاء ربط الجهاز (يتطلب مسح QR Code جديد). تُرسل فوراً بأولوية قصوى. |
| conflict | Terminal / Error | تم فتح الجلسة في جهاز آخر أو مستعرض ثانٍ (Code 440). تُرسل فوراً لحماية الحساب من التضارب. |
{
"event": "status_changed",
"timestamp": "2026-08-20T17:05:00.000Z",
"accountId": "acc_sales_morocco",
"userId": "6a8725e28ea694c93c92e127",
"webhookId": "webhook_1724174000",
"data": {
"status": "connected",
"previousStatus": "pending",
"phoneNumber": "212612345678",
"isNewLogin": true,
"statusCode": 200,
"reason": "Connection established successfully"
}
}
6. الرد الفوري من خلال استجابة الويبهوك (Auto-Reply)
الرد السريع دون الحاجة لطلب API إضافي
عندما يستلم خادمك طلب الـ Webhook الخاص بـ message_received، يمكنك ببساطة إرجاع كائن JSON يحتوي على حقل reply في استجابة الـ HTTP 200، وسيقوم WMAM بإرساله فوراً للمرسل:
// HTTP Response Header: 200 OK
{
"reply": "أهلاً بك! تم استلام رسالتك وسيتم تحويلك إلى مندوب خدمة العملاء.",
"humanize": true
}
7. التحقق من التوقيع الرقمي (HMAC Signature)
حماية مسار الويبهوك الخاص بك والتأكد من موثوقية الطلبات
إذا قمت بتعيين secret عند إنشاء الويبهوك، سيرسل WMAM هيدر خاص بالتوقيع:
X-Webhook-Signature: sha256=abcdef1234567890...
// مثال للتحقق بلغة Node.js / Express:
const crypto = require('crypto');
function verifySignature(req, res, next) {
const signature = req.headers['x-webhook-signature'];
if (!signature) return res.status(401).send('Missing Signature');
const expectedSignature = 'sha256=' + crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(JSON.stringify(req.body))
.digest('hex');
if (crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature))) {
next();
} else {
res.status(403).send('Invalid Signature');
}
}
8. أمثلة برمجية متكاملة
قوالب جاهزة للربط بلغات البرمجة المختلفة
const express = require('express');
const app = express();
app.use(express.json());
// مسار استقبال الويبهوك الموحد لجميع الحسابات
app.post('/webhook', (req, res) => {
const { event, accountId, data } = req.body;
console.log(`[Webhook] تم استلام حدث ${event} من الحساب ${accountId}`);
if (event === 'message_received') {
const sender = data.phoneNumber || data.from;
const text = data.message.text;
console.log(`رسالة من ${sender}: ${text}`);
// رد تلقائي مع تفعيل محاكاة الكتابة (isTyping / humanize)
return res.json({
reply: `أهلاً بك! تم استلام رسالتك: "${text}"`,
humanize: true
});
}
res.status(200).json({ status: 'ok' });
});
app.listen(4000, () => console.log('Webhook server running on port 4000'));