@warriorteam/redai-zalo-sdk 1.12.3 → 1.13.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 CHANGED
@@ -5,6 +5,141 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.13.0] - 2025-01-17
9
+
10
+ ### 🚀 NEW FEATURES
11
+
12
+ #### Enhanced Article API - Get All Articles
13
+ - **ADDED**: `getAllArticles()` - Lấy tất cả bài viết theo loại với tự động pagination
14
+ - **ADDED**: `getAllArticlesCombined()` - Lấy tất cả bài viết cả 2 loại (normal + video) kết hợp
15
+ - **ENHANCED**: Automatic pagination handling - không cần xử lý offset/limit thủ công
16
+ - **ADDED**: Progress tracking với callback `onProgress` để theo dõi tiến trình real-time
17
+ - **ADDED**: Flexible configuration với `batchSize`, `maxArticles`, và safety limits
18
+
19
+ #### Advanced Features
20
+ - **SAFETY**: Built-in safety checks để tránh infinite loops (max 100 batches)
21
+ - **PERFORMANCE**: Configurable batch sizes (1-100 articles per request)
22
+ - **CONTROL**: Giới hạn tổng số articles (`maxArticles`, 0 = unlimited)
23
+ - **MONITORING**: Real-time progress callbacks với detailed metrics
24
+ - **TYPE-SAFE**: Full TypeScript support với `ArticleListItem[]` return types
25
+
26
+ #### Smart Response Handling
27
+ - **ROBUST**: Handles both `ZaloResponse<T>` và direct response formats
28
+ - **FLEXIBLE**: Supports cả `response.data.medias` và `response.medias` structures
29
+ - **ERROR-SAFE**: Comprehensive error handling với `ZaloSDKError` integration
30
+
31
+ ### 📚 DOCUMENTATION
32
+
33
+ #### New Documentation Files
34
+ - **ADDED**: `docs/enhanced-article-api.md` - Comprehensive guide cho enhanced article APIs
35
+ - **ADDED**: `examples/get-all-articles-example.ts` - Practical usage examples với 4 scenarios
36
+ - **DETAILED**: API reference với parameters, return types, và best practices
37
+ - **EXAMPLES**: Real-world usage patterns và performance recommendations
38
+
39
+ #### Developer Experience
40
+ - **ENHANCED**: Detailed JSDoc comments với @example blocks
41
+ - **IMPROVED**: IntelliSense support với comprehensive type definitions
42
+ - **ADDED**: Progress tracking examples và error handling patterns
43
+ - **GUIDES**: Performance tuning và rate limiting recommendations
44
+
45
+ ### 🔧 TECHNICAL IMPROVEMENTS
46
+
47
+ #### Code Quality
48
+ - **TYPE-SAFE**: Full TypeScript compliance với proper interface definitions
49
+ - **VALIDATED**: Input validation với `ARTICLE_CONSTRAINTS` integration
50
+ - **OPTIMIZED**: Efficient pagination logic với smart batch management
51
+ - **TESTED**: Comprehensive error scenarios và edge case handling
52
+
53
+ #### API Design
54
+ - **CONSISTENT**: Follows existing SDK patterns và naming conventions
55
+ - **EXTENSIBLE**: Modular design cho future enhancements
56
+ - **BACKWARD-COMPATIBLE**: Không breaking changes cho existing `getArticleList()`
57
+ - **PERFORMANCE**: Optimized cho large datasets với configurable limits
58
+
59
+ ### 💡 USAGE EXAMPLES
60
+
61
+ ```typescript
62
+ // Simple: Get all normal articles
63
+ const result = await articleService.getAllArticles(accessToken, "normal");
64
+
65
+ // Advanced: With progress tracking và limits
66
+ const result = await articleService.getAllArticles(accessToken, "normal", {
67
+ batchSize: 50,
68
+ maxArticles: 1000,
69
+ onProgress: (progress) => console.log(`${progress.totalFetched} articles`)
70
+ });
71
+
72
+ // Combined: Get both normal và video articles
73
+ const combined = await articleService.getAllArticlesCombined(accessToken, {
74
+ maxArticlesPerType: 500
75
+ });
76
+ ```
77
+
78
+ ## [1.12.1] - 2025-01-17
79
+
80
+ ### 🔧 MAINTENANCE
81
+
82
+ - **Cập nhật**: Tối ưu tài liệu, ví dụ và xuất bản bản vá nhỏ.
83
+ - **Cải thiện**: Đồng bộ hoá typings và mô tả package để phát hành ổn định.
84
+ - **Build**: Đảm bảo `prepublishOnly` chạy `clean` + `build` trước khi publish.
85
+
86
+ ## [1.12.0] - 2025-01-17
87
+
88
+ ### 🎯 NEW FEATURES
89
+
90
+ #### Webhook Message Classification Helpers
91
+ - **ADDED**: `isUserMessageEvent()` - Phân biệt tin nhắn từ người dùng cá nhân gửi tới OA
92
+ - **ADDED**: `isGroupMessageEvent()` - Phân biệt tin nhắn từ người dùng trong group
93
+ - **ADDED**: `isOAToUserMessageEvent()` - Phân biệt tin nhắn OA gửi cho người dùng cá nhân
94
+ - **ADDED**: `isOAToGroupMessageEvent()` - Phân biệt tin nhắn OA gửi tới group
95
+ - **ADDED**: `getMessageDirection()` - Xác định hướng và đích của tin nhắn với mô tả chi tiết
96
+
97
+ #### Enhanced Type Safety
98
+ - **IMPROVED**: Better type guards cho webhook message classification
99
+ - **ENHANCED**: Comprehensive support cho 38+ message event types
100
+ - **ADDED**: Direction và target classification với Vietnamese descriptions
101
+
102
+ ### 📚 DOCUMENTATION
103
+
104
+ #### New Documentation Files
105
+ - **ADDED**: `docs/WEBHOOK_MESSAGE_HELPERS.md` - Comprehensive guide cho message classification
106
+ - **ADDED**: `examples/webhook-message-classification.ts` - Practical usage examples
107
+ - **UPDATED**: README.md với message classification helpers section
108
+
109
+ #### Developer Experience
110
+ - **ENHANCED**: IntelliSense support với detailed JSDoc comments
111
+ - **ADDED**: 13 comprehensive test cases cho message classification helpers
112
+ - **IMPROVED**: Better error handling và unknown event detection
113
+
114
+ ### 🔧 TECHNICAL IMPROVEMENTS
115
+
116
+ #### Code Organization
117
+ - **ENHANCED**: Exported helper functions từ main index.ts
118
+ - **IMPROVED**: Type safety với proper TypeScript interfaces
119
+ - **ADDED**: Comprehensive test coverage cho all helper functions
120
+
121
+ #### Supported Event Types
122
+ - **User Message Events** (12 types): `user_send_text`, `user_send_image`, etc.
123
+ - **Group Message Events** (9 types): `user_send_group_text`, `user_send_group_image`, etc.
124
+ - **OA to User Events** (7 types): `oa_send_text`, `oa_send_image`, etc.
125
+ - **OA to Group Events** (10 types): `oa_send_group_text`, `oa_send_group_image`, etc.
126
+
127
+ ## [1.11.1] - 2025-01-11
128
+
129
+ ### 🔧 API IMPROVEMENTS
130
+
131
+ #### Method Signature Enhancement
132
+ - **IMPROVED**: `createOAAuthUrl()` method signature với better parameter order
133
+ - Changed from: `(redirectUri, state?, usePkce?, pkce?)`
134
+ - Changed to: `(redirectUri, state?, pkce?, usePkce?)`
135
+ - **ENHANCED**: More intuitive API design với PKCE config trước usePkce flag
136
+ - **UPDATED**: All examples và documentation để phù hợp với signature mới
137
+ - **ADDED**: Comprehensive test coverage cho new signature
138
+
139
+ #### Developer Experience
140
+ - **IMPROVED**: Better IntelliSense support với clearer parameter ordering
141
+ - **ENHANCED**: More logical API flow cho PKCE implementation
142
+
8
143
  ## [1.11.0] - 2025-01-11
