@warriorteam/redai-zalo-sdk 1.1.1 → 1.2.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 ADDED
@@ -0,0 +1,154 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.2.0] - 2025-01-08
9
+
10
+ ### Added
11
+
12
+ #### 🆕 ConsultationService - Customer Support Messaging
13
+ - **New Service**: `ConsultationService` for sending customer support messages within 48-hour interaction window
14
+ - **Text Messages**: Send consultation text messages with automatic validation (max 2000 characters)
15
+ - **Image Messages**: Send consultation images for visual support and guides
16
+ - **File Messages**: Send consultation file attachments (manuals, guides, documents)
17
+ - **Sticker Messages**: Send consultation sticker messages for friendly interactions
18
+ - **General Messages**: Send any type of consultation message with unified interface
19
+
20
+ #### 📚 Documentation & Examples
21
+ - **Comprehensive Guide**: New `docs/CONSULTATION_SERVICE.md` with detailed usage instructions
22
+ - **Practical Examples**: New `examples/consultation-service-example.ts` with 6 real-world scenarios
23
+ - **Smart Customer Support**: Example implementation of intelligent customer support bot
24
+ - **Webhook Integration**: Complete webhook integration examples for consultation service
25
+ - **Error Handling**: Detailed error handling and retry mechanism examples
26
+
27
+ #### 🔧 SDK Integration
28
+ - **Quick Access**: Available via `zalo.consultation` property
29
+ - **Quick Methods**: Added `zalo.sendConsultationText()` and `zalo.sendConsultationImage()` convenience methods
30
+ - **Type Safety**: Full TypeScript support with comprehensive type definitions
31
+ - **Error Handling**: Enhanced error handling with `ZaloSDKError` for consultation-specific errors
32
+
33
+ #### 📖 Documentation Updates
34
+ - **README.md**: Updated with ConsultationService examples and documentation links
35
+ - **SERVICES_ADDED.md**: Added detailed ConsultationService documentation
36
+ - **Keywords**: Enhanced package keywords for better discoverability
37
+
38
+ ### Technical Details
39
+
40
+ #### Consultation Service Features
41
+ - **48-Hour Window**: Enforces Zalo's 48-hour interaction window for consultation messages
42
+ - **Content Validation**: Automatic validation of message content and format
43
+ - **Quota Management**: Built-in quota tracking and management
44
+ - **Anti-Spam**: Follows Zalo's anti-spam guidelines and best practices
45
+ - **Retry Logic**: Built-in retry mechanism for failed requests
46
+
47
+ #### Usage Conditions
48
+ - Messages must be sent within 48 hours of last user interaction
49
+ - Content must be consultation/support related (no direct advertising)
50
+ - User must have followed the OA and not blocked it
51
+ - No daily limit but must follow anti-spam guidelines
52
+
53
+ #### Integration Points
54
+ - Seamless integration with existing webhook system
55
+ - Compatible with all existing SDK features
56
+ - Follows established SDK patterns and conventions
57
+ - Full backward compatibility maintained
58
+
59
+ ### Examples Added
60
+
61
+ 1. **Basic Consultation**: Simple text message consultation
62
+ 2. **Image Support**: Sending images for visual guidance
63
+ 3. **File Attachments**: Sending documents and manuals
64
+ 4. **Smart Customer Support**: AI-powered customer support bot
65
+ 5. **Retry Mechanism**: Robust error handling and retry logic
66
+ 6. **Webhook Integration**: Complete webhook event handling
67
+
68
+ ### Files Added/Modified
69
+
70
+ #### New Files
71
+ - `src/services/consultation.service.ts` - Main ConsultationService implementation
72
+ - `docs/CONSULTATION_SERVICE.md` - Comprehensive documentation
73
+ - `examples/consultation-service-example.ts` - Practical examples
74
+ - `CHANGELOG.md` - This changelog file
75
+
76
+ #### Modified Files
77
+ - `README.md` - Added ConsultationService documentation and examples
78
+ - `SERVICES_ADDED.md` - Added ConsultationService details
79
+ - `package.json` - Updated version, description, keywords, and scripts
80
+ - `src/index.ts` - Export ConsultationService types and classes
81
+ - `src/zalo-sdk.ts` - Integrated ConsultationService into main SDK
82
+
83
+ ### Breaking Changes
84
+ None. This release maintains full backward compatibility.
85
+
86
+ ### Migration Guide
87
+ No migration required. All existing code will continue to work unchanged.
88
+
89
+ To use the new ConsultationService:
90
+
91
+ ```typescript
92
+ import { ZaloSDK } from "@warriorteam/redai-zalo-sdk";
93
+
94
+ const zalo = new ZaloSDK({
95
+ appId: "your-app-id",
96
+ appSecret: "your-app-secret"
97
+ });
98
+
99
+ // Use consultation service
100
+ await zalo.consultation.sendTextMessage(
101
+ accessToken,
102
+ { user_id: "user-id" },
103
+ { type: "text", text: "How can I help you?" }
104
+ );
105
+
106
+ // Or use quick methods
107
+ await zalo.sendConsultationText(accessToken, "user-id", "Hello!");
108
+ ```
109
+
110
+ ---
111
+
112
+ ## [1.1.1] - 2024-12-XX
113
+
114
+ ### Fixed
115
+ - Bug fixes and stability improvements
116
+ - Enhanced error handling
117
+ - Documentation updates
118
+
119
+ ### Added
120
+ - Additional webhook event types
121
+ - Improved TypeScript definitions
122
+
123
+ ---
124
+
125
+ ## [1.1.0] - 2024-11-XX
126
+
127
+ ### Added
128
+ - Group Management Service
129
+ - Article Management Service
130
+ - Video Upload Service
131
+ - Enhanced webhook handling
132
+ - Comprehensive documentation
133
+
134
+ ---
135
+
136
+ ## [1.0.0] - 2024-10-XX
137
+
138
+ ### Added
139
+ - Initial release
140
+ - Official Account API support
141
+ - ZNS (Zalo Notification Service) support
142
+ - Social API support
143
+ - Authentication flow
144
+ - Basic messaging capabilities
145
+ - TypeScript support
146
+ - Comprehensive error handling
147
+
148
+ ### Features
149
+ - OAuth 2.0 authentication
150
+ - Message sending (text, image, file, sticker)
151
+ - User management
152
+ - Template management
153
+ - Quota monitoring
154
+ - Webhook event handling
package/README.md CHANGED
@@ -3,6 +3,7 @@
3
3
  A comprehensive TypeScript/JavaScript SDK for Zalo APIs, providing easy-to-use interfaces for:
