OdyOdy مساعدة

استقبال الويب هوكس والتحقق من التوقيعات

تم التحديث Sun Aug 30 2026 00:00:00 GMT+0000 (Coordinated Universal Time)

تدفع Ody أحداث مساحة العمل — الرسائل الجديدة، نتائج المكالمات، تغييرات جهات الاتصال — إلى نقاط نهاية HTTPS التي تسجلها عبر واجهة برمجة التطبيقات، مع توقيع كل تسليم وفقًا لمواصفات Standard Webhooks حتى تتمكن من إثبات أنها جاءت من Ody.

قبل أن تبدأ

  • تحتاج إلى مفتاح API بنطاق webhooks:manage — انظر الحصول على مفتاح Ody API الخاص بك.
  • يجب أن تكون نقطة النهاية الخاصة بك عنوان URL HTTPS يستجيب بحالة 2xx بسرعة (تنتهي مهلة التسليمات بعد 10 ثوانٍ).
  • يمكن لكل مساحة عمل تسجيل ما يصل إلى 50 نقطة نهاية.

خطوة بخطوة

  1. ادرج أنواع الأحداث التي يمكنك الاشتراك فيها:
curl https://api.ody.co/v1/api/webhook-events \
  -H "Authorization: Bearer ody_live_…"

الكتالوج اليوم: message.received، message.delivered، message.failed، call.ringing، call.answered، call.completed، call.forwarded، call.missed، call.recording.completed، call.summary.completed، call.transcript.completed، call.voicemail.completed، call.flow.started، call.flow.completed، call.flow.aborted، contact.updated، contact.deleted. الاشتراك في "*" يغطي كل أنواع الأحداث الحالية والمستقبلية.

تُطلق أحداث call.flow.* عندما يتم الرد على مكالمة بواسطة تدفق مكالمات: started عندما يدخل المتصل التدفق، completed عندما يصل إلى وجهة (مع نوع الوجهة — رنين، مساعد AI، بريد صوتي، تحويل، أو إنهاء المكالمة)، وaborted إذا لم يتمكن التدفق من الانتهاء.

  1. سجل نقطة النهاية الخاصة بك:
curl https://api.ody.co/v1/api/webhooks \
  -H "Authorization: Bearer ody_live_…" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/ody-webhook","events":["message.received"],"label":"prod"}'
  1. احفظ secret من الاستجابة فورًا. يتم إرجاع سر التوقيع whsec_… فقط عند الإنشاء والتدوير — ولا يتم عرضه مرة أخرى أبدًا.
  2. أرسل لنفسك حدث اختبار موقّع وتأكد من أن نقطة النهاية الخاصة بك تتحقق منه وتقبله:
curl -X POST https://api.ody.co/v1/api/webhooks/WEBHOOK_ID/test \
  -H "Authorization: Bearer ody_live_…"

ينشر الاختبار حدث {"type":"ping"} موقّعًا تمامًا مثل التسليم الحقيقي.

كيف يبدو التسليم

كل تسليم هو طلب POST مع نص JSON وثلاثة رؤوس توقيع:

{
  "id": "evt_…",
  "apiVersion": "2026-06-01",
  "createdAt": "2026-08-16T12:00:00.000Z",
  "type": "message.received",
  "data": { "conversationId": "…", "activityId": "…", "numberE164": "+1…" }
}
الرأس المعنى
webhook-id معرف الحدث — قم بإزالة التكرارات بناءً عليه، حيث أن عمليات إعادة المحاولة تعيد استخدامه
webhook-timestamp ثواني يونكس وقت الإرسال
webhook-signature v1,<base64 HMAC-SHA256> على <id>.<timestamp>.<raw body>

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

مفتاح HMAC هو الجزء المفكوك من base64 من سرك بعد البادئة whsec_، والرسالة الموقعة هي <webhook-id>.<webhook-timestamp>.<raw body>. تحقق دائمًا من البايتات الخام للطلب — إعادة تسلسل JSON المحلل يكسر التوقيع. ارفض الطوابع الزمنية الأقدم من بضع دقائق لمنع عمليات إعادة التشغيل.

import { createHmac, timingSafeEqual } from "node:crypto";
import express from "express";

