الويب هوك
اضبط الويب هوك، واقرأ الأحداث التي نرسلها، وتحقق من توقيعها، وتعامل مع إعادة المحاولة.
نرسل أحداثك بطلب POST إلى رابط واحد على خادمك: الويب هوك. يمكنك ضبطه من لوحة التحكم (راجع الويب هوك) أو عبر الـ API.
ضبط الويب هوك
PUT /v1/webhooks| حقل المحتوى | مطلوب | المعنى |
|---|---|---|
url | نعم | رابطك http أو https الذي يستقبل الأحداث. |
secret | نعم | مفتاح التوقيع: نص عشوائي طويل. |
ضبطه مرة أخرى يستبدل القديم.
curl -X PUT https://api.wa.goupdev.net/v1/webhooks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://your-site.com/whatsapp/events", "secret": "a-long-random-secret"}'الرد 200: الويب هوك مع id وurl وsecret وactive.
| الخطأ | السبب |
|---|---|
400 {"error": "url and secret are required"} | الحقل url أو secret مفقود. |
عرض الويب هوك
GET /v1/webhooksالرد 200: { "id", "url", "secret", "active" }، أو null إذا لم يُضبط ويب هوك.
الأحداث
كل حدث كائن JSON فيه الحقل event الذي يحدد نوعه.
message.received
أرسل أحدهم رسالة إلى أحد أجهزتك.
{
"event": "message.received",
"deviceId": 7,
"from": "9665XXXXXXXX@s.whatsapp.net",
"text": "مرحبًا، هل طلبي جاهز؟",
"providerMessageId": "3EB0C767D26A1D8B4F21"
}| الحقل | المعنى |
|---|---|
deviceId | الجهاز الذي استقبل الرسالة. |
from | عنوان واتساب للمرسل. الأرقام قبل @ هي رقمه. |
text | النص، أو null للرسائل بلا نص (صور، صوت، ملصقات...). |
providerMessageId | معرّف واتساب لهذه الرسالة. استخدمه لتجاهل حدث عالجته من قبل. |
message.status_changed
وصلت رسالة أرسلتها أو قُرئت.
{
"event": "message.status_changed",
"deviceId": 7,
"messageId": 1042,
"status": "delivered"
}messageId هو الـ id الذي استلمته عند إرسال الرسالة. status قيمته delivered أو read.
device.status_changed
سُجّل خروج جهاز من واتساب، ويحتاج إلى مسح رمز QR جديد قبل أن يرسل مرة أخرى.
{
"event": "device.status_changed",
"deviceId": 7,
"status": "logged_out"
}التحقق من التوقيع
لكل حدث ترويسة X-Signature: قيمة HMAC-SHA256 لمحتوى الطلب الخام بمفتاح التوقيع، مكتوبة بصيغة hex. احسب القيمة نفسها عندك وقارن بينهما. إن اختلفتا فتجاهل الطلب، فهو ليس منا.
استخدم المحتوى الخام كما وصل، قبل تحويل JSON.
import crypto from 'node:crypto';
import express from 'express';
const app = express();
app.post('/whatsapp/events', express.raw({ type: 'application/json' }), (req, res) => {
const expected = crypto.createHmac('sha256', process.env.WEBHOOK_SECRET).update(req.body).digest('hex');
const received = req.get('X-Signature') ?? '';
const valid =
received.length === expected.length && crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
if (!valid) return res.sendStatus(401);
const event = JSON.parse(req.body.toString('utf8'));
// Handle the event (quickly), then answer 200.
res.sendStatus(200);
});إعادة المحاولة
- رُدّ بأي حالة
2xxلتأكيد استلام الحدث. - إذا ردّ خادمك بغير ذلك أو تعذّر الوصول إليه، نعيد المحاولة: حتى 5 محاولات إجمالًا، مع انتظار أطول كل مرة (نحو 10 ثوانٍ، ثم 20 و40 و80).
- بعد المحاولة الأخيرة يُهمل الحدث.
لذلك:
- رُدّ بسرعة. احفظ الحدث وردّ بـ
200فورًا، وأنجز العمل الطويل بعد ذلك. - توقّع التكرار. قد توصل إعادة المحاولة حدثًا عالجته من قبل. استخدم
providerMessageId، أوmessageIdمعstatus، لتخطّيه. - لا تعتمد على الترتيب. قد تصل الأحداث بترتيب يختلف عن ترتيب حدوثها.