4
4
 
5
5
  - **Official Account (OA) API** - Manage your Zalo Official Account
6
+ - **Consultation Service** - Send customer support messages within 48-hour window
6
7
  - **Zalo Notification Service (ZNS)** - Send template-based notification messages
7
8
  - **Social API** - Access user social information and authentication
8
9
  - **Group Message Framework (GMF)** - Send messages to Zalo groups
@@ -35,6 +36,7 @@ npm install @warriorteam/redai-zalo-sdk
35
36
  - **[Services Added](./SERVICES_ADDED.md)** - Detailed breakdown of all services and features
36
37
  - **[Group Management](./docs/GROUP_MANAGEMENT.md)** - Group messaging and management
37
38
  - **[Article Management](./docs/ARTICLE_MANAGEMENT.md)** - Content and article management
39
+ - **[Consultation Service](./docs/CONSULTATION_SERVICE.md)** - Customer service messaging guide
38
40
 
39
41
  ## Development
40
42
 
@@ -319,6 +321,49 @@ For support and questions:
319
321
  - Create an issue on GitHub
320
322
  - Contact RedAI team
321
323
 
324
+ ### Consultation Service (Customer Support)
325
+
326
+ ```typescript
327
+ // Send consultation text message
328
+ await zalo.consultation.sendTextMessage(accessToken,
329
+ { user_id: "user-id" },
330
+ {
331
+ type: "text",
332
+ text: "Xin chào! Tôi có thể hỗ trợ gì cho bạn?"
333
+ }
334
+ );
335
+
336
+ // Send consultation image with guide
337
+ await zalo.consultation.sendImageMessage(accessToken,
338
+ { user_id: "user-id" },
339
+ {
340
+ type: "image",
341
+ attachment: {
342
+ type: "image",
343
+ payload: {
344
+ url: "https://example.com/support-guide.jpg"
345
+ }
346
+ }
347
+ }
348
+ );
349
+
350
+ // Send file attachment for support
351
+ await zalo.consultation.sendFileMessage(accessToken,
352
+ { user_id: "user-id" },
353
+ {
354
+ type: "file",
355
+ url: "https://example.com/manual.pdf",
356
+ filename: "User Manual.pdf",
357
+ attachment: {
358
+ type: "file",
359
+ payload: {
360
+ url: "https://example.com/manual.pdf"
361
+ }
362
+ }
363
+ }
364
+ );
365
+ ```
366
+
322
367
  ### ZNS (Zalo Notification Service)
