telyzer

الأحداث وCloudEvents

كل حدث ينشره تيلايزر، وقائمة الأحداث، والـ Webhooks بالصيغة الكلاسيكية أو بصيغة CloudEvents 1.0، والبث المباشر في البوابة.

قائمة الدليل

عندما يحدث شيء في تيلايزر (تنتهي مكالمة، أو يصبح متصل بانتظار معاودة الاتصال، أو ينطلق تنبيه) يُنشر مرة واحدة حدثًا، في معاملة قاعدة البيانات نفسها التي سجّلت التغيير. ويصل الحدث نفسه بعد ذلك إلى الـ Webhooks لديك، وإلى الشاشات المباشرة في البوابة، وإلى شاشات وحدات تيلايزر الجديدة عند وصولها. ولا يُرسل حدث عن تغيير لم يحدث.

قائمة الأحداث

كل أنواع الأحداث مدرجة مع وحدتها ووصفها في GET /api/v1/events/types (عامة، دون مفتاح). ويمكن للـ Webhooks الاشتراك في أي نوع في القائمة.

curl https://app.telyzer.com/api/v1/events/types
الحدثيُرسل عندما
call.completedتنتهي مكالمة واردة أو صادرة، أُجيبت أم لا. المكالمات الداخلية ليست أحداثًا.
call.missedلم يُرد على مكالمة واردة من الخارج، أو حُوّلت إلى البريد الصوتي.
callback.openedأصبح متصل فائت بانتظار معاودة الاتصال (ولم يكن ينتظر من قبل). راجع معاودة الاتصال.
callback.closedعوود الاتصال بمتصل كان ينتظر، أو وصل هو بنفسه، أو أُغلق يدويًا.
alert.triggeredانطلقت قاعدة تنبيه.
report.deliveredأُرسل تقرير مجدول بالبريد.
source.silentتوقف نظام هاتف عن إرسال سجلات المكالمات خلال ساعات العمل.
  • تُرسل أحداث المكالمات ومعاودة الاتصال مرة واحدة لكل مكالمة، عند وصول آخر جزء منها. وملف مكالمات قديمة يُستورد لاحقًا تاريخ لا خبر: المكالمات التي انتهت قبل أكثر من 7 أيام لا تنتج أحداثًا.
  • تحمل الأحداث ملخصًا فقط، ولا تحمل تسجيلات أو صوتًا أبدًا. وتظهر أرقام الهاتف مخفية ما لم يكن للمستلم حق رؤيتها كاملة (راجع إخفاء الأرقام).
  • لكل نوع رقم إصدار version. والتغيير الذي قد يعطّل المستلم يأتي نوعًا أو إصدارًا جديدًا، لا تغييرًا صامتًا.

بيانات الـ Webhooks: كلاسيكية أو CloudEvents

لكل Webhook صيغة بيانات. الصيغة الكلاسيكية هي الافتراضية وهي ما تستخدمه Webhooks تيلايزر دائمًا، فتبقى المستقبِلات الحالية تعمل دون تغيير:

كلاسيكية (application/json)
{
  "event": "call.missed",
  "occurredAt": "2026-10-25T07:14:03.512Z",
  "data": { "callId": "0192…", "direction": "inbound", "outcome": "unanswered", "number": "+966•••••••77", … }
}

أما CloudEvents 1.0 فتضع data نفسها في غلاف CloudEvents القياسي (صيغة JSON، الوضع المهيكل)، الذي تقرؤه أدوات وخدمات سحابية كثيرة مباشرة:

CloudEvents (application/cloudevents+json)
{
  "specversion": "1.0",
  "id": "0192f3a1-7c4e-7b55-9a10-3c2d9e8b4f61",
  "source": "/telyzer/cdr",
  "type": "call.missed",
  "subject": "calls/0192f3a1-7c4e-7b55-9a10-3c2d9e8b4f60",
  "time": "2026-10-25T07:14:03.512Z",
  "datacontenttype": "application/json",
  "data": { "callId": "0192…", "direction": "inbound", "outcome": "unanswered", "number": "+966•••••••77", … }
}
الحقلالمعنى
idمعرّف الحدث الفريد. وتحمل إعادات الإرسال المعرّف نفسه، فيمكنك تجاهل المكرر.
sourceوحدة تيلايزر التي نشرته، مثل /telyzer/cdr لتحليلات المكالمات.
typeنوع الحدث من القائمة.
subjectما يتعلق به، مثل calls/<معرّف المكالمة> أو callbacks/<معرّف المكالمة الفائتة>.
timeوقت وقوعه (UTC).

الصيغتان موقّعتان بالطريقة نفسها (X-Telyzer-Signature، راجع التحقق من التوقيع) وتحملان ترويستي X-Telyzer-Event وX-Telyzer-Delivery. ويمكنك تغيير صيغة Webhook من تعديل الأحداث، ويسري التغيير على الأحداث التي تُجدول بعده.

التحديثات المباشرة في البوابة

تتحدث لوحة العرض وصفحة معاودة الاتصال فور انتهاء المكالمة عبر بث مباشر للأحداث (Server-Sent Events). وإذا انقطع البث تواصلان التحديث تلقائيًا كل بضع ثوانٍ، فلا تتوقف شاشة الحائط أبدًا.

  • البث هو GET /api/v1/events/stream للأعضاء المسجّلين. كل رسالة غلاف CloudEvents، و?types= يقصره على أنواع معينة.
  • يرى الأعضاء الأحداث التي يسمح بها دورهم (أحداث المكالمات تتطلب صلاحية قراءة المكالمات)، مع إخفاء الأرقام ما لم يحق لهم رؤيتها كاملة، ولمواقعهم وأقسامهم فقط إذا كان وصولهم محدودًا.
  • بعد انقطاع قصير يعيد المتصفح الاتصال ويستلم ما فاته حتى ساعة مضت. ويمكن أن تفتح المؤسسة حتى 50 اتصالًا مباشرًا في وقت واحد.
// In the portal (signed in): refresh a view when a call ends
const es = new EventSource("/api/v1/events/stream?types=call.completed,callback.opened");
es.onmessage = (m) => {
  const event = JSON.parse(m.data);   // a CloudEvents envelope
  console.log(event.type, event.subject, event.data);
};
es.addEventListener("resync", () => location.reload()); // too much was missed to replay

مدة الاحتفاظ بالأحداث

تُحفظ الأحداث 30 يومًا، وأطول فقط ما دامت إعادة إرسالها إلى Webhook جارية. أما سجل المكالمات نفسه فيتبع خطتك (راجع مدة الاحتفاظ بالسجل).