@softtynet/zca-js 2.3.3 → 2.3.5

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.
Files changed (184) hide show
  1. package/README.md +99 -21
  2. package/dist/apis/auth/exportSession.d.ts +7 -0
  3. package/dist/apis/auth/exportSession.js +17 -0
  4. package/dist/apis/call/addUserGroupCall.d.ts +11 -0
  5. package/dist/apis/call/addUserGroupCall.js +48 -0
  6. package/dist/apis/call/answerAckVoiceCall.d.ts +5 -0
  7. package/dist/apis/call/answerAckVoiceCall.js +38 -0
  8. package/dist/apis/call/answerGroupCall.d.ts +10 -0
  9. package/dist/apis/call/answerGroupCall.js +45 -0
  10. package/dist/apis/call/answerVoiceCall.d.ts +11 -0
  11. package/dist/apis/call/answerVoiceCall.js +50 -0
  12. package/dist/apis/call/broadcastGroupCallState.d.ts +10 -0
  13. package/dist/apis/call/broadcastGroupCallState.js +45 -0
  14. package/dist/apis/call/cancelGroupCall.d.ts +10 -0
  15. package/dist/apis/call/cancelGroupCall.js +45 -0
  16. package/dist/apis/call/cancelVoiceCall.d.ts +1 -1
  17. package/dist/apis/call/cancelVoiceCall.js +5 -1
  18. package/dist/apis/call/createController.d.ts +7 -0
  19. package/dist/apis/call/createController.js +9 -0
  20. package/dist/apis/call/createRtcSession.d.ts +8 -0
  21. package/dist/apis/call/createRtcSession.js +10 -0
  22. package/dist/apis/call/endGroupCall.d.ts +10 -0
  23. package/dist/apis/call/endGroupCall.js +45 -0
  24. package/dist/apis/call/finishGroupCall.d.ts +12 -0
  25. package/dist/apis/call/finishGroupCall.js +47 -0
  26. package/dist/apis/call/getGroupCallState.d.ts +3 -0
  27. package/dist/apis/call/getGroupCallState.js +38 -0
  28. package/dist/apis/call/holdVoiceCall.d.ts +5 -0
  29. package/dist/apis/call/holdVoiceCall.js +34 -0
  30. package/dist/apis/call/joinGroupCall.d.ts +11 -0
  31. package/dist/apis/call/joinGroupCall.js +46 -0
  32. package/dist/apis/call/logEndVoiceCall.d.ts +8 -0
  33. package/dist/apis/call/logEndVoiceCall.js +46 -0
  34. package/dist/apis/call/notifyGroupCall.d.ts +9 -0
  35. package/dist/apis/call/notifyGroupCall.js +44 -0
  36. package/dist/apis/call/pingGroupCall.d.ts +10 -0
  37. package/dist/apis/call/pingGroupCall.js +45 -0
  38. package/dist/apis/call/requestAudioToVideoCall.d.ts +5 -0
  39. package/dist/apis/call/requestAudioToVideoCall.js +37 -0
  40. package/dist/apis/call/requestGroupCall.d.ts +9 -0
  41. package/dist/apis/call/requestGroupCall.js +46 -0
  42. package/dist/apis/call/requestShareScreenCall.d.ts +5 -0
  43. package/dist/apis/call/requestShareScreenCall.js +37 -0
  44. package/dist/apis/call/requestVoiceCall.d.ts +10 -0
  45. package/dist/apis/call/requestVoiceCall.js +47 -0
  46. package/dist/apis/call/ringRingGroupCall.d.ts +10 -0
  47. package/dist/apis/call/ringRingGroupCall.js +45 -0
  48. package/dist/apis/call/ringRingVoiceCall.d.ts +5 -0
  49. package/dist/apis/call/ringRingVoiceCall.js +38 -0
  50. package/dist/apis/call/sendRequestGroupCall.d.ts +11 -0
  51. package/dist/apis/call/sendRequestGroupCall.js +48 -0
  52. package/dist/apis/call/sendRequestVoiceCall.d.ts +11 -0
  53. package/dist/apis/call/sendRequestVoiceCall.js +51 -0
  54. package/dist/apis/call/sendVoiceCall.d.ts +8 -1
  55. package/dist/apis/call/sendVoiceCall.js +10 -8
  56. package/dist/apis/call/shareScreenGroupCall.d.ts +10 -0
  57. package/dist/apis/call/shareScreenGroupCall.js +45 -0
  58. package/dist/apis/call/unholdVoiceCall.d.ts +5 -0
  59. package/dist/apis/call/unholdVoiceCall.js +34 -0
  60. package/dist/apis/call/updateCallMediaState.d.ts +7 -0
  61. package/dist/apis/call/updateCallMediaState.js +61 -0
  62. package/dist/apis/chat/getDirectMessageStatus.d.ts +14 -0
  63. package/dist/apis/chat/getDirectMessageStatus.js +52 -0
  64. package/dist/apis/chat/getSuggestedConversations.d.ts +5 -0
  65. package/dist/apis/chat/getSuggestedConversations.js +24 -0
  66. package/dist/apis/chat/updatePinConversations.d.ts +24 -0
  67. package/dist/apis/chat/updatePinConversations.js +40 -0
  68. package/dist/apis/friend/getFriendProfilesV2.d.ts +26 -0
  69. package/dist/apis/friend/getFriendProfilesV2.js +38 -0
  70. package/dist/apis/friend/getFriendsActivePCWeb.d.ts +6 -0
  71. package/dist/apis/friend/getFriendsActivePCWeb.js +15 -0
  72. package/dist/apis/friend/verifyFriend.d.ts +11 -0
  73. package/dist/apis/friend/verifyFriend.js +37 -0
  74. package/dist/apis/group/analyseGroup.d.ts +4 -0
  75. package/dist/apis/group/analyseGroup.js +28 -0
  76. package/dist/apis/group/checkQuotaCommunityMember.d.ts +6 -0
  77. package/dist/apis/group/checkQuotaCommunityMember.js +34 -0
  78. package/dist/apis/group/getE2eeGroupList.d.ts +7 -0
  79. package/dist/apis/group/getE2eeGroupList.js +15 -0
  80. package/dist/apis/group/getGroupCloudMessagePath.d.ts +19 -0
  81. package/dist/apis/group/getGroupCloudMessagePath.js +51 -0
  82. package/dist/apis/group/getMultiGroupCloudMessages.d.ts +5 -0
  83. package/dist/apis/group/getMultiGroupCloudMessages.js +29 -0
  84. package/dist/apis/media/getPersonalMedia.d.ts +8 -0
  85. package/dist/apis/media/getPersonalMedia.js +31 -0
  86. package/dist/apis/media/getPersonalMediaPreview.d.ts +3 -0
  87. package/dist/apis/media/getPersonalMediaPreview.js +24 -0
  88. package/dist/apis/media/removePersonalMedia.d.ts +9 -0
  89. package/dist/apis/media/removePersonalMedia.js +28 -0
  90. package/dist/apis.d.ts +126 -0
  91. package/dist/apis.js +210 -0
  92. package/dist/call-engine/ZRTPPacketCodec.d.ts +262 -0
  93. package/dist/call-engine/ZRTPPacketCodec.js +506 -0
  94. package/dist/call-engine/ZaloCallController.d.ts +134 -0
  95. package/dist/call-engine/ZaloCallController.js +638 -0
  96. package/dist/call-engine/ZaloCallTransport.d.ts +83 -0
  97. package/dist/call-engine/ZaloCallTransport.js +233 -0
  98. package/dist/call-engine/ZaloRtcSession.d.ts +609 -0
  99. package/dist/call-engine/ZaloRtcSession.js +2931 -0
  100. package/dist/call-engine/ZaloSrtpSession.d.ts +80 -0
  101. package/dist/call-engine/ZaloSrtpSession.js +278 -0
  102. package/dist/call-engine/index.d.ts +18 -0
  103. package/dist/call-engine/index.js +24 -0
  104. package/dist/cjs/apis/auth/exportSession.cjs +22 -0
  105. package/dist/cjs/apis/call/addUserGroupCall.cjs +53 -0
  106. package/dist/cjs/apis/call/answerAckVoiceCall.cjs +43 -0
  107. package/dist/cjs/apis/call/answerGroupCall.cjs +50 -0
  108. package/dist/cjs/apis/call/answerVoiceCall.cjs +55 -0
  109. package/dist/cjs/apis/call/broadcastGroupCallState.cjs +50 -0
  110. package/dist/cjs/apis/call/cancelGroupCall.cjs +50 -0
  111. package/dist/cjs/apis/call/cancelVoiceCall.cjs +5 -1
  112. package/dist/cjs/apis/call/createController.cjs +14 -0
  113. package/dist/cjs/apis/call/createRtcSession.cjs +15 -0
  114. package/dist/cjs/apis/call/endGroupCall.cjs +50 -0
  115. package/dist/cjs/apis/call/finishGroupCall.cjs +52 -0
  116. package/dist/cjs/apis/call/getGroupCallState.cjs +43 -0
  117. package/dist/cjs/apis/call/holdVoiceCall.cjs +39 -0
  118. package/dist/cjs/apis/call/joinGroupCall.cjs +51 -0
  119. package/dist/cjs/apis/call/logEndVoiceCall.cjs +51 -0
  120. package/dist/cjs/apis/call/notifyGroupCall.cjs +49 -0
  121. package/dist/cjs/apis/call/pingGroupCall.cjs +50 -0
  122. package/dist/cjs/apis/call/requestAudioToVideoCall.cjs +42 -0
  123. package/dist/cjs/apis/call/requestGroupCall.cjs +51 -0
  124. package/dist/cjs/apis/call/requestShareScreenCall.cjs +42 -0
  125. package/dist/cjs/apis/call/requestVoiceCall.cjs +52 -0
  126. package/dist/cjs/apis/call/ringRingGroupCall.cjs +50 -0
  127. package/dist/cjs/apis/call/ringRingVoiceCall.cjs +43 -0
  128. package/dist/cjs/apis/call/sendRequestGroupCall.cjs +53 -0
  129. package/dist/cjs/apis/call/sendRequestVoiceCall.cjs +56 -0
  130. package/dist/cjs/apis/call/sendVoiceCall.cjs +10 -8
  131. package/dist/cjs/apis/call/shareScreenGroupCall.cjs +50 -0
  132. package/dist/cjs/apis/call/unholdVoiceCall.cjs +39 -0
  133. package/dist/cjs/apis/call/updateCallMediaState.cjs +66 -0
  134. package/dist/cjs/apis/chat/getDirectMessageStatus.cjs +58 -0
  135. package/dist/cjs/apis/chat/getSuggestedConversations.cjs +29 -0
  136. package/dist/cjs/apis/chat/updatePinConversations.cjs +45 -0
  137. package/dist/cjs/apis/friend/getFriendProfilesV2.cjs +43 -0
  138. package/dist/cjs/apis/friend/getFriendsActivePCWeb.cjs +20 -0
  139. package/dist/cjs/apis/friend/verifyFriend.cjs +42 -0
  140. package/dist/cjs/apis/group/analyseGroup.cjs +33 -0
  141. package/dist/cjs/apis/group/checkQuotaCommunityMember.cjs +39 -0
  142. package/dist/cjs/apis/group/getE2eeGroupList.cjs +20 -0
  143. package/dist/cjs/apis/group/getGroupChatHistory.cjs +8 -7
  144. package/dist/cjs/apis/group/getGroupCloudMessagePath.cjs +69 -0
  145. package/dist/cjs/apis/group/getGroupHistoryLegacy.cjs +7 -6
  146. package/dist/cjs/apis/group/getGroupMessageStatus.cjs +7 -6
  147. package/dist/cjs/apis/group/getMultiGroupCloudMessages.cjs +34 -0
  148. package/dist/cjs/apis/media/getPersonalMedia.cjs +36 -0
  149. package/dist/cjs/apis/media/getPersonalMediaPreview.cjs +29 -0
  150. package/dist/cjs/apis/media/removePersonalMedia.cjs +33 -0
  151. package/dist/cjs/apis.cjs +210 -0
  152. package/dist/cjs/call-engine/ZRTPPacketCodec.cjs +525 -0
  153. package/dist/cjs/call-engine/ZaloCallController.cjs +643 -0
  154. package/dist/cjs/call-engine/ZaloCallTransport.cjs +239 -0
  155. package/dist/cjs/call-engine/ZaloRtcSession.cjs +2937 -0
  156. package/dist/cjs/call-engine/ZaloSrtpSession.cjs +287 -0
  157. package/dist/cjs/constants/protocol.cjs +1 -1
  158. package/dist/cjs/context.cjs +20 -2
  159. package/dist/cjs/core/zcloud-client.cjs +1 -2
  160. package/dist/cjs/crypto/ws-cipher.cjs +66 -2
  161. package/dist/cjs/index.cjs +63 -6
  162. package/dist/cjs/models/CallEvent.cjs +95 -1
  163. package/dist/cjs/realtime/handlers/control.handler.cjs +17 -3
  164. package/dist/cjs/realtime/listener.cjs +37 -6
  165. package/dist/cjs/update.cjs +10 -1
  166. package/dist/cjs/utils.cjs +21 -68
  167. package/dist/constants/protocol.d.ts +1 -1
  168. package/dist/constants/protocol.js +1 -1
  169. package/dist/context.d.ts +10 -0
  170. package/dist/context.js +20 -2
  171. package/dist/crypto/ws-cipher.d.ts +7 -0
  172. package/dist/crypto/ws-cipher.js +64 -2
  173. package/dist/index.d.ts +47 -4
  174. package/dist/index.js +2 -0
  175. package/dist/models/CallEvent.d.ts +15 -0
  176. package/dist/models/CallEvent.js +95 -1
  177. package/dist/realtime/handlers/control.handler.js +17 -3
  178. package/dist/realtime/listener.d.ts +6 -0
  179. package/dist/realtime/listener.js +37 -6
  180. package/dist/update.js +10 -1
  181. package/dist/utils.d.ts +0 -7
  182. package/dist/utils.js +15 -64
  183. package/index.d.ts +1 -1
  184. package/package.json +16 -5
