تخطّ إلى المحتوى الرئيسي

Subscriptions API

Subscriptions API هي واجهة الموافقة في Joryio. تدير، لكل جهة اتصال، حالة الموافقة أو الإلغاء في كل قناة رسائل، Email وSMS وWhatsApp وPush وViber، وعضوية قوائم الاشتراك، أي فئات أو موضوعات الموافقة، وحالة ارتداد Email وسجل التدقيق الكامل لتغييرات الموافقة.

تغطي الصفحة ثلاثة موارد:

  • موافقة جهة الاتصال: /subscriptions/contacts/... لقراءة موافقة القناة والقائمة لجهة اتصال وتغييرها.
  • قوائم الاشتراك: /lists لإنشاء القوائم وإدارتها وإجراء عمليات عضوية جماعية.
  • صفحة التفضيلات المستضافة: /subscriptions/hosted-page لتأليف صفحة مركز التفضيلات لمساحة العمل.

كل النقاط هنا نسبية إلى عنوان الأساس https://api-eu1.joryio.com. راجع نظرة عامة على API.

المصادقة

تتطلب كل الطلبات مفتاح API، وتعمل جلسة لوحة تحكم JWT أيضاً:

Authorization: Bearer jry_live_your_api_key_here
Content-Type: application/json

النطاقات لكل نقطة نهاية

نقطة النهايةالنطاق
GET /subscriptions/contacts/:userId و/lists و/history و/channels/:channel/status و/email-validcompliance:read
PUT /subscriptions/contacts/:userId/channels/:channel وPOST /clear-bounce وPOST / DELETE لعضوية قائمة جهة اتصالcompliance:write
POST /lists وPUT / DELETE للقوائم وPOST /restore وعمليات الأعضاء الجماعيةsettings:write
GET /lists وGET /lists/:listId وGET /lists/:listId/statssettings:read
GET /lists/:listId/memberscompliance:read
GET /subscriptions/hosted-page/preference-center وPOST /previewsettings:read
PUT /subscriptions/hosted-page/preference-centersettings:write

المفاهيم الأساسية

معرّف جهة الاتصال

كل مسار /subscriptions/contacts/:userId يأخذ معرّف جهة الاتصال الداخلي في Joryio، وهو id في Users API، وليس userId الخارجي الذي ترسله في الأحداث. يجب أن يكون ObjectId سداسياً من 24 حرفاً أو UUID؛ ويُرفض غير ذلك بـ 400 Bad Request.

الاشتراك وقت الإنشاء

يمكنك اشتراك جهة اتصال في قوائم في طلب إنشاء المستخدم نفسه: يقبل POST /users مصفوفة subscriptions اختيارية. تبقى نقاط هذه الصفحة الطريقة لإدارة الموافقة بعد الإنشاء: PUT /subscriptions/contacts/:userId/channels/:channel لموافقة القناة وPOST /subscriptions/contacts/:userId/lists/:listId لعضوية القائمة. لا تعيد اشتراكات الإنشاء إحياء إلغاء قائم؛ إعادة الموافقة الصريحة تتطلب POST لعضوية القائمة.

القنوات وحالاتها

القنوات الخمس هي email وsms وwhatsapp وpush وviber؛ وأي قيمة أخرى تعيد 400.

الحالةالوصف
optedInموافقة صريحة، مثل تأكيد الموافقة المزدوجة.
subscribedمشترك، موافقة مفردة أو افتراضية.
unsubscribedألغى الاشتراك.

الحالات بصيغة camelCase، أي optedIn لا opted_in. تعامل بوابات الإرسال جهة الاتصال بلا حالة مسجلة لقناة كأنها مشتركة؛ غياب السجل ليس إلغاءً.

التغييرات مدققة ومعكوسة في السجلات

