إنتقل إلى المحتوى الرئيسي

توثيق Bulk Template Message API

تتيح لكم واجهة API هذه إرسال رسائل القوالب إلى عدة مستلمين في وقت واحد عبر قناة WhatsApp.

تُعالَج الرسائل بشكل غير متزامن؛ يعيد طلب API فوراً bulkMessageId، بينما تُوضع الرسائل في قائمة الانتظار وتُعالَج في الخلفية.

POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/send.js

الميزات الرئيسية​

  • إرسال رسائل قوالب جماعية إلى 1–5,000 مستلم في طلب واحد
  • متغيرات مخصّصة لكل مستلم (HEADER وBODY وBUTTONS وCAROUSEL)
  • defaultPayload مشترك لجميع المستلمين مع دمج payload الخاص بكل مستلم (isMerge)
  • إرسال مجدول (scheduleAt)
  • تحديد المستلمين بواسطة username (رقم الهاتف) أو userId أو sessionId
  • إرسال عدة رسائل إلى المستخدم نفسه ضمن طلب جماعي واحد
  • referenceId اختياري لتتبّع السجلات مع الأنظمة الخارجية
  • إسناد المحادثات تلقائياً إلى مستخدم أو مجموعة عمل بعد الإرسال (action)
تحذير

لا تستطيع واجهة API هذه إرسال إلا القوالب المعتمدة من Meta.

يجب أن يطابق اسم القالب ورمز اللغة تماماً القالب المسجَّل في Meta Business Manager.

معاملات الطلب​

المعاملات ذات المستوى الأعلى​

المعاملالنوعمطلوبالوصف
channelUsernamestringنعمرقم قناة WhatsApp المستخدم لإرسال الرسالة (مثل "908506669933")
connectorBrandstringنعمالعلامة التجارية لموصّل القناة. القيمة المدعومة حالياً: "whatsapp"
titlestringلاعنوان الحملة. يُستخدم للعرض في لوحة التحكم. القيمة الافتراضية: "-"
scheduleAtstring (ISO 8601)لاتاريخ ووقت الإرسال المجدول (مثل "2026-06-10T10:00:00.000Z"). إذا حُذف، تُرسل الرسائل فوراً.
defaultPayloadobjectمشروط*حمولة القالب الافتراضية المطبقة على جميع المستلمين. مطلوبة إذا لم يقدّم أحد المستلمين payload خاصاً به.
recipientsarrayنعمقائمة المستلمين. الحد الأدنى 1 والحد الأقصى 5,000 مستلم.
actionobjectلاإجراء يُطبَّق على المحادثة بعد الإرسال. assign-to-user أو assign-to-workgroup.

*إذا قدّم كل مستلم payload خاصاً به، فإن defaultPayload اختياري.

بنية المستلم​

يجب تقديم واحد فقط من username أو userId أو sessionId لكل مستلم. لا يمكن استخدام عدة معرّفات معاً، وسيؤدي حذفها جميعاً إلى خطأ.

لإرسال عدة رسائل إلى المستخدم نفسه ضمن طلب جماعي واحد، أضيفوا المعرّف نفسه إلى قائمة المستلمين عدة مرات.

الحقلالنوعالوصف
usernamestringرقم هاتف المستلم (مثل "905554443322"). إذا لم يكن المستخدم موجوداً في النظام، يُنشأ تلقائياً.
userIdstringمعرّف مستخدم موجود في النظام.
sessionIdstringمعرّف جلسة محادثة موجودة في النظام.
referenceIdstringمعرّف مرجعي اختياري (بحد أقصى 256 حرفاً) للمطابقة مع سجلات الأنظمة الخارجية (CRM أو الطلبات أو التذاكر وغيرها). يجب أن يكون فريداً ضمن الطلب الجماعي إن وُجد.
payloadobjectحمولة القالب الخاصة بالمستلم (اختيارية). إذا كان isMerge: true، فتُدمج مع defaultPayload.
isMergebooleanيتجاوز سلوك الدمج لهذا المستلم (اختياري). إذا حُذف، يُستخدم defaultPayload.isMerge.

