Chuyển tới nội dung chính

Tài liệu Bulk Template Message API

API này cho phép bạn gửi tin nhắn mẫu đến nhiều người nhận cùng lúc qua kênh WhatsApp.

Việc gửi tin được xử lý bất đồng bộ; yêu cầu API trả về ngay một bulkMessageId, trong khi các tin nhắn được đưa vào hàng đợi và xử lý ở chế độ nền.

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

Tính năng chính​

  • Gửi tin nhắn mẫu hàng loạt đến 1–5.000 người nhận trong một yêu cầu
  • Biến được cá nhân hóa cho từng người nhận (HEADER, BODY, BUTTONS, CAROUSEL)
  • defaultPayload dùng chung cho mọi người nhận, với payload riêng của từng người nhận được gộp vào (isMerge)
  • Gửi theo lịch (scheduleAt)
  • Chỉ định người nhận bằng username (số điện thoại), userId hoặc sessionId
  • Gửi nhiều tin nhắn cho cùng một người dùng trong một yêu cầu hàng loạt
  • referenceId tùy chọn để theo dõi bản ghi với các hệ thống bên ngoài
  • Tự động giao cuộc trò chuyện cho một người dùng hoặc nhóm làm việc sau khi gửi (action)
cảnh báo

API này chỉ có thể gửi các mẫu tin đã được Meta duyệt.

Tên mẫu tin và mã ngôn ngữ phải khớp chính xác với mẫu tin được đăng ký trong Meta Business Manager.

Tham số yêu cầu​

Tham số cấp cao nhất​

Tham sốKiểuBắt buộcMô tả
channelUsernamestringCóSố kênh WhatsApp dùng để gửi tin nhắn (ví dụ "908506669933")
connectorBrandstringCóThương hiệu trình kết nối kênh. Giá trị hiện được hỗ trợ: "whatsapp"
titlestringKhôngTiêu đề chiến dịch. Dùng để hiển thị trên bảng điều khiển. Mặc định: "-"
scheduleAtstring (ISO 8601)KhôngNgày giờ gửi theo lịch (ví dụ "2026-06-10T10:00:00.000Z"). Nếu bỏ qua, tin nhắn được gửi ngay lập tức.
defaultPayloadobjectCó điều kiện*Payload mẫu tin mặc định áp dụng cho mọi người nhận. Bắt buộc nếu một người nhận không cung cấp payload riêng.
recipientsarrayCóDanh sách người nhận. Tối thiểu 1, tối đa 5.000 người nhận.
actionobjectKhôngHành động áp dụng cho cuộc trò chuyện sau khi gửi. assign-to-user hoặc assign-to-workgroup.

*Nếu mọi người nhận đều cung cấp payload riêng, defaultPayload là tùy chọn.

Cấu trúc người nhận​

Với mỗi người nhận, phải cung cấp đúng một trong username, userId hoặc sessionId. Không thể dùng nhiều định danh cùng lúc, và bỏ qua tất cả sẽ gây ra lỗi.

Để gửi nhiều tin nhắn cho cùng một người dùng trong một yêu cầu hàng loạt, hãy thêm cùng một định danh vào danh sách người nhận nhiều lần.

TrườngKiểuMô tả
usernamestringSố điện thoại của người nhận (ví dụ "905554443322"). Nếu người dùng chưa tồn tại trong hệ thống, họ sẽ được tạo tự động.
userIdstringId của một người dùng đã có trong hệ thống.
sessionIdstringId của một phiên trò chuyện đã có trong hệ thống.
referenceIdstringId tham chiếu tùy chọn (tối đa 256 ký tự) để đối chiếu với bản ghi của hệ thống bên ngoài (CRM, đơn hàng, ticket, v.v.). Nếu được cung cấp, phải là duy nhất trong cùng đợt gửi hàng loạt.
payloadobjectPayload mẫu tin riêng của người nhận (tùy chọn). Nếu isMerge: true, payload được gộp với defaultPayload.
isMergebooleanGhi đè hành vi gộp cho người nhận này (tùy chọn). Nếu bỏ qua, dùng defaultPayload.isMerge.