تسجل كل كتابة في API في سجل تدقيق الاشتراكات لجهة الاتصال، بالمصدر وIP وuser agent وهوية مفتاح API أو المشرف، ويمكن استرجاعها من سجل الاشتراك. تُعكس الإلغاءات أيضاً إلى دفاتر منع مرتبطة بالمعرّف: إلغاء SMS أو WhatsApp يتبع رقم الهاتف، وإلغاء Email يتبع العنوان في مساحة العمل، لذلك تغطى جهات الاتصال المكررة أيضاً. راجع Suppressions API.

موافقة جهة الاتصال

الحصول على اشتراكات جهة اتصال

GET /subscriptions/contacts/:userId

يعيد حالة موافقة كل قناة وعضويات القوائم. تكون القنوات بلا حالة مسجلة غائبة ببساطة من channels. يحمل Email حقول الارتداد الإضافية: isValid وbounceType وbounceCount وlastBounceAt. يعيد lists أول 500 صف عضوية للجهة. يعيد 404 إن لم توجد جهة الاتصال في مساحة العمل.

تحديث اشتراك قناة

PUT /subscriptions/contacts/:userId/channels/:channel
الحقلالنوعمطلوبالوصف
channelstringنعميجب أن يطابق القناة في URL؛ قيمة URL هي الفائزة عند الاختلاف.
statusstringنعمoptedIn أو subscribed أو unsubscribed.
sourcestringلامصدر التغيير، مثل api أو preference_center؛ الافتراضي api.
consentTextstringلانص الموافقة المعروض عند الاشتراك، يحفظ للامتثال.
reasonstringلاسبب نصي حر يحفظ في سجل التدقيق.
{
"channel": "email",
"status": "unsubscribed",
"source": "preference_center",
"reason": "User requested via support ticket"
}

يعيد كائن channels المحدّث بالكامل.

  • تؤدي الموافقة على Email إلى مسح حالة ارتداد مؤقت فقط، ولا تحيي ارتداداً دائماً؛ استخدم مسح حالة الارتداد لذلك.
  • يُعكس إلغاء sms أوwhatsapp في دفتر المنع المرتبط بالهاتف، ويُعكس تغيير Email في الدفتر المرتبط بالعنوان لمساحة العمل.
  • تُدقق العملية مع IP وuser agent وهوية المفتاح أو المشرف.

مسح حالة الارتداد

أعد ضبط ارتداد Email وارفع منع قابلية التسليم المرتبط بالعنوان. وهي الطريقة المعتمدة لرفع ارتداد دائم؛ لا تفعلها إعادة اشتراك المستلم.

POST /subscriptions/contacts/:userId/clear-bounce

يقبل reason اختيارياً، ويعيد { "success": true }. يمسح bounceType وbounceCount وlastBounceAt ويعيد isValid إلى true، ويحذف أيضاً صفوف hard_bounce وcomplaint لعنوان Email من دفتر المنع لمساحة العمل؛ فينطبق المسح على كل جهات الاتصال المكررة ذات العنوان نفسه.

الحصول على اشتراكات القوائم

GET /subscriptions/contacts/:userId/lists

يعيد كل صفوف عضوية قوائم جهة الاتصال، المشتركة والملغاة. تكون العضوية فريدة لكل جهة اتصال + قائمة + قناة؛ يمكن للجهة أن تكون مشتركة في قائمة على email وملغية منها على sms كسجلين منفصلين.

اشتراك جهة اتصال في قائمة

POST /subscriptions/contacts/:userId/lists/:listId

الطلب idempotent؛ تؤكد إعادة الطلب الاشتراك. وهو مسار إعادة الموافقة الصريح والمدقق الوحيد الذي يمكنه إعادة اشتراك جهة ألغت القائمة، إذ لا تفعل الإضافة الجماعية ذلك.

الحقلالنوعمطلوبالوصف
channelstringنعمemail أو sms أو whatsapp أو push أو viber.
sourcestringلامثل api أو form أو import أو preference_center؛ الافتراضي api.
consentTextstringلانص الموافقة المعروض.

يعيد صف العضوية المنشأ أو المحدّث.

إلغاء جهة اتصال من قائمة

DELETE /subscriptions/contacts/:userId/lists/:listId

تمر القناة في نص الطلب لا URL:

{ "channel": "email", "source": "preference_center" }

