Deewanالتوثيق

أسماء الحقول ورموز الأخطاء وأمثلة الشيفرة بالإنجليزية، كما تستخدمها في برنامجك.

الويب هوك

استدعاءات HTTPS موقَّعة ومعاد إرسالها لكل ما يجري في الاجتماعات.

أضف نقطة استقبال من المطوّرون ← الويب هوك (أو عبر الواجهة البرمجية). يرسل ديوان حدثًا بصيغة JSON إليها كلما وقع شيء اشتركت فيه.

الأحداث

النوعمتى
room.created / room.updated / room.deletedتغيّر غرفة عبر الواجهة البرمجية
room.startedانضمام أول شخص إلى الاجتماع
room.finishedخلوّ الاجتماع وإغلاقه
participant.joined / participant.leftدخول شخص أو خروجه
participant.stage_changedدعوة حاضر في ندوة للتحدّث، أو إعادته إلى الجمهور
meeting.scheduled / meeting.updated / meeting.cancelledتغيّر اجتماع مجدول عبر الواجهة البرمجية
poll.created / poll.closedفتح استطلاع أو إغلاقه
breakout.started / breakout.endedفتح الغرف الفرعية أو إغلاقها
recording.readyاكتمال تسجيل وإمكان جلبه
الحمولة
{
  "id": "evt_Vd9sX2…",
  "type": "participant.joined",
  "created_at": "2026-09-17T09:20:11.482Z",
  "data": {
    "room": { "id": "5f0c2b8e-…", "code": "k7pq-3mzt-9xwe", "name": "Onboarding call" },
    "participant": { "identity": "api_Qm9v….k2d9x0aa", "name": "Omar", "role": "participant" },
    "occurred_at": "2026-09-17T09:20:11.000Z"
  }
}

تحقّق من كل طلب

يحمل كل طلب ترويسة Deewan-Signature: t=<ثواني يونكس>,v1=<hex>، حيث v1 هو HMAC-SHA256 للنص <t>.<الجسم الخام> باستخدام سر نقطتك. ارفض كل ما لا يطابق أو تجاوز عمره خمس دقائق.

مسار Next.js مع حزمة SDK
import { verifyWebhook } from "@deewan/sdk";

export async function POST(request: Request) {
  const raw = await request.text(); // the raw body, not parsed JSON
  try {
    const event = await verifyWebhook(raw, request.headers.get("deewan-signature"), process.env.DEEWAN_WEBHOOK_SECRET!);
    if (event.type === "room.finished") await markSessionComplete(event.data);
    return new Response(null, { status: 204 });
  } catch {
    return new Response("invalid signature", { status: 400 });
  }
}
بايثون، بدون حزمة SDK
import hmac, hashlib, time

def verify(raw_body: bytes, header: str, secret: str, tolerance=300) -> bool:
    parts = dict(p.split("=", 1) for p in header.split(","))
    t = int(parts["t"])
    if abs(time.time() - t) > tolerance:
        return False
    expected = hmac.new(secret.encode(), f"{t}.".encode() + raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts["v1"])

التسليم

  • أجب بأي رمز 2xx خلال عشر ثوانٍ، وأجّل العمل البطيء إلى ما بعد الرد.
  • يُعاد إرسال التسليمات الفاشلة من طابور دائم بعد نحو ١٠ ثوانٍ ثم دقيقة ثم ٥ دقائق ثم ٣٠ دقيقة ثم ساعتين، فلا تضيع عند إعادة تشغيل خوادمنا. ولا يُعاد الإرسال مع ردود 4xx (عدا 408 و429).
  • التسليم مرة واحدة على الأقل: استخدم id الحدث لتجاهل المكرر.
  • قد تصل الأحداث بغير ترتيبها؛ اعتمد على occurred_at.
  • يجب أن تكون النقاط عناوين https:// عامة. وتُرفض العناوين الخاصة والمحلية وعناوين بيانات السحابة، ولا تُتَّبع عمليات إعادة التوجيه.
  • راجع آخر التسليمات من لوحة التحكم أو عبر GET /webhooks/{id}/deliveries.