بنية الإجراء​

الحقلالنوعالوصف
action.keystring"assign-to-user" يُسند المحادثة إلى موظف محدد؛ و"assign-to-workgroup" يُسندها إلى مجموعة عمل.
action.valuestringمعرّف المستخدم أو مجموعة العمل المستهدفة.

بنية حمولة القالب​

يشترك defaultPayload وpayload الخاص بالمستلم في البنية نفسها. في رسائل القوالب يجب تحديد type: "template".

{
"type": "template",
"template": {
"templateName": "order_confirmation",
"languageCode": "tr-TR",
"variables": []
},
"isMerge": true
}
الحقلالنوعمطلوبالوصف
typestringنعمنوع الحمولة. لرسائل القوالب: "template"
template.templateNamestringنعم*اسم القالب المسجَّل في Meta. اختياري في حمولات المستلمين عند استخدام isMerge: true (يُورَّث من الافتراضي).
template.languageCodestringلارمز لغة القالب (مثل "tr" أو "en" أو "tr-TR" أو "en-US"). يجب أن يطابق تماماً اللغة المسجَّلة في Meta.
template.variablesarrayلاقائمة المتغيرات المطبقة على مكوّنات القالب. مفصَّلة أدناه.
isMergebooleanلاtrue: تُدمج حمولة المستلم دمجاً عميقاً مع defaultPayload. false أو محذوف: تحل حمولة المستلم محل defaultPayload بالكامل.
سلوك isMerge
  • إذا كان defaultPayload.isMerge: true وقدّم المستلم payload خاصاً به، يُطبَّق دمج عميق.
  • مع الدمج العميق، يكفي أن يقدّم المستلم variables فقط؛ ويُورَّث templateName وlanguageCode من الحمولة الافتراضية.
  • يتجاوز حقل isMerge الخاص بالمستلم قيمة defaultPayload.isMerge.
  • إذا لم يقدّم المستلم payload، تُستخدم defaultPayload دائماً.

بنية المتغيرات​

يقابل كل عنصر في المصفوفة variables مكوّناً من مكوّنات القالب. لا يجوز أن يظهر نوع المكوّن (type) إلا مرة واحدة في المصفوفة.

typeالوصفparameterscards
"HEADER"مكوّن رأس القالب. متغير نصي أو رابط وسائط (صورة أو فيديو أو مستند)نعم—
"BODY"متغيرات النص الأساسي للقالبنعم—
"BUTTONS"متغيرات لاحقة الرابط الديناميكية للأزرارنعم—
"CAROUSEL"مكوّنات الشرائح لقوالب العرض الدوّار—نعم

صيغ المعاملات​

يمكن تقديم الحقل parameters بثلاث صيغ مختلفة:

// Format 1: Array (index-based) — for placeholders like {{1}}, {{2}}, {{3}}
"parameters": ["value1", "value2", "value3"]

// Format 2: Object (numeric keys) — alternative representation for {{1}}, {{2}}
"parameters": { "1": "value1", "2": "value2" }

// Format 3: Object (named keys) — for placeholders like {{name}}, {{amount}}
"parameters": { "name": "John", "amount": "150 USD" }
أي صيغة أستخدم؟
  • إذا كان قالب Meta لديكم يستخدم عناصر نائبة مثل {{1}} و{{2}}، فاستخدموا صيغة المصفوفة أو صيغة الكائن بمفاتيح رقمية.
  • إذا كان قالبكم يستخدم عناصر نائبة مسمّاة مثل {{firstName}} أو {{orderTotal}}، فاستخدموا صيغة الكائن بمفاتيح مسمّاة.
  • عند استخدام المصفوفات، الترتيب مهم: العنصر الأول يقابل {{1}} والثاني {{2}} وهكذا.

مكوّن HEADER​

استخدموا المكوّن HEADER عندما يحتوي رأس القالب على وسائط (صورة أو فيديو أو مستند) أو نص ديناميكي.

// Media header (image URL)
{
"type": "HEADER",
"parameters": ["https://example.com/product-image.jpg"]
}

