@warriorteam/redai-zalo-sdk 1.19.0 → 1.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,361 @@
1
+ # RedAI Zalo SDK - Broadcast Service Guide
2
+
3
+ ## Tổng quan
4
+
5
+ BroadcastService cho phép gửi tin truyền thông broadcast đến nhiều người dùng cùng lúc dựa trên các tiêu chí targeting như tuổi, giới tính, địa điểm, và platform.
6
+
7
+ ## API Endpoint
8
+
9
+ - **URL**: `https://openapi.zalo.me/v2.0/oa/message`
10
+ - **Method**: POST
11
+ - **Content-Type**: application/json
12
+ - **Header**: `access_token: <your_access_token>`
13
+
14
+ ## Khởi tạo Service
15
+
16
+ ```typescript
17
+ import { ZaloSDK } from "@warriorteam/redai-zalo-sdk";
18
+
19
+ const zalo = new ZaloSDK({
20
+ appId: "your-app-id",
21
+ appSecret: "your-app-secret"
22
+ });
23
+
24
+ // Access broadcast service
25
+ const broadcastService = zalo.broadcast;
26
+ ```
27
+
28
+ ## Các Phương Thức Chính
29
+
30
+ ### 1. Gửi Broadcast Message
31
+
32
+ ```typescript
33
+ // Gửi broadcast đến người dùng ở Hồ Chí Minh
34
+ const target = zalo.broadcast.createBroadcastTarget({
35
+ cities: ["Hồ Chí Minh"]
36
+ });
37
+
38
+ const result = await zalo.broadcast.sendBroadcastMessage(
39
+ accessToken,
40
+ { target },
41
+ "article-attachment-id"
42
+ );
43
+
44
+ console.log("Message ID:", result.data.message_id);
45
+ ```
46
+
47
+ ### 2. Gửi Nhiều Broadcast Messages
48
+
49
+ ```typescript
50
+ // Gửi nhiều article attachments tuần tự
51
+ const attachmentIds = [
52
+ "article-id-1",
53
+ "article-id-2",
54
+ "article-id-3"
55
+ ];
56
+
57
+ const target = zalo.broadcast.createBroadcastTarget({
58
+ cities: ["Hồ Chí Minh"]
59
+ });
60
+
61
+ const result = await zalo.broadcast.sendMultipleBroadcastMessages(
62
+ accessToken,
63
+ { target },
64
+ attachmentIds,
65
+ {
66
+ mode: 'sequential',
67
+ delay: 2000, // 2 giây giữa các tin
68
+ onProgress: (progress) => {
69
+ console.log(`${progress.completed}/${progress.total} completed`);
70
+ }
71
+ }
72
+ );
73
+
74
+ console.log(`Sent ${result.successfulMessages}/${result.totalMessages} messages`);
75
+ ```
76
+
77
+ ### 3. Tạo Targeting Criteria
78
+
79
+ ```typescript
80
+ // Targeting phức tạp
81
+ const complexTarget = zalo.broadcast.createBroadcastTarget({
82
+ gender: "FEMALE", // Nữ giới
83
+ ages: ["18-24", "25-34"], // Tuổi 18-34
84
+ cities: ["Hà Nội", "Đà Nẵng"], // Hà Nội và Đà Nẵng
85
+ platform: ["ANDROID", "IOS"] // Android và iOS
86
+ });
87
+ ```
88
+
89
+ ## Targeting Criteria
90
+
91
+ ### 1. Nhóm Tuổi (Ages)
92
+
93
+ | Nhóm tuổi | Mã | Mô tả |
94
+ |-----------|----|----|
95
+ | `"0-12"` | `"0"` | Tuổi từ 0-12 |
96
+ | `"13-17"` | `"1"` | Tuổi từ 13-17 |
97
+ | `"18-24"` | `"2"` | Tuổi từ 18-24 |
98
+ | `"25-34"` | `"3"` | Tuổi từ 25-34 |
99
+ | `"35-44"` | `"4"` | Tuổi từ 35-44 |
100
+ | `"45-54"` | `"5"` | Tuổi từ 45-54 |
101
+ | `"55-64"` | `"6"` | Tuổi từ 55-64 |
102
+ | `"65+"` | `"7"` | Tuổi từ 65 trở lên |
103
+
104
+ ```typescript
105
+ const target = zalo.broadcast.createBroadcastTarget({
106
+ ages: ["18-24", "25-34"] // Targeting 18-34 tuổi
107
+ });
108
+ ```
109
+
110
+ ### 2. Giới Tính (Gender)
111
+
112
+ | Giới tính | Mã | Mô tả |
113
+ |-----------|----|----|
114
+ | `"ALL"` | `"0"` | Tất cả giới tính |
115
+ | `"MALE"` | `"1"` | Nam |
116
+ | `"FEMALE"` | `"2"` | Nữ |
117
+
118
+ ```typescript
119
+ const target = zalo.broadcast.createBroadcastTarget({
120
+ gender: "MALE" // Chỉ targeting nam giới
121
+ });
122
+ ```
123
+
124
+ ### 3. Tỉnh Thành (Cities)
125
+
126
+ Hỗ trợ 63 tỉnh thành Việt Nam:
127
+
128
+ ```typescript
129
+ const target = zalo.broadcast.createBroadcastTarget({
130
+ cities: ["Hồ Chí Minh", "Hà Nội", "Đà Nẵng"]
131
+ });
132
+
133
+ // Xem tất cả mã tỉnh thành
134
+ const cityCodes = zalo.broadcast.getCityCodes();
135
+ console.log(cityCodes);
136
+ ```
137
+
138
+ ### 4. Miền (Locations)
139
+
140
+ | Miền | Mã | Mô tả |
141
+ |------|----|----|
142
+ | `"NORTH"` | `"0"` | Miền Bắc |
143
+ | `"CENTRAL"` | `"1"` | Miền Trung |
144
+ | `"SOUTH"` | `"2"` | Miền Nam |
145
+
146
+ ```typescript
147
+ const target = zalo.broadcast.createBroadcastTarget({
148
+ locations: ["SOUTH"] // Chỉ miền Nam
149
+ });
150
+ ```
151
+
152
+ ### 5. Platform
153
+
154
+ | Platform | Mã | Mô tả |
155
+ |----------|----|----|
156
+ | `"IOS"` | `"1"` | iOS |
157
+ | `"ANDROID"` | `"2"` | Android |
158
+ | `"WINDOWS_PHONE"` | `"3"` | Windows Phone |
159
+
160
+ ```typescript
161
+ const target = zalo.broadcast.createBroadcastTarget({
162
+ platforms: ["IOS", "ANDROID"] // iOS và Android
163
+ });
164
+ ```
165
+
166
+ ## Ví Dụ Sử Dụng
167
+
168
+ ### 1. Broadcast Đơn Giản
169
+
170
+ ```typescript
171
+ // Gửi đến tất cả người dùng ở Hồ Chí Minh
172
+ const target = zalo.broadcast.createBroadcastTarget({
173
+ cities: ["Hồ Chí Minh"]
174
+ });
175
+
176
+ const result = await zalo.broadcast.sendBroadcastMessage(
177
+ accessToken,
178
+ { target },
179
+ "bd5ea46bb32e5a0033f"
180
+ );
181
+ ```
182
+
183
+ ### 2. Targeting Theo Nhân Khẩu Học
184
+
185
+ ```typescript
186
+ // Nữ giới 25-34 tuổi
187
+ const target = zalo.broadcast.createBroadcastTarget({
188
+ gender: "FEMALE",
189
+ ages: ["25-34"]
190
+ });
191
+
192
+ const result = await zalo.broadcast.sendBroadcastMessage(
193
+ accessToken,
194
+ { target },
195
+ "article-id"
196
+ );
197
+ ```
198
+
199
+ ### 3. Targeting Phức Tạp
200
+
201
+ ```typescript
202
+ // Nam giới 18-34 tuổi, dùng iOS, ở miền Nam
203
+ const target = zalo.broadcast.createBroadcastTarget({
204
+ gender: "MALE",
205
+ ages: ["18-24", "25-34"],
206
+ platforms: ["IOS"],
207
+ locations: ["SOUTH"]
208
+ });
209
+
210
+ const result = await zalo.broadcast.sendBroadcastMessage(
211
+ accessToken,
212
+ { target },
213
+ "article-id"
214
+ );
215
+ ```
216
+
217
+ ### 4. Gửi Nhiều Messages Song Song
218
+
219
+ ```typescript
220
+ // Gửi nhiều articles cùng lúc (parallel)
221
+ const attachmentIds = [
222
+ "promo-article-1",
223
+ "promo-article-2",
224
+ "promo-article-3"
225
+ ];
226
+
227
+ const result = await zalo.broadcast.sendMultipleBroadcastMessages(
228
+ accessToken,
229
+ { target },
230
+ attachmentIds,
231
+ {
232
+ mode: 'parallel', // Gửi song song
233
+ onProgress: (progress) => {
234
+ console.log(`Progress: ${progress.completed}/${progress.total}`);
235
+ console.log(`Success: ${progress.successful}, Failed: ${progress.failed}`);
236
+ }
237
+ }
238
+ );
239
+
240
+ console.log("Results:", result.results.map(r => ({
241
+ attachmentId: r.attachmentId,
242
+ success: r.success,
243
+ messageId: r.messageId
244
+ })));
245
+ ```
246
+
247
+ ### 5. Gửi Với Delay Tùy Chỉnh
248
+
249
+ ```typescript
250
+ // Gửi tuần tự với delay 5 giây giữa các tin
251
+ const result = await zalo.broadcast.sendMultipleBroadcastMessages(
252
+ accessToken,
253
+ { target },
254
+ attachmentIds,
255
+ {
256
+ mode: 'sequential',
257
+ delay: 5000, // 5 giây
258
+ onProgress: (progress) => {
259
+ if (progress.isCompleted) {
260
+ console.log("All messages sent!");
261
+ } else {
262
+ console.log(`Sending: ${progress.currentAttachmentId}`);
263
+ }
264
+ }
265
+ }
266
+ );
267
+
268
+ console.log(`Campaign completed in ${result.totalDuration}ms`);
269
+ console.log(`Success rate: ${(result.successfulMessages / result.totalMessages * 100).toFixed(1)}%`);
270
+ ```
271
+
272
+ ## Error Handling
273
+
274
+ ### Các Lỗi Thường Gặp
275
+
276
+ | Mã lỗi | Mô tả | Giải pháp |
277
+ |--------|-------|-----------|
278
+ | `3001` | Không có quyền broadcast | Liên hệ Zalo để được cấp quyền |
279
+ | `3002` | Article không tồn tại | Kiểm tra attachment_id |
280
+ | `3003` | Targeting không hợp lệ | Kiểm tra các tham số targeting |
281
+ | `3004` | Vượt quota broadcast | Chờ reset quota hoặc nâng cấp |
282
+ | `3005` | Vi phạm chính sách | Kiểm tra nội dung article |
283
+
284
+ ```typescript
285
+ try {
286
+ const result = await zalo.broadcast.sendBroadcastMessage(
287
+ accessToken,
288
+ { target },
289
+ articleId
290
+ );
291
+ console.log("Success:", result.data.message_id);
292
+ } catch (error) {
293
+ switch (error.code) {
294
+ case 3001:
295
+ console.error("Không có quyền broadcast");
296
+ break;
297
+ case 3002:
298
+ console.error("Article không tồn tại");
299
+ break;
300
+ default:
301
+ console.error("Lỗi khác:", error.message);
302
+ }
303
+ }
304
+ ```
305
+
306
+ ## Yêu Cầu và Giới Hạn
307
+
308
+ ### 1. Quyền Broadcast
309
+ - OA phải được Zalo cấp quyền gửi broadcast
310
+ - Cần tuân thủ chính sách về spam và nội dung
311
+
312
+ ### 2. Article Attachment
313
+ - Chỉ hỗ trợ template type `"media"` với `media_type: "article"`
314
+ - Article phải được tạo trước và có attachment_id hợp lệ
315
+
316
+ ### 3. Targeting
317
+ - Phải có ít nhất 1 tiêu chí targeting
318
+ - Có thể kết hợp nhiều tiêu chí cùng lúc
319
+
320
+ ### 4. Rate Limiting
321
+ - Tuân thủ giới hạn số lượng broadcast theo gói dịch vụ
322
+ - Tránh gửi quá nhiều broadcast trong thời gian ngắn
323
+
324
+ ## Best Practices
325
+
326
+ ### 1. Targeting Hiệu Quả
327
+ ```typescript
328
+ // Tốt: Targeting cụ thể
329
+ const target = zalo.broadcast.createBroadcastTarget({
330
+ gender: "FEMALE",
331
+ ages: ["25-34"],
332
+ cities: ["Hồ Chí Minh"]
333
+ });
334
+
335
+ // Tránh: Targeting quá rộng
336
+ const broadTarget = zalo.broadcast.createBroadcastTarget({
337
+ gender: "ALL" // Quá rộng, có thể bị spam
338
+ });
339
+ ```
340
+
341
+ ### 2. Nội Dung Chất Lượng
342
+ - Sử dụng article có nội dung hữu ích
343
+ - Tránh nội dung spam hoặc quảng cáo quá mức
344
+ - Tuân thủ chính sách của Zalo
345
+
346
+ ### 3. Monitoring và Analytics
347
+ ```typescript
348
+ // Lưu message_id để tracking
349
+ const result = await zalo.broadcast.sendBroadcastMessage(
350
+ accessToken,
351
+ { target },
352
+ articleId
353
+ );
354
+
355
+ // Lưu vào database để theo dõi
356
+ await saveBroadcastLog({
357
+ messageId: result.data.message_id,
358
+ targetCriteria: target,
359
+ sentAt: new Date()
360
+ });
361
+ ```
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Broadcast Message Example
3
+ *
4
+ * Ví dụ về cách sử dụng BroadcastService để gửi tin truyền thông broadcast
5
+ * đến nhiều người dùng dựa trên tiêu chí targeting
6
+ */
7
+
8
+ import { ZaloSDK } from "../src/index";
9
+
10
+ async function broadcastExample() {
11
+ // Khởi tạo SDK
12
+ const zalo = new ZaloSDK({
13
+ appId: "your-app-id",
14
+ appSecret: "your-app-secret",
15
+ debug: true
16
+ });
17
+
18
+ // Access token của OA (cần có quyền broadcast)
19
+ const accessToken = "your-oa-access-token";
20
+
21
+ // ID của article attachment đã được tạo trước
22
+ const articleAttachmentId = "bd5ea46bb32e5a0033f";
23
+
24
+ try {
25
+ console.log("=== Broadcast Message Examples ===\n");
26
+
27
+ // Example 1: Broadcast đến tất cả người dùng ở Hồ Chí Minh
28
+ console.log("1. Broadcast to Ho Chi Minh City users:");
29
+ const hcmTarget = zalo.broadcast.createBroadcastTarget({
30
+ cities: ["Hồ Chí Minh"]
31
+ });
32
+
33
+ const hcmResult = await zalo.broadcast.sendBroadcastMessage(
34
+ accessToken,
35
+ { target: hcmTarget },
36
+ articleAttachmentId
37
+ );
38
+
39
+ console.log("HCM broadcast result:", {
40
+ messageId: hcmResult.data.message_id,
41
+ error: hcmResult.error,
42
+ message: hcmResult.message
43
+ });
44
+
45
+ // Example 2: Broadcast đến nam giới 25-34 tuổi
46
+ console.log("\n2. Broadcast to male users aged 25-34:");
47
+ const maleTarget = zalo.broadcast.createBroadcastTarget({
48
+ gender: "MALE",
49
+ ages: ["25-34"]
50
+ });
51
+
52
+ const maleResult = await zalo.broadcast.sendBroadcastMessage(
53
+ accessToken,
54
+ { target: maleTarget },
55
+ articleAttachmentId
56
+ );
57
+
58
+ console.log("Male 25-34 broadcast result:", {
59
+ messageId: maleResult.data.message_id,
60
+ error: maleResult.error,
61
+ message: maleResult.message
62
+ });
63
+
64
+ // Example 3: Broadcast đến người dùng iOS ở miền Nam
65
+ console.log("\n3. Broadcast to iOS users in South Vietnam:");
66
+ const iosTarget = zalo.broadcast.createBroadcastTarget({
67
+ platform: ["IOS"],
68
+ locations: ["SOUTH"]
69
+ });
70
+
71
+ const iosResult = await zalo.broadcast.sendBroadcastMessage(
72
+ accessToken,
73
+ { target: iosTarget },
74
+ articleAttachmentId
75
+ );
76
+
77
+ console.log("iOS South broadcast result:", {
78
+ messageId: iosResult.data.message_id,
79
+ error: iosResult.error,
80
+ message: iosResult.message
81
+ });
82
+
83
+ // Example 4: Broadcast phức tạp - Nữ giới 18-24 tuổi, dùng Android, ở Hà Nội và Đà Nẵng
84
+ console.log("\n4. Complex targeting broadcast:");
85
+ const complexTarget = zalo.broadcast.createBroadcastTarget({
86
+ gender: "FEMALE",
87
+ ages: ["18-24"],
88
+ platform: ["ANDROID"],
89
+ cities: ["Hà Nội", "Đà Nẵng"]
90
+ });
91
+
92
+ const complexResult = await zalo.broadcast.sendBroadcastMessage(
93
+ accessToken,
94
+ { target: complexTarget },
95
+ articleAttachmentId
96
+ );
97
+
98
+ console.log("Complex targeting broadcast result:", {
99
+ messageId: complexResult.data.message_id,
100
+ error: complexResult.error,
101
+ message: complexResult.message
102
+ });
103
+
104
+ // Example 5: Gửi nhiều broadcast messages cùng lúc
105
+ console.log("\n5. Multiple broadcast messages (Sequential):");
106
+ const multipleAttachmentIds = [
107
+ "bd5ea46bb32e5a0033f",
108
+ "cd6fb57cc43f6b1144g",
109
+ "de7gc68dd54g7c2255h"
110
+ ];
111
+
112
+ const multipleTarget = zalo.broadcast.createBroadcastTarget({
113
+ cities: ["Hà Nội"],
114
+ gender: "ALL"
115
+ });
116
+
117
+ const multipleResult = await zalo.broadcast.sendMultipleBroadcastMessages(
118
+ accessToken,
119
+ { target: multipleTarget },
120
+ multipleAttachmentIds,
121
+ {
122
+ mode: 'sequential',
123
+ delay: 2000, // 2 seconds delay between messages
124
+ onProgress: (progress) => {
125
+ console.log(`Progress: ${progress.completed}/${progress.total} - Current: ${progress.currentAttachmentId}`);
126
+ console.log(`Success: ${progress.successful}, Failed: ${progress.failed}`);
127
+ }
128
+ }
129
+ );
130
+
131
+ console.log("Multiple broadcast result:", {
132
+ totalMessages: multipleResult.totalMessages,
133
+ successful: multipleResult.successfulMessages,
134
+ failed: multipleResult.failedMessages,
135
+ duration: `${multipleResult.totalDuration}ms`,
136
+ mode: multipleResult.mode
137
+ });
138
+
139
+ // Example 6: Gửi nhiều broadcast messages song song
140
+ console.log("\n6. Multiple broadcast messages (Parallel):");
141
+ const parallelResult = await zalo.broadcast.sendMultipleBroadcastMessages(
142
+ accessToken,
143
+ { target: multipleTarget },
144
+ multipleAttachmentIds,
145
+ {
146
+ mode: 'parallel',
147
+ onProgress: (progress) => {
148
+ console.log(`Parallel progress: ${progress.completed}/${progress.total}`);
149
+ }
150
+ }
151
+ );
152
+
153
+ console.log("Parallel broadcast result:", {
154
+ totalMessages: parallelResult.totalMessages,
155
+ successful: parallelResult.successfulMessages,
156
+ failed: parallelResult.failedMessages,
157
+ duration: `${parallelResult.totalDuration}ms`,
158
+ mode: parallelResult.mode
159
+ });
160
+
161
+ // Example 7: Hiển thị các mã targeting có sẵn
162
+ console.log("\n7. Available targeting codes:");
163
+ console.log("City codes:", Object.keys(zalo.broadcast.getCityCodes()).slice(0, 10), "...");
164
+ console.log("Age group codes:", zalo.broadcast.getAgeGroupCodes());
165
+ console.log("Gender codes:", zalo.broadcast.getGenderCodes());
166
+ console.log("Location codes:", zalo.broadcast.getLocationCodes());
167
+ console.log("Platform codes:", zalo.broadcast.getPlatformCodes());
168
+
169
+ } catch (error) {
170
+ console.error("Broadcast error:", error);
171
+
172
+ if (error.code) {
173
+ switch (error.code) {
174
+ case 3001:
175
+ console.error("Không có quyền gửi broadcast. Liên hệ Zalo để được cấp quyền.");
176
+ break;
177
+ case 3002:
178
+ console.error("Article attachment không tồn tại hoặc đã hết hạn.");
179
+ break;
180
+ case 3003:
181
+ console.error("Targeting criteria không hợp lệ.");
182
+ break;
183
+ case 3004:
184
+ console.error("Vượt quá giới hạn broadcast cho phép.");
185
+ break;
186
+ case 3005:
187
+ console.error("Nội dung vi phạm chính sách Zalo.");
188
+ break;
189
+ default:
190
+ console.error("Lỗi không xác định:", error.message);
191
+ }
192
+ }
193
+ }
194
+ }
195
+
196
+ // Chạy example nếu file được execute trực tiếp
197
+ if (require.main === module) {
198
+ broadcastExample().catch(console.error);
199
+ }
200
+
201
+ export { broadcastExample };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@warriorteam/redai-zalo-sdk",
3
- "version": "1.19.0",
4
- "description": "Comprehensive TypeScript/JavaScript SDK for Zalo APIs - Official Account, ZNS, Consultation Service, Group Messaging with List APIs, Social APIs, Enhanced Article Management, and Message Sequence APIs with Real-time Tracking",
3
+ "version": "1.21.0",
4
+ "description": "Comprehensive TypeScript/JavaScript SDK for Zalo APIs - Official Account, ZNS, Consultation Service, Broadcast Service, Group Messaging with List APIs, Social APIs, Enhanced Article Management, and Message Sequence APIs with Real-time Tracking",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "scripts": {
@@ -28,6 +28,8 @@
28
28
  "official-account",
29
29
  "notification-service",
30
30
  "consultation-service",
31
+ "broadcast-service",
32
+ "mass-communication",
31
33
  "customer-support",
32
34
  "messaging",
33
35
  "article-management",