WA Gateway

الويب هوك

اضبط الويب هوك، واقرأ الأحداث التي نرسلها، وتحقق من توقيعها، وتعامل مع إعادة المحاولة.

نرسل أحداثك بطلب 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، لتخطّيه.
  • لا تعتمد على الترتيب. قد تصل الأحداث بترتيب يختلف عن ترتيب حدوثها.

في هذه الصفحة