@warriorteam/redai-zalo-sdk 1.26.1 → 1.26.2

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.
@@ -1,201 +0,0 @@
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 };
@@ -1,390 +0,0 @@
1
- /**
2
- * Ví dụ sử dụng ConsultationService - Dịch vụ tin nhắn tư vấn
3
- *
4
- * Ví dụ này minh họa cách sử dụng ConsultationService để:
5
- * - Gửi tin nhắn tư vấn văn bản
6
- * - Gửi hình ảnh hỗ trợ
7
- * - Gửi file hướng dẫn
8
- * - Xử lý lỗi và retry
9
- * - Tích hợp với webhook
10
- */
11
-
12
- import { ZaloSDK, ZaloSDKError, SendMessageResponse } from "../src/index";
13
-
14
- // Cấu hình SDK
15
- const zalo = new ZaloSDK({
16
- appId: "your-app-id",
17
- appSecret: "your-app-secret",
18
- debug: true
19
- });
20
-
21
- // Access token của OA (lấy từ quá trình authentication)
22
- const ACCESS_TOKEN = "your-oa-access-token";
23
-
24
- /**
25
- * Ví dụ 1: Gửi tin nhắn tư vấn cơ bản
26
- */
27
- async function basicConsultationExample() {
28
- console.log("=== Ví dụ 1: Tin nhắn tư vấn cơ bản ===");
29
-
30
- try {
31
- // Gửi tin nhắn văn bản tư vấn
32
- const response = await zalo.consultation.sendTextMessage(
33
- ACCESS_TOKEN,
34
- { user_id: "user-id-here" },
35
- {
36
- type: "text",
37
- text: "Xin chào! Cảm ơn bạn đã liên hệ với chúng tôi. Tôi có thể hỗ trợ gì cho bạn hôm nay?"
38
- }
39
- );
40
-
41
- console.log("✅ Gửi tin nhắn thành công!");
42
- console.log("Message ID:", response.message_id);
43
- console.log("User ID:", response.user_id);
44
-
45
- if (response.quota) {
46
- console.log("Quota còn lại:", response.quota.remain);
47
- }
48
-
49
- } catch (error) {
50
- if (error instanceof ZaloSDKError) {
51
- console.error("❌ Lỗi Zalo API:", error.message);
52
- console.error("Mã lỗi:", error.code);
53
- } else {
54
- console.error("❌ Lỗi không xác định:", error);
55
- }
56
- }
57
- }
58
-
59
- /**
60
- * Ví dụ 2: Gửi hình ảnh hỗ trợ
61
- */
62
- async function imageConsultationExample() {
63
- console.log("\n=== Ví dụ 2: Gửi hình ảnh hỗ trợ ===");
64
-
65
- try {
66
- const response = await zalo.consultation.sendImageMessage(
67
- ACCESS_TOKEN,
68
- { user_id: "user-id-here" },
69
- {
70
- type: "image",
71
- attachment: {
72
- type: "image",
73
- payload: {
74
- url: "https://example.com/support-guide.jpg"
75
- }
76
- }
77
- }
78
- );
79
-
80
- console.log("✅ Gửi hình ảnh hỗ trợ thành công!");
81
- console.log("Message ID:", response.message_id);
82
-
83
- } catch (error) {
84
- console.error("❌ Lỗi gửi hình ảnh:", error);
85
- }
86
- }
87
-
88
- /**
89
- * Ví dụ 3: Gửi file hướng dẫn
90
- */
91
- async function fileConsultationExample() {
92
- console.log("\n=== Ví dụ 3: Gửi file hướng dẫn ===");
93
-
94
- try {
95
- const response = await zalo.consultation.sendFileMessage(
96
- ACCESS_TOKEN,
97
- { user_id: "user-id-here" },
98
- {
99
- type: "file",
100
- url: "https://example.com/user-manual.pdf",
101
- filename: "Hướng dẫn sử dụng.pdf",
102
- attachment: {
103
- type: "file",
104
- payload: {
105
- url: "https://example.com/user-manual.pdf"
106
- }
107
- }
108
- }
109
- );
110
-
111
- console.log("✅ Gửi file hướng dẫn thành công!");
112
- console.log("Message ID:", response.message_id);
113
-
114
- } catch (error) {
115
- console.error("❌ Lỗi gửi file:", error);
116
- }
117
- }
118
-
119
- /**
120
- * Ví dụ 4: Hệ thống hỗ trợ khách hàng thông minh
121
- */
122
- class SmartCustomerSupport {
123
- private zalo: ZaloSDK;
124
- private accessToken: string;
125
-
126
- constructor(zalo: ZaloSDK, accessToken: string) {
127
- this.zalo = zalo;
128
- this.accessToken = accessToken;
129
- }
130
-
131
- /**
132
- * Xử lý câu hỏi của khách hàng
133
- */
134
- async handleCustomerQuestion(userId: string, question: string) {
135
- console.log(`\n📞 Xử lý câu hỏi từ user ${userId}: "${question}"`);
136
-
137
- try {
138
- // Phân tích câu hỏi và tạo phản hồi
139
- const response = this.analyzeQuestion(question);
140
-
141
- // Gửi tin nhắn phản hồi
142
- await this.zalo.consultation.sendTextMessage(
143
- this.accessToken,
144
- { user_id: userId },
145
- {
146
- type: "text",
147
- text: response.text
148
- }
149
- );
150
-
151
- // Gửi thêm tài liệu hỗ trợ nếu cần
152
- if (response.needsDocument) {
153
- await this.sendSupportDocument(userId, response.documentType);
154
- }
155
-
156
- console.log("✅ Đã phản hồi khách hàng thành công!");
157
-
158
- } catch (error) {
159
- console.error("❌ Lỗi xử lý câu hỏi khách hàng:", error);
160
-
161
- // Gửi tin nhắn lỗi cho khách hàng
162
- await this.sendErrorMessage(userId);
163
- }
164
- }
165
-
166
- /**
167
- * Phân tích câu hỏi và tạo phản hồi
168
- */
169
- private analyzeQuestion(question: string) {
170
- const lowerQuestion = question.toLowerCase();
171
-
172
- if (lowerQuestion.includes("đăng nhập") || lowerQuestion.includes("login")) {
173
- return {
174
- text: "Để đăng nhập vào hệ thống, bạn vui lòng:\n1. Truy cập trang đăng nhập\n2. Nhập email và mật khẩu\n3. Nhấn 'Đăng nhập'\n\nNếu quên mật khẩu, bạn có thể sử dụng chức năng 'Quên mật khẩu'.",
175
- needsDocument: true,
176
- documentType: "login_guide"
177
- };
178
- }
179
-
180
- if (lowerQuestion.includes("thanh toán") || lowerQuestion.includes("payment")) {
181
- return {
182
- text: "Chúng tôi hỗ trợ các phương thức thanh toán sau:\n• Thẻ tín dụng/ghi nợ\n• Ví điện tử (MoMo, ZaloPay)\n• Chuyển khoản ngân hàng\n• Thanh toán khi nhận hàng (COD)\n\nBạn cần hỗ trợ về phương thức nào?",
183
- needsDocument: true,
184
- documentType: "payment_guide"
185
- };
186
- }
187
-
188
- if (lowerQuestion.includes("giao hàng") || lowerQuestion.includes("shipping")) {
189
- return {
190
- text: "Thông tin về giao hàng:\n• Nội thành: 1-2 ngày\n• Ngoại thành: 2-3 ngày\n• Tỉnh khác: 3-5 ngày\n\nPhí ship được tính theo khoảng cách và trọng lượng đơn hàng.",
191
- needsDocument: false,
192
- documentType: null
193
- };
194
- }
195
-
196
- // Phản hồi mặc định
197
- return {
198
- text: "Cảm ơn bạn đã liên hệ! Tôi đã ghi nhận câu hỏi của bạn. Đội ngũ hỗ trợ sẽ phản hồi trong vòng 24 giờ.\n\nCác vấn đề phổ biến:\n• Đăng nhập\n• Thanh toán\n• Giao hàng\n• Đổi trả\n\nBạn có thể hỏi cụ thể về các vấn đề này để được hỗ trợ nhanh hơn.",
199
- needsDocument: false,
200
- documentType: null
201
- };
202
- }
203
-
204
- /**
205
- * Gửi tài liệu hỗ trợ
206
- */
207
- private async sendSupportDocument(userId: string, documentType: string) {
208
- const documents = {
209
- login_guide: {
210
- url: "https://example.com/guides/login-guide.pdf",
211
- filename: "Hướng dẫn đăng nhập.pdf"
212
- },
213
- payment_guide: {
214
- url: "https://example.com/guides/payment-guide.pdf",
215
- filename: "Hướng dẫn thanh toán.pdf"
216
- }
217
- };
218
-
219
- const doc = documents[documentType as keyof typeof documents];
220
- if (!doc) return;
221
-
222
- await this.zalo.consultation.sendFileMessage(
223
- this.accessToken,
224
- { user_id: userId },
225
- {
226
- type: "file",
227
- url: doc.url,
228
- filename: doc.filename,
229
- attachment: {
230
- type: "file",
231
- payload: {
232
- url: doc.url
233
- }
234
- }
235
- }
236
- );
237
- }
238
-
239
- /**
240
- * Gửi tin nhắn lỗi
241
- */
242
- private async sendErrorMessage(userId: string) {
243
- try {
244
- await this.zalo.consultation.sendTextMessage(
245
- this.accessToken,
246
- { user_id: userId },
247
- {
248
- type: "text",
249
- text: "Xin lỗi, hiện tại hệ thống đang gặp sự cố. Vui lòng thử lại sau hoặc liên hệ hotline: 1900-xxxx để được hỗ trợ trực tiếp."
250
- }
251
- );
252
- } catch (error) {
253
- console.error("❌ Không thể gửi tin nhắn lỗi:", error);
254
- }
255
- }
256
- }
257
-
258
- /**
259
- * Ví dụ 5: Retry mechanism
260
- */
261
- async function sendWithRetry(
262
- userId: string,
263
- message: string,
264
- maxRetries: number = 3
265
- ): Promise<SendMessageResponse | null> {
266
- console.log(`\n🔄 Gửi tin nhắn với retry (tối đa ${maxRetries} lần)`);
267
-
268
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
269
- try {
270
- console.log(`Lần thử ${attempt}/${maxRetries}`);
271
-
272
- const response = await zalo.consultation.sendTextMessage(
273
- ACCESS_TOKEN,
274
- { user_id: userId },
275
- { type: "text", text: message }
276
- );
277
-
278
- console.log("✅ Gửi thành công!");
279
- return response;
280
-
281
- } catch (error) {
282
- console.log(`❌ Lần thử ${attempt} thất bại:`, error instanceof ZaloSDKError ? error.message : error);
283
-
284
- if (attempt === maxRetries) {
285
- console.log("❌ Đã thử hết số lần cho phép");
286
- return null;
287
- }
288
-
289
- // Đợi trước khi thử lại (exponential backoff)
290
- const delay = Math.pow(2, attempt) * 1000;
291
- console.log(`⏳ Đợi ${delay}ms trước khi thử lại...`);
292
- await new Promise(resolve => setTimeout(resolve, delay));
293
- }
294
- }
295
-
296
- return null;
297
- }
298
-
299
- /**
300
- * Ví dụ 6: Tích hợp với webhook
301
- */
302
- function setupWebhookIntegration() {
303
- console.log("\n🔗 Thiết lập tích hợp webhook");
304
-
305
- const customerSupport = new SmartCustomerSupport(zalo, ACCESS_TOKEN);
306
-
307
- // Giả lập xử lý webhook event
308
- const handleWebhookEvent = async (event: any) => {
309
- console.log("📨 Nhận webhook event:", event.event_name);
310
-
311
- switch (event.event_name) {
312
- case "user_send_text":
313
- const userId = event.sender.id;
314
- const userMessage = event.message.text;
315
-
316
- // Kiểm tra xem có phải câu hỏi cần hỗ trợ không
317
- if (userMessage.includes("help") ||
318
- userMessage.includes("hỗ trợ") ||
319
- userMessage.includes("support")) {
320
-
321
- await customerSupport.handleCustomerQuestion(userId, userMessage);
322
- }
323
- break;
324
-
325
- case "user_send_sticker":
326
- // Phản hồi sticker bằng tin nhắn thân thiện
327
- await zalo.consultation.sendTextMessage(
328
- ACCESS_TOKEN,
329
- { user_id: event.sender.id },
330
- {
331
- type: "text",
332
- text: "Cảm ơn bạn! 😊 Tôi có thể hỗ trợ gì cho bạn không?"
333
- }
334
- );
335
- break;
336
-
337
- default:
338
- console.log("Event không cần xử lý:", event.event_name);
339
- }
340
- };
341
-
342
- return handleWebhookEvent;
343
- }
344
-
345
- /**
346
- * Chạy tất cả ví dụ
347
- */
348
- async function runAllExamples() {
349
- console.log("🚀 Bắt đầu chạy các ví dụ ConsultationService\n");
350
-
351
- // Ví dụ cơ bản
352
- await basicConsultationExample();
353
- await imageConsultationExample();
354
- await fileConsultationExample();
355
-
356
- // Ví dụ hệ thống hỗ trợ thông minh
357
- const customerSupport = new SmartCustomerSupport(zalo, ACCESS_TOKEN);
358
- await customerSupport.handleCustomerQuestion("user123", "Tôi không đăng nhập được");
359
- await customerSupport.handleCustomerQuestion("user456", "Làm sao để thanh toán?");
360
-
361
- // Ví dụ retry
362
- await sendWithRetry("user789", "Tin nhắn test retry");
363
-
364
- // Thiết lập webhook
365
- const webhookHandler = setupWebhookIntegration();
366
-
367
- // Giả lập một số webhook events
368
- await webhookHandler({
369
- event_name: "user_send_text",
370
- sender: { id: "user123" },
371
- message: { text: "Tôi cần hỗ trợ về đăng nhập" }
372
- });
373
-
374
- console.log("\n✅ Hoàn thành tất cả ví dụ!");
375
- }
376
-
377
- // Chạy ví dụ nếu file được execute trực tiếp
378
- if (require.main === module) {
379
- runAllExamples().catch(console.error);
380
- }
381
-
382
- export {
383
- basicConsultationExample,
384
- imageConsultationExample,
385
- fileConsultationExample,
386
- SmartCustomerSupport,
387
- sendWithRetry,
388
- setupWebhookIntegration,
389
- runAllExamples
390
- };