البدء السريع
أنشئ من لوحة إدارة Web تطبيقاً خارجياً مرتبطاً بالشركة المطلوبة، ثم انسخ App ID وApp Secret. أضف Callback URL اختيارياً إذا كنت تحتاج النتيجة النهائية. ينشئ Engine سجلاً في مركز الإشعارات لكل مستخدم نشط ومؤهل في الشركة المرتبطة، ويحاول إرسال Push النظام فقط إلى الأجهزة المسجلة المؤهلة.
نقطة النهاية والمصادقة
بيئات API:
- الاختبار: https://aim-api-test.proton-system.com
- الإنتاج: https://aim-api.proton-system.com
يجب أن يتضمن كل طلب JSON بين الخوادم Authorization: Basic Base64(KEY:SECRET) باستخدام HTTP Basic Authentication، حيث يكون KEY هو App ID وSECRET هو App Secret:
Endpoint: POST /openapi/v1/notifications.
curl --request POST 'https://<your-engine-host>/openapi/v1/notifications' \
--header 'Authorization: Basic <Base64(AppID:AppSecret)>' \
--header 'Content-Type: application/json' \
--data '{"requestId":"order-20260819-001","title":"اكتمل الطلب","body":"تم إكمال طلبك.","imageUrls":["https://cdn.example.com/order/001-1.webp","https://cdn.example.com/order/001-2.webp"]}'عقد الطلب
يقبل JSON الصارم الحقول الإلزامية requestId وtitle وbody، إضافة إلى الحقل الاختياري imageUrls. يعني حذف imageUrls أو إرسال null أو [] عدم وجود صور؛ وإلا فأرسل 1-9 عناوين URL بترتيب العرض. تُزال المسافات من كل قيمة، ويجب أن تكون فريدة وعنوان HTTPS مطلقاً بلا اسم مستخدم أو كلمة مرور، وألا تتجاوز 2048 حرف Unicode. يؤدي أي عنوان غير صالح إلى رفض الطلب بالكامل. يخزن Engine العناوين فقط ولا يجلب الصور أو يفحصها أو يعمل وكيلاً لها أو يخزنها مؤقتاً. الحد الأقصى للنص الكامل هو 256 KiB؛ طول requestId هو 128 حرف Unicode، وtitle هو 100، وbody هو 1000. لكل App ID حد 10 طلبات في الدقيقة و100 في الساعة.
إعادة requestId نفسه مع title وbody وimageUrls المرتبة نفسها تعيد النتيجة المخزنة الأصلية؛ لذلك قد تصبح status بعد المعالجة SUCCESS أو PARTIAL_SUCCESS أو FAILED بدلاً من ACCEPTED. أما استخدام requestId نفسه مع محتوى أو ترتيب صور مختلف فيعيد IDEMPOTENCY_CONFLICT.
استجابة القبول
يعيد الطلب الصحيح HTTP 202:
{
"requestId": "order-20260819-001",
"notificationId": "00000000-0000-0000-0000-000000000001",
"status": "ACCEPTED"
}تعني ACCEPTED أن Engine حفظ الطلب للتوزيع فقط، ولا تؤكد أن APNs/FCM أو الجهاز عرض الإشعار.
نتائج Callback
عند إعداد Callback URL يرسل Engine النتيجة النهائية:
{
"requestId": "order-20260819-001",
"status": "PARTIAL_SUCCESS",
"recipientCount": 8,
"pushAcceptedCount": 1,
"pushFailedCount": 1
}recipientCount هو عدد مستخدمي مركز الإشعارات المستلمين، بينما يمثل pushAcceptedCount وpushFailedCount عدد دفعات Push Outbox، وليس عدد المستخدمين أو الأجهزة ولا دليلاً على ظهور إشعار النظام.
اختبار Callback
يرسل كل اختبار Callback من لوحة الإدارة حدث فحص مستقلاً:
{
"requestId": "callback-test-<unique-id>",
"status": "SUCCESS",
"recipientCount": 1,
"pushAcceptedCount": 1,
"pushFailedCount": 0,
"test": true
}عندما تكون test بالقيمة true، تحقق من البنية وأعد 2xx، لكن لا تربط حدث الفحص بطلب إشعار مرسل ولا تحدّث حالة التسليم التجارية. قيم العد ثابتة للاختبار ولا تمثل مستلمين حقيقيين أو دفعات Push Outbox فعلية.
تكون قيمة status النهائية SUCCESS أو PARTIAL_SUCCESS أو FAILED. أعد أي استجابة 2xx للتأكيد؛ وإلا يعيد Engine المحاولة بعد دقيقة و5 دقائق و30 دقيقة وساعتين و6 ساعات و24 ساعة. لا يوجد توقيع HMAC حالياً: استخدم HTTPS، وطابق requestId للنتائج غير الاختبارية، وقيّد الوصول، وعالج Callback بطريقة idempotent.
مرجع الأخطاء
| HTTP | Code | المعنى |
|---|---|---|
| 400 | INVALID_REQUEST | خطأ في Content-Type أو JSON أو الحجم أو الحقول. |
| 401 | INVALID_APP_CREDENTIALS | App ID أو App Secret غير صحيح. |
| 403 | APPLICATION_INACTIVE | التطبيق أو الشركة غير نشط. |
| 409 | IDEMPOTENCY_CONFLICT | أُعيد استخدام requestId بمحتوى مختلف. |
| 429 | RATE_LIMITED | تم تجاوز حد التطبيق. |
| 503 | NOTIFICATION_UNAVAILABLE | الخدمة غير متاحة مؤقتاً. |
الأمان ونطاق الإرسال
يقبل Mobile client حداً أقصى قدره 5 MiB لكل صورة، وتنتهي مهلة عملية تنزيل الصورة كاملة بعد 10 ثوانٍ. لا يتبع العميل عمليات إعادة التوجيه 3xx، لذا يجب أن يعيد كل URL الصورة مباشرة.
App ID وApp Secret بيانات اعتماد بين الخوادم. لا تضعها في المتصفح أو تطبيق الهاتف أو مستودع عام أو URL أو تخزين العميل. أعد تعيين App Secret عند التسرب. يحصل كل مستخدم نشط ومؤهل في الشركة المرتبطة على سجل في مركز الإشعارات ويُحتسب ضمن recipientCount. ولا تتم محاولة Push النظام إلا للأجهزة التي لديها PushInstallation نشط يسمح بفئة BUSINESS، من دون ضمان ظهور شريط النظام على كل جهاز. تُعرض imageUrls في تفاصيل الإشعار فقط ولا تدخل في حمولات Push أو Callback. يجب أن يظل title وbody كاملين ومفهومين من دون الصور. لا يؤدي فشل تنزيل الصور أو عرضها إلى تغيير حالة accepted أو Callback أو Push. ينزّل تطبيق الهاتف كل صورة مباشرة من CDN العام؛ استخدم عناوين لا تتطلب مصادقة أو ملفات Cookie، وأبقها متاحة 90 يوماً على الأقل، مع مراعاة أن CDN يستقبل IP المستخدم ووقت الطلب وUser-Agent. استخدم عناوين كائنات غير قابلة للتغيير عندما يلزم ثبات العرض التاريخي.