يعيد { "success": true }. إذا لم يكن للجهة صف عضوية للقائمة والقناة، ينشئ النظام صف unsubscribed صريحاً على أي حال؛ فلا يفقد سحب الموافقة بصمت وتمنع بوابة الإرسال إرسالات القائمة لاحقاً.

الحصول على سجل الاشتراك

GET /subscriptions/contacts/:userId/history
المعاملالنوعالافتراضيالوصف
limitnumber50مدخلات الصفحة؛ القيم غير الرقمية ترجع للافتراضي.
offsetnumber0إزاحة الترقيم.

يعيد items، الأحدث أولاً، وtotal. يحتوي كل مدخل على القناة والقائمة، إن وجدت، وaction والحالة السابقة والجديدة والمصدر وIP وuser agent ونص الموافقة وmetadata ووقت الإنشاء. تكون action إحدى subscribe وunsubscribe وresubscribe وbounce وhard_bounce وsoft_bounce وcomplaint وimport وapi_update.

فحص حالة اشتراك قناة

GET /subscriptions/contacts/:userId/channels/:channel/status

يعيد { "subscribed": true } ما لم تكن جهة الاتصال unsubscribed صراحة في القناة؛ الجهة بلا حالة مسجلة تعد مشتركة. يعيد معرّف جهة اتصال غير معروف { "subscribed": false } لا 404.

فحص صلاحية Email

GET /subscriptions/contacts/:userId/email-valid

يعيد { "valid": true }. تكون valid خاطئة فقط عندما يجعل ارتداد دائم العنوان غير صالح. يعيد معرّف غير معروف { "valid": false } لا 404. يقيس هذا قابلية التسليم لا الموافقة، فتظل الجهة الملغية ذات العنوان العامل true.

قوائم الاشتراك

القوائم فئات أو موضوعات الموافقة التي يشترك بها الأشخاص، مثل النشرة وتحديثات المنتج. تعيش تعريفاتها تحت /lists، وتدار العضوية لكل جهة بنقاط الموافقة أعلاه أو بالنقاط الجماعية أدناه.

إنشاء قائمة

POST /lists
الحقلالنوعمطلوبالوصف
namestringنعماسم القائمة، حتى 255 حرفاً وفريد لكل مساحة عمل.
descriptionstringلاوصف، حتى 1000 حرف.
channelsstring[]لاالقنوات التي تنطبق عليها القائمة؛ الافتراضي ["email"].
isPublicbooleanلاتظهر في مركز التفضيلات؛ الافتراضي true.
typestringلاmarketing أو transactional؛ الافتراضي marketing.
requireDoubleOptInbooleanلاطلب موافقة مؤكدة؛ الافتراضي false.

يعيد كائن القائمة، وهو يشمل isDefault لفئة التسويق الافتراضية المنشأة تلقائياً وsenderId عند كون القائمة مجموعة اشتراك SMS أو WhatsApp لكل رقم مرتبطة بمرسل.

عرض القوائم والحصول عليها

GET /lists
GET /lists/:listId

يدعم العرض includeArchived=true لإدراج المؤرشفة ويعيد القوائم الأحدث أولاً بحد 200. يعيد الحصول على قائمة 404 إن لم توجد أو كانت مؤرشفة.

تحديث قائمة أو أرشفتها

PUT /lists/:listId
DELETE /lists/:listId
POST /lists/:listId/restore

يقبل PUT أي مجموعة فرعية من حقول الإنشاء. يؤرشف DELETE بحذف ناعم ويضبط archivedAt مع حفظ صفوف العضوية، ويعيد 204 No Content. يعيد مسار restore كائن القائمة المستعاد.

الحصول على أعضاء قائمة

GET /lists/:listId/members
المعاملالنوعالافتراضيالوصف
channelstring-فلتر اختياري لقناة.
statusstring-subscribed أو unsubscribed.
limitnumber50الصفوف في الصفحة.
offsetnumber0إزاحة الترقيم.