323
368
 
324
369
  ```typescript
package/SERVICES_ADDED.md CHANGED
@@ -4,7 +4,44 @@ This document summarizes all the services that have been added to the RedAI Zalo
4
4
 
5
5
  ## New Services Added
6
6
 
7
- ### 1. ZNSService (`src/services/zns.service.ts`)
7
+ ### 1. ConsultationService (`src/services/consultation.service.ts`)
8
+
9
+ **Purpose**: Customer Service messaging for sending consultation messages within 48-hour window
10
+
11
+ **Key Features**:
12
+
13
+ - Send consultation text messages
14
+ - Send consultation image messages
15
+ - Send consultation file messages
16
+ - Send consultation sticker messages
17
+ - Send general consultation messages
18
+ - Automatic validation of message content
19
+ - Built-in error handling and retry logic
20
+ - 48-hour interaction window enforcement
21
+
22
+ **Main Methods**:
23
+
24
+ - `sendTextMessage()` - Send consultation text message (max 2000 characters)
25
+ - `sendImageMessage()` - Send consultation image with support content
26
+ - `sendFileMessage()` - Send consultation file attachments (guides, manuals)
27
+ - `sendStickerMessage()` - Send consultation sticker messages
28
+ - `sendMessage()` - Send any type of consultation message
29
+
30
+ **Usage Conditions**:
31
+
32
+ - Must be sent within 48 hours of last user interaction
33
+ - Content must be consultation/support related (no direct advertising)
34
+ - User must have followed the OA and not blocked it
35
+ - No daily limit but must follow anti-spam guidelines
36
+
37
+ **Integration**:
38
+
39
+ - Accessible via `zalo.consultation` property
40
+ - Quick methods: `zalo.sendConsultationText()`, `zalo.sendConsultationImage()`
41
+ - Full webhook integration support
42
+ - Comprehensive error handling with ZaloSDKError
43
+
44
+ ### 2. ZNSService (`src/services/zns.service.ts`)
8
45
 
9
46
  **Purpose**: Zalo Notification Service for sending template-based notifications
10
47
 
@@ -0,0 +1,330 @@
1
+ # Consultation Service - Hướng Dẫn Sử Dụng
2
+
3
+ ## Tổng Quan
4
+
5
+ `ConsultationService` là dịch vụ chuyên dụng để gửi tin nhắn tư vấn (Customer Service) qua Zalo Official Account. Tin nhắn tư vấn cho phép OA gửi tin nhắn chủ động đến người dùng trong khung thời gian nhất định để hỗ trợ và tư vấn khách hàng.
6
+
7
+ ## Điều Kiện Gửi Tin Nhắn Tư Vấn
8
+
9
+ ### 1. Thời Gian Gửi
10
+ - **Khung thời gian**: Chỉ được gửi trong vòng **48 giờ** kể từ khi người dùng tương tác cuối cùng với OA
11
+ - **Tương tác bao gồm**:
12
+ - Gửi tin nhắn đến OA
13
+ - Nhấn button/quick reply
14
+ - Gọi điện thoại từ OA
15
+ - Truy cập website từ OA
16
+
17
+ ### 2. Nội Dung Tin Nhắn
18
+ - **Mục đích**: Phải liên quan đến tư vấn, hỗ trợ khách hàng
19
+ - **Bao gồm**: Trả lời câu hỏi, hướng dẫn sử dụng, hỗ trợ kỹ thuật
20
+ - **Không được**: Chứa nội dung quảng cáo trực tiếp
21
+
22
+ ### 3. Điều Kiện Người Dùng
23
+ - Người dùng phải đã follow OA
24
+ - Người dùng không được block OA
25
+ - Người dùng phải có tương tác gần đây với OA
26
+
27
+ ### 4. Tần Suất Gửi
28
+ - Không giới hạn số lượng tin nhắn tư vấn trong ngày
29
+ - Cần tuân thủ nguyên tắc không spam
30
+
31
+ ## Khởi Tạo Service
32
+
33
+ ```typescript
34
+ import { ZaloSDK } from "@warriorteam/redai-zalo-sdk";
35
+
36
+ const zalo = new ZaloSDK({
37
+ appId: "your-app-id",
38
+ appSecret: "your-app-secret",
39
+ debug: true
40
+ });
41
+
42
+ // Lấy consultation service
43
+ const consultationService = zalo.consultation;
44
+ ```
45
+
46
+ ## Các Phương Thức Chính
47
+
48
+ ### 1. Gửi Tin Nhắn Văn Bản
49
+
50
+ ```typescript
51
+ // Gửi tin nhắn văn bản tư vấn
52
+ const response = await consultationService.sendTextMessage(
53
+ accessToken,
54
+ { user_id: "user-id-here" },
55
+ {
56
+ type: "text",
57
+ text: "Xin chào! Tôi có thể hỗ trợ gì cho bạn?"
58
+ }
59
+ );
60
+
61
+ console.log("Message ID:", response.message_id);
62
+ console.log("Quota remaining:", response.quota?.remain);
63
+ ```
64
+
65
+ **Giới hạn văn bản:**
66
+ - Nội dung không được để trống
67
+ - Tối đa 2000 ký tự
68
+
69
+ ### 2. Gửi Tin Nhắn Hình Ảnh
70
+
71
+ ```typescript
72
+ // Gửi hình ảnh tư vấn
73
+ const response = await consultationService.sendImageMessage(
74
+ accessToken,
75
+ { user_id: "user-id-here" },
76
+ {
77
+ type: "image",
78
+ attachment: {
79
+ type: "image",
80
+ payload: {
81
+ url: "https://example.com/support-image.jpg"
82
+ }
83
+ }
84
+ }
85
+ );
86
+ ```
87
+
88
+ ### 3. Gửi File Đính Kèm
89
+
90
+ ```typescript
91
+ // Gửi file hướng dẫn
92
+ const response = await consultationService.sendFileMessage(
93
+ accessToken,
94
+ { user_id: "user-id-here" },
95
+ {
96
+ type: "file",
97
+ url: "https://example.com/user-manual.pdf",
98
+ filename: "Hướng dẫn sử dụng.pdf",
99
+ attachment: {
100
+ type: "file",
101
+ payload: {
102
+ url: "https://example.com/user-manual.pdf"
103
+ }
104
+ }
105
+ }
106
+ );
107
+ ```
108
+
109
+ ### 4. Gửi Sticker
110
+
111
+ ```typescript
112
+ // Gửi sticker thân thiện
113
+ const response = await consultationService.sendStickerMessage(
114
+ accessToken,
115
+ { user_id: "user-id-here" },
116
+ {
117
+ type: "sticker",
118
+ sticker_id: "sticker-id",
119
+ attachment: {
120
+ type: "sticker",
121
+ payload: {
122
+ id: "sticker-id"
123
+ }
124
+ }
125
+ }
126
+ );
127
+ ```
128
+
129
+ ### 5. Gửi Tin Nhắn Tổng Quát
130
+
131
+ ```typescript
132
+ // Gửi bất kỳ loại tin nhắn nào
133
+ const response = await consultationService.sendMessage(
134
+ accessToken,
135
+ { user_id: "user-id-here" },
136
+ {
137
+ type: "text",
138
+ text: "Cảm ơn bạn đã liên hệ. Chúng tôi sẽ hỗ trợ bạn ngay!"
139
+ }
140
+ );
141
+ ```
142
+
143
+ ## Xử Lý Lỗi
144
+
145
+ ```typescript
146
+ import { ZaloSDKError } from "@warriorteam/redai-zalo-sdk";
147
+
148
+ try {
149
+ const response = await consultationService.sendTextMessage(
150
+ accessToken,
151
+ { user_id: "user-id" },
152
+ { type: "text", text: "Hello!" }
153
+ );
154
+ } catch (error) {
155
+ if (error instanceof ZaloSDKError) {
156
+ console.error("Zalo API Error:", error.message);
157
+ console.error("Error Code:", error.code);
158
+
159
+ // Xử lý các lỗi phổ biến
160
+ switch (error.code) {
161
+ case -216:
162
+ console.log("Access token không hợp lệ");
163
+ break;
164
+ case -201:
165
+ console.log("Tham số không hợp lệ");
166
+ break;
167
+ case -223:
168
+ console.log("Đã vượt quá quota");
169
+ break;
170
+ default:
171
+ console.log("Lỗi khác:", error.message);
172
+ }
173
+ }
174
+ }
175
+ ```
176
+
177
+ ## Ví Dụ Thực Tế
178
+
179
+ ### Hệ Thống Hỗ Trợ Khách Hàng
180
+
181
+ ```typescript
182
+ class CustomerSupportBot {
183
+ constructor(private consultationService: ConsultationService) {}
184
+
185
+ async handleUserQuestion(accessToken: string, userId: string, question: string) {
186
+ try {
187
+ // Phân tích câu hỏi và tạo phản hồi
188
+ const response = this.generateResponse(question);
189
+
190
+ // Gửi tin nhắn tư vấn
191
+ await this.consultationService.sendTextMessage(
192
+ accessToken,
193
+ { user_id: userId },
194
+ {
195
+ type: "text",
196
+ text: response
197
+ }
198
+ );
199
+
200
+ // Gửi thêm hình ảnh hướng dẫn nếu cần
201
+ if (this.needsVisualGuide(question)) {
202
+ await this.consultationService.sendImageMessage(
203
+ accessToken,
204
+ { user_id: userId },
205
+ {
206
+ type: "image",
207
+ attachment: {
208
+ type: "image",
209
+ payload: {
210
+ url: "https://example.com/guide-image.jpg"
211
+ }
212
+ }
213
+ }
214
+ );
215
+ }
216
+
217
+ } catch (error) {
218
+ console.error("Failed to send consultation message:", error);
219
+ }
220
+ }
221
+
222
+ private generateResponse(question: string): string {
223
+ // Logic tạo phản hồi dựa trên câu hỏi
224
+ if (question.includes("đăng nhập")) {
225
+ return "Để đăng nhập, bạn vui lòng làm theo các bước sau...";
226
+ }
227
+
228
+ if (question.includes("thanh toán")) {
229
+ return "Về vấn đề thanh toán, chúng tôi hỗ trợ các phương thức...";
230
+ }
231
+
232
+ return "Cảm ơn bạn đã liên hệ. Chúng tôi sẽ hỗ trợ bạn ngay!";
233
+ }
234
+
235
+ private needsVisualGuide(question: string): boolean {
236
+ return question.includes("hướng dẫn") || question.includes("cách làm");
237
+ }
238
+ }
239
+ ```
240
+
241
+ ### Tích Hợp Với Webhook
242
+
243
+ ```typescript
244
+ // Xử lý tin nhắn từ webhook
245
+ app.post('/webhook', async (req, res) => {
246
+ const event = req.body;
247
+
248
+ if (event.event_name === 'user_send_text') {
249
+ const userId = event.sender.id;
250
+ const userMessage = event.message.text;
251
+
252
+ // Kiểm tra xem có phải câu hỏi cần hỗ trợ không
253
+ if (userMessage.includes('help') || userMessage.includes('hỗ trợ')) {
254
+
255
+ // Gửi tin nhắn tư vấn
256
+ await consultationService.sendTextMessage(
257
+ accessToken,
258
+ { user_id: userId },
259
+ {
260
+ type: "text",
261
+ text: "Tôi có thể hỗ trợ bạn về các vấn đề sau:\n1. Đăng nhập\n2. Thanh toán\n3. Sử dụng sản phẩm\nBạn cần hỗ trợ về vấn đề nào?"
262
+ }
263
+ );
264
+ }
265
+ }
266
+
267
+ res.status(200).send('OK');
268
+ });
269
+ ```
270
+
271
+ ## Best Practices
272
+
273
+ ### 1. Kiểm Tra Thời Gian Tương Tác
274
+ ```typescript
275
+ // Kiểm tra thời gian tương tác cuối cùng trước khi gửi
276
+ const lastInteraction = await getUserLastInteraction(userId);
277
+ const hoursSinceLastInteraction = (Date.now() - lastInteraction) / (1000 * 60 * 60);
278
+
279
+ if (hoursSinceLastInteraction > 48) {
280
+ console.log("Không thể gửi tin nhắn tư vấn - quá 48 giờ");
281
+ return;
282
+ }
283
+ ```
284
+
285
+ ### 2. Quản Lý Quota
286
+ ```typescript
287
+ // Kiểm tra quota trước khi gửi
288
+ const quota = await zalo.oa.getQuotaSummary(accessToken);
289
+ if (quota.consultation.remaining <= 0) {
290
+ console.log("Đã hết quota tin nhắn tư vấn");
291
+ return;
292
+ }
293
+ ```
294
+
295
+ ### 3. Retry Logic
296
+ ```typescript
297
+ async function sendWithRetry(
298
+ consultationService: ConsultationService,
299
+ accessToken: string,
300
+ recipient: MessageRecipient,
301
+ message: Message,
302
+ maxRetries = 3
303
+ ) {
304
+ for (let i = 0; i < maxRetries; i++) {
305
+ try {
306
+ return await consultationService.sendMessage(accessToken, recipient, message);
307
+ } catch (error) {
308
+ if (i === maxRetries - 1) throw error;
309
+
310
+ // Đợi trước khi retry
311
+ await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
312
+ }
313
+ }
314
+ }
315
+ ```
316
+
317
+ ## Lưu Ý Quan Trọng
318
+
319
+ 1. **Tuân thủ chính sách**: Chỉ gửi tin nhắn tư vấn thực sự, không spam
320
+ 2. **Theo dõi quota**: Kiểm tra quota thường xuyên để tránh vượt giới hạn
321
+ 3. **Xử lý lỗi**: Luôn có cơ chế xử lý lỗi phù hợp
322
+ 4. **Logging**: Ghi log để theo dõi và debug
323
+ 5. **Rate limiting**: Tránh gửi quá nhiều tin nhắn trong thời gian ngắn
324
+
325
+ ## Tài Liệu Liên Quan
326
+
327
+ - [Message Types](./MESSAGE_TYPES.md) - Các loại tin nhắn được hỗ trợ
328
+ - [Webhook Events](./WEBHOOK_EVENTS.md) - Xử lý sự kiện webhook
329
+ - [Error Handling](./ERROR_HANDLING.md) - Xử lý lỗi chi tiết
330
+ - [Quota Management](./QUOTA_MANAGEMENT.md) - Quản lý quota tin nhắn
@@ -0,0 +1,390 @@
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
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@warriorteam/redai-zalo-sdk",
3
- "version": "1.1.1",
4
- "description": "Zalo API SDK for TypeScript/JavaScript - Comprehensive SDK for Zalo Official Account, ZNS, and Social APIs",
3
+ "version": "1.2.0",
4
+ "description": "Comprehensive TypeScript/JavaScript SDK for Zalo APIs - Official Account, ZNS, Consultation Service, Group Messaging, and Social APIs",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "scripts": {
@@ -9,6 +9,11 @@
9
9
  "dev": "tsc --watch",
10
10
  "clean": "rimraf dist",
11
11
  "prepublishOnly": "npm run clean && npm run build",
12
+ "publish:npm": "npm publish --access public",
13
+ "publish:beta": "npm publish --tag beta --access public",
14
+ "version:patch": "npm version patch",
15
+ "version:minor": "npm version minor",
16
+ "version:major": "npm version major",
12
17
  "test": "jest",
13
18
  "lint": "eslint src/**/*.ts",
14
19
  "lint:fix": "eslint src/**/*.ts --fix"
@@ -21,13 +26,16 @@
21
26
  "zalo-sdk",
22
27
  "typescript",
23
28
  "official-account",
24
- "notification-service"
29
+ "notification-service",
30
+ "consultation-service",
31
+ "customer-support",
32
+ "messaging"
25
33
  ],
26
34
  "author": "RedAI Team",
27
35
  "license": "MIT",
28
36
  "repository": {
29
37
  "type": "git",
30
- "url": "https://github.com/redai/redai-zalo-sdk.git"
38
+ "url": "https://github.com/warriorteam/redai-zalo-sdk.git"
31
39
  },
32
40
  "bugs": {
33
41
  "url": "https://github.com/redai/redai-zalo-sdk/issues"
@@ -53,8 +61,10 @@
53
61
  "README.md",
54
62
  "LICENSE",
55
63
  "docs/**/*",
64
+ "examples/**/*",
56
65
  "ARCHITECTURE.md",
57
- "SERVICES_ADDED.md"
66
+ "SERVICES_ADDED.md",
67
+ "CHANGELOG.md"
58
68
  ],
59
69
  "engines": {
60
70
  "node": ">=16.0.0"