@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,171 +0,0 @@
1
- /**
2
- * Example: How to use the enhanced getAllArticles and getAllArticlesCombined methods
3
- *
4
- * This example demonstrates the new custom API methods that can fetch all articles
5
- * automatically by handling pagination internally.
6
- */
7
-
8
- import { ArticleService } from "../src/services/article.service";
9
- import { ZaloClient } from "../src/clients/zalo-client";
10
-
11
- // Initialize the services
12
- const zaloClient = new ZaloClient();
13
- const articleService = new ArticleService(zaloClient);
14
-
15
- // Your access token
16
- const ACCESS_TOKEN = "your-access-token-here";
17
-
18
- /**
19
- * Example 1: Get all normal articles with progress tracking
20
- */
21
- async function getAllNormalArticlesExample() {
22
- console.log("=== Getting All Normal Articles ===");
23
-
24
- try {
25
- const result = await articleService.getAllArticles(ACCESS_TOKEN, "normal", {
26
- batchSize: 50, // Fetch 50 articles per API call
27
- maxArticles: 1000, // Stop after 1000 articles (0 = no limit)
28
- onProgress: (progress) => {
29
- console.log(`šŸ“„ Batch ${progress.currentBatch}: ${progress.totalFetched} articles fetched, hasMore: ${progress.hasMore}`);
30
- }
31
- });
32
-
33
- console.log(`āœ… Completed! Total: ${result.totalFetched} normal articles in ${result.totalBatches} batches`);
34
- console.log(`šŸ“Š Has more articles available: ${result.hasMore}`);
35
-
36
- // Access the articles
37
- result.articles.forEach((article, index) => {
38
- console.log(`${index + 1}. ${article.title} (ID: ${article.id})`);
39
- });
40
-
41
- return result;
42
- } catch (error) {
43
- console.error("āŒ Error getting normal articles:", error);
44
- throw error;
45
- }
46
- }
47
-
48
- /**
49
- * Example 2: Get all video articles
50
- */
51
- async function getAllVideoArticlesExample() {
52
- console.log("\n=== Getting All Video Articles ===");
53
-
54
- try {
55
- const result = await articleService.getAllArticles(ACCESS_TOKEN, "video", {
56
- batchSize: 30, // Smaller batch size for videos
57
- maxArticles: 500, // Limit to 500 videos
58
- onProgress: (progress) => {
59
- console.log(`šŸŽ„ Video Batch ${progress.currentBatch}: ${progress.totalFetched} videos fetched`);
60
- }
61
- });
62
-
63
- console.log(`āœ… Completed! Total: ${result.totalFetched} video articles in ${result.totalBatches} batches`);
64
-
65
- return result;
66
- } catch (error) {
67
- console.error("āŒ Error getting video articles:", error);
68
- throw error;
69
- }
70
- }
71
-
72
- /**
73
- * Example 3: Get all articles (both normal and video) combined
74
- */
75
- async function getAllArticlesCombinedExample() {
76
- console.log("\n=== Getting All Articles Combined ===");
77
-
78
- try {
79
- const result = await articleService.getAllArticlesCombined(ACCESS_TOKEN, {
80
- batchSize: 50,
81
- maxArticlesPerType: 500, // Max 500 per type (normal + video)
82
- onProgress: (progress) => {
83
- console.log(`šŸ“± ${progress.type.toUpperCase()}: Batch ${progress.currentBatch}, Total: ${progress.totalFetched}`);
84
- }
85
- });
86
-
87
- console.log(`āœ… All articles fetched!`);
88
- console.log(`šŸ“Š Total articles: ${result.totalFetched}`);
89
- console.log(`šŸ“„ Normal articles: ${result.breakdown.normal.totalFetched}`);
90
- console.log(`šŸŽ„ Video articles: ${result.breakdown.video.totalFetched}`);
91
- console.log(`šŸ”„ Total API calls: ${result.totalBatches}`);
92
-
93
- // You can access all articles combined
94
- console.log(`\nšŸ“‹ All Articles (${result.articles.length}):`);
95
- result.articles.slice(0, 5).forEach((article, index) => {
96
- console.log(`${index + 1}. [${article.type?.toUpperCase()}] ${article.title}`);
97
- });
98
-
99
- if (result.articles.length > 5) {
100
- console.log(`... and ${result.articles.length - 5} more articles`);
101
- }
102
-
103
- return result;
104
- } catch (error) {
105
- console.error("āŒ Error getting combined articles:", error);
106
- throw error;
107
- }
108
- }
109
-
110
- /**
111
- * Example 4: Get unlimited articles (fetch everything)
112
- */
113
- async function getAllArticlesUnlimitedExample() {
114
- console.log("\n=== Getting ALL Articles (No Limit) ===");
115
-
116
- try {
117
- const result = await articleService.getAllArticles(ACCESS_TOKEN, "normal", {
118
- batchSize: 100, // Max batch size
119
- maxArticles: 0, // 0 = no limit, fetch everything
120
- onProgress: (progress) => {
121
- console.log(`šŸ”„ Batch ${progress.currentBatch}: ${progress.totalFetched} articles...`);
122
- }
123
- });
124
-
125
- console.log(`āœ… Fetched EVERYTHING! Total: ${result.totalFetched} articles`);
126
- console.log(`āš ļø Warning: This fetched all articles without limit!`);
127
-
128
- return result;
129
- } catch (error) {
130
- console.error("āŒ Error getting unlimited articles:", error);
131
- throw error;
132
- }
133
- }
134
-
135
- /**
136
- * Main function to run all examples
137
- */
138
- async function runExamples() {
139
- try {
140
- // Example 1: Normal articles
141
- await getAllNormalArticlesExample();
142
-
143
- // Example 2: Video articles
144
- await getAllVideoArticlesExample();
145
-
146
- // Example 3: Combined articles
147
- await getAllArticlesCombinedExample();
148
-
149
- // Example 4: Unlimited (commented out for safety)
150
- // await getAllArticlesUnlimitedExample();
151
-
152
- console.log("\nšŸŽ‰ All examples completed successfully!");
153
-
154
- } catch (error) {
155
- console.error("šŸ’„ Example failed:", error);
156
- }
157
- }
158
-
159
- // Export for use in other files
160
- export {
161
- getAllNormalArticlesExample,
162
- getAllVideoArticlesExample,
163
- getAllArticlesCombinedExample,
164
- getAllArticlesUnlimitedExample,
165
- runExamples
166
- };
167
-
168
- // Run examples if this file is executed directly
169
- if (require.main === module) {
170
- runExamples();
171
- }
@@ -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
- }