Webhooks
الوجهات، الأحداث، التوقيع، وإعادة المحاولة.
Webhook — إدارة الوجهات
GET /instances/{instance_id}/webhooks
POST /instances/{instance_id}/webhooks
PATCH /instances/{instance_id}/webhooks/{webhook_id}
POST /instances/{instance_id}/webhooks/{webhook_id}/enabled { "enabled": true }
DELETE /instances/{instance_id}/webhooks/{webhook_id}
POST /instances/{instance_id}/webhooks
{
"destination_url": "https://your-site.com/webhook",
"events": ["message", "message.ack", "session.status", "message.unknown"],
"client_sign_secret": "your-secret",
"ignore_status": true
}
→ 201 { "success": true, "webhook_id": "whk_…" } يُنشأ الويب هوك معطلاً — فعّله بمسار enabled. PATCH يستبدل الإعداد كاملاً فأرسل destination_url و events دائماً؛ client_sign_secret الفارغ يُبقي السر الحالي و clear_client_sign = true يزيله. يمكن إدارة كل ذلك أيضاً من صفحة الجلسة.
Webhook — الأحداث
session.status | تغيّر حالة الجلسة (WORKING، SCAN_QR_CODE، FAILED…) مع رقم الجوال المرتبط. |
message | رسالة واردة من الآخرين. |
message.any | كل رسالة في الجلسة، الواردة والصادرة (fromMe). |
message.ack | تحديث تسليم/قراءة رسالة أرسلتها (حقل ack). |
message.reaction | تفاعل (إيموجي) على رسالة. |
message.edited | تعديل رسالة. |
message.revoked | حذف رسالة لدى الجميع. |
message.unknown | حدث من المنصة: رسالة أرسلتها عبر API صارت unknown وتحتاج قرارك. |
أحداث أخرى متاحة (المجموعات، المكالمات، التصنيفات، الاستطلاعات، التواجد) — القائمة الكاملة في نموذج الويب هوك بصفحة الجلسة.
ignore_status (افتراضي true): حالات واتساب/القصص (status@broadcast) لا تُرسل إليك. اجعله false لاستقبالها ضمن أحداث الرسائل.
Webhook — شكل الطلب الواصل لوجهتك
POST https://your-site.com/webhook
Content-Type: application/json
X-TProTool-Event-Id: evt_…
X-TProTool-Timestamp: 1760209200
X-TProTool-Signature: v1=…
{
"event_id": "evt_…",
"event": "message",
"instance_id": "ins_…",
"timestamp": 1760209200000,
"payload": {
"id": "…",
"from": "[email protected]",
"from_phone": "9665xxxxxxxx",
"fromMe": false,
"body": "Hello",
"hasMedia": true,
"media": {
"status": "ready",
"mimetype": "image/jpeg",
"media_id": "med_…",
"url": "https://…/m/…",
"expires_at": "…"
}
}
}
// message.unknown
{
"event_id": "evt_…",
"event": "message.unknown",
"instance_id": "ins_…",
"payload": { "message_id": "msg_…", "client_reference": "order-123", "to": "9665xxxxxxxx", "type": "text", "error_code": "TIMEOUT" }
}
// error_code: TIMEOUT | WORKER_DIED media.status = ready | الملف محفوظ — نزّله من url قبل expires_at. |
media.status = too_large | الملف أكبر من الحد المسموح فلم يُحفظ. |
media.status = failed | تعذّر تنزيل الملف من واتساب. |
media.status = outgoing | وسيط في رسالة أرسلتها الجلسة — لا يُحفظ منه نسخة. |
media.status = unavailable | الوسيط غير متاح للتنزيل. |
Webhook — التحقق من التوقيع
عند ضبط client_sign_secret يصل الرأس X-TProTool-Signature بالقيمة v1= ثم HMAC-SHA256 للنص (timestamp + "." + جسم الطلب الخام) بالسر. X-TProTool-Event-Id و X-TProTool-Timestamp يصلان دائماً. ارفض الطلب إن لم يطابق التوقيع أو كان الوقت أقدم من 5 دقائق.
<?php
$secret = 'your-secret';
$raw = file_get_contents('php://input');
$ts = $_SERVER['HTTP_X_TPROTOOL_TIMESTAMP'] ?? '';
$sig = $_SERVER['HTTP_X_TPROTOOL_SIGNATURE'] ?? '';
$expected = 'v1=' . hash_hmac('sha256', $ts . '.' . $raw, $secret);
if (!hash_equals($expected, $sig) || abs(time() - (int) $ts) > 300) {
http_response_code(401);
exit;
}
$event = json_decode($raw, true);
// ignore if $event['event_id'] was already processed
http_response_code(200);
Webhook — الرد وإعادة المحاولة
ردّ بأي رمز 2xx خلال 8 ثوانٍ ليُعتبر التسليم ناجحاً. غير ذلك يُعاد الإرسال بفواصل متزايدة (5، 10، 20، 40، 80 ثانية) حتى 6 محاولات ثم يصبح فشلاً نهائياً، ويمكنك إعادة تسليمه يدوياً من سجل التسليم في صفحة الجلسة.
410 Gone: يُعطَّل الويب هوك ويتوقف الإرسال إليه حتى تفعّله من جديد. 429 مع Retry-After: تُؤجَّل المحاولة للوقت المطلوب (حتى ساعة).
event_id ثابت للحدث في كل المحاولات — احفظه وتجاهل أي حدث وصلك سابقاً. عالج الحدث بعد الرد بسرعة إن كانت معالجته طويلة.