Cấu trúc hành động​

TrườngKiểuMô tả
action.keystring"assign-to-user" giao cuộc trò chuyện cho một nhân viên cụ thể; "assign-to-workgroup" giao cho một nhóm làm việc.
action.valuestringId của người dùng hoặc nhóm làm việc đích.

Cấu trúc payload mẫu tin​

defaultPayload và payload riêng của người nhận có cùng cấu trúc. Với tin nhắn mẫu, phải chỉ định type: "template".

{
"type": "template",
"template": {
"templateName": "order_confirmation",
"languageCode": "tr-TR",
"variables": []
},
"isMerge": true
}
TrườngKiểuBắt buộcMô tả
typestringCóLoại payload. Với tin nhắn mẫu: "template"
template.templateNamestringCó*Tên mẫu tin đã đăng ký trong Meta. Là tùy chọn trong payload của người nhận khi dùng isMerge: true (kế thừa từ mặc định).
template.languageCodestringKhôngMã ngôn ngữ của mẫu tin (ví dụ "tr", "en", "tr-TR", "en-US"). Phải khớp chính xác với ngôn ngữ đã đăng ký trong Meta.
template.variablesarrayKhôngDanh sách các biến áp dụng cho các thành phần của mẫu tin. Chi tiết bên dưới.
isMergebooleanKhôngtrue: payload của người nhận được gộp sâu với defaultPayload. false hoặc bỏ qua: payload của người nhận thay thế hoàn toàn defaultPayload.
Hành vi của isMerge
  • Nếu defaultPayload.isMerge: true và người nhận cung cấp payload riêng, việc gộp sâu được áp dụng.
  • Với gộp sâu, người nhận có thể chỉ cung cấp variables; templateName và languageCode được kế thừa từ payload mặc định.
  • Trường isMerge của người nhận ghi đè defaultPayload.isMerge.
  • Nếu người nhận không cung cấp payload, luôn dùng defaultPayload.

Cấu trúc biến​

Mỗi phần tử trong mảng variables tương ứng với một thành phần của mẫu tin. Một loại thành phần (type) chỉ được xuất hiện một lần trong mảng.

typeMô tảparameterscards
"HEADER"Thành phần tiêu đề của mẫu tin. Biến văn bản hoặc URL phương tiện (hình ảnh, video, tài liệu)Có—
"BODY"Các biến văn bản trong nội dung của mẫu tinCó—
"BUTTONS"Các biến hậu tố URL động cho nútCó—
"CAROUSEL"Các thành phần thẻ cho mẫu tin carousel—Có

Định dạng tham số​

Trường parameters có thể được cung cấp theo ba định dạng khác nhau:

// 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" }
Tôi nên dùng định dạng nào?
  • Nếu mẫu tin Meta của bạn dùng các chỗ giữ chỗ như {{1}}, {{2}}, hãy dùng định dạng mảng hoặc định dạng đối tượng khóa số.
  • Nếu mẫu tin của bạn dùng chỗ giữ chỗ có tên như {{firstName}} hoặc {{orderTotal}}, hãy dùng định dạng đối tượng khóa có tên.
  • Khi dùng mảng, thứ tự rất quan trọng: phần tử đầu tiên ứng với {{1}}, phần tử thứ hai ứng với {{2}}, và cứ thế tiếp tục.

Thành phần HEADER​

Dùng thành phần HEADER khi tiêu đề của mẫu tin chứa phương tiện (hình ảnh, video, tài liệu) hoặc văn bản động.

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

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

Thành phần BODY​

Dùng cho các biến văn bản động trong nội dung của mẫu tin.

// 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"
}
}

Thành phần BUTTONS​