يعيد members وtotal، ويضم كل عضو معرّف جهة الاتصال والقائمة والقناة والحالة وتواريخ الاشتراك ومصدره وسياق المنظمة ومساحة العمل.

إحصاءات قائمة

GET /lists/:listId/stats

يعيد total وbyChannel وsubscribed وunsubscribed. يعد byChannel العضويات غير الملغاة لكل قناة.

إضافة أعضاء جماعياً

أضف حتى 10,000 جهة اتصال إلى قائمة على قناة واحدة:

POST /lists/:listId/members/bulk
الحقلالنوعمطلوبالوصف
contactIdsstring[]نعممعرّفات جهات اتصال Joryio، حتى 10,000.
channelstringنعمقناة القائمة.
sourcestringلايسجل كـ optInSource.

يعيد { "added": 2, "updated": 0, "skippedUnsubscribed": 0 }. تنشئ الإضافة الجماعية عضويات جديدة فقط؛ تترك القائمة القائمين كما هم، ولا تعيد اشتراك من ألغى صراحة. يظهر هؤلاء في skippedUnsubscribed. استخدم نقطة الاشتراك الصريحة لإعادة الموافقة. يبقى updated صفراً للتوافق الخلفي.

إزالة أعضاء جماعياً

ألغِ اشتراك حتى 10,000 جهة اتصال من قائمة على قناة واحدة:

DELETE /lists/:listId/members/bulk

يمر contactIds وchannel في النص ويعيد { "removed": 1 }. تقلب العملية صفوف العضوية إلى unsubscribed، ولا تحذفها، فيبقى أثر التدقيق وتُمنع الإرسالات المستقبلية للقائمة.

صفحة التفضيلات المستضافة

API لتأليف صفحة مركز التفضيلات المستضافة لمساحة العمل، التي يصل إليها المستلم من رابط إلغاء الاشتراك أو التفضيلات. العرض العام للصفحة يخدمه مسارات عامة بالرمز لا مفتاح API، وليس جزءاً من هذا المرجع.

الحصول على قالب مركز التفضيلات

GET /subscriptions/hosted-page/preference-center

يعيد type وmode وhtml وredirectUrl وdesignJson وupdatedAt. تكون mode إحدى:

  • default: صفحة Joryio المدمجة.
  • custom: قالب HTML/Liquid الخاص بك.
  • dnd: محرر مرئي، مع HTML المعروض نفسه.
  • redirect: سجل الإلغاء ثم أعد التوجيه إلى redirectUrl.

تحديث قالب مركز التفضيلات

PUT /subscriptions/hosted-page/preference-center
الحقلالنوعالوصف
modestringdefault أو custom أو dnd أو redirect.
htmlstringجسم HTML/Liquid للوضعين custom وdnd، حتى 100KB؛ يجب أن يتضمن موضع {{ preferences_form }}.
redirectUrlstringهدف وضع redirect، حتى 2048 حرفاً.
designJsonobjectحالة المحرر المرئي لدوران dnd؛ تُمسح في الأوضاع الأخرى.

يعيد القالب المحفوظ بشكل استجابة GET نفسه.

معاينة قالب

POST /subscriptions/hosted-page/preview

النص { "html": "..." } هو القالب للعرض ببيانات نموذجية. تعيد الاستجابة { "html": "<rendered, sanitized html>" }.

واجهات ذات صلة، ليست في الصفحة

  • نقاط المستلم: إلغاء بنقرة واحدة، POST /u/:token، وصفحات التفضيلات المستضافة هي نقاط عامة مصادق عليها برمز، لا بمفتاح API.
  • Web SDK: POST /v1/subscriptions/channel وPOST /v1/subscriptions/group تصادقان بمفتاح SDK في X-SDK-Key. راجع دليل إدارة الاشتراكات.
  • webhooks الموفرين: ارتدادات Email وكلمات SMS الواردة، /webhooks/email/... و/webhooks/sms/...، تكاملات موفرين يتحقق توقيعها.
  • المنع: دفتر عدم الإرسال لمساحة العمل له Suppressions API خاص به.

الخطوات التالية