المستندات/Webhooks≈ 8 دقائق قراءة

EVENTS · HMAC · POST

EasyLiveChat يتصل بك
في اللحظة التي يحدث فيها شيء.

Webhooks هي قناة الدفع في EasyLiveChat — بدلاً من استطلاع واجهتنا حسب جدول زمني، تعطينا عنوان URL ونرسل لك POST لكل حدث ذي صلة خلال ثانية من حدوثه. كل طلب موقّع بـ HMAC-SHA256 حتى يستطيع خادمك إثبات أنه جاء منا حقًا.

§ 00ما هي Webhooks

عندما يحدث شيء من جانب EasyLiveChat — يرسل عميل رسالة في الويدجت، يُغلق وكيل محادثة، يحدث إجراء يهم التدقيق — نُرسل POST عبر HTTPS إلى كل URL سجّلته. الجسم JSON ويحتوي على حمولة الحدث كاملة، حتى يستطيع خادمك التفاعل دون استطلاع.

اعتبره الصورة المرآة لـ REST API. الواجهة لكي يمتد كودك إلى EasyLiveChat. الـ Webhooks لكي تمتد EasyLiveChat إلى كودك. معظم التكاملات تستخدم كليهما.

كل نقطة مسجّلة لها سرّها الخاص. نوقّع كل جسم طلب بـ HMAC-SHA256 باستخدام ذلك السر ونرسل البصمة السداسية في رأس x-easylivechat-signature. خادمك يعيد حساب الـ HMAC بنفس السر ويقارن — التطابق يعني أن الطلب جاء منا فعلاً، وعدم التطابق يعني تجاهله.

§ 01توفر الخطة

يمكن إنشاء نقاط Webhook على كل خطة مدفوعة وخلال التجربة المجانية لمدة 14 يومًا. لا توجد فوترة لكل حدث — التوزيع على نقاط متعددة مشمول.

تدفّق audit.event مقصور على خطة Enterprise، يحرسه استحقاق auditWebhookExport. الحدثان message.created و conversation.updated يُطلقان في كل خطة تسمح بالوصول للـ API.

§ 02إعداد نقطة نهاية

أضف نقطة في https://app.livechattools.com/settings/webhooks. سننشئ سرًّا عشوائيًا خاصًا بكل نقطة ونعرضه لك مرة واحدة فقط عند الإنشاء. عامله مثل كلمة مرور — انسخه فورًا إلى مخزن أسرار خادمك.

  • العنوان (URL)يجب أن يكون https:// ويُحلَّ إلى عنوان IP عام. نرفض عناوين الاسترجاع والخاصة وعناوين بيانات السحابة عند الإنشاء وأثناء التسليم.
  • الأحداثإما اختر أسماء أحداث محددة أو اشترك في * (كل الأحداث). علامة النجمة مريحة للنماذج الأولية، لكن قوائم الأحداث الأضيق تجعل المُعالج أسهل في الفهم.
  • السريُنشأ تلقائيًا ويُعرض مرة واحدة. يُستخدم لتوقيع كل توصيل. إذا فقدته، احذف النقطة وأنشئ نقطة جديدة — لا يوجد مسار للاسترداد.

نشطة افتراضيًا. يمكنك إلغاء نقطة في أي وقت من نفس الصفحة — يتوقف التسليم على الفور.

§ 03شكل الحمولة

كل توصيل هو POST بنوع المحتوى application/json. الرؤوس تحدد الحدث وتحمل التوقيع؛ غلاف الجسم دائمًا { event, deliveredAt, data }:

POST https://your-server.example.com/webhook
content-type: application/json
user-agent: EasyLiveChat-Webhooks/1.0
x-easylivechat-event: message.created
x-easylivechat-signature: sha256=<hex>

{
  "event": "message.created",
  "deliveredAt": "2026-05-27T08:55:25.841Z",
  "data": {
    "conversationId": "cmp...",
    "message": {
      "id": "cmp...",
      "body": "Hi!",
      "senderType": "CUSTOMER",
      "createdAt": "2026-05-27T08:55:25.840Z"
    }
  }
}

event هو نفس قيمة رأس x-easylivechat-event. شكل data يختلف حسب الحدث — انظر كتالوج الأحداث أدناه.

§ 04تحقق من التوقيع

أي شخص يعرف عنوان نقطتك يمكنه إرسال POST بمحتوى غير مرغوب فيه. توقيع HMAC هو الطريقة لتمييز طلباتنا عن المزيّفة. أعِد حسابه بسرّك وارفض الطلب عند عدم التطابق.

اقرأ بايتات الجسم الخام (لا تقم بـ json.parse أولاً — إعادة التسلسل ستعيد ترتيب المفاتيح وتُكسر التجزئة). أزل البادئة sha256= من رأس التوقيع. احسب HMAC-SHA256(rawBody, secret) وقارن بطريقة آمنة زمنيًا مع الـ hex المستلم.