// Text header variable
{
"type": "HEADER",
"parameters": ["Special Campaign"]
}

مكوّن BODY​

يُستخدم للمتغيرات النصية الديناميكية داخل النص الأساسي للقالب.

// Array format — when the template uses {{1}}, {{2}}, {{3}}
{
"type": "BODY",
"parameters": ["John", "ORD-12345", "150.00 USD"]
}

// Named format — when the template uses {{name}}, {{orderAmount}}
{
"type": "BODY",
"parameters": {
"name": "John",
"orderAmount": "150.00 USD"
}
}

مكوّن BUTTONS​

يُستخدم للأزرار ذات لاحقة الرابط الديناميكية. إذا احتوى القالب على عدة أزرار روابط، فلا تُفهرَس بالتسلسل إلا الأزرار التي فيها متغيرات (تُتجاهل الأزرار التي بلا متغيرات وأزرار FLOW).

// Single URL button suffix variable
{
"type": "BUTTONS",
"parameters": ["tracking/ORD-12345"]
}

// Multiple URL button suffix variables (first URL button, second URL button)
{
"type": "BUTTONS",
"parameters": ["tracking/ORD-12345", "cancel/ORD-12345"]
}

في قوالب العرض الدوّار، تُحدَّد متغيرات المكوّنات بشكل منفصل لكل شريحة.

{
"type": "CAROUSEL",
"cards": [
{
"components": [
{
"type": "HEADER",
"parameters": ["https://example.com/card1.jpg"]
},
{
"type": "BODY",
"parameters": ["Product A", "99.00 USD"]
}
]
},
{
"components": [
{
"type": "HEADER",
"parameters": ["https://example.com/card2.jpg"]
},
{
"type": "BODY",
"parameters": ["Product B", "149.00 USD"]
}
]
}
]
}
تحذير

يجب أن يطابق طول المصفوفة cards تماماً عدد الشرائح المعرَّفة في القالب.

أمثلة​

1. قالب بسيط — بلا متغيرات ومحتوى واحد لجميع المستلمين​

هذه أبسط طريقة لإرسال قالب ثابت بلا متغيرات إلى عدة مستلمين.

{
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"title": "General Announcement",
"defaultPayload": {
"type": "template",
"template": {
"templateName": "hello_world",
"languageCode": "tr-TR"
}
},
"recipients": [{ "username": "905554443301" }, { "username": "905554443302" }, { "username": "905554443303" }]
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/send.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"title": "General Announcement",
"defaultPayload": {
"type": "template",
"template": {
"templateName": "hello_world",
"languageCode": "tr-TR"
}
},
"recipients": [
{ "username": "905554443301" },
{ "username": "905554443302" },
{ "username": "905554443303" }
]
}'
تلميح
  • يُنشأ المستلمون المحددون بواسطة username تلقائياً إذا لم يكونوا موجودين في النظام
  • يستخدم جميع المستلمين defaultPayload نفسه؛ ولا حاجة إلى بيانات خاصة بكل مستلم
  • عند عدم تحديد isMerge، يستخدم كل مستلم defaultPayload مباشرة

2. قالب بمتغيرات نص أساسي مشتركة​

يُرسل القالب نفسه إلى جميع المستلمين بقيم المتغيرات نفسها. يحتوي القالب على عناصر نائبة مثل {{1}} و{{2}}.

{
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"title": "Summer Campaign",
"defaultPayload": {
"type": "template",
"template": {
"templateName": "promo_notification",
"languageCode": "tr-TR",
"variables": [
{
"type": "BODY",
"parameters": ["30%", "July 31, 2026"]
}
]
}
},
"recipients": [{ "username": "905554443301" }, { "username": "905554443302" }]
}
تلميح
  • في هذا المثال، قد يحتوي نص القالب الأساسي على محتوى مثل: "استمتعوا بخصم {{1}} في حملتنا! العرض ساري حتى {{2}}."
  • يحل parameters[0] محل {{1}}، بينما يحل parameters[1] محل {{2}}

