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-এ নিবন্ধিত টেমপ্লেটের সঙ্গে হুবহু মিলতে হবে।
অনুরোধের প্যারামিটার
শীর্ষ-স্তরের প্যারামিটার
| প্যারামিটার | ধরন | আবশ্যক | বিবরণ |
|---|---|---|---|
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, সর্বোচ্চ 5,000 প্রাপক। |
action | object | না | পাঠানোর পর কথোপকথনে প্রযোজ্য অ্যাকশন। assign-to-user বা assign-to-workgroup। |
*প্রতিটি প্রাপক নিজের payload দিলে defaultPayload ঐচ্ছিক।
প্রাপকের কাঠামো
প্রতিটি প্রাপকের জন্য username, userId বা sessionId-এর ঠিক একটি দিতে হবে। একাধিক শনাক্তকারী একসঙ্গে ব্যবহার করা যায় না, আর সবগুলো বাদ দিলে ত্রুটি হবে।
একটি বাল্ক অনুরোধের মধ্যে একই ব্যবহারকারীকে একাধিক মেসেজ পাঠাতে প্রাপক তালিকায় একই শনাক্তকারী একাধিকবার যোগ করুন।
| ফিল্ড | ধরন | বিবরণ |
|---|---|---|
username | string | প্রাপকের ফোন নম্বর (যেমন "905554443322")। ব্যবহারকারী সিস্টেমে না থাকলে স্বয়ংক্রিয়ভাবে তৈরি হয়। |
userId | string | সিস্টেমে বিদ্যমান ব্যবহারকারীর আইডি। |
sessionId | string | সিস্টেমে বিদ্যমান কথোপকথন সেশনের আইডি। |
referenceId | string | বাইরের সিস্টেমের রেকর্ডের (CRM, অর্ডার, টিকিট ইত্যাদি) সঙ্গে মেলানোর জন্য ঐচ্ছিক রেফারেন্স আইডি (সর্বোচ্চ 256 অক্ষর)। দিলে বাল্কের মধ্যে অনন্য হতে হবে। |
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" | টেমপ্লেটের হেডার কম্পোনেন্ট। টেক্সট ভেরিয়েবল বা মিডিয়া URL (ছবি, ভিডিও, ডকুমেন্ট) | হ্যাঁ | — |
"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 সহ প্রাপকভেদে ভেরিয়েবল
প্রতিটি প্রাপকের জন্য আলাদা ভেরিয়েবল মান ব্যবহার করা হয়। defaultPayload-এ isMerge: true দিলে প্রাপকদের শুধু 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অ্যারে সম্পূর্ণ স্বাধীন - হেডার মিডিয়া URL সর্বসাধারণের জন্য প্রবেশযোগ্য হতে হবে
- প্রাপকের পেলোডে
typeবাদ দিলেdefaultPayload.typeনেওয়া হয়
4. URL বোতামের ভেরিয়েবল
টেমপ্লেটে ডাইনামিক URL সাফিক্সসহ বোতাম থাকলে BUTTONS কম্পোনেন্ট ব্যবহার করুন। উদাহরণস্বরূপ, বেস URL 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 ISO 8601 UTC টাইমস্ট্যাম্প হিসেবে দিতে হবে।
{
"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" }
}
]
}
}
}
]
}
scheduleAtUTC টাইম জোনে দিতে হবে (যেমন তুরস্কের সময় সকাল 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
অনুরোধের প্যারামিটার
| প্যারামিটার | ধরন | আবশ্যক | বিবরণ |
|---|---|---|---|
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 একটি ঐচ্ছিক ফিল্ড, যা দিয়ে আপনি ট্র্যাকিংয়ের জন্য ডেলিভারি রেকর্ডকে আপনার নিজের সিস্টেমের আইডির (যেমন অর্ডার নম্বর, টিকিট আইডি) সঙ্গে মেলাতে পারেন।
দিলে এটি বাল্কের মধ্যে অনন্য হতে হবে (সর্বোচ্চ 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
অনুরোধের প্যারামিটার
| প্যারামিটার | ধরন | আবশ্যক | বিবরণ |
|---|---|---|---|
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 | WhatsApp-এর কাছে হস্তান্তর করা হয়েছে, এখনো ডেলিভার হয়নি এমন মেসেজ |
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 কাঠামো — পেজিনেশন, ফিল্টারিং ও সর্টিং
list ও list-with-messages এন্ডপয়েন্টে ব্যবহৃত options প্যারামিটার পেজিনেশন, ফিল্টারিং ও সর্টিংয়ের জন্য একটি প্রমিত কাঠামো দেয়।
Options ফিল্ড
| ফিল্ড | ধরন | আবশ্যক | বিবরণ |
|---|---|---|---|
pagination | object | না | পেজিনেশন সেটিংস |
filtering | object | না | ফিল্টারিংয়ের শর্ত |
sorting | object | না | সর্টিং সেটিংস (যেমন {"createdAt": -1}) |
পেজিনেশনের কাঠামো
| ফিল্ড | ধরন | ডিফল্ট | বিবরণ |
|---|---|---|---|
currentPage | number | 1 | যে পেজ আনতে চান তার নম্বর |
pageItems | number | 50 | প্রতি পেজে রেকর্ডের সংখ্যা (সর্বোচ্চ: 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
অনুরোধের প্যারামিটার
| প্যারামিটার | ধরন | আবশ্যক | বিবরণ |
|---|---|---|---|
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 ইত্যাদি) ও পেলোড দেখা যায়।
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": {}
}
}
রেকর্ডের ফিল্ড
| ফিল্ড | ধরন | বিবরণ |
|---|---|---|
_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: 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 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