استقبال الويب هوكس والتحقق من التوقيعات
تدفع Ody أحداث مساحة العمل — الرسائل الجديدة، نتائج المكالمات، تغييرات جهات الاتصال — إلى نقاط نهاية HTTPS التي تسجلها عبر واجهة برمجة التطبيقات، مع توقيع كل تسليم وفقًا لمواصفات Standard Webhooks حتى تتمكن من إثبات أنها جاءت من Ody.
قبل أن تبدأ
- تحتاج إلى مفتاح API بنطاق
webhooks:manage— انظر الحصول على مفتاح Ody API الخاص بك. - يجب أن تكون نقطة النهاية الخاصة بك عنوان URL HTTPS يستجيب بحالة
2xxبسرعة (تنتهي مهلة التسليمات بعد 10 ثوانٍ). - يمكن لكل مساحة عمل تسجيل ما يصل إلى 50 نقطة نهاية.
خطوة بخطوة
- ادرج أنواع الأحداث التي يمكنك الاشتراك فيها:
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 إذا لم يتمكن التدفق من الانتهاء.
- سجل نقطة النهاية الخاصة بك:
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"}'
- احفظ
secretمن الاستجابة فورًا. يتم إرجاع سر التوقيعwhsec_…فقط عند الإنشاء والتدوير — ولا يتم عرضه مرة أخرى أبدًا. - أرسل لنفسك حدث اختبار موقّع وتأكد من أن نقطة النهاية الخاصة بك تتحقق منه وتقبله:
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_` الجديد مرة واحدة؛ وتتوقف التوقيعات القديمة عن التحقق فورًا.