9
144
 
10
145
  ### 🔐 SECURITY ENHANCEMENTS
package/README.md CHANGED
@@ -9,6 +9,7 @@ A comprehensive TypeScript/JavaScript SDK for Zalo APIs, providing easy-to-use i
9
9
  - **Group Message Framework (GMF)** - Send messages to Zalo groups
10
10
  - **User Management** - Comprehensive user profile and tag management
11
11
  - **Content Management** - Upload and manage media content (images, files, articles)
12
+ - **Enhanced Article Management** - Get all articles with auto-pagination and progress tracking
12
13
  - **Video Upload** - Upload and manage video content with processing
13
14
  - **Tag Management** - User tagging and segmentation
14
15
  - **Webhook handling** - Process Zalo webhook events
@@ -22,6 +23,7 @@ A comprehensive TypeScript/JavaScript SDK for Zalo APIs, providing easy-to-use i
22
23
  - 🛡️ **Error Handling** - Detailed error information and handling
23
24
  - 📦 **Zero Dependencies** - Only requires axios and form-data
24
25
  - 🎯 **Promise-based** - Modern async/await support
26
+ - 🔄 **Auto-Pagination** - Automatically fetch all articles with progress tracking
25
27
 
26
28
  ## Installation
27
29
 
@@ -584,7 +586,39 @@ const handlers: WebhookHandlers = {
584
586
  - **Anonymous Events** (4 types): Anonymous chat support
585
587
  - **Shop Events** (1 type): Order management
586
588
 
587
- For complete webhook documentation, see [Webhook Events Guide](./docs/WEBHOOK_EVENTS.md).
589
+ ### 🎯 Message Classification Helpers
590
+
591
+ The SDK provides helper functions to easily classify webhook message events:
592
+
593
+ ```typescript
594
+ import {
595
+ isUserMessageEvent,
596
+ isGroupMessageEvent,
597
+ isOAToUserMessageEvent,
598
+ isOAToGroupMessageEvent,
599
+ getMessageDirection,
600
+ } from "@warriorteam/redai-zalo-sdk";
601
+
602
+ function handleWebhook(event: WebhookEvent) {
603
+ if (isUserMessageEvent(event)) {
604
+ console.log("Message from individual user");
605
+ } else if (isGroupMessageEvent(event)) {
606
+ console.log("Message from group");
607
+ } else if (isOAToUserMessageEvent(event)) {
608
+ console.log("OA sent message to user");
609
+ } else if (isOAToGroupMessageEvent(event)) {
610
+ console.log("OA sent message to group");
611
+ }
612
+
613
+ // Or use the unified helper
614
+ const { direction, target, description } = getMessageDirection(event);
615
+ console.log(`${direction} message to ${target}: ${description}`);
616
+ }
617
+ ```
618
+
619
+ For complete webhook documentation, see:
620
+ - **[Webhook Events Guide](./docs/WEBHOOK_EVENTS.md)** - Complete guide for all 70+ webhook event types
621
+ - **[Message Classification Helpers](./docs/WEBHOOK_MESSAGE_HELPERS.md)** - Helper functions for message classification
588
622
 
589
623
  ## Changelog
590
624
 
package/dist/index.d.ts CHANGED
@@ -17,8 +17,9 @@ export * from "./types/article";
17
17
  export * from "./constants/zns.constants";
18
18
  export type { BaseMessage, TextMessage, ImageMessage, FileMessage, StickerMessage, TemplateMessage as MessageTemplateMessage, ReactionMessage as MessageReactionMessage, Message, MessageRecipient, SendMessageRequest, SendMessageResponse, UploadFileResponse, MessageStatus, MessageEvent, ConsultationTextMessage, ConsultationImageMessage, ConsultationFileMessage, ConsultationStickerMessage, ConsultationQuoteMessage, ConsultationRequestInfoMessage, TransactionMessage, PromotionMessage, AnonymousTextMessage, AnonymousImageMessage, AnonymousFileMessage, AnonymousStickerMessage, MiniAppMessage, ExtendedMessage, } from "./types/message";
19
19
  export * from "./types/webhook";
20
- export { UserGroupMessageEvent, isUserSendGroupTextEvent, isUserSendGroupImageEvent, isUserSendGroupVideoEvent, isUserSendGroupAudioEvent, isUserSendGroupFileEvent, isUserGroupMessageEvent, isOASendTextEvent, isOASendImageEvent, isOASendFileEvent, isOASendStickerEvent, isOASendGifEvent, isOASendGroupTextEvent, isOASendGroupImageEvent, isOASendGroupFileEvent, isOASendGroupStickerEvent, isOASendGroupGifEvent, isUserMessageEvent, isFromGroup, isFromPersonal, } from "./utils/type-guards";
21
- export type { GroupMessage, GroupTextMessage, GroupImageMessage, GroupFileMessage, GroupStickerMessage, GroupMentionMessage, GroupMessageResult, GroupInfo as GroupManagementInfo, GroupMember, GroupMemberList, GroupSettings, GroupJoinRequest, GroupJoinRequestList, GroupInvitation, GroupActivity, GroupActivityList, GroupStatistics, GroupMessageTemplate, GroupMessageSchedule, GroupBroadcast, GroupPermission, GroupWebhookEvent as GroupManagementWebhookEvent, GroupApiResponse, GroupCreateResponse, GroupUpdateResponse, GroupDeleteResponse, GroupMemberActionResponse, GroupCreateRequest, GroupCreateResult, GroupUpdateRequest, GroupAvatarUpdateRequest, GroupMemberInviteRequest, GroupMemberActionRequest, GroupAdminActionRequest, GroupDeleteRequest, GroupPendingMember, GroupQuota, GroupQuotaAsset, GroupRecentChat, GroupConversationMessage, GroupsOfOAResponse, GroupDetailResponse, GroupPendingMembersResponse, GroupAcceptPendingMembersRequest, GroupAcceptPendingMembersResponse, GroupRemoveMembersRequest, GroupRemoveMembersResponse, GroupMembersResponse, GroupQuotaMessageRequest, GroupQuotaMessageResponse, } from "./types/group";
20
+ export { UserGroupMessageEvent, isUserSendGroupTextEvent, isUserSendGroupImageEvent, isUserSendGroupVideoEvent, isUserSendGroupAudioEvent, isUserSendGroupFileEvent, isUserGroupMessageEvent, isOASendTextEvent, isOASendImageEvent, isOASendFileEvent, isOASendStickerEvent, isOASendGifEvent, isOASendGroupTextEvent, isOASendGroupImageEvent, isOASendGroupFileEvent, isOASendGroupStickerEvent, isOASendGroupGifEvent, isFromGroup, isFromPersonal, } from "./utils/type-guards";
21
+ export { isUserMessageEvent, isGroupMessageEvent, isOAToUserMessageEvent, isOAToGroupMessageEvent, getMessageDirection, } from "./types/webhook";
22
+ export type { GroupMessage, GroupTextMessage, GroupImageMessage, GroupFileMessage, GroupStickerMessage, GroupMentionMessage, GroupMessageResult, GroupInfo as GroupManagementInfo, GroupMember, GroupMemberList, GroupSettings, GroupJoinRequest, GroupJoinRequestList, GroupInvitation, GroupActivity, GroupActivityList, GroupStatistics, GroupMessageTemplate, GroupMessageSchedule, GroupBroadcast, GroupPermission, GroupWebhookEvent as GroupManagementWebhookEvent, GroupApiResponse, GroupCreateResponse, GroupUpdateResponse, GroupDeleteResponse, GroupMemberActionResponse, GroupCreateRequest, GroupCreateResult, GroupUpdateRequest, GroupAvatarUpdateRequest, GroupMemberInviteRequest, GroupMemberActionRequest, GroupAdminActionRequest, GroupDeleteRequest, GroupPendingMember, GroupQuota, GroupQuotaAsset, GroupRecentChat, GroupConversationMessage, GroupsOfOAResponse, GroupDetailResponse, GroupPendingMembersResponse, GroupAcceptPendingMembersRequest, GroupAcceptPendingMembersResponse, GroupRemoveMembersRequest, GroupRemoveMembersResponse, GroupMembersResponse, GroupQuotaMessageRequest, GroupQuotaMessageResponse, AllGroupMembersResponse, GetAllMembersProgress, EnhancedGroupMember, AllGroupMembersWithDetailsResponse, GetAllMembersWithDetailsProgress, } from "./types/group";
22
23
  export type { UserProfile as UserManagementProfile, UserList as UserManagementList, UserTag, UserTagList, UserNote, UserInteraction, UserAnalytics, UserSegment, UserCustomField, UserCustomFieldValue, UserBehavior, UserJourney, UserPreference, UserActivity, UserExport, UserImport, UserSearch, UserSearchResult, BulkUserOperation, } from "./types/user-management";
23
24
  export { BaseClient } from "./clients/base-client";
24
25
  export { ZaloClient } from "./clients/zalo-client";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -24,7 +24,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
24
24
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
25
25
  };