Dùng cho các nút có hậu tố URL động. Nếu mẫu tin chứa nhiều nút URL, chỉ các nút có biến mới được đánh chỉ số tuần tự (các nút không có biến hoặc nút FLOW bị bỏ qua).

// 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"]
}

Với mẫu tin carousel, các biến của thành phần được định nghĩa riêng cho từng thẻ.

{
"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"]
}
]
}
]
}
cảnh báo

Độ dài của mảng cards phải khớp chính xác với số thẻ được định nghĩa trong mẫu tin.

Ví dụ​

1. Mẫu tin đơn giản — Không có biến, cùng nội dung cho mọi người nhận​

Đây là cách đơn giản nhất để gửi một mẫu tin tĩnh không có biến đến nhiều người nhận.

{
"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" }
]
}'
mẹo
  • Những người nhận được chỉ định qua username sẽ được tự động tạo nếu chưa tồn tại trong hệ thống
  • Mọi người nhận dùng cùng một defaultPayload; không cần dữ liệu riêng cho từng người nhận
  • Khi không chỉ định isMerge, mỗi người nhận dùng trực tiếp defaultPayload

2. Mẫu tin có biến nội dung dùng chung​

Cùng một mẫu tin được gửi đến mọi người nhận với các giá trị biến giống hệt nhau. Mẫu tin chứa các chỗ giữ chỗ như {{1}} và {{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" }]
}
mẹo
  • Trong ví dụ này, nội dung mẫu tin có thể là: "Enjoy a {{1}} discount in our campaign! Offer valid until {{2}}."
  • parameters[0] thay thế {{1}}, còn parameters[1] thay thế {{2}}

3. Mẫu tin được cá nhân hóa — Biến riêng cho từng người nhận với isMerge​

Mỗi người nhận dùng các giá trị biến khác nhau. Bằng cách đặt isMerge: true trong defaultPayload, người nhận chỉ cần cung cấp variables; templateName và languageCode được kế thừa từ payload mặc định.

Trong ví dụ này, mẫu tin gồm cả tiêu đề phương tiện và các biến nội dung được cá nhân hóa.

{
"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"]
}
]
}
}
}
]
}
mẹo
  • Nhờ isMerge: true, không cần lặp lại templateName trong payload của từng người nhận
  • Mảng variables của mỗi người nhận hoàn toàn độc lập
  • URL phương tiện của tiêu đề phải truy cập công khai được
  • Nếu bỏ qua type trong payload của người nhận, defaultPayload.type sẽ được kế thừa

4. Biến của nút URL​

Dùng thành phần BUTTONS khi mẫu tin chứa một nút có hậu tố URL động. Ví dụ, một mã theo dõi được nối vào URL gốc 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"]
}
]
}
}
}
]
}
mẹo
  • Các tham số BUTTONS được khớp theo thứ tự của các nút có chứa biến
  • Nút FLOW và các nút không có biến bị bỏ qua; việc đánh chỉ số chỉ áp dụng cho các nút URL động
  • Nếu URL của nút trong mẫu tin là https://example.com/track/{{1}}, thì parameters[0] thay thế {{1}}

5. Gửi theo lịch​

Lên lịch gửi tin nhắn vào một ngày giờ trong tương lai. scheduleAt phải được cung cấp dưới dạng dấu thời gian UTC theo 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" }
}
]
}
}
}
]
}
mẹo
  • scheduleAt phải được cung cấp theo múi giờ UTC (ví dụ, với 10:00 sáng giờ Thổ Nhĩ Kỳ, dùng 07:00:00.000Z)
  • Ví dụ này dùng định dạng tham số có tên; mẫu tin nên chứa các chỗ giữ chỗ như {{name}} và {{discountRate}}
  • Với action, các cuộc trò chuyện được tạo khi gửi tin nhắn sẽ tự động được giao cho nhóm làm việc đã chỉ định

Phản hồi​

Một yêu cầu thành công trả về bulkMessageId, có thể dùng để theo dõi quá trình gửi:

{
"bulkMessageId": "abc123xyz789"
}

