@warriorteam/redai-zalo-sdk 1.26.1 → 1.27.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.
@@ -1,288 +0,0 @@
1
- import {
2
- GroupMessageService,
3
- GroupMessageItem,
4
- SendMessageListToGroupRequest,
5
- SendMessageListToMultipleGroupsRequest,
6
- GroupMessageProgressInfo,
7
- MultipleGroupsProgressInfo
8
- } from "../src/services/group-message.service";
9
- import { ZaloClient } from "../src/clients/zalo-client";
10
-
11
- /**
12
- * Ví dụ sử dụng API gửi danh sách tin nhắn tới 1 group với callback tracking
13
- */
14
- async function sendMessageListToGroupExample() {
15
- // Khởi tạo Zalo client và group message service
16
- const zaloClient = new ZaloClient();
17
- const groupMessageService = new GroupMessageService(zaloClient);
18
-
19
- // Thông tin cấu hình
20
- const accessToken = "YOUR_ACCESS_TOKEN";
21
- const groupId = "GROUP_ID_TO_SEND_TO";
22
-
23
- // Định nghĩa danh sách tin nhắn thông báo
24
- const messages: GroupMessageItem[] = [
25
- {
26
- type: "text",
27
- text: "📢 THÔNG BÁO QUAN TRỌNG",
28
- delay: 2000,
29
- },
30
- {
31
- type: "text",
32
- text: "🔧 Hệ thống sẽ bảo trì từ 2:00 - 4:00 sáng ngày mai (15/09/2024)",
33
- delay: 1500,
34
- },
35
- {
36
- type: "image",
37
- imageUrl: "https://example.com/maintenance-schedule.jpg",
38
- caption: "Lịch trình bảo trì chi tiết",
39
- delay: 2000,
40
- },
41
- {
42
- type: "text",
43
- text: "⚠️ Trong thời gian bảo trì, các dịch vụ sau sẽ tạm ngưng:\n• Website chính\n• Mobile App\n• API Services",
44
- delay: 1500,
45
- },
46
- {
47
- type: "sticker",
48
- stickerId: "MAINTENANCE_STICKER_ID",
49
- delay: 1000,
50
- },
51
- {
52
- type: "text",
53
- text: "📞 Hotline hỗ trợ khẩn cấp: 1900-xxxx\n📧 Email: support@company.com",
54
- },
55
- ];
56
-
57
- // Callback function để tracking tiến trình
58
- const onProgress = (progress: GroupMessageProgressInfo) => {
59
- const percentage = Math.round(((progress.messageIndex + 1) / progress.totalMessages) * 100);
60
-
61
- switch (progress.status) {
62
- case 'started':
63
- console.log(`🚀 [${percentage}%] Bắt đầu gửi tin nhắn ${progress.messageIndex + 1}/${progress.totalMessages} (${progress.messageType})`);
64
- break;
65
-
66
- case 'completed':
67
- const duration = progress.endTime ? progress.endTime - progress.startTime : 0;
68
- console.log(`✅ [${percentage}%] Hoàn thành tin nhắn ${progress.messageIndex + 1}/${progress.totalMessages} - ${duration}ms`);
69
- break;
70
-
71
- case 'failed':
72
- const failDuration = progress.endTime ? progress.endTime - progress.startTime : 0;
73
- console.log(`❌ [${percentage}%] Thất bại tin nhắn ${progress.messageIndex + 1}/${progress.totalMessages} - ${failDuration}ms - Lỗi: ${progress.error}`);
74
- break;
75
- }
76
- };
77
-
78
- // Tạo request
79
- const request: SendMessageListToGroupRequest = {
80
- accessToken,
81
- groupId,
82
- messages,
83
- defaultDelay: 1000, // Delay mặc định 1 giây giữa các tin nhắn
84
- onProgress, // Callback tracking
85
- };
86
-
87
- try {
88
- console.log("📢 Bắt đầu gửi danh sách tin nhắn thông báo tới group...");
89
- console.log(`👥 Group ID: ${groupId}`);
90
- console.log(`📝 Tổng số tin nhắn: ${messages.length}`);
91
- console.log("─".repeat(60));
92
-
93
- // Gửi danh sách tin nhắn tới group
94
- const result = await groupMessageService.sendMessageListToGroup(request);
95
-
96
- console.log("─".repeat(60));
97
- console.log("🎊 KẾT QUẢ:");
98
- console.log(`📝 Tổng tin nhắn: ${result.totalMessages}`);
99
- console.log(`✅ Thành công: ${result.successfulMessages} (${Math.round((result.successfulMessages / result.totalMessages) * 100)}%)`);
100
- console.log(`❌ Thất bại: ${result.failedMessages} (${Math.round((result.failedMessages / result.totalMessages) * 100)}%)`);
101
- console.log(`⏱️ Tổng thời gian: ${result.totalDuration}ms (${Math.round(result.totalDuration / 1000)}s)`);
102
-
103
- // In chi tiết từng tin nhắn
104
- console.log("\n📋 CHI TIẾT TỪNG TIN NHẮN:");
105
- result.messageResults.forEach((messageResult, index) => {
106
- const status = messageResult.success ? "✅" : "❌";
107
- console.log(`${status} [${index + 1}] ${messageResult.messageType} - ${messageResult.duration}ms`);
108
-
109
- if (!messageResult.success && messageResult.error) {
110
- console.log(` ❌ Lỗi: ${messageResult.error}`);
111
- }
112
- });
113
-
114
- } catch (error) {
115
- console.error("❌ Lỗi khi gửi danh sách tin nhắn tới group:", error);
116
- }
117
- }
118
-
119
- /**
120
- * Ví dụ gửi danh sách tin nhắn tới nhiều groups
121
- */
122
- async function sendMessageListToMultipleGroupsExample() {
123
- const zaloClient = new ZaloClient();
124
- const groupMessageService = new GroupMessageService(zaloClient);
125
-
126
- const accessToken = "YOUR_ACCESS_TOKEN";
127
- const groupIds = [
128
- "GROUP_ID_1",
129
- "GROUP_ID_2",
130
- "GROUP_ID_3",
131
- "GROUP_ID_4"
132
- ];
133
-
134
- // Danh sách tin nhắn marketing
135
- const messages: GroupMessageItem[] = [
136
- {
137
- type: "text",
138
- text: "🎉 FLASH SALE 24H - GIẢM GIÁ SỐC!",
139
- delay: 2000,
140
- },
141
- {
142
- type: "image",
143
- imageUrl: "https://example.com/flash-sale-banner.jpg",
144
- caption: "🔥 Giảm tới 70% + Freeship toàn quốc",
145
- delay: 3000,
146
- },
147
- {
148
- type: "text",
149
- text: "⏰ Chỉ còn 12 giờ! Số lượng có hạn!\n🛒 Mua ngay: https://shop.example.com/flash-sale",
150
- delay: 1500,
151
- },
152
- {
153
- type: "sticker",
154
- stickerId: "SALE_STICKER_ID",
155
- },
156
- ];
157
-
158
- // Callback tracking cho multiple groups
159
- let completedGroups = 0;
160
- const onProgress = (progress: MultipleGroupsProgressInfo) => {
161
- switch (progress.status) {
162
- case 'started':
163
- console.log(`🎯 Bắt đầu gửi tới Group ${progress.groupIndex + 1}/${progress.totalGroups} (${progress.groupId})`);
164
- break;
165
-
166
- case 'completed':
167
- completedGroups++;
168
- const successRate = progress.result ?
169
- Math.round((progress.result.successfulMessages / progress.result.totalMessages) * 100) : 0;
170
- console.log(`✅ Hoàn thành Group ${completedGroups}/${progress.totalGroups} - Thành công: ${successRate}%`);
171
- break;
172
-
173
- case 'failed':
174
- console.log(`❌ Thất bại Group ${progress.groupIndex + 1}/${progress.totalGroups} - Lỗi: ${progress.error}`);
175
- break;
176
- }
177
- };
178
-
179
- const request: SendMessageListToMultipleGroupsRequest = {
180
- accessToken,
181
- groupIds,
182
- messages,
183
- defaultDelay: 1000, // Delay giữa tin nhắn
184
- delayBetweenGroups: 3000, // Delay 3 giây giữa các groups
185
- onProgress,
186
- };
187
-
188
- try {
189
- console.log("🎯 Bắt đầu chiến dịch marketing tới nhiều groups...");
190
- console.log(`👥 Tổng số groups: ${groupIds.length}`);
191
- console.log(`📝 Tổng số tin nhắn mỗi group: ${messages.length}`);
192
- console.log(`📊 Tổng số tin nhắn sẽ gửi: ${groupIds.length * messages.length}`);
193
- console.log("─".repeat(60));
194
-
195
- const result = await groupMessageService.sendMessageListToMultipleGroups(request);
196
-
197
- console.log("─".repeat(60));
198
- console.log("🎊 KẾT QUẢ TỔNG QUAN:");
199
- console.log(`👥 Tổng groups: ${result.totalGroups}`);
200
- console.log(`✅ Groups thành công: ${result.successfulGroups} (${Math.round((result.successfulGroups / result.totalGroups) * 100)}%)`);
201
- console.log(`❌ Groups thất bại: ${result.failedGroups} (${Math.round((result.failedGroups / result.totalGroups) * 100)}%)`);
202
- console.log(`⏱️ Tổng thời gian: ${result.totalDuration}ms (${Math.round(result.totalDuration / 1000)}s)`);
203
-
204
- console.log("\n📊 THỐNG KÊ TIN NHẮN:");
205
- console.log(`✅ Tin nhắn thành công: ${result.messageStats.totalSuccessfulMessages}`);
206
- console.log(`❌ Tin nhắn thất bại: ${result.messageStats.totalFailedMessages}`);
207
- console.log(`📝 Tổng tin nhắn: ${result.messageStats.totalMessages}`);
208
- console.log(`📈 Tỷ lệ thành công: ${Math.round((result.messageStats.totalSuccessfulMessages / result.messageStats.totalMessages) * 100)}%`);
209
-
210
- // In chi tiết từng group
211
- console.log("\n📋 CHI TIẾT TỪNG GROUP:");
212
- result.groupResults.forEach((groupResult, index) => {
213
- const status = groupResult.success ? "✅" : "❌";
214
- const successRate = groupResult.messageListResult ?
215
- Math.round((groupResult.messageListResult.successfulMessages / groupResult.messageListResult.totalMessages) * 100) : 0;
216
-
217
- console.log(`${status} Group ${index + 1}: ${groupResult.groupId} - ${groupResult.duration}ms - Thành công: ${successRate}%`);
218
-
219
- if (!groupResult.success && groupResult.error) {
220
- console.log(` ❌ Lỗi: ${groupResult.error}`);
221
- }
222
- });
223
-
224
- } catch (error) {
225
- console.error("❌ Lỗi khi gửi danh sách tin nhắn tới nhiều groups:", error);
226
- }
227
- }
228
-
229
- /**
230
- * Ví dụ gửi tin nhắn mention tới group
231
- */
232
- async function sendMentionMessageListExample() {
233
- const zaloClient = new ZaloClient();
234
- const groupMessageService = new GroupMessageService(zaloClient);
235
-
236
- const accessToken = "YOUR_ACCESS_TOKEN";
237
- const groupId = "GROUP_ID";
238
-
239
- const messages: GroupMessageItem[] = [
240
- {
241
- type: "text",
242
- text: "🎯 Cuộc họp quan trọng sắp diễn ra!",
243
- delay: 1000,
244
- },
245
- {
246
- type: "mention",
247
- text: "@Admin @Manager Vui lòng chuẩn bị tài liệu cho cuộc họp lúc 14:00",
248
- mentions: [
249
- { user_id: "ADMIN_USER_ID", offset: 0, length: 6 },
250
- { user_id: "MANAGER_USER_ID", offset: 7, length: 8 }
251
- ],
252
- delay: 2000,
253
- },
254
- {
255
- type: "text",
256
- text: "📋 Agenda:\n1. Báo cáo tháng\n2. Kế hoạch quý mới\n3. Q&A",
257
- },
258
- ];
259
-
260
- const onProgress = (progress: GroupMessageProgressInfo) => {
261
- if (progress.status === 'completed') {
262
- console.log(`✅ Đã gửi tin nhắn ${progress.messageIndex + 1}: ${progress.messageType}`);
263
- } else if (progress.status === 'failed') {
264
- console.log(`❌ Gửi thất bại tin nhắn ${progress.messageIndex + 1}: ${progress.error}`);
265
- }
266
- };
267
-
268
- try {
269
- const result = await groupMessageService.sendMessageListToGroup({
270
- accessToken,
271
- groupId,
272
- messages,
273
- defaultDelay: 1500,
274
- onProgress,
275
- });
276
-
277
- console.log(`\n📢 Đã gửi thông báo cuộc họp: ${result.successfulMessages}/${result.totalMessages} tin nhắn thành công`);
278
- } catch (error) {
279
- console.error("❌ Lỗi gửi thông báo cuộc họp:", error);
280
- }
281
- }
282
-
283
- // Export các function để sử dụng
284
- export {
285
- sendMessageListToGroupExample,
286
- sendMessageListToMultipleGroupsExample,
287
- sendMentionMessageListExample,
288
- };
@@ -1,179 +0,0 @@
1
- /**
2
- * Example: Official Account Authentication with PKCE
3
- * Demonstrates how to use the updated createOAAuthUrl method with PKCE support
4
- */
5
-
6
- import { ZaloSDK } from '../src';
7
-
8
- // Initialize SDK
9
- const sdk = new ZaloSDK({
10
- appId: 'your_app_id',
11
- appSecret: 'your_app_secret',
12
- });
13
-
14
- // Example 1: Basic OA Auth without PKCE
15
- async function basicOAAuth() {
16
- console.log('=== Basic OA Auth (without PKCE) ===');
17
-
18
- const redirectUri = 'https://your-app.com/callback';
19
-
20
- // Create auth URL - state will be auto-generated with 'zalo_oa_' prefix
21
- const authResult = sdk.auth.createOAAuthUrl(redirectUri);
22
-
23
- console.log('Authorization URL:', authResult.url);
24
- console.log('Generated State:', authResult.state);
25
-
26
- // You can also provide custom state
27
- const customAuthResult = sdk.auth.createOAAuthUrl(redirectUri, 'my_custom_state');
28
- console.log('Custom State URL:', customAuthResult.url);
29
- console.log('Custom State:', customAuthResult.state);
30
- }
31
-
32
- // Example 2: OA Auth with PKCE for enhanced security (Manual PKCE)
33
- async function oaAuthWithPKCE() {
34
- console.log('\n=== OA Auth with Manual PKCE ===');
35
-
36
- const redirectUri = 'https://your-app.com/callback';
37
-
38
- // Step 1: Generate PKCE configuration
39
- const pkce = sdk.auth.generatePKCE();
40
- console.log('Generated PKCE:');
41
- console.log('- Code Verifier:', pkce.code_verifier);
42
- console.log('- Code Challenge:', pkce.code_challenge);
43
- console.log('- Challenge Method:', pkce.code_challenge_method);
44
-
45
- // Step 2: Create auth URL with manual PKCE
46
- const authResult = sdk.auth.createOAAuthUrl(redirectUri, undefined, pkce, true);
47
-
48
- console.log('\nAuthorization URL with PKCE:', authResult.url);
49
- console.log('Generated State:', authResult.state);
50
- console.log('Used PKCE:', authResult.pkce);
51
-
52
- // IMPORTANT: Store the code_verifier and state for later use
53
- // You'll need these when exchanging the authorization code for access token
54
- console.log('\n⚠️ IMPORTANT: Store these values for token exchange:');
55
- console.log('- Code Verifier:', pkce.code_verifier);
56
- console.log('- State:', authResult.state);
57
-
58
- return { pkce, state: authResult.state };
59
- }
60
-
61
- // Example 2b: OA Auth with Auto-Generated PKCE
62
- async function oaAuthWithAutoPKCE() {
63
- console.log('\n=== OA Auth with Auto-Generated PKCE ===');
64
-
65
- const redirectUri = 'https://your-app.com/callback';
66
-
67
- // Create auth URL with auto-generated PKCE (pkce=undefined, usePkce=true)
68
- const authResult = sdk.auth.createOAAuthUrl(redirectUri, undefined, undefined, true);
69
-
70
- console.log('Authorization URL with Auto PKCE:', authResult.url);
71
- console.log('Generated State:', authResult.state);
72
- console.log('Auto-Generated PKCE:', authResult.pkce);
73
-
74
- // IMPORTANT: Store the auto-generated PKCE and state
75
- console.log('\n⚠️ IMPORTANT: Store these auto-generated values:');
76
- console.log('- Code Verifier:', authResult.pkce?.code_verifier);
77
- console.log('- State:', authResult.state);
78
-
79
- return authResult;
80
- }
81
-
82
- // Example 3: Complete flow - Authorization + Token Exchange
83
- async function completeOAFlow() {
84
- console.log('\n=== Complete OA Flow with PKCE ===');
85
-
86
- const redirectUri = 'https://your-app.com/callback';
87
-
88
- // Step 1: Generate PKCE and create auth URL
89
- const pkce = sdk.auth.generatePKCE();
90
- const authResult = sdk.auth.createOAAuthUrl(redirectUri, 'my_oa_flow', pkce);
91
-
92
- console.log('1. Redirect user to:', authResult.url);
93
- console.log('2. Store state and code_verifier:', {
94
- state: authResult.state,
95
- code_verifier: pkce.code_verifier
96
- });
97
-
98
- // Step 2: After user authorizes and returns with code
99
- // (This would happen in your callback handler)
100
- const simulateCallback = async (authorizationCode: string, returnedState: string) => {
101
- console.log('\n3. User returned with authorization code');
102
-
103
- // Verify state matches
104
- if (returnedState !== authResult.state) {
105
- throw new Error('State mismatch - possible CSRF attack');
106
- }
107
-
108
- // Step 3: Exchange code for access token with PKCE
109
- try {
110
- const tokenResult = await sdk.auth.getOAAccessToken({
111
- app_id: 'your_app_id',
112
- app_secret: 'your_app_secret',
113
- code: authorizationCode,
114
- redirect_uri: redirectUri,
115
- code_verifier: pkce.code_verifier, // Include code_verifier for PKCE
116
- });
117
-
118
- console.log('4. Successfully obtained access token:', {
119
- access_token: tokenResult.access_token.substring(0, 20) + '...',
120
- expires_in: tokenResult.expires_in,
121
- has_refresh_token: !!tokenResult.refresh_token
122
- });
123
-
124
- return tokenResult;
125
- } catch (error) {
126
- console.error('Failed to exchange code for token:', error);
127
- throw error;
128
- }
129
- };
130
-
131
- // Simulate the callback (in real app, this would be handled by your callback endpoint)
132
- console.log('\n--- Simulating callback ---');
133
- // await simulateCallback('simulated_auth_code', authResult.state);
134
- }
135
-
136
- // Example 4: Using getAuthUrls method
137
- async function getAuthUrlsExample() {
138
- console.log('\n=== Get Auth URLs ===');
139
-
140
- const redirectUri = 'https://your-app.com/callback';
141
- const pkce = sdk.auth.generatePKCE();
142
-
143
- const authUrls = sdk.auth.getAuthUrls(redirectUri, pkce);
144
-
145
- console.log('All auth URLs:', {
146
- oa_auth_url: authUrls.oa_auth_url,
147
- social_auth_url: authUrls.social_auth_url,
148
- token_url: authUrls.token_url,
149
- refresh_url: authUrls.refresh_url
150
- });
151
- }
152
-
153
- // Run examples
154
- async function runExamples() {
155
- try {
156
- await basicOAAuth();
157
- await oaAuthWithPKCE();
158
- await oaAuthWithAutoPKCE();
159
- await completeOAFlow();
160
- await getAuthUrlsExample();
161
- } catch (error) {
162
- console.error('Example error:', error);
163
- }
164
- }
165
-
166
- // Export for use in other files
167
- export {
168
- basicOAAuth,
169
- oaAuthWithPKCE,
170
- oaAuthWithAutoPKCE,
171
- completeOAFlow,
172
- getAuthUrlsExample,
173
- runExamples
174
- };
175
-
176
- // Run if this file is executed directly
177
- if (require.main === module) {
178
- runExamples();
179
- }