const app = express();
app.post("/ody-webhook", express.raw({ type: "application/json" }), (req, res) => {
  const secret = process.env.ODY_WEBHOOK_SECRET; // whsec_…
  const id = req.headers["webhook-id"];
  const timestamp = req.headers["webhook-timestamp"];
  const signature = req.headers["webhook-signature"];

  // Replay guard: reject deliveries older than 5 minutes.
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return res.status(401).end();

  const key = Buffer.from(secret.slice("whsec_".length), "base64");
  const expected = "v1," + createHmac("sha256", key)
    .update(`${id}.${timestamp}.${req.body}`)
    .digest("base64");

  const a = Buffer.from(expected);
  const b = Buffer.from(String(signature));
  if (a.length !== b.length || !timingSafeEqual(a, b)) return res.status(401).end();

  const event = JSON.parse(req.body.toString("utf8"));
  console.log("verified event:", event.type);
  res.status(200).end();
});

تأتي حزم SDK الرسمية مع هذه الوظيفة كسطر واحد — verifyWebhookSignature (TypeScript) وverify_webhook_signature (Python)، وكلاهما يتضمن مقارنة بوقت ثابت وحماية إعادة التشغيل لمدة 5 دقائق. انظر البدء السريع لحزم SDK: TypeScript و Python.

إعادة المحاولات، السجل، والإدارة

  • إعادة المحاولات: يتم إعادة محاولة التسليم الفاشل (غير 2xx، مهلة، أو خطأ اتصال) بعد حوالي 5 ثوانٍ ثم 30 ثانية بعد المحاولة الأولى — ثلاث محاولات إجمالاً، مهلة 10 ثوانٍ لكل منها.
  • السجل: GET /v1/api/webhooks/:id/deliveries يسرد التسليمات الأخيرة الأحدث أولاً، مع رموز الحالة والأخطاء والمدد لكل محاولة — محطتك الأولى عندما تبدو الأحداث مفقودة.
  • إدارة نقاط النهاية: GET /v1/api/webhooks يسردها (لا يظهر السر أبدًا)، PATCH /v1/api/webhooks/:id يحدث url، events، label، أو status (enabled/disabled)، وDELETE /v1/api/webhooks/:id يزيل واحدة مع سجل تسليماتها.
  • تدوير السر في أي وقت باستخدام POST /v1/api/webhooks/:id/rotate — يتم إرجاع whsec_… الجديد مرة واحدة، وتتوقف التوقيعات القديمة عن التحقق فورًا.

استكشاف الأخطاء وإصلاحها

  • فشل التحقق من التوقيع دائمًا — ربما تتحقق من نص معاد تسلسله. استخدم البايتات الخام للطلب، وتأكد من أنك فككت تشفير base64 للسر بعد إزالة whsec_.
  • عدم وصول التسليمات — تحقق من أن status نقطة النهاية هو enabled، وأن قائمة events الخاصة بها تتضمن النوع الذي تتوقعه (أو "*"), وسجل التسليمات بحثًا عن أخطاء لكل محاولة.
  • أحداث مكررة — عمليات إعادة المحاولة تعيد استخدام نفس webhook-id. قم بإزالة التكرارات بناءً عليه.
  • webhook limit reached — لقد وصلت إلى 50 نقطة نهاية لمساحة العمل؛ احذف واحدة غير مستخدمة أولاً.

مقالات ذات صلة

الأسئلة الشائعة

كيف يتم توقيع تسليمات الويب هوك؟

وفقًا لمواصفات Standard Webhooks: رأس `webhook-signature` بالشكل `v1,<base64 HMAC-SHA256>` محسوبًا على أساس `<webhook-id>.<webhook-timestamp>.<raw body>` باستخدام سرك `whsec_`.

ماذا يحدث إذا كانت نقطة النهاية الخاصة بي معطلة؟

تعيد Ody المحاولة مرتين — حوالي 5 ثوانٍ ثم 30 ثانية بعد الفشل الأول. تحقق من `GET /v1/api/webhooks/:id/deliveries` لمعرفة رموز الحالة والأخطاء لكل محاولة.

لقد فقدت سر التوقيع الخاص بي — ماذا أفعل الآن؟

قم بتدويره باستخدام `POST /v1/api/webhooks/:id/rotate`. يتم إرجاع سر `whsec_` الجديد مرة واحدة؛ وتتوقف التوقيعات القديمة عن التحقق فورًا.

المزيد في واجهة برمجة تطبيقات المطور (API)