3. قالب مخصّص — متغيرات لكل مستلم مع isMerge​

تُستخدم قيم متغيرات مختلفة لكل مستلم. بضبط isMerge: true في defaultPayload، يكفي أن يقدّم المستلمون variables فقط؛ ويُورَّث templateName وlanguageCode من الحمولة الافتراضية.

في هذا المثال، يتضمن القالب رأس وسائط ومتغيرات نص أساسي مخصّصة.

{
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"title": "Personal Order Notification",
"defaultPayload": {
"type": "template",
"template": {
"templateName": "order_confirmation",
"languageCode": "tr-TR"
},
"isMerge": true
},
"recipients": [
{
"username": "905554443301",
"payload": {
"template": {
"variables": [
{
"type": "HEADER",
"parameters": ["https://s3.example.com/product-a.jpg"]
},
{
"type": "BODY",
"parameters": ["Ahmet", "ORD-001", "150.00 TRY"]
}
]
}
}
},
{
"username": "905554443302",
"payload": {
"template": {
"variables": [
{
"type": "HEADER",
"parameters": ["https://s3.example.com/product-b.jpg"]
},
{
"type": "BODY",
"parameters": ["Fatma", "ORD-002", "289.00 TRY"]
}
]
}
}
}
]
}
تلميح
  • بفضل isMerge: true، لا حاجة إلى تكرار templateName في حمولة كل مستلم
  • مصفوفة variables الخاصة بكل مستلم مستقلة تماماً
  • يجب أن يكون رابط وسائط الرأس متاحاً للعموم
  • إذا حُذف type في حمولة المستلم، يُورَّث defaultPayload.type

4. متغير زر رابط​

استخدموا المكوّن BUTTONS عندما يحتوي القالب على زر بلاحقة رابط ديناميكية. مثلاً رقم تتبّع يُلحَق بالرابط الأساسي https://example.com/track/.

{
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"title": "Shipment Tracking Notification",
"defaultPayload": {
"type": "template",
"template": {
"templateName": "shipment_tracking",
"languageCode": "tr-TR"
},
"isMerge": true
},
"recipients": [
{
"username": "905554443301",
"payload": {
"template": {
"variables": [
{
"type": "BODY",
"parameters": ["Ahmet", "TK-98765"]
},
{
"type": "BUTTONS",
"parameters": ["TK-98765"]
}
]
}
}
},
{
"username": "905554443302",
"payload": {
"template": {
"variables": [
{
"type": "BODY",
"parameters": ["Recep", "TK-12345"]
},
{
"type": "BUTTONS",
"parameters": ["TK-12345"]
}
]
}
}
}
]
}
تلميح
  • تُطابَق معاملات BUTTONS بحسب ترتيب الأزرار التي تحتوي على متغيرات
  • تُتجاهل أزرار FLOW والأزرار التي بلا متغيرات؛ ولا تنطبق الفهرسة إلا على أزرار الروابط الديناميكية
  • إذا كان رابط زر القالب https://example.com/track/{{1}}، فإن parameters[0] يحل محل {{1}}

5. إرسال مجدول​

جدولوا إرسال رسالة في تاريخ ووقت مستقبليين. يجب تقديم scheduleAt بصيغة طابع زمني UTC وفق ISO 8601.

{
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"title": "Morning Campaign Message",
"scheduleAt": "2026-06-10T07:00:00.000Z",
"defaultPayload": {
"type": "template",
"template": {
"templateName": "morning_campaign",
"languageCode": "en-US"
},
"isMerge": true
},
"action": {
"key": "assign-to-workgroup",
"value": "WORKGROUP_ID"
},
"recipients": [
{
"username": "905554443301",
"payload": {
"template": {
"variables": [
{
"type": "BODY",
"parameters": { "name": "Ahmet", "discountRate": "25" }
}
]
}
}
},
{
"username": "905554443302",
"payload": {
"template": {
"variables": [
{
"type": "BODY",
"parameters": { "name": "Zeynep", "discountRate": "40" }
}
]
}
}
}
]
}
تلميح
  • يجب تقديم scheduleAt بالمنطقة الزمنية UTC (مثلاً للساعة 10:00 صباحاً بتوقيت تركيا، استخدموا 07:00:00.000Z)
  • يستخدم هذا المثال صيغة المعاملات المسمّاة؛ ويجب أن يحتوي القالب على عناصر نائبة مثل {{name}} و{{discountRate}}
  • مع action، تُسند المحادثات التي أنشأها إرسال الرسائل تلقائياً إلى مجموعة العمل المحددة

