Webhooks
اجعل Cliento Pro ينادي نقطتك الطرفية عند وقوع الحدث، بدل أن تستطلعه أنت باستمرار.
آخر مراجعة: 2026-08-23
ما الـ Webhook هنا
كل تغيّر في حالة مساحة العمل يكتب حدثًا - إنشاء جهة اتصال، ربح صفقة، سداد فاتورة. والاشتراك في Webhook تعليمة دائمة بإرسال تلك الأحداث عبر POST إلى عنوان تتحكم فيه، لحظة وقوعها.
استخدمه بدل استطلاع GET /events على مؤقّت. الاستطلاع يكلّفك زمن استجابة لا يمكنك تحسينه، ويكلّف مساحة العمل طلبًا لكل فترة ولكل تكامل؛ أما الـ Webhook فيصل خلال ثوانٍ من التغيير ولا يكلّف شيئًا حين لا يحدث شيء.
إنشاء اشتراك
أنشئه من التطبيق عبر الإعدادات ← Webhooks، أو عبر الـ API بصلاحية webhooks.write.
curl -sS -X POST "$CLIENTO_HOST/api/v1/webhooks" \
-H "Authorization: Bearer $CLIENTO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Warehouse sync",
"description": "Mirrors contacts and deals into the data warehouse",
"target_url": "https://hooks.example.com/cliento",
"event_types": ["ContactCreated", "ContactUpdated", "DealWon"],
"max_attempts": 5,
"is_active": true
}'{
"id": 7,
"name": "Warehouse sync",
"target_url": "https://hooks.example.com/cliento",
"event_types": ["ContactCreated", "ContactUpdated", "DealWon"],
"secret": "whsec_M2Yx…",
"max_attempts": 5,
"is_active": true,
"last_delivery_at": null,
"created_at": "2026-08-23T10:20:00"
}| الحقل | المعنى |
|---|---|
target_url | وجهة الـ POST. يجب أن يكون HTTPS ومتاحًا من الإنترنت. |
event_types | أي الأحداث تُرسَل. ["*"] تعني كلها. |
extra_headers | ترويسات ثابتة تُضاف إلى كل تسليم - رمز مشترك لبوابتك مثلًا. |
masked_fields | حقول يجب ألا تصل هذه الوجهة أبدًا. انظر أدناه. |
max_attempts | عدد المحاولات قبل التخلّي عن التسليم. الافتراضي 5. |
is_active | اجعلها false للإيقاف المؤقت دون حذف - عندها تُهمَل التسليمات المصطفّة. |
ما يجب أن تفعله نقطتك
- أن تكون HTTPS ومتاحة للعموم. العنوان الخاص لا يُنادى أبدًا.
- أن تجيب بـ2xx بمعنى «استُلم». وأي شيء آخر - بما فيه إعادة التوجيه - يُعدّ إخفاقًا ويُعاد.
- أن تجيب خلال 10 ثوانٍ. تلك مهلة المقبس؛ والرد الأبطأ محاولة فاشلة ولو عالجته لاحقًا.
- أن تؤجّل العمل. تحقّق، ثم صُفّ، ثم أعد 200. المعالجة الفورية هي ما يحوّل قاعدة بيانات بطيئة إلى عاصفة إعادات.
- أن تقبل التكرار. التسليم «مرة واحدة على الأقل» - راجع دليل التسليم.
الحمولة
كل تسليم هو POST بصيغة JSON بالمغلّف نفسه. payload هو الحدث، والحقول الثلاثة حوله بيانات وصفية للتسليم ذاته.
POST /cliento HTTP/1.1
Host: hooks.example.com
Content-Type: application/json
X-Cliento-Signature: sha256=6b2f…
X-Cliento-Delivery-Id: 88213
X-Cliento-Event-Type: ContactCreated{
"delivery_id": 88213,
"event_type": "ContactCreated",
"timestamp": "2026-08-23T10:21:07Z",
"payload": {
"id": 91442,
"tenant_id": 17,
"user_id": 5,
"entity_type": "contact",
"entity_type_label": { "en": "Contact", "fa": "مخاطب", "ar": "جهة اتصال" },
"entity_id": 4182,
"event_type": "ContactCreated",
"event_type_label": { "en": "Contact created", "fa": "مخاطب ایجاد شد", "ar": "تم إنشاء جهة الاتصال" },
"source": "api",
"metadata": { "email": "sara@example.com" },
"occurred_at": "2026-08-23T10:21:06"
}
}| الحقل | استخدامه |
|---|---|
delivery_id | إزالة التكرار. الرقم نفسه عند الإعادة، ورقم جديد لتسليم جديد فعلًا. |
event_type | التوجيه. رمز آلي مستقر. |
timestamp | وقت بناء التسليم (UTC). |
payload.entity_type / entity_id | أي سجل تغيّر - اجلبه عبر الـ API إن احتجت الصف كاملًا. |
payload.metadata | إضافات خاصة بالحدث. تختلف بحسب نوعه؛ عامِل المفاتيح المجهولة كاختيارية. |
الأحداث المتاحة
أنواع الأحداث أسماء بصيغة PascalCase على هيئة <كيان><فعل ماضٍ>. اشترك بالأسماء التي تعالجها بالضبط بدل *، حتى لا يبدأ نوع حدث جديد يُضاف إلى المنتج بالوصول إلى نقطة لا كود لها لمعالجته.
ContactCreated ContactUpdated ContactDeleted
LeadCreated LeadStatusChanged LeadConverted
DealCreated DealStageChanged DealWon DealLost
TaskCreated TaskUpdated
PipelineCreated PipelineStageUpdated
TagCreated SegmentUpdated CampaignCreatedالقائمة الكاملة والحالية هي ما يظهر في سجل أحداث مساحة عملك: GET /events يعيد أحداثًا حقيقية بـevent_type الخاص بها، وشاشة الإعدادات ← Webhooks تعرض الكتالوغ نفسه كمُنتقٍ. وكلاهما يُولَّد من المنتج، فلا يتقادمان كما تتقادم قائمة مكتوبة يدويًا هنا.
إبقاء حقول خارج الحمولة
masked_fields يسمّي الحقول التي يجب ألا تصل هذه الوجهة أبدًا - رقم هاتف يجوز أن يغادر نظامك لكن لا يجوز أن يغادر بلدك مثلًا. وGET /webhooks/maskable-fields يسرد كتالوغ المفاتيح.
curl -sS -X PATCH "$CLIENTO_HOST/api/v1/webhooks/7" \
-H "Authorization: Bearer $CLIENTO_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "masked_fields": ["contact.phone", "contact.email"] }'يُطبَّق التقنيع قبل تخزين التسليم، فيكون الصف المصطفّ مُقنَّعًا أصلًا ولا تستطيع إعادة المحاولة إرسال الأصل. ويعني ذلك أن GET /webhooks/{subscription_id}/deliveries - سجل التسليمات - لا يحتفظ أبدًا بنسخة غير مقنَّعة.