@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.
- package/dist/services/consultation.service.d.ts +50 -17
- package/dist/services/consultation.service.d.ts.map +1 -1
- package/dist/services/consultation.service.js +120 -26
- package/dist/services/consultation.service.js.map +1 -1
- package/package.json +1 -1
- package/examples/article-status-update.ts +0 -178
- package/examples/broadcast-example.ts +0 -201
- package/examples/consultation-service-example.ts +0 -390
- package/examples/get-all-articles-example.ts +0 -171
- package/examples/group-message-list.ts +0 -288
- package/examples/oa-auth-with-pkce.ts +0 -179
- package/examples/promotion-examples.ts +0 -514
- package/examples/send-message-sequence.ts +0 -200
- package/examples/user-list-post-example.ts +0 -186
- package/examples/video-upload-combined.example.ts +0 -228
- package/examples/webhook-message-classification.ts +0 -285
- package/examples/zns-template-edit.example.ts +0 -317
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Example: Using POST method to get user list
|
|
3
|
-
* Demonstrates the new postUserList method in UserService
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { ZaloSDK, UserListRequest } from "../src/index";
|
|
7
|
-
|
|
8
|
-
async function demonstratePostUserList() {
|
|
9
|
-
// Initialize SDK
|
|
10
|
-
const zalo = new ZaloSDK({
|
|
11
|
-
appId: "your-app-id",
|
|
12
|
-
appSecret: "your-app-secret"
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
const accessToken = "your-access-token";
|
|
16
|
-
|
|
17
|
-
try {
|
|
18
|
-
console.log("=== POST User List Example ===\n");
|
|
19
|
-
|
|
20
|
-
// Example 1: Basic user list with POST method
|
|
21
|
-
console.log("1. Getting user list with POST method:");
|
|
22
|
-
const basicRequest: UserListRequest = {
|
|
23
|
-
offset: 0,
|
|
24
|
-
count: 10
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const basicResult = await zalo.user.postUserList(accessToken, basicRequest);
|
|
28
|
-
console.log("Basic POST result:", {
|
|
29
|
-
total: basicResult.total,
|
|
30
|
-
userCount: basicResult.users.length,
|
|
31
|
-
users: basicResult.users.map(user => ({
|
|
32
|
-
user_id: user.user_id,
|
|
33
|
-
display_name: user.display_name,
|
|
34
|
-
user_is_follower: user.user_is_follower
|
|
35
|
-
}))
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
// Example 2: Filtered user list with tag
|
|
39
|
-
console.log("\n2. Getting users with specific tag (POST method):");
|
|
40
|
-
const taggedRequest: UserListRequest = {
|
|
41
|
-
offset: 0,
|
|
42
|
-
count: 20,
|
|
43
|
-
tag_name: "VIP_CUSTOMER"
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const taggedResult = await zalo.user.postUserList(accessToken, taggedRequest);
|
|
47
|
-
console.log("Tagged users POST result:", {
|
|
48
|
-
total: taggedResult.total,
|
|
49
|
-
userCount: taggedResult.users.length,
|
|
50
|
-
tag_filter: "VIP_CUSTOMER"
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
// Example 3: Followers only with POST method
|
|
54
|
-
console.log("\n3. Getting followers only (POST method):");
|
|
55
|
-
const followersRequest: UserListRequest = {
|
|
56
|
-
offset: 0,
|
|
57
|
-
count: 15,
|
|
58
|
-
is_follower: true
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
const followersResult = await zalo.user.postUserList(accessToken, followersRequest);
|
|
62
|
-
console.log("Followers POST result:", {
|
|
63
|
-
total: followersResult.total,
|
|
64
|
-
userCount: followersResult.users.length,
|
|
65
|
-
followers_only: true
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
// Example 4: Users with recent interaction (POST method)
|
|
69
|
-
console.log("\n4. Getting users with recent interaction (POST method):");
|
|
70
|
-
const recentRequest: UserListRequest = {
|
|
71
|
-
offset: 0,
|
|
72
|
-
count: 25,
|
|
73
|
-
last_interaction_period: "7d" // Last 7 days
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
const recentResult = await zalo.user.postUserList(accessToken, recentRequest);
|
|
77
|
-
console.log("Recent interaction POST result:", {
|
|
78
|
-
total: recentResult.total,
|
|
79
|
-
userCount: recentResult.users.length,
|
|
80
|
-
interaction_period: "7d"
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
// Example 5: Compare GET vs POST methods
|
|
84
|
-
console.log("\n5. Comparing GET vs POST methods:");
|
|
85
|
-
|
|
86
|
-
const compareRequest: UserListRequest = {
|
|
87
|
-
offset: 0,
|
|
88
|
-
count: 5
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
// GET method
|
|
92
|
-
const getResult = await zalo.user.getUserList(accessToken, compareRequest);
|
|
93
|
-
console.log("GET method result:", {
|
|
94
|
-
total: getResult.total,
|
|
95
|
-
userCount: getResult.users.length,
|
|
96
|
-
method: "GET"
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
// POST method
|
|
100
|
-
const postResult = await zalo.user.postUserList(accessToken, compareRequest);
|
|
101
|
-
console.log("POST method result:", {
|
|
102
|
-
total: postResult.total,
|
|
103
|
-
userCount: postResult.users.length,
|
|
104
|
-
method: "POST"
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
console.log("Results should be identical:", {
|
|
108
|
-
totals_match: getResult.total === postResult.total,
|
|
109
|
-
counts_match: getResult.users.length === postResult.users.length
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
} catch (error) {
|
|
113
|
-
console.error("Error in POST user list example:", error);
|
|
114
|
-
|
|
115
|
-
if (error instanceof Error) {
|
|
116
|
-
console.error("Error details:", {
|
|
117
|
-
name: error.name,
|
|
118
|
-
message: error.message,
|
|
119
|
-
stack: error.stack
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Example usage with pagination using POST method
|
|
126
|
-
async function demonstratePaginationWithPost() {
|
|
127
|
-
const zalo = new ZaloSDK({
|
|
128
|
-
appId: "your-app-id",
|
|
129
|
-
appSecret: "your-app-secret"
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
const accessToken = "your-access-token";
|
|
133
|
-
|
|
134
|
-
try {
|
|
135
|
-
console.log("\n=== POST Method Pagination Example ===\n");
|
|
136
|
-
|
|
137
|
-
let offset = 0;
|
|
138
|
-
const count = 10;
|
|
139
|
-
let allUsers: any[] = [];
|
|
140
|
-
let totalUsers = 0;
|
|
141
|
-
|
|
142
|
-
do {
|
|
143
|
-
const request: UserListRequest = {
|
|
144
|
-
offset,
|
|
145
|
-
count
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
const result = await zalo.user.postUserList(accessToken, request);
|
|
149
|
-
|
|
150
|
-
console.log(`Page ${Math.floor(offset / count) + 1}:`, {
|
|
151
|
-
offset,
|
|
152
|
-
returned: result.users.length,
|
|
153
|
-
total: result.total
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
allUsers.push(...result.users);
|
|
157
|
-
totalUsers = result.total;
|
|
158
|
-
offset += count;
|
|
159
|
-
|
|
160
|
-
// Break if we've got all users or no more users returned
|
|
161
|
-
if (result.users.length < count || allUsers.length >= totalUsers) {
|
|
162
|
-
break;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
} while (true);
|
|
166
|
-
|
|
167
|
-
console.log("\nPagination complete:", {
|
|
168
|
-
total_users: totalUsers,
|
|
169
|
-
fetched_users: allUsers.length,
|
|
170
|
-
method: "POST"
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
} catch (error) {
|
|
174
|
-
console.error("Error in POST pagination example:", error);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// Run examples
|
|
179
|
-
if (require.main === module) {
|
|
180
|
-
demonstratePostUserList()
|
|
181
|
-
.then(() => demonstratePaginationWithPost())
|
|
182
|
-
.then(() => console.log("\n✅ POST User List examples completed!"))
|
|
183
|
-
.catch(error => console.error("❌ Example failed:", error));
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
export { demonstratePostUserList, demonstratePaginationWithPost };
|
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Example: Combined Video Upload and Status Checking
|
|
3
|
-
*
|
|
4
|
-
* This example demonstrates how to use the new combined method
|
|
5
|
-
* uploadVideoAndWaitForCompletion() which handles both video upload
|
|
6
|
-
* and status checking in a single call.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { ZaloSDK, VideoUploadStatus } from '../src/index';
|
|
10
|
-
import * as fs from 'fs';
|
|
11
|
-
|
|
12
|
-
async function videoUploadCombinedExample() {
|
|
13
|
-
// Initialize SDK
|
|
14
|
-
const zalo = new ZaloSDK();
|
|
15
|
-
|
|
16
|
-
// Your access token
|
|
17
|
-
const accessToken = "YOUR_ACCESS_TOKEN";
|
|
18
|
-
|
|
19
|
-
try {
|
|
20
|
-
console.log("🚀 Starting combined video upload example...");
|
|
21
|
-
|
|
22
|
-
// Read video file
|
|
23
|
-
const videoBuffer = fs.readFileSync('./path/to/your/video.mp4');
|
|
24
|
-
console.log(`📁 Video file size: ${videoBuffer.length} bytes`);
|
|
25
|
-
|
|
26
|
-
// Method 1: Combined upload and wait for completion
|
|
27
|
-
console.log("\n📤 Method 1: Using combined uploadVideoAndWaitForCompletion()");
|
|
28
|
-
|
|
29
|
-
const startTime = Date.now();
|
|
30
|
-
const finalResult = await zalo.videoUpload.uploadVideoAndWaitForCompletion(
|
|
31
|
-
accessToken,
|
|
32
|
-
videoBuffer,
|
|
33
|
-
"example-video.mp4",
|
|
34
|
-
5 * 60 * 1000, // 5 minutes timeout
|
|
35
|
-
5 * 1000 // 5 seconds polling interval
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
const duration = Date.now() - startTime;
|
|
39
|
-
console.log(`✅ Video upload completed in ${duration}ms`);
|
|
40
|
-
console.log(`📹 Video ID: ${finalResult.video_id}`);
|
|
41
|
-
console.log(`📊 Status: ${finalResult.status} (${getStatusDescription(finalResult.status)})`);
|
|
42
|
-
console.log(`📝 Status Message: ${finalResult.status_message}`);
|
|
43
|
-
console.log(`🎬 Video Name: ${finalResult.video_name}`);
|
|
44
|
-
console.log(`📏 Video Size: ${finalResult.video_size} bytes`);
|
|
45
|
-
console.log(`🔄 Convert Progress: ${finalResult.convert_percent}%`);
|
|
46
|
-
|
|
47
|
-
// Method 2: Manual step-by-step approach (for comparison)
|
|
48
|
-
console.log("\n📤 Method 2: Manual step-by-step approach");
|
|
49
|
-
|
|
50
|
-
// Step 1: Upload video
|
|
51
|
-
const uploadResult = await zalo.videoUpload.uploadVideo(
|
|
52
|
-
accessToken,
|
|
53
|
-
videoBuffer,
|
|
54
|
-
"example-video-manual.mp4"
|
|
55
|
-
);
|
|
56
|
-
console.log(`🎫 Upload token: ${uploadResult.token}`);
|
|
57
|
-
|
|
58
|
-
// Step 2: Check status manually
|
|
59
|
-
let attempts = 0;
|
|
60
|
-
const maxAttempts = 60; // 5 minutes with 5-second intervals
|
|
61
|
-
|
|
62
|
-
while (attempts < maxAttempts) {
|
|
63
|
-
const status = await zalo.videoUpload.checkVideoStatus(accessToken, uploadResult.token);
|
|
64
|
-
|
|
65
|
-
console.log(`🔍 Attempt ${attempts + 1}: Status ${status.status} - ${status.status_message} (${status.convert_percent}%)`);
|
|
66
|
-
|
|
67
|
-
if (status.status === VideoUploadStatus.SUCCESS && status.video_id) {
|
|
68
|
-
console.log(`✅ Manual upload completed!`);
|
|
69
|
-
console.log(`📹 Video ID: ${status.video_id}`);
|
|
70
|
-
break;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (status.status === VideoUploadStatus.FAILED) {
|
|
74
|
-
console.error(`❌ Manual upload failed: ${status.status_message}`);
|
|
75
|
-
break;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (status.status === VideoUploadStatus.LOCKED) {
|
|
79
|
-
console.error(`🔒 Video has been locked: ${status.status_message}`);
|
|
80
|
-
break;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (status.status === VideoUploadStatus.DELETED) {
|
|
84
|
-
console.error(`🗑️ Video has been deleted: ${status.status_message}`);
|
|
85
|
-
break;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Continue polling for PROCESSING or UNKNOWN status
|
|
89
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
90
|
-
attempts++;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (attempts >= maxAttempts) {
|
|
94
|
-
console.error(`⏰ Manual upload timeout after ${maxAttempts} attempts`);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Method 3: Upload from URL (bonus feature)
|
|
98
|
-
console.log("\n🌐 Method 3: Upload video from URL");
|
|
99
|
-
|
|
100
|
-
try {
|
|
101
|
-
const urlUploadResult = await zalo.videoUpload.uploadVideoFromUrl(
|
|
102
|
-
accessToken,
|
|
103
|
-
"https://example.com/sample-video.mp4"
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
console.log(`🎫 URL upload token: ${urlUploadResult.token}`);
|
|
107
|
-
|
|
108
|
-
// Wait for completion
|
|
109
|
-
const urlFinalResult = await zalo.videoUpload.waitForUploadCompletion(
|
|
110
|
-
accessToken,
|
|
111
|
-
urlUploadResult.token
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
console.log(`✅ URL upload completed!`);
|
|
115
|
-
console.log(`📹 Video ID: ${urlFinalResult.video_id}`);
|
|
116
|
-
} catch (error) {
|
|
117
|
-
console.log(`ℹ️ URL upload example skipped (URL not accessible): ${error.message}`);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
} catch (error) {
|
|
121
|
-
console.error("❌ Error in video upload example:", error);
|
|
122
|
-
|
|
123
|
-
if (error.message.includes("Token cannot be empty")) {
|
|
124
|
-
console.log("💡 Please set your access token in the example");
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (error.message.includes("Video file size exceeds")) {
|
|
128
|
-
console.log("💡 Video file is too large. Maximum size is 50MB");
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (error.message.includes("Unsupported video format")) {
|
|
132
|
-
console.log("💡 Only MP4 and AVI formats are supported");
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Get human-readable status description
|
|
139
|
-
*/
|
|
140
|
-
function getStatusDescription(status: number): string {
|
|
141
|
-
switch (status) {
|
|
142
|
-
case VideoUploadStatus.UNKNOWN:
|
|
143
|
-
return "Trạng thái không xác định";
|
|
144
|
-
case VideoUploadStatus.SUCCESS:
|
|
145
|
-
return "Video đã được xử lý thành công và có thể sử dụng";
|
|
146
|
-
case VideoUploadStatus.LOCKED:
|
|
147
|
-
return "Video đã bị khóa";
|
|
148
|
-
case VideoUploadStatus.PROCESSING:
|
|
149
|
-
return "Video đang được xử lý";
|
|
150
|
-
case VideoUploadStatus.FAILED:
|
|
151
|
-
return "Video xử lý thất bại";
|
|
152
|
-
case VideoUploadStatus.DELETED:
|
|
153
|
-
return "Video đã bị xóa";
|
|
154
|
-
default:
|
|
155
|
-
return "Unknown status";
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Example usage with error handling and retry logic
|
|
161
|
-
*/
|
|
162
|
-
async function robustVideoUploadExample() {
|
|
163
|
-
const zalo = new ZaloSDK();
|
|
164
|
-
const accessToken = "YOUR_ACCESS_TOKEN";
|
|
165
|
-
|
|
166
|
-
try {
|
|
167
|
-
const videoBuffer = fs.readFileSync('./path/to/your/video.mp4');
|
|
168
|
-
|
|
169
|
-
// Retry logic for robust upload
|
|
170
|
-
const maxRetries = 3;
|
|
171
|
-
let attempt = 0;
|
|
172
|
-
|
|
173
|
-
while (attempt < maxRetries) {
|
|
174
|
-
try {
|
|
175
|
-
console.log(`🔄 Upload attempt ${attempt + 1}/${maxRetries}`);
|
|
176
|
-
|
|
177
|
-
const result = await zalo.videoUpload.uploadVideoAndWaitForCompletion(
|
|
178
|
-
accessToken,
|
|
179
|
-
videoBuffer,
|
|
180
|
-
"robust-upload.mp4",
|
|
181
|
-
10 * 60 * 1000, // 10 minutes timeout
|
|
182
|
-
3 * 1000 // 3 seconds polling interval
|
|
183
|
-
);
|
|
184
|
-
|
|
185
|
-
console.log(`✅ Upload successful on attempt ${attempt + 1}`);
|
|
186
|
-
console.log(`📹 Video ID: ${result.video_id}`);
|
|
187
|
-
return result;
|
|
188
|
-
|
|
189
|
-
} catch (error) {
|
|
190
|
-
attempt++;
|
|
191
|
-
console.log(`❌ Attempt ${attempt} failed: ${error.message}`);
|
|
192
|
-
|
|
193
|
-
if (attempt >= maxRetries) {
|
|
194
|
-
throw new Error(`Upload failed after ${maxRetries} attempts: ${error.message}`);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// Wait before retry
|
|
198
|
-
console.log(`⏳ Waiting 10 seconds before retry...`);
|
|
199
|
-
await new Promise(resolve => setTimeout(resolve, 10000));
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
} catch (error) {
|
|
204
|
-
console.error("❌ Robust upload failed:", error);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Run examples
|
|
209
|
-
if (require.main === module) {
|
|
210
|
-
console.log("🎬 Zalo Video Upload Combined Example");
|
|
211
|
-
console.log("=====================================\n");
|
|
212
|
-
|
|
213
|
-
videoUploadCombinedExample()
|
|
214
|
-
.then(() => {
|
|
215
|
-
console.log("\n🎯 Basic example completed");
|
|
216
|
-
return robustVideoUploadExample();
|
|
217
|
-
})
|
|
218
|
-
.then(() => {
|
|
219
|
-
console.log("\n🛡️ Robust example completed");
|
|
220
|
-
console.log("\n✨ All examples completed successfully!");
|
|
221
|
-
})
|
|
222
|
-
.catch(error => {
|
|
223
|
-
console.error("\n💥 Example failed:", error);
|
|
224
|
-
process.exit(1);
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
export { videoUploadCombinedExample, robustVideoUploadExample };
|
|
@@ -1,285 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Ví dụ sử dụng các hàm helper để phân loại tin nhắn webhook
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
isUserMessageEvent,
|
|
7
|
-
isGroupMessageEvent,
|
|
8
|
-
isOAToUserMessageEvent,
|
|
9
|
-
isOAToGroupMessageEvent,
|
|
10
|
-
getMessageDirection,
|
|
11
|
-
WebhookEvent,
|
|
12
|
-
UserMessageWebhookEvent,
|
|
13
|
-
GroupWebhookEvent,
|
|
14
|
-
OAMessageWebhookEvent,
|
|
15
|
-
} from '@warriorteam/redai-zalo-sdk';
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Service xử lý webhook với phân loại tin nhắn
|
|
19
|
-
*/
|
|
20
|
-
export class ZaloWebhookMessageHandler {
|
|
21
|
-
/**
|
|
22
|
-
* Xử lý webhook event chính
|
|
23
|
-
*/
|
|
24
|
-
public handleWebhook(event: WebhookEvent): void {
|
|
25
|
-
console.log('=== Webhook Event Received ===');
|
|
26
|
-
console.log('Event Name:', event.event_name);
|
|
27
|
-
console.log('Timestamp:', event.timestamp);
|
|
28
|
-
|
|
29
|
-
// Phương pháp 1: Sử dụng các hàm kiểm tra riêng lẻ
|
|
30
|
-
this.classifyBySpecificChecks(event);
|
|
31
|
-
|
|
32
|
-
// Phương pháp 2: Sử dụng getMessageDirection
|
|
33
|
-
this.classifyByDirection(event);
|
|
34
|
-
|
|
35
|
-
// Xử lý tin nhắn dựa trên loại
|
|
36
|
-
this.processMessage(event);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Phân loại bằng các hàm kiểm tra riêng lẻ
|
|
41
|
-
*/
|
|
42
|
-
private classifyBySpecificChecks(event: WebhookEvent): void {
|
|
43
|
-
console.log('\n--- Classification by Specific Checks ---');
|
|
44
|
-
|
|
45
|
-
if (isUserMessageEvent(event)) {
|
|
46
|
-
console.log('✅ Tin nhắn từ người dùng cá nhân');
|
|
47
|
-
this.logUserMessageDetails(event);
|
|
48
|
-
} else if (isGroupMessageEvent(event)) {
|
|
49
|
-
console.log('✅ Tin nhắn từ group');
|
|
50
|
-
this.logGroupMessageDetails(event);
|
|
51
|
-
} else if (isOAToUserMessageEvent(event)) {
|
|
52
|
-
console.log('✅ OA gửi tin nhắn cho người dùng cá nhân');
|
|
53
|
-
this.logOAToUserDetails(event);
|
|
54
|
-
} else if (isOAToGroupMessageEvent(event)) {
|
|
55
|
-
console.log('✅ OA gửi tin nhắn tới group');
|
|
56
|
-
this.logOAToGroupDetails(event);
|
|
57
|
-
} else {
|
|
58
|
-
console.log('❓ Sự kiện không phải tin nhắn hoặc không xác định');
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Phân loại bằng getMessageDirection
|
|
64
|
-
*/
|
|
65
|
-
private classifyByDirection(event: WebhookEvent): void {
|
|
66
|
-
console.log('\n--- Classification by Direction ---');
|
|
67
|
-
|
|
68
|
-
const messageInfo = getMessageDirection(event);
|
|
69
|
-
console.log(`Direction: ${messageInfo.direction}`);
|
|
70
|
-
console.log(`Target: ${messageInfo.target}`);
|
|
71
|
-
console.log(`Description: ${messageInfo.description}`);
|
|
72
|
-
|
|
73
|
-
// Xử lý dựa trên direction và target
|
|
74
|
-
const key = `${messageInfo.direction}-${messageInfo.target}`;
|
|
75
|
-
switch (key) {
|
|
76
|
-
case 'incoming-user':
|
|
77
|
-
console.log('🔵 Xử lý tin nhắn đến từ user cá nhân');
|
|
78
|
-
break;
|
|
79
|
-
case 'incoming-group':
|
|
80
|
-
console.log('🟢 Xử lý tin nhắn đến từ group');
|
|
81
|
-
break;
|
|
82
|
-
case 'outgoing-user':
|
|
83
|
-
console.log('🟡 Xử lý tin nhắn OA gửi cho user');
|
|
84
|
-
break;
|
|
85
|
-
case 'outgoing-group':
|
|
86
|
-
console.log('🟠 Xử lý tin nhắn OA gửi tới group');
|
|
87
|
-
break;
|
|
88
|
-
default:
|
|
89
|
-
console.log('⚪ Sự kiện không xác định');
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Xử lý tin nhắn dựa trên loại
|
|
95
|
-
*/
|
|
96
|
-
private processMessage(event: WebhookEvent): void {
|
|
97
|
-
console.log('\n--- Message Processing ---');
|
|
98
|
-
|
|
99
|
-
if (isUserMessageEvent(event)) {
|
|
100
|
-
this.processUserMessage(event);
|
|
101
|
-
} else if (isGroupMessageEvent(event)) {
|
|
102
|
-
this.processGroupMessage(event);
|
|
103
|
-
} else if (isOAToUserMessageEvent(event)) {
|
|
104
|
-
this.processOAToUserMessage(event);
|
|
105
|
-
} else if (isOAToGroupMessageEvent(event)) {
|
|
106
|
-
this.processOAToGroupMessage(event);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Xử lý tin nhắn từ user cá nhân
|
|
112
|
-
*/
|
|
113
|
-
private processUserMessage(event: UserMessageWebhookEvent): void {
|
|
114
|
-
console.log('Processing user message...');
|
|
115
|
-
|
|
116
|
-
// Logic xử lý tin nhắn từ user cá nhân
|
|
117
|
-
// - Lưu vào database
|
|
118
|
-
// - Trigger AI response
|
|
119
|
-
// - Update conversation state
|
|
120
|
-
|
|
121
|
-
console.log('✅ User message processed');
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Xử lý tin nhắn từ group
|
|
126
|
-
*/
|
|
127
|
-
private processGroupMessage(event: GroupWebhookEvent): void {
|
|
128
|
-
console.log('Processing group message...');
|
|
129
|
-
|
|
130
|
-
// Logic xử lý tin nhắn từ group
|
|
131
|
-
// - Check if OA is mentioned
|
|
132
|
-
// - Apply group-specific rules
|
|
133
|
-
// - Handle group moderation
|
|
134
|
-
|
|
135
|
-
console.log('✅ Group message processed');
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Xử lý tin nhắn OA gửi cho user
|
|
140
|
-
*/
|
|
141
|
-
private processOAToUserMessage(event: OAMessageWebhookEvent): void {
|
|
142
|
-
console.log('Processing OA to user message...');
|
|
143
|
-
|
|
144
|
-
// Logic xử lý tin nhắn OA gửi
|
|
145
|
-
// - Log outbound message
|
|
146
|
-
// - Update delivery status
|
|
147
|
-
// - Track engagement metrics
|
|
148
|
-
|
|
149
|
-
console.log('✅ OA to user message processed');
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Xử lý tin nhắn OA gửi tới group
|
|
154
|
-
*/
|
|
155
|
-
private processOAToGroupMessage(event: GroupWebhookEvent): void {
|
|
156
|
-
console.log('Processing OA to group message...');
|
|
157
|
-
|
|
158
|
-
// Logic xử lý tin nhắn OA gửi tới group
|
|
159
|
-
// - Log group broadcast
|
|
160
|
-
// - Track group engagement
|
|
161
|
-
// - Update group statistics
|
|
162
|
-
|
|
163
|
-
console.log('✅ OA to group message processed');
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Log chi tiết tin nhắn user
|
|
168
|
-
*/
|
|
169
|
-
private logUserMessageDetails(event: UserMessageWebhookEvent): void {
|
|
170
|
-
console.log(` - Sender ID: ${event.sender.id}`);
|
|
171
|
-
console.log(` - Recipient ID: ${event.recipient.id}`);
|
|
172
|
-
if ('message' in event && event.message.text) {
|
|
173
|
-
console.log(` - Text: ${event.message.text}`);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Log chi tiết tin nhắn group
|
|
179
|
-
*/
|
|
180
|
-
private logGroupMessageDetails(event: GroupWebhookEvent): void {
|
|
181
|
-
console.log(` - Sender ID: ${event.sender.id}`);
|
|
182
|
-
console.log(` - Group ID: ${event.recipient.id}`);
|
|
183
|
-
if ('oa_id' in event) {
|
|
184
|
-
console.log(` - OA ID: ${event.oa_id}`);
|
|
185
|
-
}
|
|
186
|
-
if ('message' in event && event.message.text) {
|
|
187
|
-
console.log(` - Text: ${event.message.text}`);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Log chi tiết OA to user
|
|
193
|
-
*/
|
|
194
|
-
private logOAToUserDetails(event: OAMessageWebhookEvent): void {
|
|
195
|
-
console.log(` - OA ID: ${event.sender.id}`);
|
|
196
|
-
console.log(` - User ID: ${event.recipient.id}`);
|
|
197
|
-
if ('message' in event && event.message.text) {
|
|
198
|
-
console.log(` - Text: ${event.message.text}`);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Log chi tiết OA to group
|
|
204
|
-
*/
|
|
205
|
-
private logOAToGroupDetails(event: GroupWebhookEvent): void {
|
|
206
|
-
console.log(` - OA ID: ${event.sender.id}`);
|
|
207
|
-
console.log(` - Group ID: ${event.recipient.id}`);
|
|
208
|
-
if ('oa_id' in event) {
|
|
209
|
-
console.log(` - OA ID: ${event.oa_id}`);
|
|
210
|
-
}
|
|
211
|
-
if ('message' in event && event.message.text) {
|
|
212
|
-
console.log(` - Text: ${event.message.text}`);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Ví dụ sử dụng
|
|
219
|
-
*/
|
|
220
|
-
export function exampleUsage(): void {
|
|
221
|
-
const handler = new ZaloWebhookMessageHandler();
|
|
222
|
-
|
|
223
|
-
// Ví dụ 1: Tin nhắn từ user cá nhân
|
|
224
|
-
const userMessage = {
|
|
225
|
-
app_id: 'test-app',
|
|
226
|
-
user_id_by_app: 'test-user',
|
|
227
|
-
event_name: 'user_send_text',
|
|
228
|
-
timestamp: '1234567890',
|
|
229
|
-
sender: { id: 'user123' },
|
|
230
|
-
recipient: { id: 'oa123' },
|
|
231
|
-
message: { msg_id: 'msg123', text: 'Xin chào!' }
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
console.log('=== Example 1: User Message ===');
|
|
235
|
-
handler.handleWebhook(userMessage as any);
|
|
236
|
-
|
|
237
|
-
// Ví dụ 2: Tin nhắn từ group
|
|
238
|
-
const groupMessage = {
|
|
239
|
-
app_id: 'test-app',
|
|
240
|
-
user_id_by_app: 'test-user',
|
|
241
|
-
event_name: 'user_send_group_text',
|
|
242
|
-
timestamp: '1234567890',
|
|
243
|
-
oa_id: 'oa123',
|
|
244
|
-
sender: { id: 'user456' },
|
|
245
|
-
recipient: { id: 'group789' },
|
|
246
|
-
message: { msg_id: 'msg456', text: 'Hello group!' }
|
|
247
|
-
};
|
|
248
|
-
|
|
249
|
-
console.log('\n=== Example 2: Group Message ===');
|
|
250
|
-
handler.handleWebhook(groupMessage as any);
|
|
251
|
-
|
|
252
|
-
// Ví dụ 3: OA gửi cho user
|
|
253
|
-
const oaToUserMessage = {
|
|
254
|
-
app_id: 'test-app',
|
|
255
|
-
user_id_by_app: 'test-user',
|
|
256
|
-
event_name: 'oa_send_text',
|
|
257
|
-
timestamp: '1234567890',
|
|
258
|
-
sender: { id: 'oa123' },
|
|
259
|
-
recipient: { id: 'user789' },
|
|
260
|
-
message: { msg_id: 'msg789', text: 'Cảm ơn bạn đã liên hệ!' }
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
console.log('\n=== Example 3: OA to User Message ===');
|
|
264
|
-
handler.handleWebhook(oaToUserMessage as any);
|
|
265
|
-
|
|
266
|
-
// Ví dụ 4: OA gửi tới group
|
|
267
|
-
const oaToGroupMessage = {
|
|
268
|
-
app_id: 'test-app',
|
|
269
|
-
user_id_by_app: 'test-user',
|
|
270
|
-
event_name: 'oa_send_group_text',
|
|
271
|
-
timestamp: '1234567890',
|
|
272
|
-
oa_id: 'oa123',
|
|
273
|
-
sender: { id: 'oa123' },
|
|
274
|
-
recipient: { id: 'group456' },
|
|
275
|
-
message: { msg_id: 'msg101', text: 'Thông báo từ OA!' }
|
|
276
|
-
};
|
|
277
|
-
|
|
278
|
-
console.log('\n=== Example 4: OA to Group Message ===');
|
|
279
|
-
handler.handleWebhook(oaToGroupMessage as any);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// Chạy ví dụ nếu file được execute trực tiếp
|
|
283
|
-
if (require.main === module) {
|
|
284
|
-
exampleUsage();
|
|
285
|
-
}
|