স্কিপ করে মূল কন্টেন্ট এ যান

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বাইরের সিস্টেমের রেকর্ডের (CRM, অর্ডার, টিকিট ইত্যাদি) সঙ্গে মেলানোর জন্য ঐচ্ছিক রেফারেন্স আইডি (সর্বোচ্চ 256 অক্ষর)। দিলে বাল্কের মধ্যে অনন্য হতে হবে।
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"টেমপ্লেটের হেডার কম্পোনেন্ট। টেক্সট ভেরিয়েবল বা মিডিয়া 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"]
}

ক্যারোসেল টেমপ্লেটে প্রতিটি কার্ডের জন্য কম্পোনেন্টের ভেরিয়েবল আলাদাভাবে নির্ধারণ করা হয়।

{
"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" }
}
]
}
}
}
]
}
টিপ
  • scheduleAt UTC টাইম জোনে দিতে হবে (যেমন তুরস্কের সময় সকাল 10:00-এর জন্য 07:00:00.000Z ব্যবহার করুন)
  • এই উদাহরণে নামযুক্ত প্যারামিটার ফরম্যাট ব্যবহার করা হয়েছে; টেমপ্লেটে {{name}} ও {{discountRate}}-এর মতো প্লেসহোল্ডার থাকা উচিত
  • action দিলে মেসেজ ডেলিভারির ফলে তৈরি হওয়া কথোপকথন স্বয়ংক্রিয়ভাবে নির্দিষ্ট ওয়ার্কগ্রুপকে দায়িত্ব দেওয়া হয়

রেসপন্স​

সফল অনুরোধ একটি bulkMessageId ফেরত দেয়, যা দিয়ে ডেলিভারির অগ্রগতি ট্র্যাক করা যায়:

{
"bulkMessageId": "abc123xyz789"
}

ত্রুটির রেসপন্স​

স্ট্যাটাসবিবরণ
Channel not foundchannelUsername ও 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বর্তমানে পাঠানো হচ্ছে এমন মেসেজ
sentnumberWhatsApp-এর কাছে হস্তান্তর করা হয়েছে, এখনো ডেলিভার হয়নি এমন মেসেজ
deliverednumberপ্রাপকের ফোনে ডেলিভার হওয়া মেসেজ
readnumberপ্রাপক পড়েছেন এমন মেসেজ
deletednumberমুছে ফেলা মেসেজ
warningnumberসতর্কবার্তাসহ মেসেজ
errornumberত্রুটিসহ মেসেজ
unknownnumberঅজানা অবস্থার মেসেজ
not-sendednumberপাঠানো যায়নি এমন মেসেজ
no-messagenumberএখনো মেসেজ তৈরি হয়নি এমন রেকর্ড (এখনো কিউতে)
totalnumberমোট রেকর্ডের সংখ্যা
ব্যবহারের টিপস
  • no-message-এর সংখ্যা বেশি হলে বোঝায় ডেলিভারি এখনো চলছে
  • delivered-এর সংখ্যা সফল মেসেজ ডেলিভারি দেখায়
  • read-এর সংখ্যা দিয়ে ক্যাম্পেইনের এনগেজমেন্ট মাপা যায়
  • রিয়েল-টাইম ট্র্যাকিংয়ের জন্য আপনি এই এন্ডপয়েন্টে নিয়মিত বিরতিতে পোল করতে পারেন

Options কাঠামো — পেজিনেশন, ফিল্টারিং ও সর্টিং​

list ও list-with-messages এন্ডপয়েন্টে ব্যবহৃত options প্যারামিটার পেজিনেশন, ফিল্টারিং ও সর্টিংয়ের জন্য একটি প্রমিত কাঠামো দেয়।

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 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
সতর্কবার্তা

এই কাজ ফেরানো যায় না। বন্ধ করা ডেলিভারি আর চালু করা যায় না।

অনুরোধের প্যারামিটার​

প্যারামিটারধরনআবশ্যকবিবরণ
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