الاستجابة​

يعيد الطلب الناجح bulkMessageId يمكن استخدامه لتتبّع عملية الإرسال:

{
"bulkMessageId": "abc123xyz789"
}

استجابات الأخطاء​

الحالةالوصف
Channel not foundلم يُعثر على قناة موثَّقة تطابق channelUsername وconnectorBrand
Channel is not verifiedالقناة المطابقة موجودة لكنها لم تُوثَّق بعد
invalidRequestقُدّمت عدة معرّفات لمستلم، أو حمولة مطلوبة مفقودة
channelNotFoundلم يُعثر على قناة نشطة تطابق channelId المقدَّم
schema-errorفشل حقل في جسم الطلب في التحقق من المخطط (حقل مطلوب مفقود، أو نوع غير صحيح، أو قيمة غير مدعومة)

يمكن استخدام bulkMessageId المُعاد مع نقاط النهاية أدناه للاستعلام عن إحصاءات الإرسال وإيقافه.


Stats — إحصاءات الإرسال​

يجلب الحالة الراهنة لإرسال رسالة جماعية. يعيد أعداد السجلات المعلّقة والناجحة والفاشلة والملغاة.

POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/stats.js

معاملات الطلب​

المعاملالنوعمطلوبالوصف
bulkMessageIdstringنعممعرّف الرسالة الجماعية المراد تتبّعها (يُعاد من createBulkPerRecipient)
{
"bulkMessageId": "abc123xyz789"
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/stats.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"bulkMessageId": "abc123xyz789"
}'

الاستجابة​

{
"bulkMessage": {
"_id": "abc123xyz789",
"slug": "my-workspace",
"title": "Campaign Title",
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"connectorSlug": "whatsapp-cloud",
"payload": {
"recipientCount": 100,
"defaultPayloadType": "template",
"jobId": "job_abc123"
},
"schedule": {
"date": "2026-06-10T07:00:00.000Z",
"type": "later"
},
"createdAt": "2026-06-08T10:00:00.000Z",
"updatedAt": "2026-06-08T10:30:00.000Z"
},
"stats": {
"pending": 45,
"success": 42,
"failed": 3,
"cancelled": 10,
"total": 100
}
}

حقول Stats​

الحقلالنوعالوصف
stats.pendingnumberعدد السجلات التي لا تزال تنتظر في القائمة
stats.successnumberعدد السجلات التي عُولجت بنجاح للإرسال
stats.failednumberعدد السجلات التي واجهت خطأ في الإرسال
stats.cancellednumberعدد السجلات الملغاة
stats.totalnumberإجمالي عدد السجلات (pending + success + failed + cancelled)
ملاحظة

يشير stats.success إلى أن النظام سلّم الرسالة بنجاح. وهو لا يضمن أن Meta سلّمت الرسالة إلى المستلم. أما تحديثات الحالة اللاحقة الصادرة عن Meta (مثل delivered أو read أو failed) فلا تؤثر في هذا العداد ولا تنعكس هنا.

Stats مقابل Message Stats
  • نقطة النهاية stats: تعرض حالة مهمة الإرسال (pending وsuccess وfailed وcancelled)
  • نقطة النهاية message-stats: تعرض حالة الرسالة الفعلية (pending وsending وsent وdelivered وread وerror وغيرها)
  • قد تنجح المهمة بينما لا تكون الرسالة قد سُلّمت أو قُرئت بعد

المعرّف المرجعي​

referenceId حقل اختياري يمكنكم استخدامه لمطابقة سجلات الإرسال بمعرّف من نظامكم الخاص لأغراض التتبّع (مثل رقم الطلب أو معرّف التذكرة).