Phản hồi lỗi​

Trạng tháiMô tả
Channel not foundKhông tìm thấy kênh đã xác minh nào khớp với channelUsername và connectorBrand
Channel is not verifiedKênh khớp tồn tại nhưng chưa được xác minh
invalidRequestMột người nhận được cung cấp nhiều định danh hoặc thiếu payload bắt buộc
channelNotFoundKhông tìm thấy kênh đang hoạt động nào khớp với channelId đã cung cấp
schema-errorMột trường trong nội dung yêu cầu không qua được kiểm tra lược đồ (thiếu trường bắt buộc, sai kiểu hoặc giá trị không được hỗ trợ)

bulkMessageId được trả về có thể dùng với các endpoint bên dưới để truy vấn thống kê gửi tin và dừng quá trình gửi.


Stats — Thống kê gửi tin​

Lấy trạng thái gửi hiện tại của một tin nhắn hàng loạt. Trả về số lượng bản ghi đang chờ, thành công, thất bại và đã hủy.

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

Tham số yêu cầu​

Tham sốKiểuBắt buộcMô tả
bulkMessageIdstringCóId của tin nhắn hàng loạt cần theo dõi (được trả về từ 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"
}'

Phản hồi​

{
"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
}
}

Các trường Stats​

TrườngKiểuMô tả
stats.pendingnumberSố bản ghi vẫn đang chờ trong hàng đợi
stats.successnumberSố bản ghi đã được xử lý để gửi thành công
stats.failednumberSố bản ghi gặp lỗi khi gửi
stats.cancellednumberSố bản ghi đã bị hủy
stats.totalnumberTổng số bản ghi (pending + success + failed + cancelled)
ghi chú

stats.success cho biết tin nhắn đã được hệ thống chuyển giao thành công. Điều này không bảo đảm rằng Meta đã gửi tin nhắn đến người nhận. Các cập nhật trạng thái tiếp theo do Meta tạo ra (như delivered, read hoặc failed) không ảnh hưởng đến bộ đếm này và không được phản ánh ở đây.

Stats so với Message Stats
  • Endpoint stats: Hiển thị trạng thái tác vụ gửi (pending, success, failed, cancelled)
  • Endpoint message-stats: Hiển thị trạng thái thực tế của tin nhắn (pending, sending, sent, delivered, read, error, v.v.)
  • Một tác vụ có thể thành công, nhưng tin nhắn có thể chưa được gửi đến/đọc

Reference ID​

referenceId là trường tùy chọn mà bạn có thể dùng để đối chiếu các bản ghi gửi tin với một id từ hệ thống của chính bạn nhằm mục đích theo dõi (ví dụ: số đơn hàng, id ticket).

Nếu được cung cấp, phải là duy nhất trong cùng đợt gửi hàng loạt (tối đa 256 ký tự).

Quan trọng
  • Không bắt buộc phải dùng
  • Không thể trùng lặp trong cùng một tin nhắn hàng loạt
  • Có thể dùng lại ở các tin nhắn hàng loạt khác nhau

Message Stats — Trạng thái tin nhắn WhatsApp​

Lấy thống kê trạng thái tin nhắn của một tin nhắn hàng loạt. Khác với endpoint stats, endpoint này hiển thị message.status thực tế của từng bản ghi thay vì trạng thái tác vụ.

Các trạng thái tin nhắn có thể có: 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

Tham số yêu cầu​

Tham sốKiểuBắt buộcMô tả
bulkMessageIdstringCóId của tin nhắn hàng loạt cần truy vấn
{
"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"
}'

Phản hồi​

{
"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
}
}

Các trường Message Stats​