Node.js

import crypto from 'node:crypto';
import express from 'express';

const SECRET = process.env.WEBHOOK_SECRET;
const app = express();
app.use(express.raw({ type: 'application/json' }));

app.post('/webhook', (req, res) => {
  const received = (req.header('x-easylivechat-signature') || '').replace(/^sha256=/, '');
  const expected = crypto.createHmac('sha256', SECRET).update(req.body).digest('hex');
  const ok =
    received.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(received, 'hex'), Buffer.from(expected, 'hex'));
  if (!ok) return res.status(401).send('bad signature');

  const event = JSON.parse(req.body.toString('utf8'));
  // handle event.event, event.data...
  res.status(200).send('ok');
});

Python (Flask)

import hmac, hashlib, os
from flask import Flask, request, abort

SECRET = os.environ["WEBHOOK_SECRET"].encode()
app = Flask(__name__)

@app.post("/webhook")
def webhook():
    received = request.headers.get("x-easylivechat-signature", "").removeprefix("sha256=")
    expected = hmac.new(SECRET, request.get_data(), hashlib.sha256).hexdigest()
    if not hmac.compare_digest(received, expected):
        abort(401)
    event = request.get_json()
    # handle event["event"], event["data"]...
    return "ok", 200

curl (debugging)

# Recompute the signature locally and compare with the header.
echo -n "$RAW_BODY" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET"

timingSafeEqual / hmac.compare_digestاستخدم دائمًا مقارنة بزمن ثابت حتى لا يستطيع المهاجمون فحص السر بايتًا بايتًا.

§ 05كتالوج الأحداث

تطلق المنصة اليوم أربعة أنواع أحداث. نضيف المزيد مع شحن الميزات — اشترك في * إذا أردت توافقًا مستقبليًا.

الحدثيُطلق عندشكل البيانات
message.createdتصل رسالة جديدة إلى محادثة، بغض النظر عن من أرسلها (عميل وارد، وكيل صادر، إرسال REST API).{ conversationId, message }
conversation.updatedتتغير حالة محادثة (OPEN · SNOOZED · CLOSED) أو assignedAgentId الخاص بها.{ conversationId, status?, assignedAgentId? }
audit.eventكلما كُتب سجل تدقيق — تسجيل دخول وكيل، تغيير دور، إنشاء تكامل، إلغاء مفتاح، إلخ. (خطة Enterprise.){ action, entity, entityId, actorId, metadata }
webhook.testتنقر على "Test" في الإعدادات ← Webhooks. موقّع ومشكّل تمامًا مثل حدث حقيقي.{ tenantId, test: true }

اشترك في * لاستلام كل حدث حالي ومستقبلي. اشترك بأسماء محددة إذا أردت تقييد ما يجب أن يعرفه المُعالج.

§ 06اختبار التكامل

زر "Test" في الإعدادات ← Webhooks يُطلق حدث webhook.test على نقطتك ويُبلّغ بحالة HTTP والوقت المنقضي. استخدمه للتحقق من معالجك قبل توجيه حركة حقيقية إليه.

تستخدم حمولة الاختبار نفس غلاف الجسم وأسماء الرؤوس ومخطط HMAC تمامًا كأحداث الإنتاج — إذا نجح تحققك من webhook.test، فسينجح من message.created وكل شيء آخر.

§ 07إعادة المحاولة والمهلات

نمنح خادمك 10 ثوانٍ للرد. أي حالة غير 2xx أو خطأ شبكة هو فشل. التوصيلات الفاشلة تُعاد محاولتها حتى 5 مرات بتراجع أُسّي يبدأ من ثانيتين، فحتى نقطة غير مستقرة تحصل على عدة فرص قبل أن نتخلى عن ذلك الحدث.

لا نضمن التسليم لمرة واحدة بالضبط — تحت تذبذب الشبكة قد يصل الحدث نفسه مرتين. اجعل المُعالج عند نقطته (idempotent): أزل التكرار بناءً على data.message.id الداخلي (أو أي معرّف منطقي لذلك الحدث).

§ 08قائمة الأمان

  • استخدم https:// دائمًا — تُرفض نقاط http:// العادية عند الإنشاء.
  • نحجب عناوين IP الخاصة وlooking وcloud-metadata في وقت الإنشاء والتسليم، حتى لا يُستخدم سجل DNS مُكوّن خطأ للتمحور داخل شبكتك.
  • قارن التواقيع باستخدام مساواة آمنة زمنيًا (Node crypto.timingSafeEqual، Python hmac.compare_digest، Go hmac.Equal).
  • قم بالتدوير بحذف النقطة وإنشاء جديدة بنفس الـ URL. حدّث مخزن الأسرار بشكل ذرّي.