@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.
- package/CHANGELOG.md +129 -0
- package/README.md +51 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/services/broadcast.service.d.ts +108 -0
- package/dist/services/broadcast.service.d.ts.map +1 -0
- package/dist/services/broadcast.service.js +361 -0
- package/dist/services/broadcast.service.js.map +1 -0
- package/dist/types/broadcast.d.ts +331 -0
- package/dist/types/broadcast.d.ts.map +1 -0
- package/dist/types/broadcast.js +114 -0
- package/dist/types/broadcast.js.map +1 -0
- package/dist/zalo-sdk.d.ts +2 -0
- package/dist/zalo-sdk.d.ts.map +1 -1
- package/dist/zalo-sdk.js +2 -0
- package/dist/zalo-sdk.js.map +1 -1
- package/docs/API_REFERENCE.md +67 -0
- package/docs/BROADCAST_SERVICE.md +361 -0
- package/examples/broadcast-example.ts +201 -0
- package/package.json +4 -2
|
@@ -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.
|
|
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",
|