TrườngKiểuMô tả
pendingnumberTin nhắn chưa được gửi
sendingnumberTin nhắn đang được gửi
sentnumberTin nhắn đã chuyển cho WhatsApp, chưa được gửi đến
deliverednumberTin nhắn đã được gửi đến điện thoại của người nhận
readnumberTin nhắn đã được người nhận đọc
deletednumberTin nhắn đã bị xóa
warningnumberTin nhắn có cảnh báo
errornumberTin nhắn có lỗi
unknownnumberTin nhắn có trạng thái không xác định
not-sendednumberTin nhắn không thể gửi
no-messagenumberBản ghi chưa có tin nhắn (vẫn trong hàng đợi)
totalnumberTổng số bản ghi
Mẹo sử dụng
  • Số no-message cao cho biết quá trình gửi vẫn đang diễn ra
  • Số delivered cho biết số tin nhắn đã gửi đến thành công
  • Số read có thể dùng để đo mức độ tương tác của chiến dịch
  • Bạn có thể gọi endpoint này định kỳ để theo dõi theo thời gian thực

Cấu trúc Options — Phân trang, lọc và sắp xếp​

Tham số options dùng trong các endpoint list và list-with-messages cung cấp một cấu trúc chuẩn cho phân trang, lọc và sắp xếp.

Các trường Options​

TrườngKiểuBắt buộcMô tả
paginationobjectKhôngCài đặt phân trang
filteringobjectKhôngTiêu chí lọc
sortingobjectKhôngCài đặt sắp xếp (ví dụ {"createdAt": -1})

Cấu trúc phân trang​

TrườngKiểuMặc địnhMô tả
currentPagenumber1Số trang cần lấy
pageItemsnumber50Số bản ghi mỗi trang (tối đa: 50)

Cấu trúc lọc​

Việc lọc dùng định dạng truy vấn MongoDB. Bạn có thể lọc theo các trường của bản ghi. Trong endpoint list-with-messages, bạn cũng có thể lọc theo các trường của tin nhắn (ví dụ 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"]
}
}
}
}

Cấu trúc sắp xếp​

Việc sắp xếp dùng định dạng sắp xếp MongoDB. 1 nghĩa là tăng dần, -1 nghĩa là giảm dần.

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

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

Ví dụ sử dụng kết hợp​

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

Ví dụ này sắp xếp các tin nhắn đã gửi đến từ mới nhất đến cũ nhất.

Mẹo thực tế
  • Kết hợp filtering và pagination cho các truy vấn có mục tiêu
  • Phản hồi có options.pagination.totalCount và options.pagination.totalPages để điều hướng
  • Bộ lọc message.status chỉ hoạt động trong endpoint list-with-messages

Records — Chi tiết và danh sách bản ghi​

Liệt kê mọi bản ghi gửi tin của một tin nhắn hàng loạt. Mỗi bản ghi đại diện cho một tin nhắn gửi đến một người nhận.

List — Danh sách bản ghi​

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

Tham số yêu cầu​

Tham sốKiểuBắt buộcMô tả
bulkMessageIdstringCóId của tin nhắn hàng loạt cần liệt kê
optionsobjectKhôngTùy chọn phân trang, lọc, sắp xếp. Xem chi tiết tại Cấu trúc Options.

Yêu cầu — Cách dùng cơ bản​

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

Yêu cầu — Lọc theo trạng thái cụ thể​

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

Chỉ liệt kê các bản ghi gửi thành công (record.status = "success").

Phản hồi​

{
"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 — Danh sách kèm chi tiết tin nhắn​

Có các tính năng giống endpoint list (phân trang, lọc, sắp xếp). Điểm khác biệt duy nhất: nếu một bản ghi có messageId, đối tượng message liên quan cũng được trả về. Điều này cho phép bạn xem trạng thái tin nhắn (delivered, read, error, v.v.) và payload trong một lần truy vấn.

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

Yêu cầu — Cách dùng cơ bản​

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

Yêu cầu — Lọc theo trạng thái tin nhắn​

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

Ví dụ này chỉ lấy các tin nhắn có trạng thái "delivered".

Yêu cầu — Liệt kê tin nhắn thất bại​

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

Dùng để xem lại các tin nhắn gặp lỗi khi gửi.

Phản hồi​

{
"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": {}
}
}

