@softtynet/zca-js 2.2.1 → 2.2.3

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 (94) hide show
  1. package/README.md +47 -21
  2. package/dist/apis/cancelPullMobile.d.ts +11 -0
  3. package/dist/apis/cancelPullMobile.js +33 -0
  4. package/dist/apis/cancelVoiceCall.d.ts +7 -0
  5. package/dist/apis/cancelVoiceCall.js +43 -0
  6. package/dist/apis/decryptGids.d.ts +2 -1
  7. package/dist/apis/decryptGids.js +2 -0
  8. package/dist/apis/endVoiceCall.d.ts +5 -0
  9. package/dist/apis/endVoiceCall.js +41 -0
  10. package/dist/apis/getNoisedIds.d.ts +9 -0
  11. package/dist/apis/getNoisedIds.js +67 -0
  12. package/dist/apis/getSyncData.d.ts +13 -0
  13. package/dist/apis/getSyncData.js +103 -0
  14. package/dist/apis/listen.d.ts +11 -3
  15. package/dist/apis/listen.js +71 -14
  16. package/dist/apis/preloadConversations.d.ts +20 -2
  17. package/dist/apis/preloadConversations.js +56 -3
  18. package/dist/apis/pullMobile.d.ts +15 -0
  19. package/dist/apis/pullMobile.js +38 -0
  20. package/dist/apis/requestSyncFromPhone.d.ts +17 -1
  21. package/dist/apis/requestSyncFromPhone.js +34 -20
  22. package/dist/apis/sendVoiceCall.d.ts +29 -0
  23. package/dist/apis/sendVoiceCall.js +105 -0
  24. package/dist/apis/uploadAttachment.js +6 -1
  25. package/dist/apis.d.ts +14 -0
  26. package/dist/apis.js +14 -0
  27. package/dist/cjs/apis/addReaction.cjs +2 -0
  28. package/dist/cjs/apis/addUnreadMark.cjs +2 -0
  29. package/dist/cjs/apis/cancelPullMobile.cjs +38 -0
  30. package/dist/cjs/apis/cancelVoiceCall.cjs +48 -0
  31. package/dist/cjs/apis/createReminder.cjs +2 -0
  32. package/dist/cjs/apis/decryptGids.cjs +2 -0
  33. package/dist/cjs/apis/deleteChat.cjs +2 -0
  34. package/dist/cjs/apis/deleteMessage.cjs +2 -0
  35. package/dist/cjs/apis/editReminder.cjs +2 -0
  36. package/dist/cjs/apis/endVoiceCall.cjs +46 -0
  37. package/dist/cjs/apis/findUser.cjs +2 -0
  38. package/dist/cjs/apis/findUserByUsername.cjs +2 -0
  39. package/dist/cjs/apis/forwardMessage.cjs +2 -0
  40. package/dist/cjs/apis/getAllFriends.cjs +2 -0
  41. package/dist/cjs/apis/getAvatarUrlProfile.cjs +2 -0
  42. package/dist/cjs/apis/getGroupChatHistory.cjs +2 -0
  43. package/dist/cjs/apis/getListBoard.cjs +2 -0
  44. package/dist/cjs/apis/getListReminder.cjs +2 -0
  45. package/dist/cjs/apis/getMultiUsersByPhones.cjs +2 -0
  46. package/dist/cjs/apis/getNoisedIds.cjs +72 -0
  47. package/dist/cjs/apis/getSyncData.cjs +108 -0
  48. package/dist/cjs/apis/getUserInfo.cjs +2 -0
  49. package/dist/cjs/apis/listen.cjs +71 -14
  50. package/dist/cjs/apis/preloadConversations.cjs +69 -3
  51. package/dist/cjs/apis/pullMobile.cjs +43 -0
  52. package/dist/cjs/apis/removeReminder.cjs +2 -0
  53. package/dist/cjs/apis/removeUnreadMark.cjs +2 -0
  54. package/dist/cjs/apis/requestSyncFromPhone.cjs +33 -19
  55. package/dist/cjs/apis/sendBankCard.cjs +2 -0
  56. package/dist/cjs/apis/sendCard.cjs +2 -0
  57. package/dist/cjs/apis/sendDeliveredEvent.cjs +2 -0
  58. package/dist/cjs/apis/sendLink.cjs +2 -0
  59. package/dist/cjs/apis/sendMessage.cjs +2 -0
  60. package/dist/cjs/apis/sendReport.cjs +2 -0
  61. package/dist/cjs/apis/sendSeenEvent.cjs +2 -0
  62. package/dist/cjs/apis/sendSticker.cjs +2 -0
  63. package/dist/cjs/apis/sendTypingEvent.cjs +2 -0
  64. package/dist/cjs/apis/sendVideo.cjs +2 -0
  65. package/dist/cjs/apis/sendVoice.cjs +2 -0
  66. package/dist/cjs/apis/sendVoiceCall.cjs +110 -0
  67. package/dist/cjs/apis/setHiddenConversations.cjs +2 -0
  68. package/dist/cjs/apis/setMute.cjs +2 -0
  69. package/dist/cjs/apis/setPinnedConversations.cjs +2 -0
  70. package/dist/cjs/apis/undo.cjs +2 -0
  71. package/dist/cjs/apis/updateAutoDeleteChat.cjs +2 -0
  72. package/dist/cjs/apis/uploadAttachment.cjs +8 -1
  73. package/dist/cjs/apis.cjs +14 -0
  74. package/dist/cjs/index.cjs +24 -0
  75. package/dist/cjs/models/CallEvent.cjs +51 -0
  76. package/dist/cjs/models/ClearUnread.cjs +17 -0
  77. package/dist/cjs/models/SyncEvent.cjs +54 -0
  78. package/dist/cjs/utils.cjs +153 -1
  79. package/dist/index.d.ts +11 -1
  80. package/dist/index.js +2 -0
  81. package/dist/models/CallEvent.d.ts +30 -0
  82. package/dist/models/CallEvent.js +47 -0
  83. package/dist/models/ClearUnread.d.ts +22 -0
  84. package/dist/models/ClearUnread.js +12 -0
  85. package/dist/models/SyncData.d.ts +35 -0
  86. package/dist/models/SyncData.js +1 -0
  87. package/dist/models/SyncEvent.d.ts +83 -0
  88. package/dist/models/SyncEvent.js +50 -0
  89. package/dist/models/index.d.ts +4 -0
  90. package/dist/models/index.js +4 -0
  91. package/dist/utils.d.ts +34 -0
  92. package/dist/utils.js +148 -1
  93. package/docs/REA_REVERSE_ENGINEERING_PLAN.md +140 -0
  94. package/package.json +3 -1
