توثيق Bulk Template Message API — v2
تتيح لكم واجهة API هذه إرسال رسائل القوالب إلى عدة مستلمين في وقت واحد عبر قناة WhatsApp.
تُعالَج الرسائل بشكل غير متزامن؛ يعيد طلب API فوراً bulkOperationId، بينما تُوضع الرسائل في قائمة الانتظار وتُعالَج في الخلفية.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/send.js
كل نقطة نهاية في هذا المستند هي دالة مخصّصة (custom function). يحمل جسم استجابة HTTP حقول الدالة نفسها (_id وtitle وpathString…)، أما الاستجابة الفعلية لنقطة النهاية فتوجد تحت result. تعرض أمثلة الاستجابات في هذا المستند محتوى result:
{
"_id": "function_id",
"title": "Show",
"pathString": "/bulk-message-api-app/api/v2/bulk-operation/show.js",
"result": {
"bulkOperation": { "_id": "abc123xyz789", "status": "running" }
}
}
الانتقال من v1
يعمل v2 جنباً إلى جنب مع v1، لذا يمكنكم الانتقال وفق جدولكم الزمني. سيتم إيقاف نقاط نهاية v1 (/api/bulk-message/… و/api/bulk-message-records/…)؛ ويجب أن تستخدم عمليات التكامل الجديدة v2.
- انقلوا مسارات نقاط النهاية إلى v2: يصبح
…/api/bulk-message/…هو…/api/v2/bulk-operation/…، ويصبح…/api/bulk-message-records/…هو…/api/v2/bulk-operation-items/…. لا يتغيّر جسم طلبsend؛ إذ يقبل الطلب الواحد الآن ما يصل إلى 100,000 مستلم بدلاً من 5,000. - أرسلوا
bulkOperationIdبدلاً منbulkMessageIdفي الطلبات. - استبدلوا
stats.jsبـshow.js. - اقرأوا الاستجابات بأسماء الحقول الجديدة الواردة في الجدول أدناه.
لا تعرف نقاط نهاية v2 إلا العمليات الجماعية التي أُنشئت باستخدام send في v2. ولتتبّع رسالة جماعية أُنشئت باستخدام v1 قبل انتقالكم، واصلوا استخدام نقاط نهاية v1 لها.
نقاط النهاية
| v1 | v2 | ما الذي يتغيّر في الاستجابة |
|---|---|---|
bulk-message/send.js | v2/bulk-operation/send.js | يصبح { bulkMessageId } هو { bulkOperationId } |
bulk-message/stats.js | v2/bulk-operation/show.js | يصبح { bulkMessage, stats } هو { bulkOperation } |
bulk-message/message-stats.js | v2/bulk-operation/message-stats.js | توجد العدّادات في الجذر بدلاً من messageStats |
bulk-message/stop.js | v2/bulk-operation/stop.js | لا شيء |
bulk-message-records/list.js | v2/bulk-operation-items/list.js | يصبح bulkMessageRecords هو bulkOperationItems |
bulk-message-records/list-with-messages.js | v2/bulk-operation-items/list-with-messages.js | مثل list، ويحمل كل عنصر أيضاً session |
أسماء الحقول
| v1 | v2 |
|---|---|
stats.success | bulkOperation.progress.succeeded |
stats.pending وstats.failed وstats.cancelled وstats.total | bulkOperation.progress.pending و.failed و.cancelled و.total |
| — | bulkOperation.progress.unknown وbulkOperation.status وbulkOperation.result.outcome |
bulkMessage (رسالة جماعية) | bulkOperation (عملية جماعية) |
bulkMessageRecord (سجل) | bulkOperationItem (عنصر) |
bulkMessageId في الطلبات وفي استجابة send وفي السجلات | bulkOperationId |
username / userId / sessionId في السجل كما أُرسلت | payload.username / payload.userId / payload.sessionId |
referenceId في السجل | payload.referenceId |
payload في السجل (حمولة القالب الخاصة بالمستلم) | payload.payload |
userId وsessionId وmessageId في السجل بعد الإرسال | result.userId وresult.sessionId وresult.messageId |
حالة السجل success | succeeded |
errorMessage في السجلات الفاشلة | error.message، إلى جانب error.code وerror.retryable |
| — | position (موضع المستلم في recipients) |
المرشِّح {"status": "success"} | {"status": "succeeded"} |
المرشِّح {"referenceId": "…"} | {"payload.referenceId": "…"} |
أخطاء schema-error وinvalidRequest في send | zod-schema-error، مع مسار الحقل غير الصالح في الرسالة |
الميزات الرئيسية
- إرسال رسائل قوالب جماعية إلى 1–100,000 مستلم في طلب واحد
- متغيرات مخصّصة لكل مستلم (HEADER وBODY وBUTTONS وCAROUSEL)
defaultPayloadمشترك لجميع المستلمين مع دمجpayloadالخاص بكل مستلم (isMerge)- إرسال مجدول (
scheduleAt) - تحديد المستلمين بواسطة
username(رقم الهاتف) أوuserIdأوsessionId - إرسال عدة رسائل إلى المستخدم نفسه ضمن طلب جماعي واحد
referenceIdاختياري لتتبّع السجلات مع الأنظمة الخارجية- إسناد المحادثات تلقائياً إلى مستخدم أو مجموعة عمل بعد الإرسال (
action)
لا تستطيع واجهة API هذه إرسال إلا القوالب المعتمدة من Meta.
يجب أن يطابق اسم القالب ورمز اللغة تماماً القالب المسجَّل في Meta Business Manager.
معاملات الطلب
المعاملات ذات المستوى الأعلى
| المعامل | النوع | مطلوب | الوصف |
|---|---|---|---|
channelUsername | string | نعم | رقم قناة WhatsApp المستخدم لإرسال الرسالة (مثل "908506669933") |
connectorBrand | string | نعم | العلامة التجارية لموصّل القناة. القيمة المدعومة حالياً: "whatsapp" |
title | string | لا | عنوان الحملة. يُستخدم للعرض في لوحة التحكم. القيمة الافتراضية: "-" |
scheduleAt | string (ISO 8601) | لا | تاريخ ووقت الإرسال المجدول (مثل "2026-06-10T10:00:00.000Z"). إذا حُذف، تُرسل الرسائل فوراً. |
defaultPayload | object | مشروط* | حمولة القالب الافتراضية المطبقة على جميع المستلمين. مطلوبة إذا لم يقدّم أحد المستلمين payload خاصاً به. |
recipients | array | نعم | قائمة المستلمين. الحد الأدنى 1 والحد الأقصى 100,000 مستلم. |
action | object | لا | إجراء يُطبَّق على المحادثة بعد الإرسال. assign-to-user أو assign-to-workgroup. |
*إذا قدّم كل مستلم payload خاصاً به، فإن defaultPayload اختياري.
بنية المستلم
يجب تقديم واحد فقط من username أو userId أو sessionId لكل مستلم. لا يمكن استخدام عدة معرّفات معاً، وسيؤدي حذفها جميعاً إلى خطأ.
لإرسال عدة رسائل إلى المستخدم نفسه ضمن طلب جماعي واحد، أضيفوا المعرّف نفسه إلى قائمة المستلمين عدة مرات.
| الحقل | النوع | الوصف |
|---|---|---|
username | string | رقم هاتف المستلم (مثل "905554443322"). إذا لم يكن المستخدم موجوداً في النظام، يُنشأ تلقائياً. |
userId | string | معرّف مستخدم موجود في النظام. |
sessionId | string | معرّف جلسة محادثة موجودة في النظام. |
referenceId | string | معرّف مرجعي اختياري (بحد أقصى 256 حرفاً) للمطابقة مع سجلات الأنظمة الخارجية (CRM أو الطلبات أو التذاكر وغيرها). يجب أن يكون فريداً ضمن الطلب الجماعي إن وُجد. |
payload | object | حمولة القالب الخاصة بالمستلم (اختيارية). إذا كان isMerge: true، فتُدمج مع defaultPayload. |
isMerge | boolean | يتجاوز سلوك الدمج لهذا المستلم (اختياري). إذا حُذف، يُستخدم defaultPayload.isMerge. |
بنية الإجراء
| الحقل | النوع | الوصف |
|---|---|---|
action.key | string | "assign-to-user" يُسند المحادثة إلى موظف محدد؛ و"assign-to-workgroup" يُسندها إلى مجموعة عمل. |
action.value | string | معرّف المستخدم أو مجموعة العمل المستهدفة. |
بنية حمولة القالب
يشترك defaultPayload وpayload الخاص بالمستلم في البنية نفسها. في رسائل القوالب يجب تحديد type: "template".
{
"type": "template",
"template": {
"templateName": "order_confirmation",
"languageCode": "tr-TR",
"variables": []
},
"isMerge": true
}
| الحقل | النوع | مطلوب | الوصف |
|---|---|---|---|
type | string | نعم | نوع الحمولة. لرسائل القوالب: "template" |
template.templateName | string | نعم* | اسم القالب المسجَّل في Meta. اختياري في حمولات المستلمين عند استخدام isMerge: true (يُورَّث من الافتراضي). |
template.languageCode | string | لا | رمز لغة القالب (مثل "tr" أو "en" أو "tr-TR" أو "en-US"). يجب أن يطابق تماماً اللغة المسجَّلة في Meta. |
template.variables | array | لا | قائمة المتغيرات المطبقة على مكوّنات القالب. مفصَّلة أدناه. |
isMerge | boolean | لا | true: تُدمج حمولة المستلم دمجاً عميقاً مع defaultPayload. false أو محذوف: تحل حمولة المستلم محل defaultPayload بالكامل. |
- إذا كان
defaultPayload.isMerge: trueوقدّم المستلمpayloadخاصاً به، يُطبَّق دمج عميق. - مع الدمج العميق، يكفي أن يقدّم المستلم
variablesفقط؛ ويُورَّثtemplateNameوlanguageCodeمن الحمولة الافتراضية. - يتجاوز حقل
isMergeالخاص بالمستلم قيمةdefaultPayload.isMerge. - إذا لم يقدّم المستلم
payload، تُستخدمdefaultPayloadدائماً.
بنية المتغيرات
يقابل كل عنصر في المصفوفة variables مكوّناً من مكوّنات القالب. لا يجوز أن يظهر نوع المكوّن (type) إلا مرة واحدة في المصفوفة.
| type | الوصف | parameters | cards |
|---|---|---|---|
"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"]
}
مكوّن CAROUSEL
في قوالب العرض الدوّار، تُحدَّد متغيرات المكوّنات بشكل منفصل لكل شريحة.
{
"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/v2/bulk-operation/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، تُسند المحادثات التي أنشأها إرسال الرسائل تلقائياً إلى مجموعة العمل المحددة
الاستجابة
يعيد الطلب الناجح bulkOperationId يمكن استخدامه لتتبّع عملية الإرسال:
{
"bulkOperationId": "abc123xyz789"
}
استجابات الأخطاء
| الحالة | الوصف |
|---|---|
recipients field is required | لم يُرسَل الحقل recipients |
Channel not found | لم يُعثر على قناة موثَّقة تطابق channelUsername وconnectorBrand |
Channel is not verified | القناة المطابقة موجودة لكنها لم تُوثَّق بعد |
zod-schema-error | فشل حقل في جسم الطلب في التحقق من المخطط (حقل مطلوب مفقود، أو نوع غير صحيح، أو قيمة غير مدعومة، أو أكثر من معرّف واحد لمستلم، أو payload مفقودة). تذكر الرسالة اسم الحقل، مثل recipients.0.referenceId: referenceId must be unique |
يمكن استخدام bulkOperationId المُعاد مع نقاط النهاية أدناه للاستعلام عن إحصاءات الإرسال وإيقافه.
Show — حالة العملية الجماعية وإحصاءاتها
يجلب العملية الجماعية مع حالتها الراهنة وعدّادات الإرسال الخاصة بعناصرها، تحت المفتاح bulkOperation.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/show.js
معاملات الطلب
| المعامل | النوع | مطلوب | الوصف |
|---|---|---|---|
bulkOperationId | string | نعم | معرّف العملية الجماعية المراد تتبّعها (يُعاد من send) |
{
"bulkOperationId": "abc123xyz789"
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/show.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"bulkOperationId": "abc123xyz789"
}'
الاستجابة
{
"bulkOperation": {
"_id": "abc123xyz789",
"type": "send-bulk-message",
"slug": "my-workspace",
"userId": "agent_user_id",
"payload": {
"title": "Campaign Title",
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"connectorSlug": "om2WabVegaCloud",
"defaultLanguageCode": "tr-TR",
"sentUser": { "firstname": "John", "lastname": "Doe" },
"defaultPayload": {
"type": "template",
"template": { "templateName": "order_confirmation", "languageCode": "tr-TR" },
"isMerge": true
},
"source": { "type": "recipients", "bulkOperationInputGroupId": "group_id" }
},
"status": "running",
"result": { "outcome": "unknown", "hasErrors": false },
"progress": {
"total": 100,
"pending": 45,
"succeeded": 42,
"failed": 3,
"cancelled": 10,
"unknown": 0
},
"scheduleAt": "2026-06-10T07:00:00.000Z",
"createdAt": "2026-06-08T10:00:00.000Z",
"updatedAt": "2026-06-10T07:00:30.000Z",
"startedAt": "2026-06-10T07:00:05.000Z"
}
}
حقول Show
توجد الحقول تحت bulkOperation.
| الحقل | النوع | الوصف |
|---|---|---|
status | string | حالة العملية الجماعية: preparing أو scheduled أو pending أو running أو stopping أو stopped أو completed أو failed |
progress.total | number | إجمالي عدد العناصر |
progress.pending | number | العناصر التي لا تزال تنتظر في القائمة |
progress.succeeded | number | العناصر التي عُولجت بنجاح للإرسال |
progress.failed | number | العناصر التي واجهت خطأ في الإرسال |
progress.cancelled | number | العناصر التي أُلغيت بواسطة stop |
progress.unknown | number | العناصر التي تعذّر تحديد نتيجتها |
result.outcome | string | النتيجة النهائية بعد انتهاء العملية الجماعية: success أو partial أو all-failed أو cancelled أو unknown |
result.hasErrors | boolean | true إذا فشل عنصر واحد على الأقل |
scheduleAt | string | وقت الإرسال المجدول (للعمليات الجماعية المجدولة فقط) |
startedAt وcompletedAt | string | وقت بدء الإرسال وانتهائه |
يشير progress.succeeded إلى أن النظام سلّم الرسالة بنجاح. وهو لا يضمن أن Meta سلّمت الرسالة إلى المستلم. أما تحديثات الحالة اللاحقة الصادرة عن Meta (مثل delivered أو read أو failed) فلا تؤثر في هذا العداد ولا تنعكس هنا.
- نقطة النهاية show: تعرض حالة إرسال العناصر (
pendingوsucceededوfailedوcancelledوunknown) - نقطة النهاية message-stats: تعرض حالة الرسالة الفعلية (
pendingوsendingوsentوdeliveredوreadوerrorوغيرها) - قد يكون العنصر
succeededبينما لا تكون الرسالة قد سُلّمت أو قُرئت بعد
المعرّف المرجعي
referenceId حقل اختياري يمكنكم استخدامه لمطابقة عناصر الإرسال بمعرّف من نظامكم الخاص لأغراض التتبّع (مثل رقم الطلب أو معرّف التذكرة). ويُعاد في كل عنصر بوصفه payload.referenceId.
إذا قُدّم، يجب أن يكون فريداً ضمن الطلب الجماعي (بحد أقصى 256 حرفاً).
- استخدامه غير مطلوب
- لا يمكن تكراره ضمن العملية الجماعية نفسها
- يمكن إعادة استخدامه عبر عمليات جماعية مختلفة
Message Stats — حالة رسائل WhatsApp
يجلب إحصاءات حالة الرسائل لعملية جماعية. وعلى عكس نقطة النهاية show، تعرض هذه النقطة 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/v2/bulk-operation/message-stats.js
معاملات الطلب
| المعامل | النوع | مطلوب | الوصف |
|---|---|---|---|
bulkOperationId | string | نعم | معرّف العملية الجماعية المراد الاستعلام عنها |
{
"bulkOperationId": "abc123xyz789"
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/message-stats.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"bulkOperationId": "abc123xyz789"
}'
الاستجابة
{
"pending": 5,
"sending": 2,
"sent": 10,
"delivered": 45,
"read": 30,
"deleted": 2,
"warning": 1,
"error": 3,
"unknown": 0,
"not-sended": 2,
"no-message": 20,
"total": 120
}
حقول Message Stats
| الحقل | النوع | الوصف |
|---|---|---|
pending | number | رسائل لم تُرسل بعد |
sending | number | رسائل قيد الإرسال حالياً |
sent | number | رسائل سُلّمت إلى WhatsApp ولم تصل بعد |
delivered | number | رسائل وصلت إلى هاتف المستلم |
read | number | رسائل قرأها المستلم |
deleted | number | رسائل محذوفة |
warning | number | رسائل بها تحذيرات |
error | number | رسائل بها أخطاء |
unknown | number | رسائل بحالة غير معروفة |
not-sended | number | رسائل تعذّر إرسالها |
no-message | number | عناصر بلا رسالة (لا تزال في القائمة، أو فشلت، أو أُلغيت) |
total | number | إجمالي عدد العناصر |
- يشير ارتفاع عدد
no-messageأثناء كون العملية الجماعية في حالةrunningإلى أن الإرسال لا يزال جارياً - يبيّن عدد
deliveredنجاح وصول الرسائل - يمكن استخدام عدد
readلقياس تفاعل الحملة - يمكنكم استعلام نقطة النهاية هذه دورياً للتتبّع الفوري
بنية Options — التقسيم إلى صفحات والتصفية والفرز
يوفّر المعامل options المستخدم في نقطتي النهاية list وlist-with-messages بنية قياسية للتقسيم إلى صفحات والتصفية والفرز.
حقول Options
| الحقل | النوع | مطلوب | الوصف |
|---|---|---|---|
pagination | object | لا | إعدادات التقسيم إلى صفحات |
filtering | object | لا | معايير التصفية |
sorting | object | لا | إعدادات الفرز (مثل {"position": 1}) |
بنية التقسيم إلى صفحات
إذا لم يُرسَل pagination، تُعاد الصفحة الأولى بما يصل إلى 50 عنصراً. وإذا أُرسل، يكون currentPage مطلوباً.
| الحقل | النوع | الافتراضي | الوصف |
|---|---|---|---|
currentPage | number | — | رقم الصفحة المراد جلبها (مطلوب عند إرسال pagination) |
pageItems | number | 50 | عدد العناصر في الصفحة (الحد الأقصى: 50) |
بنية التصفية
تتم التصفية بصيغة استعلام MongoDB على حقول العنصر، باستخدام أسماء الحقول كما تظهر في الاستجابة تماماً (مثل status وpayload.referenceId وresult.messageId). وفي نقطة النهاية list-with-messages يمكنكم أيضاً التصفية بحسب حقول الرسالة (مثل message.status).
// Filter by item status
{
"options": {
"filtering": {
"status": "succeeded"
}
}
}
// Filter by referenceId
{
"options": {
"filtering": {
"payload.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"]
}
}
}
}
// List items that have no message (only list-with-messages)
{
"options": {
"filtering": {
"message": {
"$exists": false
}
}
}
}
بنية الفرز
يتم الفرز بصيغة فرز MongoDB. تعني 1 تصاعدياً و-1 تنازلياً. وposition هو ترتيب المستلم في المصفوفة recipients في الطلب (بدءاً من 0).
// Sort in the order the recipients were sent in the request
{
"options": {
"sorting": {
"position": 1
}
}
}
// Sort by multiple fields
{
"options": {
"sorting": {
"status": 1,
"position": 1
}
}
}
مثال على الاستخدام المركّب
{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 2,
"pageItems": 50
},
"filtering": {
"message.status": "delivered"
},
"sorting": {
"position": 1
}
}
}
يعرض هذا المثال الصفحة الثانية من الرسائل المُسلَّمة بترتيب المستلمين.
- ادمجوا
filteringمعpaginationللاستعلامات المستهدفة - تتضمن الاستجابة
options.pagination.totalCountوoptions.pagination.totalPagesللتنقّل - لا يعمل مرشِّح
message.statusإلا في نقطة النهايةlist-with-messages
Items — تفاصيل العناصر وعرضها
يعرض جميع عناصر الإرسال لعملية جماعية. يمثل كل عنصر إدخالاً واحداً من المصفوفة recipients.
List — قائمة العناصر
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation-items/list.js
معاملات الطلب
| المعامل | النوع | مطلوب | الوصف |
|---|---|---|---|
bulkOperationId | string | نعم | معرّف العملية الجماعية المراد عرضها |
options | object | لا | خيارات التقسيم إلى صفحات والتصفية والفرز. راجعوا بنية Options للتفاصيل. |
الطلب — الاستخدام الأساسي
{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
}
}
}
الطلب — التصفية بحسب حالة محددة
{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"status": "failed"
}
}
}
يعرض عناصر الإرسال الفاشلة فقط، مع السبب في error.
الاستجابة
{
"bulkOperationItems": [
{
"_id": "item_1",
"bulkOperationId": "abc123xyz789",
"bulkOperationBatchId": "batch_1",
"slug": "my-workspace",
"position": 0,
"payload": {
"username": "905554443301",
"referenceId": "ORDER-12345",
"payload": {
"template": {
"variables": [{ "type": "BODY", "parameters": ["Ahmet", "ORD-001"] }]
}
}
},
"status": "succeeded",
"attempt": 1,
"result": {
"userId": "user_123",
"sessionId": "session_456",
"messageId": "msg_789"
},
"createdAt": "2026-06-10T10:00:00.000Z",
"updatedAt": "2026-06-10T10:00:01.000Z",
"completedAt": "2026-06-10T10:00:01.000Z"
},
{
"_id": "item_2",
"bulkOperationId": "abc123xyz789",
"bulkOperationBatchId": "batch_1",
"slug": "my-workspace",
"position": 1,
"payload": { "username": "905554443302", "referenceId": "ORDER-12346" },
"status": "failed",
"attempt": 1,
"error": { "code": "error", "message": "Variable missing", "retryable": false },
"result": { "userId": "user_124", "sessionId": "session_457" },
"createdAt": "2026-06-10T10:00:00.000Z",
"updatedAt": "2026-06-10T10:00:01.000Z",
"completedAt": "2026-06-10T10:00:01.000Z"
}
],
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50,
"totalCount": 150,
"totalPages": 3
},
"sorting": {},
"filtering": {},
"searching": {}
}
}
List With Messages — قائمة مع تفاصيل الرسائل
له ميزات نقطة النهاية list نفسها (التقسيم إلى صفحات والتصفية والفرز). والفرق: يحمل كل عنصر أيضاً كائنَي message وsession المرتبطين به عند وجودهما. وهذا يتيح لكم رؤية حالة الرسالة (delivered أو read أو error وغيرها) وحمولتها في استعلام واحد.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation-items/list-with-messages.js
الطلب — الاستخدام الأساسي
{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
}
}
}
الطلب — التصفية بحسب حالة الرسالة
{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"message.status": "delivered"
}
}
}
يجلب هذا المثال الرسائل ذات الحالة "delivered" فقط.
الطلب — عرض الرسائل الفاشلة
{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"message.status": "error"
}
}
}
يُستخدم لمراجعة الرسائل التي واجهت أخطاء في الإرسال.
الاستجابة
{
"bulkOperationItems": [
{
"_id": "item_1",
"bulkOperationId": "abc123xyz789",
"position": 0,
"payload": { "username": "905554443301", "referenceId": "ORDER-12345" },
"status": "succeeded",
"result": {
"userId": "user_123",
"sessionId": "session_456",
"messageId": "msg_789"
},
"message": {
"_id": "msg_789",
"type": "template",
"status": "delivered",
"payload": {
"template": {
"name": "order_notification"
}
},
"createdAt": "2026-06-10T10:01:00.000Z"
},
"session": {
"_id": "session_456",
"status": "opened"
}
}
],
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50,
"totalCount": 150,
"totalPages": 3
},
"sorting": {},
"filtering": {},
"searching": {}
}
}
حقول العنصر
| الحقل | النوع | الوصف |
|---|---|---|
_id | string | معرّف العنصر |
bulkOperationId | string | معرّف العملية الجماعية التي ينتمي إليها هذا العنصر |
position | number | ترتيب المستلم في المصفوفة recipients في الطلب، بدءاً من 0 |
payload | object | المستلم كما أُرسل في الطلب تماماً (username / userId / sessionId وreferenceId وpayload وisMerge) |
status | string | حالة العنصر: pending أو succeeded أو failed أو cancelled أو unknown |
error | object | في العناصر failed فقط: code وmessage وretryable |
result.userId | string | معرّف مستخدم المستلم |
result.sessionId | string | معرّف جلسة المحادثة |
result.messageId | string | معرّف الرسالة المُرسَلة (غير موجود إذا لم تُرسَل رسالة) |
completedAt | string | وقت معالجة العنصر |
message | object | تفاصيل الرسالة (في list-with-messages فقط) |
session | object | تفاصيل المحادثة (في list-with-messages فقط) |
مقارنة List وList-With-Messages
| الميزة | list | list-with-messages |
|---|---|---|
| التقسيم إلى صفحات | نعم | نعم |
| التصفية | نعم (حقول العنصر فقط) | نعم (حقول العنصر والرسالة) |
| الرسالة / الجلسة | لا | نعم (إن وُجدتا) |
| الأداء | سريع | متوسط (ينفّذ JOIN) |
| مرشِّح message.status | غير متاح | متاح |
- list: عرض كل العناصر بسرعة، والتصفية بحسب referenceId، والتحقق من حالات العناصر
- list-with-messages: الاطلاع على حالات رسائل WhatsApp (delivered وread)، وفحص حمولات الرسائل
- أمثلة على التصفية:
{"status": "failed"}— عناصر الإرسال الفاشلة{"payload.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 فقط){"message": {"$exists": false}}— العناصر التي لا رسالة لها (list-with-messages فقط){"status": {"$in": ["succeeded", "pending"]}}— العناصر الناجحة أو المعلّقة
- نقطة النهاية
listأسرع؛ فضّلوها لفحوص الحالة العامة - استخدموا
list-with-messagesعندما تحتاجون إلى تفاصيل الرسائل - الحد الأقصى للعناصر في الصفحة (pageItems) هو 50؛ وتكون القيمة الافتراضية 50 إذا لم تُحدَّد
- لا يعمل مرشِّح
message.statusإلا فيlist-with-messages - العناصر التي ليس لها
result.messageIdلا تحتوي على كائنmessage
Stop — إلغاء الإرسال
يوقف إرسال عملية جماعية جارية. تُنقل جميع العناصر pending إلى الحالة cancelled وتصبح العملية الجماعية stopped. أما العناصر التي عُولجت بالفعل بحالة succeeded أو failed فلا تتأثر. ويمكن أيضاً إيقاف عملية جماعية مجدولة قبل حلول وقت scheduleAt الخاص بها.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/stop.js
لا يمكن التراجع عن هذا الإجراء. ولا يمكن استئناف إرسال تم إيقافه.
معاملات الطلب
| المعامل | النوع | مطلوب | الوصف |
|---|---|---|---|
bulkOperationId | string | نعم | معرّف العملية الجماعية المراد إيقافها |
{
"bulkOperationId": "abc123xyz789"
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/stop.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"bulkOperationId": "abc123xyz789"
}'
الاستجابة
عند نجاح الطلب يكون جسم الاستجابة فارغاً. وتشير حالة HTTP 200 إلى أن العملية اكتملت بنجاح.
{}
- لا يمكن إيقاف إلا العمليات الجماعية التي أُنشئت عبر واجهة API هذه
- بعد إيقاف الإرسال، يمكنكم استخدام نقطة النهاية
showللتحقق من عدد العناصر الملغاة (bulkOperation.progress.cancelled) - إذا تعذّر العثور على العملية الجماعية، تعيد API الخطأ:
Bulk operation not found.