26
26
  Object.defineProperty(exports, "__esModule", { value: true });
27
- exports.default = exports.ZaloSDK = exports.MessageManagementService = exports.GeneralMessageService = exports.PromotionService = exports.TransactionService = exports.ConsultationService = exports.VideoUploadService = exports.ArticleService = exports.GroupManagementService = exports.GroupMessageService = exports.ZNSService = exports.UserService = exports.OAService = exports.AuthService = exports.ZaloClient = exports.BaseClient = exports.isFromPersonal = exports.isFromGroup = exports.isUserMessageEvent = exports.isOASendGroupGifEvent = exports.isOASendGroupStickerEvent = exports.isOASendGroupFileEvent = exports.isOASendGroupImageEvent = exports.isOASendGroupTextEvent = exports.isOASendGifEvent = exports.isOASendStickerEvent = exports.isOASendFileEvent = exports.isOASendImageEvent = exports.isOASendTextEvent = exports.isUserGroupMessageEvent = exports.isUserSendGroupFileEvent = exports.isUserSendGroupAudioEvent = exports.isUserSendGroupVideoEvent = exports.isUserSendGroupImageEvent = exports.isUserSendGroupTextEvent = void 0;
27
+ exports.default = exports.ZaloSDK = exports.MessageManagementService = exports.GeneralMessageService = exports.PromotionService = exports.TransactionService = exports.ConsultationService = exports.VideoUploadService = exports.ArticleService = exports.GroupManagementService = exports.GroupMessageService = exports.ZNSService = exports.UserService = exports.OAService = exports.AuthService = exports.ZaloClient = exports.BaseClient = exports.getMessageDirection = exports.isOAToGroupMessageEvent = exports.isOAToUserMessageEvent = exports.isGroupMessageEvent = exports.isUserMessageEvent = exports.isFromPersonal = exports.isFromGroup = exports.isOASendGroupGifEvent = exports.isOASendGroupStickerEvent = exports.isOASendGroupFileEvent = exports.isOASendGroupImageEvent = exports.isOASendGroupTextEvent = exports.isOASendGifEvent = exports.isOASendStickerEvent = exports.isOASendFileEvent = exports.isOASendImageEvent = exports.isOASendTextEvent = exports.isUserGroupMessageEvent = exports.isUserSendGroupFileEvent = exports.isUserSendGroupAudioEvent = exports.isUserSendGroupVideoEvent = exports.isUserSendGroupImageEvent = exports.isUserSendGroupTextEvent = void 0;
28
28
  // Export types