@@ -1,4 +1,18 @@
1
- export type PreloadConversationsResponse = {
1
+ import { ClearUnread, type Message, type TClearUnreadItem, type TGroupMessage, type TMessage } from "../models/index.js";
2
+ export type PreloadConversationsRawResponse = {
3
+ msgs?: TMessage[];
4
+ groupMsgs?: TGroupMessage[];
5
+ allmsgs?: Array<TMessage | (TGroupMessage & {
6
+ isGroup?: boolean | number;
7
+ })>;
8
+ eeMsgs?: unknown[];
9
+ pageMsgs?: unknown[];
10
+ clearUnreads?: TClearUnreadItem[];
11
+ clearUnreadsReact?: TClearUnreadItem[];
12
+ seens?: unknown[];
13
+ lastActionId?: string;
14
+ lastActionIdOther?: string;
15
+ more?: number;
2
16
  conversations?: Array<{
3
17
  conv_id: string;
4
18
  last_msgs?: unknown[];
@@ -7,4 +21,8 @@ export type PreloadConversationsResponse = {
7
21
  }>;
8
22
  [key: string]: unknown;
9
23
  };
10
- export declare const preloadConversationsFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => () => Promise<PreloadConversationsResponse>;
24
+ export type PreloadConversationsResponse = PreloadConversationsRawResponse & {
25
+ messages: Message[];
26
+ unreadCleared: ClearUnread[];
27
+ };
28
+ export declare const preloadConversationsFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (threadIdLocalMsgId?: Record<string, string | number>) => Promise<PreloadConversationsResponse>;
@@ -1,15 +1,18 @@
1
1
  import { ZaloApiError } from "../Errors/ZaloApiError.js";
2
+ import { ClearUnread, GroupMessage, UserMessage, } from "../models/index.js";
2
3
  import { apiFactory } from "../utils.js";
3
4
  export const preloadConversationsFactory = apiFactory()((api, ctx, utils) => {
4
5
  const serviceURL = utils.makeURL(`${api.zpwServiceMap.conversation[0]}/api/preloadconvers/get-last-msgs`);
5
6
  /**
6
- * Preload last messages across all active conversations.
7
+ * Preload last messages and unread-cleared states across active conversations.
7
8
  * Useful for initial state loading and catching up missed messages after reconnect.
8
9
  *
10
+ * @param threadIdLocalMsgId Optional map of `{ [threadId]: lastLocalMsgId }` (defaults to `{}`)
9
11
  * @throws {ZaloApiError}
10
12
  */
11
- return async function preloadConversations() {
13
+ return async function preloadConversations(threadIdLocalMsgId = {}) {
12
14
  const params = {
15
+ threadIdLocalMsgId: JSON.stringify(threadIdLocalMsgId !== null && threadIdLocalMsgId !== void 0 ? threadIdLocalMsgId : {}),
13
16
  imei: ctx.imei,
14
17
  };
15
18
  const encryptedParams = utils.encodeAES(JSON.stringify(params));
@@ -18,6 +21,56 @@ export const preloadConversationsFactory = apiFactory()((api, ctx, utils) => {
18
21
  const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
19
22
  method: "GET",
20
23
  });
21
- return utils.resolve(response);
24
+ return utils.resolve(response, (result) => {
25
+ var _a, _b, _c, _d;
26
+ let data = ((_a = result.data) !== null && _a !== void 0 ? _a : {});
27
+ if (typeof data === "string") {
28
+ data = JSON.parse(data);
29
+ }
30
+ const messages = [];
31
+ const seenMsgIds = new Set();
32
+ if (Array.isArray(data.msgs)) {
33
+ for (const msg of data.msgs) {
34
+ const id = String((_b = msg.msgId) !== null && _b !== void 0 ? _b : "");
35
+ if (id && seenMsgIds.has(id))
36
+ continue;
37
+ if (id)
38
+ seenMsgIds.add(id);
39
+ messages.push(new UserMessage(ctx.uid, msg));
40
+ }
41
+ }
42
+ if (Array.isArray(data.groupMsgs)) {
43
+ for (const msg of data.groupMsgs) {
44
+ const id = String((_c = msg.msgId) !== null && _c !== void 0 ? _c : "");
45
+ if (id && seenMsgIds.has(id))
46
+ continue;
47
+ if (id)
48
+ seenMsgIds.add(id);
49
+ messages.push(new GroupMessage(ctx.uid, msg));
50
+ }
51
+ }
52
+ if (Array.isArray(data.allmsgs)) {
53
+ for (const msg of data.allmsgs) {
54
+ const id = String((_d = msg.msgId) !== null && _d !== void 0 ? _d : "");
55
+ if (id && seenMsgIds.has(id))
56
+ continue;
57
+ if (id)
58
+ seenMsgIds.add(id);
59
+ const isGroup = ("isGroup" in msg && Boolean(msg.isGroup)) ||
60
+ (typeof msg.idTo === "string" && msg.idTo.startsWith("g"));
61
+ if (isGroup) {
62
+ messages.push(new GroupMessage(ctx.uid, msg));
63
+ }
64
+ else {
65
+ messages.push(new UserMessage(ctx.uid, msg));
66
+ }
67
+ }
68
+ }
69
+ const unreadCleared = Array.isArray(data.clearUnreads)
70
+ ? data.clearUnreads.map((item) => new ClearUnread(item))
71
+ : [];
72
+ return Object.assign(Object.assign({}, data), { messages,
73
+ unreadCleared });
74
+ });
22
75
  };
23
76
  });
@@ -0,0 +1,15 @@
1
+ export type PullMobileResponse = {
2
+ error_code?: number | string;
3
+ error_message?: string;
4
+ data?: string;
5
+ [key: string]: unknown;
6
+ };
7
+ export type PullMobileParams = {
8
+ public_key: string;
9
+ pc_name?: string;
10
+ from_seq_id?: number;
11
+ is_retry?: number;
12
+ min_seq_id?: number;
13
+ temp_key?: string;
14
+ };
15
+ export declare const pullMobileFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => ({ public_key, pc_name, from_seq_id, is_retry, min_seq_id, temp_key, }: PullMobileParams) => Promise<PullMobileResponse>;
@@ -0,0 +1,38 @@
1
+ import { ZaloApiError } from "../Errors/ZaloApiError.js";
2
+ import { apiFactory } from "../utils.js";
3
+ export const pullMobileFactory = apiFactory()((api, ctx, utils) => {
4
+ const baseURL = utils.makeURL(`${api.zpwServiceMap.file[0]}/api/message/pull_mobile_msg`);
5
+ /**
6
+ * Yêu cầu thiết bị di động Zalo đóng gói và tải lên bản sao lưu tin nhắn (`pull_mobile_msg`, command `12000`).
7
+ * Sự kiện tiến trình (`user_confirm`, `syncmsg_info`, `transfer_error`) sẽ được đẩy về qua `api.listener.on("sync_event")`.
8
+ *
9
+ * @param params Tham số khởi tạo đồng bộ (bao gồm `public_key` RSA SPKI DER Base64)
10
+ * @throws {ZaloApiError}
11
+ */
12
+ return async function pullMobile({ public_key, pc_name = "Web", from_seq_id = 0, is_retry = 0, min_seq_id = 0, temp_key = "", }) {
13
+ if (!public_key)
14
+ throw new ZaloApiError("Missing public_key");
15
+ const payload = {
16
+ pc_name,
17
+ public_key,
18
+ from_seq_id,
19
+ is_retry,
20
+ min_seq_id,
21
+ temp_key,
22
+ imei: ctx.imei,
23
+ };
24
+ const encryptedParams = utils.encodeAES(JSON.stringify(payload));
25
+ if (!encryptedParams)
26
+ throw new ZaloApiError("Failed to encrypt params");
27
+ const serviceURL = utils.makeURL(baseURL, {
28
+ zpw_ver: ctx.API_VERSION,
29
+ zpw_type: ctx.API_TYPE,
30
+ params: encryptedParams,
31
+ nretry: 0,
32
+ }, false);
33
+ const response = await utils.request(serviceURL, {
34
+ method: "GET",
35
+ });
36
+ return utils.resolve(response);
37
+ };
38
+ });
@@ -1,4 +1,20 @@
1
+ export type RequestSyncFromPhoneOptions = {
2
+ pcName?: string;
3
+ fromSeqId?: number;
4
+ isRetry?: number;
5
+ minSeqId?: number;
6
+ tempKey?: string;
7
+ publicKeyBase64?: string;
8
+ privateKeyBase64?: string;
9
+ publicKey?: string;
10
+ privateKey?: string;
11
+ };
1
12
  export type RequestSyncFromPhoneResponse = {
2
13
  success: boolean;
14
+ pcName: string;
15
+ publicKeyBase64: string;
16
+ privateKeyBase64: string;
17
+ publicKey: string;
18
+ privateKey: string;
3
19
  };
4
- export declare const requestSyncFromPhoneFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => () => Promise<RequestSyncFromPhoneResponse>;
20
+ export declare const requestSyncFromPhoneFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (options?: RequestSyncFromPhoneOptions) => Promise<RequestSyncFromPhoneResponse>;
@@ -1,27 +1,41 @@
1
- import { ZaloApiError } from "../Errors/ZaloApiError.js";
2
- import { apiFactory } from "../utils.js";
3
- export const requestSyncFromPhoneFactory = apiFactory()((api, ctx) => {
1
+ import { apiFactory, generateRSAKeyPair } from "../utils.js";
2
+ export const requestSyncFromPhoneFactory = apiFactory()((api) => {
4
3
  /**
5
- * Gửi tín hiệu kích hoạt yêu cầu đồng bộ tin nhắn từ xa sang app điện thoại (Trường hợp 2)
4
+ * Phát tín hiệu yêu cầu đồng bộ tin nhắn từ ứng dụng Zalo trên điện thoại (`pull_mobile_msg`, command `12000`).
6
5
  *
6
+ * Tự động sinh cặp khoá RSA 2048-bit (nếu chưa truyền vào) và gọi `api.pullMobile(...)`.
7
+ * Điện thoại của người dùng sẽ hiển thị thông báo yêu cầu xác nhận đồng bộ (hoặc tự động đồng bộ nếu có `tempKey` từ `transfer_after_login`).
8
+ * Lắng nghe sự kiện `api.listener.on("sync_event", ...)` để nhận tiến trình xác nhận (`user_confirm`) và thông tin file sao lưu (`syncmsg_info`).
9
+ *
10
+ * @param options Tuỳ chọn đồng bộ (`pcName`, `tempKey`, hoặc cặp khoá RSA tự quản lý)
7
11
  * @throws {ZaloApiError}
8
12
  */
9
- return async function requestSyncFromPhone() {
10
- if (!api.listener) {
11
- throw new ZaloApiError("WebSocket listener is not initialized. Please call api.listener.start() first.");
12
- }
13
- // Gửi frame yêu cầu đồng bộ qua WebSocket
14
- const syncPayload = {
15
- version: 1,
16
- cmd: 510,
17
- subCmd: 0,
18
- data: {
19
- act: "sync_request",
20
- imei: ctx.imei,
21
- ts: Date.now(),
22
- },
13
+ return async function requestSyncFromPhone(options = {}) {
14
+ var _a, _b, _c, _d, _e, _f, _g;
15
+ const generated = options.publicKeyBase64 && options.privateKey
16
+ ? {
17
+ publicKeyBase64: options.publicKeyBase64,
18
+ privateKeyBase64: (_a = options.privateKeyBase64) !== null && _a !== void 0 ? _a : "",
19
+ publicKey: (_b = options.publicKey) !== null && _b !== void 0 ? _b : options.publicKeyBase64,
20
+ privateKey: options.privateKey,
21
+ }
22
+ : generateRSAKeyPair();
23
+ const pcName = (_c = options.pcName) !== null && _c !== void 0 ? _c : "Web";
24
+ await api.pullMobile({
25
+ pc_name: pcName,
26
+ public_key: generated.publicKeyBase64,
27
+ from_seq_id: (_d = options.fromSeqId) !== null && _d !== void 0 ? _d : 0,
28
+ is_retry: (_e = options.isRetry) !== null && _e !== void 0 ? _e : 0,
29
+ min_seq_id: (_f = options.minSeqId) !== null && _f !== void 0 ? _f : 0,
30
+ temp_key: (_g = options.tempKey) !== null && _g !== void 0 ? _g : "",
31
+ });
32
+ return {
33
+ success: true,
34
+ pcName,
35
+ publicKeyBase64: generated.publicKeyBase64,
36
+ privateKeyBase64: generated.privateKeyBase64,
37
+ publicKey: generated.publicKey,
38
+ privateKey: generated.privateKey,
23
39
  };
24
- api.listener.sendWs(syncPayload, true);
25
- return { success: true };
26
40
  };
27
41
  });
@@ -0,0 +1,29 @@
1
+ export declare enum CallType {
2
+ Audio = 1,
3
+ Video = 2
4
+ }
5
+ export type SendVoiceCallOptions = {
6
+ callType?: CallType;
7
+ callId?: number;
8
+ codec?: string;
9
+ };
10
+ export type RequestCallServerInfo = {
11
+ sessId: string;
12
+ rtpServer: string;
13
+ rtcpServer: string;
14
+ zrtpKey?: string;
15
+ expiredTime?: number;
16
+ codec?: string;
17
+ [key: string]: unknown;
18
+ };
19
+ export type SendVoiceCallResponse = {
20
+ callId: number;
21
+ sessId: string;
22
+ rtpServer: string;
23
+ rtcpServer: string;
24
+ zrtpKey?: string;
25
+ expiredTime?: number;
26
+ codec?: string;
27
+ requestResult?: unknown;
28
+ };
29
+ export declare const sendVoiceCallFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (calleeId: string, options?: SendVoiceCallOptions) => Promise<SendVoiceCallResponse>;
@@ -0,0 +1,105 @@
1
+ import { ZaloApiError } from "../Errors/ZaloApiError.js";
2
+ import { apiFactory, resolveResponse } from "../utils.js";
3
+ export var CallType;
4
+ (function (CallType) {
5
+ CallType[CallType["Audio"] = 1] = "Audio";
6
+ CallType[CallType["Video"] = 2] = "Video";
7
+ })(CallType || (CallType = {}));
8
+ function parseServerEndpoint(addr) {
9
+ if (!addr)
10
+ return { host: "", ip: "0.0.0.0", port: 0 };
11
+ const idx = addr.lastIndexOf(":");
12
+ if (idx === -1)
13
+ return { host: addr, ip: addr, port: 0 };
14
+ const ip = addr.slice(0, idx);
15
+ const port = Number.parseInt(addr.slice(idx + 1), 10) || 0;
16
+ return { host: addr, ip, port };
17
+ }
18
+ export const sendVoiceCallFactory = apiFactory()((api, ctx, utils) => {
19
+ var _a;
20
+ const voiceCallService = (_a = api.zpwServiceMap.voice_call) === null || _a === void 0 ? void 0 : _a[0];
21
+ /**
22
+ * Khởi tạo cuộc gọi thoại / video (Signaling 2 bước: `/api/voicecall/requestcall` command `11300`
23
+ * + `/api/voicecall/request` command `11301`) giúp đổ chuông trực tiếp trên thiết bị của người nhận.
24
+ *
25
+ * @param calleeId User ID của người nhận cuộc gọi
26
+ * @param options Tuỳ chọn loại cuộc gọi (`CallType.Audio` hoặc `CallType.Video`) và `callId`
27
+ * @throws {ZaloApiError}
28
+ */
29
+ return async function sendVoiceCall(calleeId, options = {}) {
30
+ var _a, _b, _c, _d, _e, _f, _g;
31
+ if (!calleeId)
32
+ throw new ZaloApiError("Missing calleeId");
33
+ if (!voiceCallService)
34
+ throw new ZaloApiError("Missing voice_call service URL in zpwServiceMap");
35
+ const callType = (_a = options.callType) !== null && _a !== void 0 ? _a : CallType.Audio;
36
+ const callId = (_b = options.callId) !== null && _b !== void 0 ? _b : Math.floor(Math.random() * 2000000000);
37
+ const codec = (_c = options.codec) !== null && _c !== void 0 ? _c : "[]";
38
+ const numericCalleeId = Number.isNaN(Number(calleeId)) ? calleeId : Number(calleeId);
39
+ // Step 1: Allocate call session & RTP/RTCP relay endpoints (/api/voicecall/requestcall, command 11300)
40
+ const step1Params = {
41
+ calleeId: numericCalleeId,
42
+ callId,
43
+ codec,
44
+ typeRequest: callType,
45
+ imei: ctx.imei,
46
+ };
47
+ const encryptedStep1 = utils.encodeAES(JSON.stringify(step1Params));
48
+ if (!encryptedStep1)
49
+ throw new ZaloApiError("Failed to encrypt requestcall params");
50
+ const requestCallURL = utils.makeURL(`${voiceCallService}/api/voicecall/requestcall`, {
51
+ zpw_type: 24,
52
+ params: encryptedStep1,
53
+ });
54
+ const step1Res = await utils.request(requestCallURL, {
55
+ method: "GET",
56
+ });
57
+ const serverInfo = await resolveResponse(ctx, step1Res, (result) => {
58
+ const raw = result.data;
59
+ return typeof raw === "string" ? JSON.parse(raw) : raw;
60
+ });
61
+ const rtp = parseServerEndpoint(serverInfo === null || serverInfo === void 0 ? void 0 : serverInfo.rtpServer);
62
+ const rtcp = parseServerEndpoint(serverInfo === null || serverInfo === void 0 ? void 0 : serverInfo.rtcpServer);
63
+ const sessId = (_d = serverInfo === null || serverInfo === void 0 ? void 0 : serverInfo.sessId) !== null && _d !== void 0 ? _d : `${numericCalleeId}_${callId}_401`;
64
+ const resolvedCodec = (_e = serverInfo === null || serverInfo === void 0 ? void 0 : serverInfo.codec) !== null && _e !== void 0 ? _e : codec;
65
+ // Step 2: Send ringing signaling request (/api/voicecall/request, command 11301)
66
+ const extendData = JSON.stringify({
67
+ rtcpDiff: 0,
68
+ rtcp: [{ ip: rtcp.ip, port: rtcp.port }],
69
+ rtp: [{ ip: rtp.ip, port: rtp.port }],
70
+ status: 0,
71
+ });
72
+ const step2Params = {
73
+ calleeId: numericCalleeId,
74
+ rtcpAddress: rtcp.host,
75
+ rtpAddress: rtp.host,
76
+ codec: resolvedCodec,
77
+ session: sessId,
78
+ callId,
79
+ imei: ctx.imei,
80
+ subCommand: 3,
81
+ extendData,
82
+ };
83
+ const encryptedStep2 = utils.encodeAES(JSON.stringify(step2Params));
84
+ if (!encryptedStep2)
85
+ throw new ZaloApiError("Failed to encrypt voicecall request params");
86
+ const requestURL = utils.makeURL(`${voiceCallService}/api/voicecall/request`, {
87
+ zpw_type: 24,
88
+ params: encryptedStep2,
89
+ });
90
+ const step2Res = await utils.request(requestURL, {
91
+ method: "GET",
92
+ });
93
+ const requestResult = await utils.resolve(step2Res);
94
+ return {
95
+ callId,
96
+ sessId,
97
+ rtpServer: (_f = serverInfo === null || serverInfo === void 0 ? void 0 : serverInfo.rtpServer) !== null && _f !== void 0 ? _f : "",
98
+ rtcpServer: (_g = serverInfo === null || serverInfo === void 0 ? void 0 : serverInfo.rtcpServer) !== null && _g !== void 0 ? _g : "",
99
+ zrtpKey: serverInfo === null || serverInfo === void 0 ? void 0 : serverInfo.zrtpKey,
100
+ expiredTime: serverInfo === null || serverInfo === void 0 ? void 0 : serverInfo.expiredTime,
101
+ codec: resolvedCodec,
102
+ requestResult,
103
+ };
104
+ };
105
+ });
@@ -159,9 +159,14 @@ export const uploadAttachmentFactory = apiFactory()((api, ctx, utils) => {
159
159
  */
160
160
  const resData = await resolveResponse(ctx, response);
161
161
  if (resData && resData.fileId != "-1" && resData.photoId != "-1")
162
- await new Promise((resolve) => {
162
+ await new Promise((resolve, reject) => {
163
163
  if (data.fileType == "video" || data.fileType == "others") {
164
+ const timeoutId = setTimeout(() => {
165
+ ctx.uploadCallbacks.delete(resData.fileId.toString());
166
+ reject(new ZaloApiError("Upload attachment timed out after 5 minutes"));
167
+ }, 5 * 60 * 1000);
164
168
  const uploadCallback = async (wsData) => {
169
+ clearTimeout(timeoutId);
165
170
  const result = Object.assign(Object.assign(Object.assign({ fileType: data.fileType }, resData), wsData), { totalSize: data.fileData.totalSize, fileName: data.fileData.fileName, checksum: (await getMd5LargeFileObject(data.source, data.fileData.totalSize)).data });
166
171
  results[atmIndex] = result;
167
172
  resolve();
package/dist/apis.d.ts CHANGED
@@ -9,6 +9,8 @@ import { addUnreadMarkFactory } from "./apis/addUnreadMark.js";
9
9
  import { addUserToGroupFactory } from "./apis/addUserToGroup.js";
10
10
  import { blockUserFactory } from "./apis/blockUser.js";
11
11
  import { blockViewFeedFactory } from "./apis/blockViewFeed.js";
12
+ import { cancelPullMobileFactory } from "./apis/cancelPullMobile.js";
13
+ import { cancelVoiceCallFactory } from "./apis/cancelVoiceCall.js";
12
14
  import { changeAccountAvatarFactory } from "./apis/changeAccountAvatar.js";
13
15
  import { changeFriendAliasFactory } from "./apis/changeFriendAlias.js";
14
16
  import { changeGroupAvatarFactory } from "./apis/changeGroupAvatar.js";
@@ -37,6 +39,7 @@ import { downloadTransferSyncFactory } from "./apis/downloadTransferSync.js";
37
39
  import { editNoteFactory } from "./apis/editNote.js";
38
40
  import { editReminderFactory } from "./apis/editReminder.js";
39
41
  import { enableGroupLinkFactory } from "./apis/enableGroupLink.js";
42
+ import { endVoiceCallFactory } from "./apis/endVoiceCall.js";
40
43
  import { fetchAccountInfoFactory } from "./apis/fetchAccountInfo.js";
41
44
  import { findUserFactory } from "./apis/findUser.js";
42
45
  import { findUserByUsernameFactory } from "./apis/findUserByUsername.js";
@@ -76,6 +79,7 @@ import { getListDeviceFactory } from "./apis/getListDevice.js";
76
79
  import { getListReminderFactory } from "./apis/getListReminder.js";
77
80
  import { getMultiUsersByPhonesFactory } from "./apis/getMultiUsersByPhones.js";
78
81
  import { getMuteFactory } from "./apis/getMute.js";
82
+ import { getNoisedIdsFactory } from "./apis/getNoisedIds.js";
79
83
  import { getOwnIdFactory } from "./apis/getOwnId.js";
80
84
  import { getPendingGroupMembersFactory } from "./apis/getPendingGroupMembers.js";
81
85
  import { getPinConversationsFactory } from "./apis/getPinConversations.js";
@@ -91,6 +95,7 @@ import { getSettingsFactory } from "./apis/getSettings.js";
91
95
  import { getStickerCategoryDetailFactory } from "./apis/getStickerCategoryDetail.js";
92
96
  import { getStickersFactory } from "./apis/getStickers.js";
93
97
  import { getStickersDetailFactory } from "./apis/getStickersDetail.js";
98
+ import { getSyncDataFactory } from "./apis/getSyncData.js";
94
99
  import { getUnreadMarkFactory } from "./apis/getUnreadMark.js";
95
100
  import { getUserInfoFactory } from "./apis/getUserInfo.js";
96
101
  import { inviteUserToGroupsFactory } from "./apis/inviteUserToGroups.js";
@@ -103,6 +108,7 @@ import { lockPollFactory } from "./apis/lockPoll.js";
103
108
  import { lostFocusFactory } from "./apis/lostFocus.js";
104
109
  import { parseLinkFactory } from "./apis/parseLink.js";
105
110
  import { preloadConversationsFactory } from "./apis/preloadConversations.js";
111
+ import { pullMobileFactory } from "./apis/pullMobile.js";
106
112
  import { registerCatalogFactory } from "./apis/registerCatalog.js";
107
113
  import { rejectFriendRequestFactory } from "./apis/rejectFriendRequest.js";
108
114
  import { removeFriendFactory } from "./apis/removeFriend.js";
@@ -131,6 +137,7 @@ import { sendStickerFactory } from "./apis/sendSticker.js";
131
137
  import { sendTypingEventFactory } from "./apis/sendTypingEvent.js";
132
138
  import { sendVideoFactory } from "./apis/sendVideo.js";
133
139
  import { sendVoiceFactory } from "./apis/sendVoice.js";
140
+ import { sendVoiceCallFactory } from "./apis/sendVoiceCall.js";
134
141
  import { setHiddenConversationsFactory } from "./apis/setHiddenConversations.js";
135
142
  import { setMuteFactory } from "./apis/setMute.js";
136
143
  import { setPinnedConversationsFactory } from "./apis/setPinnedConversations.js";
@@ -172,6 +179,8 @@ export declare class API {
172
179
  addUserToGroup: ReturnType<typeof addUserToGroupFactory>;
173
180
  blockUser: ReturnType<typeof blockUserFactory>;
174
181
  blockViewFeed: ReturnType<typeof blockViewFeedFactory>;
182
+ cancelPullMobile: ReturnType<typeof cancelPullMobileFactory>;
183
+ cancelVoiceCall: ReturnType<typeof cancelVoiceCallFactory>;
175
184
  changeAccountAvatar: ReturnType<typeof changeAccountAvatarFactory>;
176
185
  changeFriendAlias: ReturnType<typeof changeFriendAliasFactory>;
177
186
  changeGroupAvatar: ReturnType<typeof changeGroupAvatarFactory>;
@@ -200,6 +209,7 @@ export declare class API {
200
209
  editNote: ReturnType<typeof editNoteFactory>;
201
210
  editReminder: ReturnType<typeof editReminderFactory>;
202
211
  enableGroupLink: ReturnType<typeof enableGroupLinkFactory>;
212
+ endVoiceCall: ReturnType<typeof endVoiceCallFactory>;
203
213
  fetchAccountInfo: ReturnType<typeof fetchAccountInfoFactory>;
204
214
  findUser: ReturnType<typeof findUserFactory>;
205
215
  findUserByUsername: ReturnType<typeof findUserByUsernameFactory>;
@@ -239,6 +249,7 @@ export declare class API {
239
249
  getListReminder: ReturnType<typeof getListReminderFactory>;
240
250
  getMultiUsersByPhones: ReturnType<typeof getMultiUsersByPhonesFactory>;
241
251
  getMute: ReturnType<typeof getMuteFactory>;
252
+ getNoisedIds: ReturnType<typeof getNoisedIdsFactory>;
242
253
  getOwnId: ReturnType<typeof getOwnIdFactory>;
243
254
  getPendingGroupMembers: ReturnType<typeof getPendingGroupMembersFactory>;
244
255
  getPinConversations: ReturnType<typeof getPinConversationsFactory>;
@@ -254,6 +265,7 @@ export declare class API {
254
265
  getStickerCategoryDetail: ReturnType<typeof getStickerCategoryDetailFactory>;
255
266
  getStickers: ReturnType<typeof getStickersFactory>;
256
267
  getStickersDetail: ReturnType<typeof getStickersDetailFactory>;
268
+ getSyncData: ReturnType<typeof getSyncDataFactory>;
257
269
  getUnreadMark: ReturnType<typeof getUnreadMarkFactory>;
258
270
  getUserInfo: ReturnType<typeof getUserInfoFactory>;
259
271
  inviteUserToGroups: ReturnType<typeof inviteUserToGroupsFactory>;
@@ -266,6 +278,7 @@ export declare class API {
266
278
  lostFocus: ReturnType<typeof lostFocusFactory>;
267
279
  parseLink: ReturnType<typeof parseLinkFactory>;
268
280
  preloadConversations: ReturnType<typeof preloadConversationsFactory>;
281
+ pullMobile: ReturnType<typeof pullMobileFactory>;
269
282
  registerCatalog: ReturnType<typeof registerCatalogFactory>;
270
283
  rejectFriendRequest: ReturnType<typeof rejectFriendRequestFactory>;
271
284
  removeFriend: ReturnType<typeof removeFriendFactory>;
@@ -294,6 +307,7 @@ export declare class API {
294
307
  sendTypingEvent: ReturnType<typeof sendTypingEventFactory>;
295
308
  sendVideo: ReturnType<typeof sendVideoFactory>;
296
309
  sendVoice: ReturnType<typeof sendVoiceFactory>;
310
+ sendVoiceCall: ReturnType<typeof sendVoiceCallFactory>;
297
311
  setHiddenConversations: ReturnType<typeof setHiddenConversationsFactory>;
298
312
  setMute: ReturnType<typeof setMuteFactory>;
299
313
  setPinnedConversations: ReturnType<typeof setPinnedConversationsFactory>;
package/dist/apis.js CHANGED
@@ -9,6 +9,8 @@ import { addUnreadMarkFactory } from "./apis/addUnreadMark.js";
9
9
  import { addUserToGroupFactory } from "./apis/addUserToGroup.js";
10
10
  import { blockUserFactory } from "./apis/blockUser.js";
11
11
  import { blockViewFeedFactory } from "./apis/blockViewFeed.js";
12
+ import { cancelPullMobileFactory } from "./apis/cancelPullMobile.js";
13
+ import { cancelVoiceCallFactory } from "./apis/cancelVoiceCall.js";
12
14
  import { changeAccountAvatarFactory } from "./apis/changeAccountAvatar.js";
13
15
  import { changeFriendAliasFactory } from "./apis/changeFriendAlias.js";
14
16
  import { changeGroupAvatarFactory } from "./apis/changeGroupAvatar.js";
@@ -37,6 +39,7 @@ import { downloadTransferSyncFactory } from "./apis/downloadTransferSync.js";
37
39
  import { editNoteFactory } from "./apis/editNote.js";
38
40
  import { editReminderFactory } from "./apis/editReminder.js";
39
41
  import { enableGroupLinkFactory } from "./apis/enableGroupLink.js";
42
+ import { endVoiceCallFactory } from "./apis/endVoiceCall.js";
40
43
  import { fetchAccountInfoFactory } from "./apis/fetchAccountInfo.js";
41
44
  import { findUserFactory } from "./apis/findUser.js";
42
45
  import { findUserByUsernameFactory } from "./apis/findUserByUsername.js";
@@ -76,6 +79,7 @@ import { getListDeviceFactory } from "./apis/getListDevice.js";
76
79
  import { getListReminderFactory } from "./apis/getListReminder.js";
77
80
  import { getMultiUsersByPhonesFactory } from "./apis/getMultiUsersByPhones.js";
78
81
  import { getMuteFactory } from "./apis/getMute.js";
82
+ import { getNoisedIdsFactory } from "./apis/getNoisedIds.js";
79
83
  import { getOwnIdFactory } from "./apis/getOwnId.js";
80
84
  import { getPendingGroupMembersFactory } from "./apis/getPendingGroupMembers.js";
81
85
  import { getPinConversationsFactory } from "./apis/getPinConversations.js";
@@ -91,6 +95,7 @@ import { getSettingsFactory } from "./apis/getSettings.js";
91
95
  import { getStickerCategoryDetailFactory } from "./apis/getStickerCategoryDetail.js";
92
96
  import { getStickersFactory } from "./apis/getStickers.js";
93
97
  import { getStickersDetailFactory } from "./apis/getStickersDetail.js";
98
+ import { getSyncDataFactory } from "./apis/getSyncData.js";
94
99
  import { getUnreadMarkFactory } from "./apis/getUnreadMark.js";
95
100
  import { getUserInfoFactory } from "./apis/getUserInfo.js";
96
101
  import { inviteUserToGroupsFactory } from "./apis/inviteUserToGroups.js";
@@ -103,6 +108,7 @@ import { lockPollFactory } from "./apis/lockPoll.js";
103
108
  import { lostFocusFactory } from "./apis/lostFocus.js";
104
109
  import { parseLinkFactory } from "./apis/parseLink.js";
105
110
  import { preloadConversationsFactory } from "./apis/preloadConversations.js";
111
+ import { pullMobileFactory } from "./apis/pullMobile.js";
106
112
  import { registerCatalogFactory } from "./apis/registerCatalog.js";
107
113
  import { rejectFriendRequestFactory } from "./apis/rejectFriendRequest.js";
108
114
  import { removeFriendFactory } from "./apis/removeFriend.js";
@@ -131,6 +137,7 @@ import { sendStickerFactory } from "./apis/sendSticker.js";
131
137
  import { sendTypingEventFactory } from "./apis/sendTypingEvent.js";
132
138
  import { sendVideoFactory } from "./apis/sendVideo.js";
133
139
  import { sendVoiceFactory } from "./apis/sendVoice.js";
140
+ import { sendVoiceCallFactory } from "./apis/sendVoiceCall.js";
134
141
  import { setHiddenConversationsFactory } from "./apis/setHiddenConversations.js";
135
142
  import { setMuteFactory } from "./apis/setMute.js";
136
143
  import { setPinnedConversationsFactory } from "./apis/setPinnedConversations.js";
@@ -172,6 +179,8 @@ export class API {
172
179
  this.addUserToGroup = addUserToGroupFactory(ctx, this);
173
180
  this.blockUser = blockUserFactory(ctx, this);
174
181
  this.blockViewFeed = blockViewFeedFactory(ctx, this);
182
+ this.cancelPullMobile = cancelPullMobileFactory(ctx, this);
183
+ this.cancelVoiceCall = cancelVoiceCallFactory(ctx, this);
175
184
  this.changeAccountAvatar = changeAccountAvatarFactory(ctx, this);
176
185
  this.changeFriendAlias = changeFriendAliasFactory(ctx, this);
177
186
  this.changeGroupAvatar = changeGroupAvatarFactory(ctx, this);
@@ -200,6 +209,7 @@ export class API {
200
209
  this.editNote = editNoteFactory(ctx, this);
201
210
  this.editReminder = editReminderFactory(ctx, this);
202
211
  this.enableGroupLink = enableGroupLinkFactory(ctx, this);
212
+ this.endVoiceCall = endVoiceCallFactory(ctx, this);
203
213
  this.fetchAccountInfo = fetchAccountInfoFactory(ctx, this);
204
214
  this.findUser = findUserFactory(ctx, this);
205
215
  this.findUserByUsername = findUserByUsernameFactory(ctx, this);
@@ -239,6 +249,7 @@ export class API {
239
249
  this.getListReminder = getListReminderFactory(ctx, this);
240
250
  this.getMultiUsersByPhones = getMultiUsersByPhonesFactory(ctx, this);
241
251
  this.getMute = getMuteFactory(ctx, this);
252
+ this.getNoisedIds = getNoisedIdsFactory(ctx, this);
242
253
  this.getOwnId = getOwnIdFactory(ctx, this);
243
254
  this.getPendingGroupMembers = getPendingGroupMembersFactory(ctx, this);
244
255
  this.getPinConversations = getPinConversationsFactory(ctx, this);
@@ -254,6 +265,7 @@ export class API {
254
265
  this.getStickerCategoryDetail = getStickerCategoryDetailFactory(ctx, this);
255
266
  this.getStickers = getStickersFactory(ctx, this);
256
267
  this.getStickersDetail = getStickersDetailFactory(ctx, this);
268
+ this.getSyncData = getSyncDataFactory(ctx, this);
257
269
  this.getUnreadMark = getUnreadMarkFactory(ctx, this);
258
270
  this.getUserInfo = getUserInfoFactory(ctx, this);
259
271
  this.inviteUserToGroups = inviteUserToGroupsFactory(ctx, this);
@@ -266,6 +278,7 @@ export class API {
266
278
  this.lostFocus = lostFocusFactory(ctx, this);
267
279
  this.parseLink = parseLinkFactory(ctx, this);
268
280
  this.preloadConversations = preloadConversationsFactory(ctx, this);
281
+ this.pullMobile = pullMobileFactory(ctx, this);
269
282
  this.registerCatalog = registerCatalogFactory(ctx, this);
270
283
  this.rejectFriendRequest = rejectFriendRequestFactory(ctx, this);
271
284
  this.removeFriend = removeFriendFactory(ctx, this);
@@ -294,6 +307,7 @@ export class API {
294
307
  this.sendTypingEvent = sendTypingEventFactory(ctx, this);
295
308
  this.sendVideo = sendVideoFactory(ctx, this);
296
309
  this.sendVoice = sendVoiceFactory(ctx, this);
310
+ this.sendVoiceCall = sendVoiceCallFactory(ctx, this);
297
311
  this.setHiddenConversations = setHiddenConversationsFactory(ctx, this);
298
312
  this.setMute = setMuteFactory(ctx, this);
299
313
  this.setPinnedConversations = setPinnedConversationsFactory(ctx, this);
@@ -11,6 +11,8 @@ require('../models/GroupEvent.cjs');
11
11
  var Reaction = require('../models/Reaction.cjs');
12
12
  require('../models/Reminder.cjs');
13
13
  require('../models/ZBusiness.cjs');
14
+ require('../models/SyncEvent.cjs');
15
+ require('../models/CallEvent.cjs');
14
16
  var utils = require('../utils.cjs');
15
17
 
16
18
  const addReactionFactory = utils.apiFactory()((api, ctx, utils) => {
@@ -11,6 +11,8 @@ require('../models/GroupEvent.cjs');
11
11
  require('../models/Reaction.cjs');
12
12
  require('../models/Reminder.cjs');
13
13
  require('../models/ZBusiness.cjs');
14
+ require('../models/SyncEvent.cjs');
15
+ require('../models/CallEvent.cjs');
14
16
  var utils = require('../utils.cjs');
15
17
 
16
18
  const addUnreadMarkFactory = utils.apiFactory()((api, ctx, utils) => {
@@ -0,0 +1,38 @@
1
+ 'use strict';
2
+
3
+ var ZaloApiError = require('../Errors/ZaloApiError.cjs');
4
+ var utils = require('../utils.cjs');
5
+
6
+ const cancelPullMobileFactory = utils.apiFactory()((api, ctx, utils) => {
7
+ const baseURL = utils.makeURL(`${api.zpwServiceMap.file[0]}/api/message/cancel_pull_mobile_msg`);
8
+ /**
9
+ * Huỷ yêu cầu đồng bộ tin nhắn từ điện thoại đang chờ (`cancel_pull_mobile_msg`, command `12700`).
10
+ *
11
+ * @param params Tham số huỷ đồng bộ (`public_key`, `pc_name`)
12
+ * @throws {ZaloApiError}
13
+ */
14
+ return async function cancelPullMobile({ public_key, pc_name = "Web" }) {
15
+ if (!public_key)
16
+ throw new ZaloApiError.ZaloApiError("Missing public_key");
17
+ const payload = {
18
+ pc_name,
19
+ public_key,
20
+ imei: ctx.imei,
21
+ };
22
+ const encryptedParams = utils.encodeAES(JSON.stringify(payload));
23
+ if (!encryptedParams)
24
+ throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
25
+ const serviceURL = utils.makeURL(baseURL, {
26
+ zpw_ver: ctx.API_VERSION,
27
+ zpw_type: ctx.API_TYPE,
28
+ params: encryptedParams,
29
+ nretry: 0,
30
+ }, false);
31
+ const response = await utils.request(serviceURL, {
32
+ method: "GET",
33
+ });
34
+ return utils.resolve(response);
35
+ };
36
+ });
37
+
38
+ exports.cancelPullMobileFactory = cancelPullMobileFactory;