package/README.md CHANGED
@@ -2,10 +2,22 @@
2
2
 
3
3
  <p align="left">
4
4
  <a href="https://www.npmjs.com/package/@softtynet/zca-js"><img src="https://img.shields.io/npm/v/@softtynet/zca-js.svg?label=%40softtynet%2Fzca-js&color=0068ff" alt="npm version" /></a>
5
+ <a href="https://softtyos.github.io/zca-js-docs/"><img src="https://img.shields.io/badge/Docs-VitePress-646cff.svg" alt="Documentation" /></a>
5
6
  <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-green.svg" alt="License: MIT" /></a>
6
7
  </p>
7
8
 
8
- **`@softtynet/zca-js`** là bộ thư viện client hỗ trợ kết nối và tương tác Zalo dành cho Node.js, TypeScript và Bun, được duy trì nội bộ bởi **Softtynet Co., Ltd.**
9
+ **`@softtynet/zca-js`** là bộ thư viện SDK kết nối và tương tác Zalo dành cho **Node.js**, **TypeScript** và **Bun**, được phát triển và duy trì bởi **Softtynet Co., Ltd.** dựa trên phân tích giao thức Zalo PC `26.7.10`.
10
+
11
+ - **Trang tài liệu chính thức (Documentation)**: [**https://softtyos.github.io/zca-js-docs/**](https://softtyos.github.io/zca-js-docs/)
12
+
13
+ ---
14
+
15
+ ## Điểm nổi bật
16
+
17
+ - **Kiến trúc 12 Domains (`252 API nguyên bản`)**: Tổ chức trực quan qua `api.auth`, `api.chat`, `api.group`, `api.friend`, `api.profile`, `api.sync`, `api.zcloud`, `api.call`, `api.media`, `api.sticker`, `api.board`, `api.business` (vẫn hỗ trợ gọi phẳng `api.<method>` tương thích ngược 100%).
18
+ - **Đồng bộ lịch sử Mobile (`ZDB 4.0`) & Catch-up Sync**: Hỗ trợ đầy đủ luồng `requestSyncFromPhone` $\rightarrow$ `getSyncData` (giải mã RSA-2048 OAEP/PKCS1 + ZDB 4.0 64KB multi-chunk AES-256-CBC + Deflate) & `pullMobile`.
19
+ - **ZCloud, MediaStore & Bảo toàn Số nguyên 64-bit (`preParseJsonIds`)**: Tự động giữ nguyên độ chính xác chuỗi 19 chữ số cho `owner_id`, `group_id`, `globalMsgId`, `cliMsgId` trước khi `JSON.parse()` và tích hợp bộ mã hóa `98yS` AES-256-CBC cho ZCloud/ZFamily.
20
+ - **Zalo Call Engine thuần TypeScript (`30 API` trong `api.call` + `ZaloRtcSession` / `ZaloCallController`)**: Hỗ trợ đầy đủ cả **Gọi Đi** và **Nhận Cuộc Gọi Đến** (Thoại 1-1, Video Call H.264 FU-A Annex-B 2 chiều, Gọi Nhóm), nâng cấp Thoại $\rightarrow$ Video giữa cuộc gọi, bật/tắt Camera/Mic, Tạm giữ (Hold/Unhold), Tái kết nối UDP (`reconnectUdp`), và **Bàn giao kết nối UDP trực tiếp cho Mobile App (`signalingOnly` / `handoffUdpToExternal`)**.
9
21
 
10
22
  ---
11
23
 
@@ -19,8 +31,6 @@ bun add @softtynet/zca-js
19
31
 
20
32
  ### Cấu hình `imageMetadataGetter` (Tùy chọn khi gửi ảnh từ file nội bộ)
21
33
 
22
- Nếu ứng dụng cần gửi ảnh hoặc GIF từ đường dẫn file trên máy, bạn có thể truyền hàm `imageMetadataGetter` (ví dụ sử dụng `sharp`):
23
-
24
34
  ```ts
25
35
  import { Zalo } from "@softtynet/zca-js";
26
36
  import sharp from "sharp";
@@ -41,6 +51,27 @@ const zalo = new Zalo({ imageMetadataGetter });
41
51
 
42
52
  ---
43
53
 
54
+ ## Kiến trúc 12 Phân hệ (Domains)
55
+
56
+ | Phân hệ | Namespace | Số lượng API | Tài liệu chi tiết |
57
+ | :--- | :--- | :---: | :--- |
58
+ | **Xác thực & Phiên** | `api.auth` | 14 | [`docs/api/auth.md`](docs/api/auth.md) |
59
+ | **Tin nhắn & Hội thoại** | `api.chat` | 41 | [`docs/api/chat.md`](docs/api/chat.md) |
60
+ | **Nhóm & Cộng đồng** | `api.group` | 44 | [`docs/api/group.md`](docs/api/group.md) |
61
+ | **Bạn bè & Danh bạ** | `api.friend` | 33 | [`docs/api/friend.md`](docs/api/friend.md) |
62
+ | **Hồ sơ cá nhân** | `api.profile` | 16 | [`docs/api/profile.md`](docs/api/profile.md) |
63
+ | **Đồng bộ Mobile ZDB 4.0** | `api.sync` | 5 | [`docs/api/sync.md`](docs/api/sync.md) |
64
+ | **Đám mây ZCloud & ZFamily** | `api.zcloud` | 9 | [`docs/api/zcloud.md`](docs/api/zcloud.md) |
65
+ | **Gọi thoại, Video & Gọi nhóm** | `api.call` | 30 | [`docs/api/call.md`](docs/api/call.md) |
66
+ | **Kho lưu trữ & Voice-to-Text** | `api.media` | 8 | [`docs/api/media.md`](docs/api/media.md) |
67
+ | **Nhãn dán & Biểu cảm** | `api.sticker` | 10 | [`docs/api/sticker.md`](docs/api/sticker.md) |
68
+ | **Bảng tin, Bình chọn & Lịch hẹn** | `api.board` | 16 | [`docs/api/board.md`](docs/api/board.md) |
69
+ | **Zalo Business & Danh mục** | `api.business` | 26 | [`docs/api/business.md`](docs/api/business.md) |
70
+
71
+ > Xem tổng quan toàn bộ tài liệu tại [`docs/api/index.md`](docs/api/index.md) hoặc chạy trang tài liệu VitePress cục bộ bằng lệnh `npm run docs:dev`.
72
+
73
+ ---
74
+
44
75
  ## Sử dụng cơ bản
45
76
 
46
77
  ### 1. Đăng nhập bằng mã QR
@@ -53,7 +84,7 @@ const api = await zalo.loginQR();
53
84
  console.log("Đã đăng nhập:", api.getOwnId());
54
85
  ```
55
86
 
56
- ### 2. Lắng nghe tin nhắn
87
+ ### 2. Lắng nghe sự kiện WebSocket thời gian thực
57
88
 
58
89
  ```ts
59
90
  import { Zalo, ThreadType } from "@softtynet/zca-js";
@@ -74,25 +105,72 @@ api.listener.on("message", (message) => {
74
105
  api.listener.start({ retryOnClose: true });
75
106
  ```
76
107
 
77
- ### 3. Gửi tin nhắn văn bản & Sticker
108
+ ### 3. Gọi API theo Domain Namespace
78
109
 
79
110
  ```ts
80
- // Trả lời tin nhắn văn bản
81
- await api.sendMessage(
82
- {
83
- msg: "Xin chào!",
84
- quote: message.data,
85
- },
86
- message.threadId,
87
- message.type,
88
- );
89
-
90
- // Tìm và gửi Sticker
91
- const stickerIds = await api.getStickers("xin chào");
92
- if (stickerIds.length > 0) {
93
- const stickerObject = await api.getStickersDetail(stickerIds[0]);
94
- await api.sendMessageSticker(stickerObject, message.threadId, message.type);
95
- }
111
+ // Nhóm & Lịch sử tin nhắn Cloud
112
+ const groupInfo = await api.group.getGroupInfo("888999000");
113
+ const history = await api.group.getGroupChatHistory("888999000", { count: 50, cursor: 0 });
114
+ const msgStatus = await api.group.getGroupMessageStatus("888999000", ["1000000000000000001"]);
115
+
116
+ // Kho lưu trữ Media / File / Link
117
+ const mediaPreview = await api.media.getMediaStorePreview("888999000", 50);
118
+ const mediaList = await api.media.getConversationMedia({
119
+ groupId: "888999000",
120
+ mediaType: "media",
121
+ limit: 50,
122
+ });
123
+
124
+ // Giải mã thông tin thành viên hàng loạt
125
+ const profiles = await api.group.getGroupMembersInfo(["1000000000000000001"]);
126
+ ```
127
+
128
+ ### 4. Gọi Thoại, Video Call 2 chiều & Nhận Cuộc Gọi Đến (`ZaloRtcSession`)
129
+
130
+ ```ts
131
+ import { CallType } from "@softtynet/zca-js";
132
+
133
+ const session = api.call.createRtcSession({ autoAttachListener: true });
134
+
135
+ // 1) Gọi đi (Audio hoặc Video Call)
136
+ const params = await session.startOutgoingCall("5249661060655759359", {
137
+ callType: CallType.Video,
138
+ });
139
+
140
+ // 2) Nhận luồng Audio Opus & Video H.264 Annex-B thời gian thực
141
+ session.on("audio_frame", (frame) => {
142
+ // frame.payload: Buffer (Opus 16kHz mono)
143
+ });
144
+ session.on("video_annexb_frame", (frame) => {
145
+ // frame.annexB: Buffer (00 00 00 01 + SPS/PPS/IDR/P-Slice), frame.isKeyframe: boolean
146
+ });
147
+
148
+ // 3) Nhận cuộc gọi đến từ sự kiện WebSocket `call_event`
149
+ api.listener.on("call_event", async (ev) => {
150
+ if (ev.act === "request" || ev.act === "group_request") {
151
+ await session.ringIncomingCall(ev); // Báo máy đang đổ chuông (402 / 502)
152
+ const incomingParams = await session.acceptIncomingCall(ev, { skipRingRing: true });
153
+ console.log("Đã bắt máy cuộc gọi đến:", incomingParams.callId, incomingParams.rtpAddress);
154
+ }
155
+ });
156
+
157
+ // 4) Chế độ Worker tạo cuộc gọi và bàn giao gói UDP trực tiếp cho Mobile App:
158
+ const handoffParams = await session.startOutgoingCall("5249661060655759359", {
159
+ callType: CallType.Audio,
160
+ signalingOnly: true, // Worker không mở UDP, xuất sẵn gói `params.mobileDirectHandoff` cho Mobile
161
+ });
162
+ ```
163
+
164
+ ---
165
+
166
+ ## Chạy trang Tài liệu (VitePress Docs)
167
+
168
+ ```bash
169
+ # Khởi chạy máy chủ tài liệu VitePress cục bộ (http://localhost:5173)
170
+ npm run docs:dev
171
+
172
+ # Sinh lại tài liệu từ mã nguồn src/apis/* và đóng gói tĩnh
173
+ npm run docs:build
96
174
  ```
97
175
 
98
176
  ---
@@ -0,0 +1,7 @@
1
+ import type toughCookie from "tough-cookie";
2
+ import type { Credentials } from "../../zalo.js";
3
+ export type ExportedSession = Credentials & {
4
+ uid: string;
5
+ cookie: toughCookie.SerializedCookie[];
6
+ };
7
+ export declare const exportSessionFactory: (ctx: import("../../context.js").ContextBase, api: import("../../apis.js").API) => () => ExportedSession;
@@ -0,0 +1,17 @@
1
+ import { apiFactory } from "../../utils.js";
2
+ export const exportSessionFactory = apiFactory()((_api, ctx) => {
3
+ /**
4
+ * Xuất toàn bộ thông tin phiên đăng nhập hiện tại (`uid`, `imei`, `userAgent`, `language`, `cookie`)
5
+ * dưới định dạng chuẩn `Credentials` để lưu trữ (JSON/Database) và truyền trực tiếp vào `zalo.login(session)`.
6
+ */
7
+ return function exportSession() {
8
+ const serializedJar = ctx.cookie?.toJSON();
9
+ return {
10
+ uid: ctx.uid,
11
+ imei: ctx.imei,
12
+ userAgent: ctx.userAgent,
13
+ language: ctx.language || "vi",
14
+ cookie: serializedJar?.cookies ?? [],
15
+ };
16
+ };
17
+ });
@@ -0,0 +1,11 @@
1
+ import { CallType } from "./sendVoiceCall.js";
2
+ export type AddUserGroupCallOptions = {
3
+ calleeId?: string;
4
+ callType?: CallType | number;
5
+ hostCall: string;
6
+ data?: string | Record<string, unknown>;
7
+ session: string;
8
+ partners: string[];
9
+ };
10
+ export type AddUserGroupCallResponse = Record<string, unknown>;
11
+ export declare const addUserGroupCallFactory: (ctx: import("../../context.js").ContextBase, api: import("../../apis.js").API) => (callId: number, options: AddUserGroupCallOptions) => Promise<AddUserGroupCallResponse>;
@@ -0,0 +1,48 @@
1
+ import { ZaloApiError } from "../../Errors/ZaloApiError.js";
2
+ import { apiFactory } from "../../utils.js";
3
+ import { CallType } from "./sendVoiceCall.js";
4
+ export const addUserGroupCallFactory = apiFactory()((api, _ctx, utils) => {
5
+ const voiceCallService = api.zpwServiceMap.voice_call?.[0];
6
+ /**
7
+ * Mời thêm thành viên vào cuộc gọi nhóm đang diễn ra (`/api/voicecall/group/adduser`, command `12435`).
8
+ *
9
+ * @param callId ID của cuộc gọi nhóm
10
+ * @param options Thông tin `hostCall`, `session`, `partners`, `calleeId`, `callType` và `data`
11
+ * @throws {ZaloApiError}
12
+ */
13
+ return async function addUserGroupCall(callId, options) {
14
+ if (!callId)
15
+ throw new ZaloApiError("Missing callId");
16
+ if (!options?.hostCall)
17
+ throw new ZaloApiError("Missing hostCall");
18
+ if (!options?.session)
19
+ throw new ZaloApiError("Missing session");
20
+ if (!voiceCallService)
21
+ throw new ZaloApiError("Missing voice_call service URL in zpwServiceMap");
22
+ const dataStr = options.data === undefined
23
+ ? "{}"
24
+ : typeof options.data === "string"
25
+ ? options.data
26
+ : JSON.stringify(options.data);
27
+ const params = {
28
+ calleeId: options.calleeId ?? "",
29
+ callId,
30
+ callType: options.callType ?? CallType.GroupAudio,
31
+ hostCall: String(options.hostCall),
32
+ data: dataStr,
33
+ session: options.session,
34
+ partners: (options.partners ?? []).map(String),
35
+ };
36
+ const encryptedParams = utils.encodeAES(JSON.stringify(params));
37
+ if (!encryptedParams)
38
+ throw new ZaloApiError("Failed to encrypt addUserGroupCall params");
39
+ const url = utils.makeURL(`${voiceCallService}/api/voicecall/group/adduser`, {
40
+ zpw_type: 24,
41
+ params: encryptedParams,
42
+ });
43
+ const response = await utils.request(url, {
44
+ method: "GET",
45
+ });
46
+ return utils.resolve(response);
47
+ };
48
+ });
@@ -0,0 +1,5 @@
1
+ export type AnswerAckVoiceCallOptions = {
2
+ status?: number;
3
+ };
4
+ export type AnswerAckVoiceCallResponse = Record<string, unknown>;
5
+ export declare const answerAckVoiceCallFactory: (ctx: import("../../context.js").ContextBase, api: import("../../apis.js").API) => (calleeId: string, callId: number, options?: AnswerAckVoiceCallOptions) => Promise<AnswerAckVoiceCallResponse>;
@@ -0,0 +1,38 @@
1
+ import { ZaloApiError } from "../../Errors/ZaloApiError.js";
2
+ import { apiFactory } from "../../utils.js";
3
+ export const answerAckVoiceCallFactory = apiFactory()((api, ctx, utils) => {
4
+ const voiceCallService = api.zpwServiceMap.voice_call?.[0];
5
+ /**
6
+ * Xác nhận bắt tay hoàn tất từ phía người gọi sau khi người nhận bắt máy (`/api/voicecall/answerack`, command `11304`, signal `408`).
7
+ *
8
+ * @param calleeId User ID của người nhận cuộc gọi
9
+ * @param callId ID của cuộc gọi
10
+ * @param options Tuỳ chọn mã trạng thái (`status`, mặc định `0`)
11
+ * @throws {ZaloApiError}
12
+ */
13
+ return async function answerAckVoiceCall(calleeId, callId, options = {}) {
14
+ if (!calleeId)
15
+ throw new ZaloApiError("Missing calleeId");
16
+ if (!callId)
17
+ throw new ZaloApiError("Missing callId");
18
+ if (!voiceCallService)
19
+ throw new ZaloApiError("Missing voice_call service URL in zpwServiceMap");
20
+ const params = {
21
+ calleeId: String(calleeId),
22
+ callId,
23
+ status: options.status ?? 0,
24
+ imei: ctx.imei,
25
+ };
26
+ const encryptedParams = utils.encodeAES(JSON.stringify(params));
27
+ if (!encryptedParams)
28
+ throw new ZaloApiError("Failed to encrypt answerAckVoiceCall params");
29
+ const url = utils.makeURL(`${voiceCallService}/api/voicecall/answerack`, {
30
+ zpw_type: 24,
31
+ params: encryptedParams,
32
+ });
33
+ const response = await utils.request(url, {
34
+ method: "GET",
35
+ });
36
+ return utils.resolve(response);
37
+ };
38
+ });
@@ -0,0 +1,10 @@
1
+ import { CallType } from "./sendVoiceCall.js";
2
+ export type AnswerGroupCallOptions = {
3
+ calleeId?: string;
4
+ callType?: CallType | number;
5
+ hostCall: string;
6
+ data?: string | Record<string, unknown>;
7
+ partners?: string[];
8
+ };
9
+ export type AnswerGroupCallResponse = Record<string, unknown>;
10
+ export declare const answerGroupCallFactory: (ctx: import("../../context.js").ContextBase, api: import("../../apis.js").API) => (callId: number, options: AnswerGroupCallOptions) => Promise<AnswerGroupCallResponse>;
@@ -0,0 +1,45 @@
1
+ import { ZaloApiError } from "../../Errors/ZaloApiError.js";
2
+ import { apiFactory } from "../../utils.js";
3
+ import { CallType } from "./sendVoiceCall.js";
4
+ export const answerGroupCallFactory = apiFactory()((api, ctx, utils) => {
5
+ const voiceCallService = api.zpwServiceMap.voice_call?.[0];
6
+ /**
7
+ * Chấp nhận / Nghe cuộc gọi nhóm đến (`/api/voicecall/group/answer`, command `12436`).
8
+ *
9
+ * @param callId ID của cuộc gọi nhóm
10
+ * @param options Thông tin `hostCall`, `calleeId`, `callType`, `partners` và `data`
11
+ * @throws {ZaloApiError}
12
+ */
13
+ return async function answerGroupCall(callId, options) {
14
+ if (!callId)
15
+ throw new ZaloApiError("Missing callId");
16
+ if (!options?.hostCall)
17
+ throw new ZaloApiError("Missing hostCall");
18
+ if (!voiceCallService)
19
+ throw new ZaloApiError("Missing voice_call service URL in zpwServiceMap");
20
+ const dataStr = options.data === undefined
21
+ ? "{}"
22
+ : typeof options.data === "string"
23
+ ? options.data
24
+ : JSON.stringify(options.data);
25
+ const params = {
26
+ calleeId: String(options.calleeId ?? ctx.uid),
27
+ callId,
28
+ callType: options.callType ?? CallType.GroupAudio,
29
+ hostCall: String(options.hostCall),
30
+ data: dataStr,
31
+ partners: (options.partners ?? []).map(String),
32
+ };
33
+ const encryptedParams = utils.encodeAES(JSON.stringify(params));
34
+ if (!encryptedParams)
35
+ throw new ZaloApiError("Failed to encrypt answerGroupCall params");
36
+ const url = utils.makeURL(`${voiceCallService}/api/voicecall/group/answer`, {
37
+ zpw_type: 24,
38
+ params: encryptedParams,
39
+ });
40
+ const response = await utils.request(url, {
41
+ method: "GET",
42
+ });
43
+ return utils.resolve(response);
44
+ };
45
+ });
@@ -0,0 +1,11 @@
1
+ export type AnswerVoiceCallOptions = {
2
+ status?: number;
3
+ codec?: string;
4
+ rtcpAddress?: string;
5
+ rtpAddress?: string;
6
+ sessionId?: string;
7
+ extendData?: string | Record<string, unknown>;
8
+ subCommand?: number;
9
+ };
10
+ export type AnswerVoiceCallResponse = Record<string, unknown>;
11
+ export declare const answerVoiceCallFactory: (ctx: import("../../context.js").ContextBase, api: import("../../apis.js").API) => (callerId: string, callId: number, options?: AnswerVoiceCallOptions) => Promise<AnswerVoiceCallResponse>;
@@ -0,0 +1,50 @@
1
+ import { ZaloApiError } from "../../Errors/ZaloApiError.js";
2
+ import { apiFactory } from "../../utils.js";
3
+ export const answerVoiceCallFactory = apiFactory()((api, _ctx, utils) => {
4
+ const voiceCallService = api.zpwServiceMap.voice_call?.[0];
5
+ /**
6
+ * Chấp nhận / Nghe cuộc gọi thoại hoặc video đến (`/api/voicecall/answer`, command `11303`, signal `402`).
7
+ *
8
+ * @param callerId User ID của người gọi đến
9
+ * @param callId ID của cuộc gọi
10
+ * @param options Thông tin `sessionId`, `rtpAddress`, `rtcpAddress`, `codec`, `extendData` và `status`
11
+ * @throws {ZaloApiError}
12
+ */
13
+ return async function answerVoiceCall(callerId, callId, options = {}) {
14
+ if (!callerId)
15
+ throw new ZaloApiError("Missing callerId");
16
+ if (!callId)
17
+ throw new ZaloApiError("Missing callId");
18
+ if (!voiceCallService)
19
+ throw new ZaloApiError("Missing voice_call service URL in zpwServiceMap");
20
+ const extendDataStr = options.extendData === undefined
21
+ ? undefined
22
+ : typeof options.extendData === "string"
23
+ ? options.extendData
24
+ : JSON.stringify(options.extendData);
25
+ const params = {
26
+ callerId: String(callerId),
27
+ callId,
28
+ status: options.status ?? 0,
29
+ codec: options.codec ?? "",
30
+ rtcpAddress: options.rtcpAddress ?? "",
31
+ rtpAddress: options.rtpAddress ?? "",
32
+ session_id: options.sessionId ?? "",
33
+ };
34
+ if (extendDataStr) {
35
+ params.extendData = extendDataStr;
36
+ params.subCommand = options.subCommand ?? 3;
37
+ }
38
+ const encryptedParams = utils.encodeAES(JSON.stringify(params));
39
+ if (!encryptedParams)
40
+ throw new ZaloApiError("Failed to encrypt answerVoiceCall params");
41
+ const url = utils.makeURL(`${voiceCallService}/api/voicecall/answer`, {
42
+ zpw_type: 24,
43
+ params: encryptedParams,
44
+ });
45
+ const response = await utils.request(url, {
46
+ method: "GET",
47
+ });
48
+ return utils.resolve(response);
49
+ };
50
+ });
@@ -0,0 +1,10 @@
1
+ export type BroadcastGroupCallStateOptions = {
2
+ hostCall: string;
3
+ userId?: string;
4
+ callState?: number;
5
+ audioState?: number;
6
+ videoState?: number;
7
+ params?: string | Record<string, unknown>;
8
+ };
9
+ export type BroadcastGroupCallStateResponse = Record<string, unknown>;
10
+ export declare const broadcastGroupCallStateFactory: (ctx: import("../../context.js").ContextBase, api: import("../../apis.js").API) => (callId: number, options: BroadcastGroupCallStateOptions) => Promise<BroadcastGroupCallStateResponse>;
@@ -0,0 +1,45 @@
1
+ import { ZaloApiError } from "../../Errors/ZaloApiError.js";
2
+ import { apiFactory } from "../../utils.js";
3
+ export const broadcastGroupCallStateFactory = apiFactory()((api, ctx, utils) => {
4
+ const voiceCallService = api.zpwServiceMap.voice_call?.[0];
5
+ /**
6
+ * Phát (broadcast) trạng thái âm thanh / hình ảnh của thành viên trong cuộc gọi nhóm (`/api/voicecall/group/broadcast`, command `12098`).
7
+ *
8
+ * @param callId ID của cuộc gọi nhóm
9
+ * @param options Thông tin `hostCall`, `userId`, `callState`, `audioState`, `videoState` và `params`
10
+ * @throws {ZaloApiError}
11
+ */
12
+ return async function broadcastGroupCallState(callId, options) {
13
+ if (!callId)
14
+ throw new ZaloApiError("Missing callId");
15
+ if (!options?.hostCall)
16
+ throw new ZaloApiError("Missing hostCall");
17
+ if (!voiceCallService)
18
+ throw new ZaloApiError("Missing voice_call service URL in zpwServiceMap");
19
+ const paramsStr = options.params === undefined
20
+ ? "{}"
21
+ : typeof options.params === "string"
22
+ ? options.params
23
+ : JSON.stringify(options.params);
24
+ const payload = {
25
+ callId,
26
+ hostCall: String(options.hostCall),
27
+ userId: String(options.userId ?? ctx.uid),
28
+ callstate: options.callState ?? 1,
29
+ audiostate: options.audioState ?? 1,
30
+ videostate: options.videoState ?? 0,
31
+ params: paramsStr,
32
+ };
33
+ const encryptedParams = utils.encodeAES(JSON.stringify(payload));
34
+ if (!encryptedParams)
35
+ throw new ZaloApiError("Failed to encrypt broadcastGroupCallState params");
36
+ const url = utils.makeURL(`${voiceCallService}/api/voicecall/group/broadcast`, {
37
+ zpw_type: 24,
38
+ params: encryptedParams,
39
+ });
40
+ const response = await utils.request(url, {
41
+ method: "GET",
42
+ });
43
+ return utils.resolve(response);
44
+ };
45
+ });
@@ -0,0 +1,10 @@
1
+ import { CallType } from "./sendVoiceCall.js";
2
+ export type CancelGroupCallOptions = {
3
+ calleeId?: string;
4
+ callType?: CallType | number;
5
+ hostCall: string;
6
+ data?: string | Record<string, unknown>;
7
+ partners?: string[];
8
+ };
9
+ export type CancelGroupCallResponse = Record<string, unknown>;
10
+ export declare const cancelGroupCallFactory: (ctx: import("../../context.js").ContextBase, api: import("../../apis.js").API) => (callId: number, options: CancelGroupCallOptions) => Promise<CancelGroupCallResponse>;
@@ -0,0 +1,45 @@
1
+ import { ZaloApiError } from "../../Errors/ZaloApiError.js";
2
+ import { apiFactory } from "../../utils.js";
3
+ import { CallType } from "./sendVoiceCall.js";
4
+ export const cancelGroupCallFactory = apiFactory()((api, ctx, utils) => {
5
+ const voiceCallService = api.zpwServiceMap.voice_call?.[0];
6
+ /**
7
+ * Từ chối / Huỷ lời mời tham gia cuộc gọi nhóm (`/api/voicecall/group/cancel`, command `12437`).
8
+ *
9
+ * @param callId ID của cuộc gọi nhóm
10
+ * @param options Thông tin `hostCall`, `calleeId`, `callType`, `partners` và `data`
11
+ * @throws {ZaloApiError}
12
+ */
13
+ return async function cancelGroupCall(callId, options) {
14
+ if (!callId)
15
+ throw new ZaloApiError("Missing callId");
16
+ if (!options?.hostCall)
17
+ throw new ZaloApiError("Missing hostCall");
18
+ if (!voiceCallService)
19
+ throw new ZaloApiError("Missing voice_call service URL in zpwServiceMap");
20
+ const dataStr = options.data === undefined
21
+ ? "{}"
22
+ : typeof options.data === "string"
23
+ ? options.data
24
+ : JSON.stringify(options.data);
25
+ const params = {
26
+ calleeId: String(options.calleeId ?? ctx.uid),
27
+ callId,
28
+ callType: options.callType ?? CallType.GroupAudio,
29
+ hostCall: String(options.hostCall),
30
+ data: dataStr,
31
+ partners: (options.partners ?? []).map(String),
32
+ };
33
+ const encryptedParams = utils.encodeAES(JSON.stringify(params));
34
+ if (!encryptedParams)
35
+ throw new ZaloApiError("Failed to encrypt cancelGroupCall params");
36
+ const url = utils.makeURL(`${voiceCallService}/api/voicecall/group/cancel`, {
37
+ zpw_type: 24,
38
+ params: encryptedParams,
39
+ });
40
+ const response = await utils.request(url, {
41
+ method: "GET",
42
+ });
43
+ return utils.resolve(response);
44
+ };
45
+ });
@@ -1,6 +1,6 @@
1
1
  import { CallType } from "./sendVoiceCall.js";
2
2
  export type CancelVoiceCallOptions = {
3
- callType?: CallType;
3
+ callType?: CallType | number;
4
4
  status?: number;
5
5
  };
6
6
  export type CancelVoiceCallResponse = Record<string, unknown>;
@@ -18,10 +18,14 @@ export const cancelVoiceCallFactory = apiFactory()((api, ctx, utils) => {
18
18
  throw new ZaloApiError("Missing callId");
19
19
  if (!voiceCallService)
20
20
  throw new ZaloApiError("Missing voice_call service URL in zpwServiceMap");
21
+ const rawCallType = options.callType ?? CallType.Audio;
22
+ // Khớp với ZMessageSerializer::sendCancelCall (0x100026acc): callType = (callType != 1 ? 1 : 0)
23
+ // Cho phép truyền trực tiếp 0 (Audio) hoặc 1 (Video), hoặc CallType.Audio (1) -> 0, CallType.Video (3) -> 1
24
+ const normalizedCallType = rawCallType === 0 || rawCallType === CallType.Audio ? 0 : 1;
21
25
  const params = {
22
26
  callerId: String(calleeId),
23
27
  callId,
24
- callType: options.callType ?? CallType.Audio,
28
+ callType: normalizedCallType,
25
29
  status: options.status ?? 0,
26
30
  imei: ctx.imei,
27
31
  };
@@ -0,0 +1,7 @@
1
+ import type { API } from "../../apis.js";
2
+ import { ZaloCallController, type ZaloCallControllerOptions } from "../../call-engine/ZaloCallController.js";
3
+ import type { ContextSession } from "../../context.js";
4
+ /**
5
+ * Khởi tạo bộ điều phối cuộc gọi thuần TypeScript `ZaloCallController` (tích hợp `ZaloRtcSession` và kênh IPC `ZaloCallTransport`).
6
+ */
7
+ export declare function createControllerFactory(_ctx: ContextSession, api: API): (options?: ZaloCallControllerOptions) => ZaloCallController;
@@ -0,0 +1,9 @@
1
+ import { ZaloCallController } from "../../call-engine/ZaloCallController.js";
2
+ /**
3
+ * Khởi tạo bộ điều phối cuộc gọi thuần TypeScript `ZaloCallController` (tích hợp `ZaloRtcSession` và kênh IPC `ZaloCallTransport`).
4
+ */
5
+ export function createControllerFactory(_ctx, api) {
6
+ return function createController(options = {}) {
7
+ return new ZaloCallController(api, options);
8
+ };
9
+ }
@@ -0,0 +1,8 @@
1
+ import type { API } from "../../apis.js";
2
+ import { ZaloRtcSession, type ZaloRtcSessionOptions } from "../../call-engine/ZaloRtcSession.js";
3
+ import type { ContextSession } from "../../context.js";
4
+ /**
5
+ * Khởi tạo phiên gọi Thoại & Video thuần TypeScript / Node.js (`ZaloRtcSession` — UDP `ZRTPPacket` + `SRTP`)
6
+ * hoạt động độc lập 100% trên Worker / Server / Desktop / Mobile Bridge mà không cần cài đặt Zalo PC.
7
+ */
8
+ export declare function createRtcSessionFactory(_ctx: ContextSession, api: API): (options?: ZaloRtcSessionOptions) => ZaloRtcSession;
@@ -0,0 +1,10 @@
1
+ import { ZaloRtcSession } from "../../call-engine/ZaloRtcSession.js";
2
+ /**
3
+ * Khởi tạo phiên gọi Thoại & Video thuần TypeScript / Node.js (`ZaloRtcSession` — UDP `ZRTPPacket` + `SRTP`)
4
+ * hoạt động độc lập 100% trên Worker / Server / Desktop / Mobile Bridge mà không cần cài đặt Zalo PC.
5
+ */
6
+ export function createRtcSessionFactory(_ctx, api) {
7
+ return function createRtcSession(options = {}) {
8
+ return new ZaloRtcSession(api, options);
9
+ };
10
+ }
@@ -0,0 +1,10 @@
1
+ import { CallType } from "./sendVoiceCall.js";
2
+ export type EndGroupCallOptions = {
3
+ calleeId?: string;
4
+ callType?: CallType | number;
5
+ hostCall: string;
6
+ data?: string | Record<string, unknown>;
7
+ partners?: string[];
8
+ };
9
+ export type EndGroupCallResponse = Record<string, unknown>;
10
+ export declare const endGroupCallFactory: (ctx: import("../../context.js").ContextBase, api: import("../../apis.js").API) => (callId: number, options: EndGroupCallOptions) => Promise<EndGroupCallResponse>;