إذا قُدّم، يجب أن يكون فريداً ضمن الطلب الجماعي (بحد أقصى 256 حرفاً).

مهم
  • استخدامه غير مطلوب
  • لا يمكن تكراره ضمن الرسالة الجماعية نفسها
  • يمكن إعادة استخدامه عبر رسائل جماعية مختلفة

Message Stats — حالة رسائل WhatsApp​

يجلب إحصاءات حالة الرسائل لرسالة جماعية. وعلى عكس نقطة النهاية stats، تعرض هذه النقطة message.status الفعلي لكل سجل بدلاً من حالة المهمة.

حالات الرسائل الممكنة: pending وsending وsent وdelivered وread وdeleted وwarning وerror وunknown وnot-sended

POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/message-stats.js

معاملات الطلب​

المعاملالنوعمطلوبالوصف
bulkMessageIdstringنعممعرّف الرسالة الجماعية المراد الاستعلام عنها
{
"bulkMessageId": "abc123xyz789"
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/message-stats.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"bulkMessageId": "abc123xyz789"
}'

الاستجابة​

{
"bulkMessage": {
"_id": "abc123xyz789",
"slug": "my-workspace",
"type": "perRecipient",
"title": "Campaign Title"
},
"messageStats": {
"pending": 5,
"sending": 2,
"sent": 10,
"delivered": 45,
"read": 30,
"deleted": 2,
"warning": 1,
"error": 3,
"unknown": 0,
"not-sended": 2,
"no-message": 10,
"total": 120
}
}

حقول Message Stats​

الحقلالنوعالوصف
pendingnumberرسائل لم تُرسل بعد
sendingnumberرسائل قيد الإرسال حالياً
sentnumberرسائل سُلّمت إلى WhatsApp ولم تصل بعد
deliverednumberرسائل وصلت إلى هاتف المستلم
readnumberرسائل قرأها المستلم
deletednumberرسائل محذوفة
warningnumberرسائل بها تحذيرات
errornumberرسائل بها أخطاء
unknownnumberرسائل بحالة غير معروفة
not-sendednumberرسائل تعذّر إرسالها
no-messagenumberسجلات بلا رسالة بعد (لا تزال في القائمة)
totalnumberإجمالي عدد السجلات
نصائح الاستخدام
  • يشير ارتفاع عدد no-message إلى أن الإرسال لا يزال جارياً
  • يبيّن عدد delivered نجاح وصول الرسائل
  • يمكن استخدام عدد read لقياس تفاعل الحملة
  • يمكنكم استعلام نقطة النهاية هذه دورياً للتتبّع الفوري

بنية Options — التقسيم إلى صفحات والتصفية والفرز​

يوفّر المعامل options المستخدم في نقطتي النهاية list وlist-with-messages بنية قياسية للتقسيم إلى صفحات والتصفية والفرز.

حقول Options​

الحقلالنوعمطلوبالوصف
paginationobjectلاإعدادات التقسيم إلى صفحات
filteringobjectلامعايير التصفية
sortingobjectلاإعدادات الفرز (مثل {"createdAt": -1})

بنية التقسيم إلى صفحات​

الحقلالنوعالافتراضيالوصف
currentPagenumber1رقم الصفحة المراد جلبها
pageItemsnumber50عدد السجلات في الصفحة (الحد الأقصى: 50)

بنية التصفية​

تتم التصفية بصيغة استعلام MongoDB. يمكنكم التصفية بحسب حقول السجل. وفي نقطة النهاية list-with-messages يمكنكم أيضاً التصفية بحسب حقول الرسالة (مثل message.status).

// Filter by record status
{
"options": {
"filtering": {
"status": "success"
}
}
}

// Filter by referenceId
{
"options": {
"filtering": {
"referenceId": "ORDER-12345"
}
}
}

// Filter by message status (only list-with-messages)
{
"options": {
"filtering": {
"message.status": "delivered"
}
}
}

