مستندات Bulk Template Message API
این API به شما امکان میدهد پیامهای قالب را همزمان از طریق کانال واتساپ برای چند گیرنده ارسال کنید.
ارسال پیامها بهصورت ناهمگام (asynchronous) پردازش میشود؛ درخواست API بلافاصله یک bulkMessageId برمیگرداند و پیامها در پسزمینه صفبندی و پردازش میشوند.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/send.js
ویژگیهای کلیدی
- ارسال پیامهای قالب گروهی به ۱ تا ۵٬۰۰۰ گیرنده در یک درخواست
- متغیرهای شخصیسازیشده برای هر گیرنده (HEADER، BODY، BUTTONS، CAROUSEL)
defaultPayloadمشترک برای همهٔ گیرندگان و ادغامpayloadاختصاصی هر گیرنده (isMerge)- ارسال زمانبندیشده (
scheduleAt) - مشخصکردن گیرندگان با
username(شمارهٔ تلفن)،userIdیاsessionId - ارسال چند پیام به یک کاربر در یک درخواست گروهی
referenceIdاختیاری برای پیگیری رکوردها در سیستمهای بیرونی- واگذاری خودکار گفتگوها به یک کاربر یا گروه کاری پس از ارسال (
action)
این API فقط میتواند قالبهایی را ارسال کند که توسط Meta تأیید شدهاند.
نام قالب و کد زبان باید دقیقاً با قالب ثبتشده در Meta Business Manager مطابقت داشته باشند.
پارامترهای درخواست
پارامترهای سطح بالا
| پارامتر | نوع | الزامی | توضیحات |
|---|---|---|---|
channelUsername | string | بله | شمارهٔ کانال واتساپ که برای ارسال پیام استفاده میشود (مثلاً "908506669933") |
connectorBrand | string | بله | برند اتصالدهندهٔ کانال. مقدار پشتیبانیشدهٔ فعلی: "whatsapp" |
title | string | خیر | عنوان کمپین. برای نمایش در داشبورد استفاده میشود. پیشفرض: "-" |
scheduleAt | string (ISO 8601) | خیر | تاریخ و زمان ارسال زمانبندیشده (مثلاً "2026-06-10T10:00:00.000Z"). اگر ذکر نشود، پیامها بلافاصله ارسال میشوند. |
defaultPayload | object | مشروط* | payload پیشفرض قالب که برای همهٔ گیرندگان اعمال میشود. اگر گیرندهای payload اختصاصی خودش را نداشته باشد، الزامی است. |
recipients | array | بله | فهرست گیرندگان. حداقل ۱ و حداکثر ۵٬۰۰۰ گیرنده. |
action | object | خیر | اقدامی که پس از ارسال روی گفتگو اعمال میشود. assign-to-user یا assign-to-workgroup. |
*اگر همهٔ گیرندگان payload اختصاصی خودشان را داشته باشند، defaultPayload اختیاری است.
ساختار گیرنده
برای هر گیرنده باید دقیقاً یکی از username، userId یا sessionId داده شود. چند شناسه را نمیتوان همزمان به کار برد و ندادن هیچکدام به خطا منجر میشود.
برای ارسال چند پیام به یک کاربر در یک درخواست گروهی، همان شناسه را چند بار به فهرست گیرندگان اضافه کنید.
| فیلد | نوع | توضیحات |
|---|---|---|
username | string | شمارهٔ تلفن گیرنده (مثلاً "905554443322"). اگر کاربر در سیستم وجود نداشته باشد، بهصورت خودکار ساخته میشود. |
userId | string | شناسهٔ یک کاربر موجود در سیستم. |
sessionId | string | شناسهٔ یک نشست گفتگوی موجود در سیستم. |
referenceId | string | شناسهٔ مرجع اختیاری (حداکثر ۲۵۶ نویسه) برای تطبیق با رکوردهای سیستم بیرونی (CRM، سفارش، تیکت و غیره). در صورت ذکر، باید در همان درخواست گروهی یکتا باشد. |
payload | object | payload قالب اختصاصی گیرنده (اختیاری). اگر isMerge: true باشد، با defaultPayload ادغام میشود. |
isMerge | boolean | رفتار ادغام را برای این گیرنده بازنویسی میکند (اختیاری). اگر ذکر نشود، defaultPayload.isMerge استفاده میشود. |
ساختار اقدام
| فیلد | نوع | توضیحات |
|---|---|---|
action.key | string | "assign-to-user" گفتگو را به یک کارشناس مشخص و "assign-to-workgroup" آن را به یک گروه کاری واگذار میکند. |
action.value | string | شناسهٔ کاربر یا گروه کاری مقصد. |
ساختار Payload قالب
defaultPayload و payload اختصاصی گیرنده ساختار یکسانی دارند. برای پیامهای قالب باید type: "template" مشخص شود.
{
"type": "template",
"template": {
"templateName": "order_confirmation",
"languageCode": "tr-TR",
"variables": []
},
"isMerge": true
}
| فیلد | نوع | الزامی | توضیحات |
|---|---|---|---|
type | string | بله | نوع payload. برای پیامهای قالب: "template" |
template.templateName | string | بله* | نام قالب ثبتشده در Meta. وقتی isMerge: true به کار رود، در payload گیرندگان اختیاری است (از payload پیشفرض به ارث میرسد). |
template.languageCode | string | خیر | کد زبان قالب (مثلاً "tr"، "en"، "tr-TR"، "en-US"). باید دقیقاً با زبان ثبتشده در Meta مطابقت داشته باشد. |
template.variables | array | خیر | فهرست متغیرهایی که روی اجزای قالب اعمال میشوند. جزئیات در ادامه آمده است. |
isMerge | boolean | خیر | true: payload گیرنده بهصورت عمیق با defaultPayload ادغام میشود. false یا ذکرنشده: payload گیرنده بهطور کامل جایگزین defaultPayload میشود. |
- اگر
defaultPayload.isMerge: trueباشد و گیرندهpayloadاختصاصی خودش را بدهد، ادغام عمیق اعمال میشود. - در ادغام عمیق، گیرنده میتواند فقط
variablesرا بدهد؛templateNameوlanguageCodeاز payload پیشفرض به ارث میرسند. - فیلد
isMergeگیرنده،defaultPayload.isMergeرا بازنویسی میکند. - اگر گیرنده
payloadندهد، همیشهdefaultPayloadاستفاده میشود.
ساختار متغیرها
هر مورد از آرایهٔ variables با یک جزء قالب متناظر است. نوع هر جزء (type) فقط یک بار میتواند در آرایه بیاید.
| type | توضیحات | parameters | cards |
|---|---|---|---|
"HEADER" | جزء سرایند قالب. متغیر متنی یا نشانی رسانه (تصویر، ویدیو، سند) | بله | — |
"BODY" | متغیرهای متنی بدنهٔ قالب | بله | — |
"BUTTONS" | متغیرهای پسوند URL پویا برای دکمهها | بله | — |
"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
برای دکمههایی با پسوند URL پویا استفاده میشود. اگر قالب چند دکمهٔ URL داشته باشد، فقط دکمههای دارای متغیر بهترتیب نمایهگذاری میشوند (دکمههای بدون متغیر یا دکمههای 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/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 از payload پیشفرض به ارث میرسند.
در این مثال، قالب هم سرایند رسانهای دارد و هم متغیرهای شخصیسازیشدهٔ بدنه.
{
"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در payload هر گیرنده تکرار شود - آرایهٔ
variablesهر گیرنده کاملاً مستقل است - نشانی رسانهٔ سرایند باید بهصورت عمومی در دسترس باشد
- اگر
typeدر payload گیرنده ذکر نشود،defaultPayload.typeبه ارث میرسد
4. متغیر دکمهٔ URL
وقتی قالب دکمهای با پسوند URL پویا دارد، از جزء 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 و دکمههای بدون متغیر نادیده گرفته میشوند؛ نمایهگذاری فقط برای دکمههای URL پویا اعمال میشود
- اگر URL دکمهٔ قالب
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 داده شود (مثلاً برای ساعت ۱۰:۰۰ صبح به وقت ترکیه، از07:00:00.000Zاستفاده کنید)- این مثال از قالب پارامتر نامدار استفاده میکند؛ قالب باید جانشینهایی مانند
{{name}}و{{discountRate}}داشته باشد - با
action، گفتگوهایی که در اثر ارسال پیام ایجاد میشوند بهصورت خودکار به گروه کاری مشخصشده واگذار میشوند
پاسخ
یک درخواست موفق یک bulkMessageId برمیگرداند که میتوان از آن برای پیگیری روند ارسال استفاده کرد:
{
"bulkMessageId": "abc123xyz789"
}
پاسخهای خطا
| وضعیت | توضیحات |
|---|---|
Channel not found | کانال تأییدشدهای که با channelUsername و connectorBrand مطابقت داشته باشد پیدا نشد |
Channel is not verified | کانال مطابق وجود دارد اما هنوز تأیید نشده است |
invalidRequest | برای یک گیرنده چند شناسه داده شده یا payload لازم وجود ندارد |
channelNotFound | کانال فعالی که با channelId دادهشده مطابقت داشته باشد پیدا نشد |
schema-error | یکی از فیلدهای بدنهٔ درخواست در اعتبارسنجی طرحواره رد شد (فیلد الزامی وجود ندارد، نوع نادرست است یا مقدار پشتیبانینشده است) |
bulkMessageId برگشتی را میتوان با اندپوینتهای زیر برای پرسوجوی آمار ارسال و متوقفکردن روند ارسال به کار برد.
Stats — آمار ارسال
وضعیت فعلی ارسال یک پیام گروهی را دریافت میکند. تعداد رکوردهای در انتظار، موفق، ناموفق و لغوشده را برمیگرداند.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/stats.js
پارامترهای درخواست
| پارامتر | نوع | الزامی | توضیحات |
|---|---|---|---|
bulkMessageId | string | بله | شناسهٔ پیام گروهی که باید پیگیری شود (از 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.pending | number | تعداد رکوردهایی که هنوز در صف منتظرند |
stats.success | number | تعداد رکوردهایی که با موفقیت برای ارسال پردازش شدهاند |
stats.failed | number | تعداد رکوردهایی که در ارسال با خطا مواجه شدهاند |
stats.cancelled | number | تعداد رکوردهای لغوشده |
stats.total | number | تعداد کل رکوردها (pending + success + failed + cancelled) |
stats.success نشان میدهد پیام با موفقیت از سوی سیستم تحویل داده شده است. این به معنای تضمین تحویل پیام به گیرنده توسط Meta نیست. بهروزرسانیهای وضعیت بعدی که Meta تولید میکند (مانند delivered، read یا failed) روی این شمارنده اثری ندارند و در آن منعکس نمیشوند.
- اندپوینت stats: وضعیت کار ارسال را نشان میدهد (pending، success، failed، cancelled)
- اندپوینت message-stats: وضعیت واقعی پیام را نشان میدهد (
pending،sending،sent،delivered،read،errorو غیره) - ممکن است یک کار موفق باشد، اما پیام هنوز تحویل داده نشده یا خوانده نشده باشد
شناسهٔ مرجع
referenceId یک فیلد اختیاری است که میتوانید برای پیگیری از آن استفاده کنید تا رکوردهای ارسال را با شناسهای از سیستم خودتان (مثلاً شمارهٔ سفارش یا شناسهٔ تیکت) تطبیق دهید.
در صورت ذکر، باید در همان درخواست گروهی یکتا باشد (حداکثر ۲۵۶ نویسه).
- استفاده از آن الزامی نیست
- در یک پیام گروهی نمیتواند تکراری باشد
- میتوان آن را در پیامهای گروهی مختلف دوباره استفاده کرد
Message Stats — وضعیت پیام واتساپ
آمار وضعیت پیامهای یک پیام گروهی را دریافت میکند. برخلاف اندپوینت 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
پارامترهای درخواست
| پارامتر | نوع | الزامی | توضیحات |
|---|---|---|---|
bulkMessageId | string | بله | شناسهٔ پیام گروهی که باید پرسوجو شود |
{
"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
| فیلد | نوع | توضیحات |
|---|---|---|
pending | number | پیامهایی که هنوز ارسال نشدهاند |
sending | number | پیامهایی که اکنون در حال ارسالاند |
sent | number | پیامهایی که به واتساپ تحویل داده شدهاند اما هنوز به مقصد نرسیدهاند |
delivered | number | پیامهایی که به گوشی گیرنده رسیدهاند |
read | number | پیامهایی که گیرنده خوانده است |
deleted | number | پیامهای حذفشده |
warning | number | پیامهای دارای هشدار |
error | number | پیامهای دارای خطا |
unknown | number | پیامهای با وضعیت نامشخص |
not-sended | number | پیامهایی که نتوانستند ارسال شوند |
no-message | number | رکوردهایی که هنوز پیامی ندارند (هنوز در صفاند) |
total | number | تعداد کل رکوردها |
- بالا بودن تعداد
no-messageنشان میدهد ارسال هنوز در جریان است - تعداد
deliveredتحویل موفق پیام را نشان میدهد - از تعداد
readمیتوان برای سنجش تعامل کمپین استفاده کرد - برای پیگیری لحظهای میتوانید این اندپوینت را بهصورت دورهای فراخوانی کنید
ساختار Options — صفحهبندی، فیلتر و مرتبسازی
پارامتر options که در اندپوینتهای list و list-with-messages استفاده میشود، ساختاری استاندارد برای صفحهبندی، فیلتر و مرتبسازی فراهم میکند.
فیلدهای Options
| فیلد | نوع | الزامی | توضیحات |
|---|---|---|---|
pagination | object | خیر | تنظیمات صفحهبندی |
filtering | object | خیر | معیارهای فیلتر |
sorting | object | خیر | تنظیمات مرتبسازی (مثلاً {"createdAt": -1}) |
ساختار صفحهبندی
| فیلد | نوع | پیشفرض | توضیحات |
|---|---|---|---|
currentPage | number | 1 | شمارهٔ صفحهای که باید دریافت شود |
pageItems | number | 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"]
}
}
}
}
ساختار مرتبسازی
مرتبسازی با قالب sort در 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
پارامترهای درخواست
| پارامتر | نوع | الزامی | توضیحات |
|---|---|---|---|
bulkMessageId | string | بله | شناسهٔ پیام گروهی که باید فهرست شود |
options | object | خیر | گزینههای صفحهبندی، فیلتر و مرتبسازی. جزئیات را در ساختار 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 و غیره) و payload آن را در یک پرسوجو ببینید.
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": {}
}
}
فیلدهای Record
| فیلد | نوع | توضیحات |
|---|---|---|
_id | string | شناسهٔ رکورد |
bulkMessageId | string | شناسهٔ پیام گروهی که این رکورد به آن تعلق دارد |
userId | string | شناسهٔ کاربر گیرنده |
sessionId | string | شناسهٔ نشست گفتگو |
messageId | string | شناسهٔ پیام ارسالشده (اگر هنوز ارسال نشده باشد null) |
referenceId | string | شناسهٔ مرجع اختیاری (در صورت ذکر) |
status | string | وضعیت رکورد: pending، success، failed، cancelled |
message | object | جزئیات پیام (فقط در list-with-messages) |
مقایسهٔ List و List-With-Messages
| ویژگی | list | list-with-messages |
|---|---|---|
| صفحهبندی | بله | بله |
| فیلتر | بله (فقط فیلدهای رکورد) | بله (فیلدهای رکورد + پیام) |
| شیء پیام | خیر | بله (اگر messageId وجود داشته باشد) |
| کارایی | سریع | متوسط (JOIN انجام میدهد) |
| فیلتر message.status | در دسترس نیست | در دسترس |
- list: همهٔ رکوردها را سریع فهرست کنید، بر اساس referenceId فیلتر کنید، وضعیت رکوردها را بررسی کنید
- list-with-messages: وضعیت پیامهای واتساپ (delivered، read) را ببینید، payload پیامها را بررسی کنید
- نمونههای فیلتر:
{"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) ۵۰ است؛ اگر ذکر نشود پیشفرض ۵۰ است
- فیلتر
message.statusفقط درlist-with-messagesکار میکند - رکوردهایی که messageId آنها null است، شیء
messageآنها هم null خواهد بود
Stop — لغو ارسال
ارسال در حال انجام یک پیام گروهی را متوقف میکند. کار صفشده لغو میشود و همهٔ رکوردهای pending به وضعیت cancelled منتقل میشوند. رکوردهایی که قبلاً با وضعیت success یا failed پردازش شدهاند تحت تأثیر قرار نمیگیرند.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/stop.js
این اقدام قابل بازگشت نیست. ارسال متوقفشده را نمیتوان از سر گرفت.
پارامترهای درخواست
| پارامتر | نوع | الزامی | توضیحات |
|---|---|---|---|
bulkMessageId | string | بله | شناسهٔ پیام گروهی که باید متوقف شود |
{
"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را برمیگرداند