Webhooksسجّل webhook

Webhooks

سجّل webhook

يسجّل رابط https تستدعيه Sofia بحدث JSON موقّع، مع إعادة المحاولة حتى خمس مرات عند الفشل. يظهر السر مرة واحدة؛ 10 webhooks كحد أقصى.

POSThttps://api.sofia-post.com/api/v1/webhooks
POSThttps://api.sofia-post.com/api/v1/webhooks

سجّل webhook

يسجّل رابط https تستدعيه Sofia بحدث JSON موقّع، مع إعادة المحاولة حتى خمس مرات عند الفشل. يظهر السر مرة واحدة؛ 10 webhooks كحد أقصى.

التفويضات

Authorizationstringمطلوب

مفتاحك الشخصي أو رمز وصول OAuth، يُرسل كـ Bearer <token>.

يبقى في هذا التبويب فقط، ويُرسل إلى api.sofia-post.com فقط. احصل على مفتاح API

الجسم

يؤثر هذا الطلب على حسابك الحقيقي.

تسجيل webhook

سجّل عنوان https عامًا والأحداث المطلوبة. لا يظهر سرّ التوقيع (whsec_…) إلا في هذا الرد. يمكن للتطبيق أن يملك حتى 10 webhooks.

curl -X POST https://api.sofia-post.com/api/v1/webhooks \
  -H "Authorization: Bearer $SOFIA_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://app.example.com/hooks/sofia","events":["post.published","post.failed"]}'

الأحداث

الحدثdata
post.publishedpostId وestablishmentId وplatform وpublishedAt وpermalink
post.failedpostId وestablishmentId وplatform وerror
webhook.testwebhookId

ترسل Sofia كل حدث بـ POST بصيغة JSON { id, type, createdAt, data }، مع الترويسات Sofia-Event-Id وSofia-Event-Type وSofia-Signature. لا تُعلَن سوى المنشورات التي أنشأها تطبيقك.

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

قيمة Sofia-Signature هي t=<unix time>,v1=<hex>، حيث v1 هو HMAC-SHA256 للقيمة <t>.<raw body> بسرّك. تحقق منه على الجسم الخام، وارفض ختمًا زمنيًا قديمًا:

import { createHmac, timingSafeEqual } from 'node:crypto';

const isSignedBySofia = (header, rawBody, secret) => {
  const parts = Object.fromEntries(
    (header ?? '').split(',').map((part) => part.trim().split('=', 2)),
  );
  const timestamp = Number(parts.t);
  if (!Number.isInteger(timestamp) || typeof parts.v1 !== 'string') return false;
  if (Math.abs(Date.now() / 1000 - timestamp) > 300) return false;
  const expected = createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest();
  const received = Buffer.from(parts.v1, 'hex');
  return received.length === expected.length && timingSafeEqual(received, expected);
};

التسليم وإعادة المحاولة

  • رد 2xx يسلّم الحدث. وأي رد آخر، أو تحويل (لا يُتَّبع أبدًا)، أو 10 ثوانٍ دون رد، يطلق محاولة جديدة بعد دقيقة، ثم 5 دقائق، ثم 30 دقيقة، ثم ساعتين، حتى 5 محاولات.
  • قد يصل الحدث نفسه مرتين: أزل التكرار بحسب Sofia-Event-Id.
  • أجب بسرعة وعالج الحدث بعد ذلك.

التفويضات

  • Authorizationstringheaderمطلوب

    مفتاحك الشخصي أو رمز وصول OAuth، يُرسل كـ Bearer <token>.

الجسم

application/json
  • urlstringمطلوب

    عنوان https الذي تستدعيه Sofia. يُرفض المضيف الذي يُحلّ إلى عنوان خاص أو loopback أو link-local

  • eventsstring[]مطلوب

    الأحداث المراد استلامها

الاستجابة

الـ webhook وسرّ توقيعه، يظهر مرة واحدة فقط.

  • idstringمطلوب

    معرّف الـ webhook

  • urlstringمطلوب

    العنوان الذي تستدعيه Sofia

  • eventsstring[]مطلوب

    الأحداث المشترك فيها

  • createdAtstring<date-time>مطلوب

    وقت تسجيل الـ webhook

  • secretstringمطلوب

    مفتاح HMAC-SHA256 الذي يوقّع كل عملية تسليم (Sofia-Signature). يظهر هذه المرة فقط

هل كانت هذه الصفحة مفيدة؟