29
29
  __exportStar(require("./types/common"), exports);
30
30
  __exportStar(require("./types/auth"), exports);
@@ -54,9 +54,15 @@ Object.defineProperty(exports, "isOASendGroupImageEvent", { enumerable: true, ge
54
54
  Object.defineProperty(exports, "isOASendGroupFileEvent", { enumerable: true, get: function () { return type_guards_1.isOASendGroupFileEvent; } });
55
55
  Object.defineProperty(exports, "isOASendGroupStickerEvent", { enumerable: true, get: function () { return type_guards_1.isOASendGroupStickerEvent; } });
56
56
  Object.defineProperty(exports, "isOASendGroupGifEvent", { enumerable: true, get: function () { return type_guards_1.isOASendGroupGifEvent; } });
57
- Object.defineProperty(exports, "isUserMessageEvent", { enumerable: true, get: function () { return type_guards_1.isUserMessageEvent; } });
58
57
  Object.defineProperty(exports, "isFromGroup", { enumerable: true, get: function () { return type_guards_1.isFromGroup; } });
59
58
  Object.defineProperty(exports, "isFromPersonal", { enumerable: true, get: function () { return type_guards_1.isFromPersonal; } });
59
+ // Export webhook helper functions
60
+ var webhook_1 = require("./types/webhook");
61
+ Object.defineProperty(exports, "isUserMessageEvent", { enumerable: true, get: function () { return webhook_1.isUserMessageEvent; } });
62
+ Object.defineProperty(exports, "isGroupMessageEvent", { enumerable: true, get: function () { return webhook_1.isGroupMessageEvent; } });
63
+ Object.defineProperty(exports, "isOAToUserMessageEvent", { enumerable: true, get: function () { return webhook_1.isOAToUserMessageEvent; } });
64
+ Object.defineProperty(exports, "isOAToGroupMessageEvent", { enumerable: true, get: function () { return webhook_1.isOAToGroupMessageEvent; } });
65
+ Object.defineProperty(exports, "getMessageDirection", { enumerable: true, get: function () { return webhook_1.getMessageDirection; } });
60
66
  // Export clients
61
67
  var base_client_1 = require("./clients/base-client");
62
68
  Object.defineProperty(exports, "BaseClient", { enumerable: true, get: function () { return base_client_1.BaseClient; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;;;;;;;;;;;;;;;AAEH,eAAe;AACf,iDAA+B;AAC/B,+CAA6B;AAC7B,6CAA2B;AAC3B,+CAA6B;AAC7B,8CAA4B;AAC5B,kDAAgC;AAEhC,mCAAmC;AACnC,4DAA0C;AAkC1C,yEAAyE;AACzE,kDAAgC;AAEhC,yEAAyE;AACzE,mDAqB6B;AAnB3B,uHAAA,wBAAwB,OAAA;AACxB,wHAAA,yBAAyB,OAAA;AACzB,wHAAA,yBAAyB,OAAA;AACzB,wHAAA,yBAAyB,OAAA;AACzB,uHAAA,wBAAwB,OAAA;AACxB,sHAAA,uBAAuB,OAAA;AACvB,gHAAA,iBAAiB,OAAA;AACjB,iHAAA,kBAAkB,OAAA;AAClB,gHAAA,iBAAiB,OAAA;AACjB,mHAAA,oBAAoB,OAAA;AACpB,+GAAA,gBAAgB,OAAA;AAChB,qHAAA,sBAAsB,OAAA;AACtB,sHAAA,uBAAuB,OAAA;AACvB,qHAAA,sBAAsB,OAAA;AACtB,wHAAA,yBAAyB,OAAA;AACzB,oHAAA,qBAAqB,OAAA;AACrB,iHAAA,kBAAkB,OAAA;AAClB,0GAAA,WAAW,OAAA;AACX,6GAAA,cAAc,OAAA;AA+EhB,iBAAiB;AACjB,qDAAmD;AAA1C,yGAAA,UAAU,OAAA;AACnB,qDAAmD;AAA1C,yGAAA,UAAU,OAAA;AAEnB,kBAAkB;AAClB,wDAAsD;AAA7C,2GAAA,WAAW,OAAA;AACpB,oDAAkD;AAAzC,uGAAA,SAAS,OAAA;AAClB,2GAA2G;AAC3G,wDAAsD;AAA7C,2GAAA,WAAW,OAAA;AACpB,+DAA+D;AAC/D,sDAAoD;AAA3C,yGAAA,UAAU,OAAA;AACnB,0EAAuE;AAA9D,4HAAA,mBAAmB,OAAA;AAC5B,gFAA6E;AAApE,kIAAA,sBAAsB,OAAA;AAC/B,8DAA4D;AAAnD,iHAAA,cAAc,OAAA;AACvB,wEAAqE;AAA5D,0HAAA,kBAAkB,OAAA;AAE3B,iDAAiD;AACjD,wEAAsE;AAA7D,2HAAA,mBAAmB,OAAA;AAC5B,sEAAoE;AAA3D,yHAAA,kBAAkB,OAAA;AAC3B,kEAAgE;AAAvD,qHAAA,gBAAgB,OAAA;AACzB,8EAA2E;AAAlE,gIAAA,qBAAqB,OAAA;AAC9B,oFAQ+C;AAP7C,sIAAA,wBAAwB,OAAA;AAS1B,wBAAwB;AACxB,uCAAqC;AAA5B,mGAAA,OAAO,OAAA;AAEhB,iBAAiB;AACjB,uCAAgD;AAAvC,mGAAA,OAAO,OAAW"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;;;;;;;;;;;;;;;AAEH,eAAe;AACf,iDAA+B;AAC/B,+CAA6B;AAC7B,6CAA2B;AAC3B,+CAA6B;AAC7B,8CAA4B;AAC5B,kDAAgC;AAEhC,mCAAmC;AACnC,4DAA0C;AAkC1C,yEAAyE;AACzE,kDAAgC;AAEhC,yEAAyE;AACzE,mDAoB6B;AAlB3B,uHAAA,wBAAwB,OAAA;AACxB,wHAAA,yBAAyB,OAAA;AACzB,wHAAA,yBAAyB,OAAA;AACzB,wHAAA,yBAAyB,OAAA;AACzB,uHAAA,wBAAwB,OAAA;AACxB,sHAAA,uBAAuB,OAAA;AACvB,gHAAA,iBAAiB,OAAA;AACjB,iHAAA,kBAAkB,OAAA;AAClB,gHAAA,iBAAiB,OAAA;AACjB,mHAAA,oBAAoB,OAAA;AACpB,+GAAA,gBAAgB,OAAA;AAChB,qHAAA,sBAAsB,OAAA;AACtB,sHAAA,uBAAuB,OAAA;AACvB,qHAAA,sBAAsB,OAAA;AACtB,wHAAA,yBAAyB,OAAA;AACzB,oHAAA,qBAAqB,OAAA;AACrB,0GAAA,WAAW,OAAA;AACX,6GAAA,cAAc,OAAA;AAEhB,kCAAkC;AAClC,2CAMyB;AALvB,6GAAA,kBAAkB,OAAA;AAClB,8GAAA,mBAAmB,OAAA;AACnB,iHAAA,sBAAsB,OAAA;AACtB,kHAAA,uBAAuB,OAAA;AACvB,8GAAA,mBAAmB,OAAA;AAoFrB,iBAAiB;AACjB,qDAAmD;AAA1C,yGAAA,UAAU,OAAA;AACnB,qDAAmD;AAA1C,yGAAA,UAAU,OAAA;AAEnB,kBAAkB;AAClB,wDAAsD;AAA7C,2GAAA,WAAW,OAAA;AACpB,oDAAkD;AAAzC,uGAAA,SAAS,OAAA;AAClB,2GAA2G;AAC3G,wDAAsD;AAA7C,2GAAA,WAAW,OAAA;AACpB,+DAA+D;AAC/D,sDAAoD;AAA3C,yGAAA,UAAU,OAAA;AACnB,0EAAuE;AAA9D,4HAAA,mBAAmB,OAAA;AAC5B,gFAA6E;AAApE,kIAAA,sBAAsB,OAAA;AAC/B,8DAA4D;AAAnD,iHAAA,cAAc,OAAA;AACvB,wEAAqE;AAA5D,0HAAA,kBAAkB,OAAA;AAE3B,iDAAiD;AACjD,wEAAsE;AAA7D,2HAAA,mBAAmB,OAAA;AAC5B,sEAAoE;AAA3D,yHAAA,kBAAkB,OAAA;AAC3B,kEAAgE;AAAvD,qHAAA,gBAAgB,OAAA;AACzB,8EAA2E;AAAlE,gIAAA,qBAAqB,OAAA;AAC9B,oFAQ+C;AAP7C,sIAAA,wBAAwB,OAAA;AAS1B,wBAAwB;AACxB,uCAAqC;AAA5B,mGAAA,OAAO,OAAA;AAEhB,iBAAiB;AACjB,uCAAgD;AAAvC,mGAAA,OAAO,OAAW"}
@@ -1,5 +1,5 @@
1
1
  import { ZaloClient } from "../clients/zalo-client";
2
- import { ArticleRequest, ArticleNormalRequest, ArticleVideoRequest, ArticleResponse, ArticleProcessResponse, ArticleVerifyResponse, ArticleDetail, ArticleListRequest, ArticleListResponse, ArticleRemoveResponse, ArticleUpdateRequest, ArticleUpdateNormalRequest, ArticleUpdateVideoRequest, ArticleUpdateResponse, ArticleStatus, CommentStatus } from "../types/article";
2
+ import { ArticleRequest, ArticleNormalRequest, ArticleVideoRequest, ArticleResponse, ArticleProcessResponse, ArticleVerifyResponse, ArticleDetail, ArticleListRequest, ArticleListResponse, ArticleListItem, ArticleRemoveResponse, ArticleUpdateRequest, ArticleUpdateNormalRequest, ArticleUpdateVideoRequest, ArticleUpdateResponse, ArticleStatus, CommentStatus } from "../types/article";
3
3
  /**
4
4
  * Service for handling Zalo Official Account Article Management APIs
5
5
  *
@@ -82,6 +82,108 @@ export declare class ArticleService {
82
82
  * @returns Article list
83
83
  */
84
84
  getArticleList(accessToken: string, request: ArticleListRequest): Promise<ArticleListResponse>;
85
+ /**
86
+ * Get all articles by automatically fetching all pages
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * // Get all normal articles with progress tracking
91
+ * const result = await articleService.getAllArticles(accessToken, "normal", {
92
+ * batchSize: 50,
93
+ * maxArticles: 1000,
94
+ * onProgress: (progress) => {
95
+ * console.log(`Batch ${progress.currentBatch}: ${progress.totalFetched} articles fetched`);
96
+ * }
97
+ * });
98
+ *
99
+ * console.log(`Total: ${result.totalFetched} articles in ${result.totalBatches} batches`);
100
+ * console.log(`Has more: ${result.hasMore}`);
101
+ * ```
102
+ *
103
+ * @param accessToken OA access token
104
+ * @param type Article type ("normal" or "video")
105
+ * @param options Configuration options for fetching
106
+ * @returns All articles with pagination info
107
+ */
108
+ getAllArticles(accessToken: string, type?: "normal" | "video", options?: {
109
+ /** Number of articles to fetch per request (default: 50, max: 100) */
110
+ batchSize?: number;
111
+ /** Maximum number of articles to fetch (default: 1000, 0 = no limit) */
112
+ maxArticles?: number;
113
+ /** Optional callback to track progress */
114
+ onProgress?: (progress: {
115
+ currentBatch: number;
116
+ totalFetched: number;
117
+ hasMore: boolean;
118
+ }) => void;
119
+ }): Promise<{
120
+ /** Array of all fetched articles */
121
+ articles: ArticleListItem[];
122
+ /** Total number of articles fetched */
123
+ totalFetched: number;
124
+ /** Number of API calls made */
125
+ totalBatches: number;
126
+ /** Whether there are more articles available */
127
+ hasMore: boolean;
128
+ }>;
129
+ /**
130
+ * Get all articles of both types (normal and video) combined
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * // Get all articles (both normal and video)
135
+ * const result = await articleService.getAllArticlesCombined(accessToken, {
136
+ * batchSize: 50,
137
+ * maxArticlesPerType: 500,
138
+ * onProgress: (progress) => {
139
+ * console.log(`${progress.type}: Batch ${progress.currentBatch}, Total: ${progress.totalFetched}`);
140
+ * }
141
+ * });
142
+ *
143
+ * console.log(`Total articles: ${result.totalFetched}`);
144
+ * console.log(`Normal articles: ${result.breakdown.normal.totalFetched}`);
145
+ * console.log(`Video articles: ${result.breakdown.video.totalFetched}`);
146
+ * ```
147
+ *
148
+ * @param accessToken OA access token
149
+ * @param options Configuration options for fetching
150
+ * @returns All articles (normal + video) with combined pagination info
151
+ */
152
+ getAllArticlesCombined(accessToken: string, options?: {
153
+ /** Number of articles to fetch per request for each type (default: 50, max: 100) */
154
+ batchSize?: number;
155
+ /** Maximum number of articles to fetch per type (default: 500, 0 = no limit) */
156
+ maxArticlesPerType?: number;
157
+ /** Optional callback to track progress */
158
+ onProgress?: (progress: {
159
+ type: "normal" | "video";
160
+ currentBatch: number;
161
+ totalFetched: number;
162
+ hasMore: boolean;
163
+ }) => void;
164
+ }): Promise<{
165
+ /** Array of all fetched articles (normal + video) */
166
+ articles: ArticleListItem[];
167
+ /** Breakdown by type */
168
+ breakdown: {
169
+ normal: {
170
+ articles: ArticleListItem[];
171
+ totalFetched: number;
172
+ totalBatches: number;
173
+ hasMore: boolean;
174
+ };
175
+ video: {
176
+ articles: ArticleListItem[];
177
+ totalFetched: number;
178
+ totalBatches: number;
179
+ hasMore: boolean;
180
+ };
181
+ };
182
+ /** Total number of articles fetched */
183
+ totalFetched: number;
184
+ /** Total number of API calls made */
185
+ totalBatches: number;
186
+ }>;
85
187
  /**
86
188
  * Remove article
87
189
  * @param accessToken OA access token
@@ -1 +1 @@
1
- {"version":3,"file":"article.service.d.ts","sourceRoot":"","sources":["../../src/services/article.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,aAAa,EAGb,kBAAkB,EAClB,mBAAmB,EAEnB,qBAAqB,EACrB,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,qBAAqB,EAIrB,aAAa,EACb,aAAa,EAId,MAAM,kBAAkB,CAAC;AAG1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,cAAc;IAab,OAAO,CAAC,QAAQ,CAAC,MAAM;IAXnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CASf;gBAEkB,MAAM,EAAE,UAAU;IAE/C;;;;;OAKG;IACG,mBAAmB,CACvB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,eAAe,CAAC;IAuC3B;;;;;OAKG;IACG,kBAAkB,CACtB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,eAAe,CAAC;IA2B3B;;;;;OAKG;IACG,aAAa,CACjB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,eAAe,CAAC;IAa3B;;;;;OAKG;IACG,mBAAmB,CACvB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,sBAAsB,CAAC;IAuDlC;;;;;OAKG;IACG,aAAa,CACjB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,qBAAqB,CAAC;IAsBjC;;;;;OAKG;IACG,gBAAgB,CACpB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,aAAa,CAAC;IAkBzB;;;;;OAKG;IACG,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,mBAAmB,CAAC;IAqB/B;;;;;OAKG;IACG,aAAa,CACjB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,qBAAqB,CAAC;IAgCjC,OAAO,CAAC,kBAAkB;IAqB1B;;;;;OAKG;IACG,mBAAmB,CACvB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,qBAAqB,CAAC;IAwCjC;;;;;OAKG;IACG,kBAAkB,CACtB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,qBAAqB,CAAC;IA4BjC;;;;;OAKG;IACG,aAAa,CACjB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAajC;;;;;;;OAOG;IACG,mBAAmB,CACvB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,aAAa,EACrB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,qBAAqB,CAAC;IAwEjC;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAqDpC;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAkCnC;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAqBlC;;OAEG;IACH,OAAO,CAAC,kCAAkC;IAW1C;;OAEG;IACH,OAAO,CAAC,iCAAiC;IAWzC;;OAEG;IACH,OAAO,CAAC,aAAa;IA2CrB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAwDxB,OAAO,CAAC,mBAAmB;CAQ5B"}
1
+ {"version":3,"file":"article.service.d.ts","sourceRoot":"","sources":["../../src/services/article.service.ts"],"names":[],"mappings":"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"}
@@ -238,6 +238,173 @@ class ArticleService {
238
238
  throw this.handleArticleError(error, "Failed to get article list");
239
239
  }
240
240
  }
241
+ /**
242
+ * Get all articles by automatically fetching all pages
243
+ *
244
+ * @example
245
+ * ```typescript
246
+ * // Get all normal articles with progress tracking
247
+ * const result = await articleService.getAllArticles(accessToken, "normal", {
248
+ * batchSize: 50,
249
+ * maxArticles: 1000,
250
+ * onProgress: (progress) => {
251
+ * console.log(`Batch ${progress.currentBatch}: ${progress.totalFetched} articles fetched`);
252
+ * }
253
+ * });
254
+ *
255
+ * console.log(`Total: ${result.totalFetched} articles in ${result.totalBatches} batches`);
256
+ * console.log(`Has more: ${result.hasMore}`);
257
+ * ```
258
+ *
259
+ * @param accessToken OA access token
260
+ * @param type Article type ("normal" or "video")
261
+ * @param options Configuration options for fetching
262
+ * @returns All articles with pagination info
263
+ */
264
+ async getAllArticles(accessToken, type = "normal", options = {}) {
265
+ try {
266
+ const { batchSize = 50, maxArticles = 1000, onProgress } = options;
267
+ // Validate parameters
268
+ if (batchSize <= 0 || batchSize > article_1.ARTICLE_CONSTRAINTS.LIST_MAX_LIMIT) {
269
+ throw new common_1.ZaloSDKError(`Batch size must be between 1 and ${article_1.ARTICLE_CONSTRAINTS.LIST_MAX_LIMIT}`, -1);
270
+ }
271
+ if (maxArticles < 0) {
272
+ throw new common_1.ZaloSDKError("Max articles must be >= 0 (0 = no limit)", -1);
273
+ }
274
+ if (!["normal", "video"].includes(type)) {
275
+ throw new common_1.ZaloSDKError('Type must be "normal" or "video"', -1);
276
+ }
277
+ const allArticles = [];
278
+ let offset = 0;
279
+ let currentBatch = 0;
280
+ let hasMore = true;
281
+ while (hasMore) {
282
+ currentBatch++;
283
+ // Calculate limit for this batch
284
+ let currentLimit = batchSize;
285
+ if (maxArticles > 0) {
286
+ const remaining = maxArticles - allArticles.length;
287
+ if (remaining <= 0)
288
+ break;
289
+ currentLimit = Math.min(batchSize, remaining);
290
+ }
291
+ // Fetch current batch
292
+ const response = await this.getArticleList(accessToken, {
293
+ offset,
294
+ limit: currentLimit,
295
+ type
296
+ });
297
+ // Add articles to collection
298
+ // Check if response is successful and has data
299
+ if ('data' in response && response.data?.medias && response.data.medias.length > 0) {
300
+ allArticles.push(...response.data.medias);
301
+ offset += response.data.medias.length;
302
+ // Check if we have more data
303
+ hasMore = response.data.medias.length === currentLimit;
304
+ // Stop if we've reached max articles
305
+ if (maxArticles > 0 && allArticles.length >= maxArticles) {
306
+ hasMore = false;
307
+ }
308
+ }
309
+ else if ('medias' in response && response.medias && response.medias.length > 0) {
310
+ // Handle direct response format (fallback)
311
+ allArticles.push(...response.medias);
312
+ offset += response.medias.length;
313
+ // Check if we have more data
314
+ hasMore = response.medias.length === currentLimit;
315
+ // Stop if we've reached max articles
316
+ if (maxArticles > 0 && allArticles.length >= maxArticles) {
317
+ hasMore = false;
318
+ }
319
+ }
320
+ else {
321
+ hasMore = false;
322
+ }
323
+ // Call progress callback if provided
324
+ if (onProgress) {
325
+ onProgress({
326
+ currentBatch,
327
+ totalFetched: allArticles.length,
328
+ hasMore
329
+ });
330
+ }
331
+ // Safety check to prevent infinite loops
332
+ if (currentBatch > 100) {
333
+ console.warn("Reached maximum batch limit (100), stopping fetch");
334
+ break;
335
+ }
336
+ }
337
+ return {
338
+ articles: allArticles,
339
+ totalFetched: allArticles.length,
340
+ totalBatches: currentBatch,
341
+ hasMore: hasMore && (maxArticles === 0 || allArticles.length < maxArticles)
342
+ };
343
+ }
344
+ catch (error) {
345
+ throw this.handleArticleError(error, "Failed to get all articles");
346
+ }
347
+ }
348
+ /**
349
+ * Get all articles of both types (normal and video) combined
350
+ *
351
+ * @example
352
+ * ```typescript
353
+ * // Get all articles (both normal and video)
354
+ * const result = await articleService.getAllArticlesCombined(accessToken, {
355
+ * batchSize: 50,
356
+ * maxArticlesPerType: 500,
357
+ * onProgress: (progress) => {
358
+ * console.log(`${progress.type}: Batch ${progress.currentBatch}, Total: ${progress.totalFetched}`);
359
+ * }
360
+ * });
361
+ *
362
+ * console.log(`Total articles: ${result.totalFetched}`);
363
+ * console.log(`Normal articles: ${result.breakdown.normal.totalFetched}`);
364
+ * console.log(`Video articles: ${result.breakdown.video.totalFetched}`);
365
+ * ```
366
+ *
367
+ * @param accessToken OA access token
368
+ * @param options Configuration options for fetching
369
+ * @returns All articles (normal + video) with combined pagination info
370
+ */
371
+ async getAllArticlesCombined(accessToken, options = {}) {
372
+ try {
373
+ const { batchSize = 50, maxArticlesPerType = 500, onProgress } = options;
374
+ // Fetch normal articles
375
+ const normalResult = await this.getAllArticles(accessToken, "normal", {
376
+ batchSize,
377
+ maxArticles: maxArticlesPerType,
378
+ onProgress: onProgress ? (progress) => onProgress({
379
+ type: "normal",
380
+ ...progress
381
+ }) : undefined
382
+ });
383
+ // Fetch video articles
384
+ const videoResult = await this.getAllArticles(accessToken, "video", {
385
+ batchSize,
386
+ maxArticles: maxArticlesPerType,
387
+ onProgress: onProgress ? (progress) => onProgress({
388
+ type: "video",
389
+ ...progress
390
+ }) : undefined
391
+ });
392
+ // Combine results
393
+ const allArticles = [...normalResult.articles, ...videoResult.articles];
394
+ return {
395
+ articles: allArticles,
396
+ breakdown: {
397
+ normal: normalResult,
398
+ video: videoResult
399
+ },
400
+ totalFetched: allArticles.length,
401
+ totalBatches: normalResult.totalBatches + videoResult.totalBatches
402
+ };
403
+ }
404
+ catch (error) {
405
+ throw this.handleArticleError(error, "Failed to get all articles combined");
406
+ }
407
+ }
241
408
  /**
242
409
  * Remove article
243
410
  * @param accessToken OA access token