// Filter by multiple statuses using $in (MongoDB operator)
{
"options": {
"filtering": {
"message.status": {
"$in": ["delivered", "read"]
}
}
}
}

// Exclude specific statuses using $nin (MongoDB operator)
{
"options": {
"filtering": {
"message.status": {
"$nin": ["error", "not-sended"]
}
}
}
}

بنية الفرز​

يتم الفرز بصيغة فرز MongoDB. تعني 1 تصاعدياً و-1 تنازلياً.

// Sort by creation date descending (newest first)
{
"options": {
"sorting": {
"createdAt": -1
}
}
}

// Sort by multiple fields
{
"options": {
"sorting": {
"status": 1,
"createdAt": -1
}
}
}

مثال على الاستخدام المركّب​

{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 2,
"pageItems": 50
},
"filtering": {
"message.status": "delivered"
},
"sorting": {
"createdAt": -1
}
}
}

يفرز هذا المثال الرسائل المُسلَّمة من الأحدث إلى الأقدم.

نصائح عملية
  • ادمجوا filtering مع pagination للاستعلامات المستهدفة
  • تتضمن الاستجابة options.pagination.totalCount وoptions.pagination.totalPages للتنقّل
  • لا يعمل مرشِّح message.status إلا في نقطة النهاية list-with-messages

Records — تفاصيل السجلات وعرضها​

يعرض جميع سجلات الإرسال لرسالة جماعية. يمثل كل سجل رسالة واحدة أُرسلت إلى مستلم.

List — قائمة السجلات​

POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message-records/list.js

معاملات الطلب​

المعاملالنوعمطلوبالوصف
bulkMessageIdstringنعممعرّف الرسالة الجماعية المراد عرضها
optionsobjectلاخيارات التقسيم إلى صفحات والتصفية والفرز. راجعوا بنية Options للتفاصيل.

الطلب — الاستخدام الأساسي​

{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
}
}
}

الطلب — التصفية بحسب حالة محددة​

{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"status": "success"
}
}
}

يعرض سجلات الإرسال الناجحة فقط (record.status = "success").

الاستجابة​

{
"bulkMessageRecords": [
{
"_id": "record_1",
"bulkMessageId": "abc123xyz789",
"slug": "my-workspace",
"userId": "user_123",
"sessionId": "session_456",
"messageId": "msg_789",
"referenceId": "ORDER-12345",
"status": "success",
"createdAt": "2026-06-10T10:00:00.000Z"
}
],
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50,
"totalCount": 150,
"totalPages": 3
},
"sorting": {},
"filtering": {}
}
}

List With Messages — قائمة مع تفاصيل الرسائل​

له ميزات نقطة النهاية list نفسها (التقسيم إلى صفحات والتصفية والفرز). والفرق الوحيد: إذا كان للسجل messageId، يُعاد أيضاً كائن message المرتبط به. وهذا يتيح لكم رؤية حالة الرسالة (delivered أو read أو error وغيرها) وحمولتها في استعلام واحد.

POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message-records/list-with-messages.js

الطلب — الاستخدام الأساسي​

{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
}
}
}

الطلب — التصفية بحسب حالة الرسالة​

{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"message.status": "delivered"
}
}
}

يجلب هذا المثال الرسائل ذات الحالة "delivered" فقط.

الطلب — عرض الرسائل الفاشلة​

{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"message.status": "error"
}
}
}

يُستخدم لمراجعة الرسائل التي واجهت أخطاء في الإرسال.

الاستجابة​

{
"bulkMessageRecords": [
{
"_id": "record_1",
"bulkMessageId": "abc123xyz789",
"userId": "user_123",
"messageId": "msg_789",
"referenceId": "ORDER-12345",
"status": "success",
"message": {
"_id": "msg_789",
"status": "delivered",
"payload": {
"type": "template",
"template": {
"templateName": "order_notification"
}
},
"createdAt": "2026-06-10T10:01:00.000Z",
"deliveredAt": "2026-06-10T10:01:05.000Z"
}
}
],
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50,
"totalCount": 150,
"totalPages": 3
},
"sorting": {},
"filtering": {}
}
}