Các trường của bản ghi​

TrườngKiểuMô tả
_idstringId bản ghi
bulkMessageIdstringId tin nhắn hàng loạt mà bản ghi này thuộc về
userIdstringId người dùng của người nhận
sessionIdstringId phiên trò chuyện
messageIdstringId tin nhắn đã gửi (null nếu chưa gửi)
referenceIdstringId tham chiếu tùy chọn (nếu được cung cấp)
statusstringTrạng thái bản ghi: pending, success, failed, cancelled
messageobjectChi tiết tin nhắn (chỉ có trong list-with-messages)

So sánh List và List-With-Messages​

Tính nănglistlist-with-messages
Phân trangCóCó
LọcCó (chỉ các trường bản ghi)Có (trường bản ghi + trường tin nhắn)
Đối tượng MessageKhôngCó (nếu có messageId)
Hiệu năngNhanhTrung bình (thực hiện JOIN)
Bộ lọc message.statusKhông khả dụngKhả dụng
Các tình huống sử dụng
  • list: Liệt kê nhanh mọi bản ghi, lọc theo referenceId, kiểm tra trạng thái bản ghi
  • list-with-messages: Xem trạng thái tin nhắn WhatsApp (delivered, read), kiểm tra payload của tin nhắn
  • Ví dụ lọc:
    • {"status": "failed"} — Các bản ghi gửi thất bại
    • {"referenceId": "ORDER-123"} — Một reference ID cụ thể
    • {"message.status": "delivered"} — Tin nhắn đã gửi đến (chỉ list-with-messages)
    • {"message.status": "read"} — Tin nhắn đã đọc (chỉ list-with-messages)
    • {"message.status": "error"} — Tin nhắn có lỗi (chỉ list-with-messages)
    • {"message.status": {"$in": ["delivered", "read"]}} — Tin nhắn đã gửi đến hoặc đã đọc (chỉ list-with-messages)
    • {"message.status": {"$nin": ["error", "not-sended"]}} — Tin nhắn trừ các tin lỗi và chưa gửi (chỉ list-with-messages)
    • {"status": {"$in": ["success", "pending"]}} — Các bản ghi thành công hoặc đang chờ
Lưu ý về hiệu năng và cách dùng
  • Endpoint list nhanh hơn; ưu tiên dùng cho các lần kiểm tra trạng thái thông thường
  • Dùng list-with-messages khi cần chi tiết tin nhắn
  • Số bản ghi tối đa mỗi trang (pageItems) là 50; mặc định là 50 nếu không chỉ định
  • Bộ lọc message.status chỉ hoạt động trong list-with-messages
  • Các bản ghi có messageId null sẽ có đối tượng message là null

Stop — Hủy gửi tin​

Dừng một đợt gửi tin nhắn hàng loạt đang diễn ra. Tác vụ trong hàng đợi bị hủy, và mọi bản ghi pending được chuyển sang trạng thái cancelled. Các bản ghi đã được xử lý là success hoặc failed không bị ảnh hưởng.

POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/stop.js
cảnh báo

Hành động này không thể hoàn tác. Một đợt gửi đã dừng không thể tiếp tục.

Tham số yêu cầu​

Tham sốKiểuBắt buộcMô tả
bulkMessageIdstringCóId của tin nhắn hàng loạt cần dừng
{
"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"
}'

Phản hồi​

Với một yêu cầu thành công, nội dung phản hồi để trống. Mã trạng thái HTTP 200 cho biết thao tác đã hoàn tất thành công.

{}
mẹo
  • Chỉ có thể dừng các tin nhắn hàng loạt được tạo qua API này
  • Sau khi dừng một đợt gửi, bạn có thể dùng endpoint stats để xác minh số bản ghi đã hủy
  • Nếu không tìm thấy tin nhắn hàng loạt, API trả về lỗi: bulkMessageNotFound