حقول السجل​

الحقلالنوعالوصف
_idstringمعرّف السجل
bulkMessageIdstringمعرّف الرسالة الجماعية التي ينتمي إليها هذا السجل
userIdstringمعرّف مستخدم المستلم
sessionIdstringمعرّف جلسة المحادثة
messageIdstringمعرّف الرسالة المُرسَلة (null إذا لم تُرسل بعد)
referenceIdstringالمعرّف المرجعي الاختياري (إن قُدّم)
statusstringحالة السجل: pending أو success أو failed أو cancelled
messageobjectتفاصيل الرسالة (في list-with-messages فقط)

مقارنة List وList-With-Messages​

الميزةlistlist-with-messages
التقسيم إلى صفحاتنعمنعم
التصفيةنعم (حقول السجل فقط)نعم (حقول السجل والرسالة)
كائن الرسالةلانعم (إذا وُجد messageId)
الأداءسريعمتوسط (ينفّذ JOIN)
مرشِّح message.statusغير متاحمتاح
سيناريوهات الاستخدام
  • list: عرض كل السجلات بسرعة، والتصفية بحسب referenceId، والتحقق من حالات السجلات
  • list-with-messages: الاطلاع على حالات رسائل WhatsApp (delivered وread)، وفحص حمولات الرسائل
  • أمثلة على التصفية:
    • {"status": "failed"} — سجلات الإرسال الفاشلة
    • {"referenceId": "ORDER-123"} — معرّف مرجعي محدد
    • {"message.status": "delivered"} — الرسائل المُسلَّمة (list-with-messages فقط)
    • {"message.status": "read"} — الرسائل المقروءة (list-with-messages فقط)
    • {"message.status": "error"} — الرسائل التي بها أخطاء (list-with-messages فقط)
    • {"message.status": {"$in": ["delivered", "read"]}} — الرسائل المُسلَّمة أو المقروءة (list-with-messages فقط)
    • {"message.status": {"$nin": ["error", "not-sended"]}} — الرسائل باستثناء الأخطاء وغير المُرسَلة (list-with-messages فقط)
    • {"status": {"$in": ["success", "pending"]}} — السجلات الناجحة أو المعلّقة
ملاحظات الأداء والاستخدام
  • نقطة النهاية list أسرع؛ فضّلوها لفحوص الحالة العامة
  • استخدموا list-with-messages عندما تحتاجون إلى تفاصيل الرسائل
  • الحد الأقصى للسجلات في الصفحة (pageItems) هو 50؛ وتكون القيمة الافتراضية 50 إذا لم تُحدَّد
  • لا يعمل مرشِّح message.status إلا في list-with-messages
  • السجلات ذات messageId الفارغ سيكون كائن message فيها فارغاً

Stop — إلغاء الإرسال​

يوقف إرسال رسالة جماعية جارٍ. تُلغى المهمة الموجودة في القائمة، وتُنقل جميع السجلات pending إلى الحالة cancelled. أما السجلات التي عُولجت بالفعل بحالة success أو failed فلا تتأثر.

POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/stop.js
تحذير

لا يمكن التراجع عن هذا الإجراء. ولا يمكن استئناف إرسال تم إيقافه.

معاملات الطلب​

المعاملالنوعمطلوبالوصف
bulkMessageIdstringنعممعرّف الرسالة الجماعية المراد إيقافها
{
"bulkMessageId": "abc123xyz789"
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/stop.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"bulkMessageId": "abc123xyz789"
}'

الاستجابة​

عند نجاح الطلب يكون جسم الاستجابة فارغاً. وتشير حالة HTTP 200 إلى أن العملية اكتملت بنجاح.

{}
تلميح
  • لا يمكن إيقاف إلا الرسائل الجماعية التي أُنشئت عبر واجهة API هذه
  • بعد إيقاف الإرسال، يمكنكم استخدام نقطة النهاية stats للتحقق من عدد السجلات الملغاة
  • إذا تعذّر العثور على الرسالة الجماعية، تعيد API الخطأ: bulkMessageNotFound