@softtynet/zca-js 2.3.1 → 2.3.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.
@@ -16,65 +16,87 @@ require('../../models/ZBusiness.cjs');
16
16
  require('../../models/SyncEvent.cjs');
17
17
  require('../../models/CallEvent.cjs');
18
18
 
19
- const getGroupChatHistoryFactory = utils.apiFactory()((api, ctx, utils) => {
20
- const serviceURL = utils.makeURL(`${api.zpwServiceMap.group_cloud_message[0]}/api/cm/getrecentv2`);
19
+ const getGroupChatHistoryFactory = utils.apiFactory()((api, ctx, utils$1) => {
20
+ const recentServiceURL = utils$1.makeURL(`${api.zpwServiceMap.group_cloud_message[0]}/api/cm/getrecentv2`);
21
+ const oldServiceURL = utils$1.makeURL(`${api.zpwServiceMap.group_cloud_message[0]}/api/cm/getoldv2`);
21
22
  /**
22
- * Get group chat history from Zalo Cloud Message (newest first)
23
+ * Lấy lịch sử tin nhắn nhóm từ Zalo Cloud Message (hỗ trợ cả `/api/cm/getrecentv2` cmd 12506 và `/api/cm/getoldv2` cmd 12507)
23
24
  *
24
- * @param groupId group id
25
- * @param count count of messages to return (default: 50, max safe limit: 200)
25
+ * @param groupId ID nhóm
26
+ * @param countOrOptions Số lượng tin nhắn cần tải (mặc định: `50`) hoặc đối tượng cấu hình phân trang `GetGroupChatHistoryOptions`
26
27
  *
27
28
  * @throws {ZaloApiError}
28
29
  */
29
- return async function getGroupChatHistory(groupId, count = 50) {
30
+ return async function getGroupChatHistory(groupId, countOrOptions = 50) {
30
31
  if (!groupId)
31
32
  throw new ZaloApiError.ZaloApiError("Missing groupId");
32
33
  if (groupId.startsWith("g"))
33
34
  groupId = groupId.slice(1);
34
- const safeCount = Math.min(Math.max(count, 1), 200);
35
+ const options = typeof countOrOptions === "number" ? { count: countOrOptions } : countOrOptions || {};
36
+ const requestedCount = Math.max(options.count ?? 50, 1);
37
+ const maxPages = options.maxPages ?? Math.max(10, Math.ceil(requestedCount / 50) + 2);
38
+ const targetServiceURL = options.useOldEndpoint ? oldServiceURL : recentServiceURL;
39
+ const msgIds = options.msgIds ?? [];
40
+ const src = options.src ?? 3;
35
41
  const messages = [];
36
- let cursor = 0;
42
+ const seenMsgIds = new Set();
43
+ let cursor = options.cursor ?? 0;
37
44
  let lastPage = null;
38
45
  let pageCount = 0;
39
- while (messages.length < safeCount && pageCount < 10) {
46
+ while (messages.length < requestedCount && pageCount < maxPages) {
40
47
  pageCount++;
41
48
  const params = {
42
49
  groupId,
43
50
  globalMsgId: cursor,
44
- count: Math.min(50, safeCount - messages.length),
45
- msgIds: [],
51
+ count: Math.min(50, requestedCount - messages.length),
52
+ msgIds,
46
53
  imei: ctx.imei,
47
- src: 3,
54
+ src,
48
55
  };
49
- const encryptedParams = utils.encodeAES(JSON.stringify(params));
56
+ if (options.isOA) {
57
+ params.isOA = 1;
58
+ }
59
+ const encryptedParams = utils$1.encodeAES(JSON.stringify(params));
50
60
  if (!encryptedParams)
51
61
  throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
52
- const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams, nretry: 0 }), {
62
+ const response = await utils$1.request(utils$1.makeURL(targetServiceURL, { params: encryptedParams, nretry: 0 }), {
53
63
  method: "GET",
54
64
  });
55
- lastPage = await utils.resolve(response, (result) => {
65
+ lastPage = await utils$1.resolve(response, (result) => {
56
66
  let data = result.data;
57
67
  if (typeof data === "string") {
58
- data = JSON.parse(data);
68
+ data = JSON.parse(utils.preParseJsonIds(data));
59
69
  }
60
70
  return data;
61
71
  });
62
72
  if (!lastPage || !Array.isArray(lastPage.groupMsgs))
63
73
  break;
64
74
  for (const rawMsg of lastPage.groupMsgs) {
65
- if (messages.length >= safeCount)
75
+ if (messages.length >= requestedCount)
66
76
  break;
67
- if (messages.some((m) => m.msgId === rawMsg.msgId))
77
+ const msgIdKey = String(rawMsg.msgId ?? rawMsg.cliMsgId ?? "");
78
+ if (msgIdKey && seenMsgIds.has(msgIdKey))
68
79
  continue;
80
+ if (msgIdKey)
81
+ seenMsgIds.add(msgIdKey);
69
82
  messages.push(rawMsg);
70
83
  }
71
- const nextCursor = Number(lastPage.lastMsgId);
72
- if (!lastPage.hasMore || !nextCursor || nextCursor === cursor)
84
+ const nextCursor = lastPage.lastMsgId;
85
+ if (!lastPage.hasMore ||
86
+ nextCursor === undefined ||
87
+ nextCursor === null ||
88
+ nextCursor === "" ||
89
+ nextCursor === 0 ||
90
+ String(nextCursor) === String(cursor)) {
73
91
  break;
92
+ }
74
93
  cursor = nextCursor;
75
94
  }
76
95
  const groupMsgs = messages.map((data) => new Message.GroupMessage(ctx.uid, data));
77
- return Object.assign({}, lastPage || {}, { groupMsgs });
96
+ return Object.assign({}, lastPage || {}, {
97
+ groupMsgs,
98
+ nextCursor: lastPage?.lastMsgId,
99
+ });
78
100
  };
79
101
  });
80
102
 
@@ -0,0 +1,79 @@
1
+ 'use strict';
2
+
3
+ var ZaloApiError = require('../../Errors/ZaloApiError.cjs');
4
+ require('../../models/AutoReply.cjs');
5
+ require('../../models/Bank.cjs');
6
+ require('../../models/Board.cjs');
7
+ require('../../models/Enum.cjs');
8
+ require('../../models/FriendEvent.cjs');
9
+ require('../../models/Group.cjs');
10
+ require('../../models/GroupEvent.cjs');
11
+ var Message = require('../../models/Message.cjs');
12
+ require('../../models/Reaction.cjs');
13
+ require('../../models/Reminder.cjs');
14
+ require('../../models/ZBusiness.cjs');
15
+ require('../../models/SyncEvent.cjs');
16
+ require('../../models/CallEvent.cjs');
17
+ var utils = require('../../utils.cjs');
18
+
19
+ const getGroupHistoryLegacyFactory = utils.apiFactory()((api, ctx, utils$1) => {
20
+ const serviceURL = utils$1.makeURL(`${api.zpwServiceMap.group[0]}/api/group/history`);
21
+ /**
22
+ * Lấy lịch sử tin nhắn nhóm qua endpoint `/api/group/history` trên miền `group` (command 11240)
23
+ *
24
+ * @param groupId ID của nhóm
25
+ * @param count Số lượng tin nhắn cần tải (mặc định: `20`)
26
+ * @throws {ZaloApiError}
27
+ */
28
+ return async function getGroupHistoryLegacy(groupId, count = 20) {
29
+ if (!groupId) {
30
+ throw new ZaloApiError.ZaloApiError("Missing groupId");
31
+ }
32
+ const cleanGroupId = groupId.startsWith("g") ? groupId.slice(1) : groupId;
33
+ const params = {
34
+ grid: cleanGroupId,
35
+ count,
36
+ };
37
+ const encryptedParams = utils$1.encodeAES(JSON.stringify(params));
38
+ if (!encryptedParams) {
39
+ throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
40
+ }
41
+ const response = await utils$1.request(utils$1.makeURL(serviceURL, { params: encryptedParams }), {
42
+ method: "GET",
43
+ });
44
+ return utils$1.resolve(response, (result) => {
45
+ let data = result.data;
46
+ if (typeof data === "string") {
47
+ try {
48
+ data = JSON.parse(utils.preParseJsonIds(data));
49
+ }
50
+ catch {
51
+ data = {};
52
+ }
53
+ }
54
+ if (Array.isArray(data)) {
55
+ const groupMsgs = data.map((m) => new Message.GroupMessage(ctx.uid, m));
56
+ return { groupMsgs };
57
+ }
58
+ if (data && typeof data === "object") {
59
+ const obj = data;
60
+ const rawList = Array.isArray(obj.groupMsgs)
61
+ ? obj.groupMsgs
62
+ : Array.isArray(obj.msgs)
63
+ ? obj.msgs
64
+ : null;
65
+ if (rawList) {
66
+ const groupMsgs = rawList.map((m) => new Message.GroupMessage(ctx.uid, m));
67
+ return {
68
+ ...obj,
69
+ groupMsgs,
70
+ };
71
+ }
72
+ return obj;
73
+ }
74
+ return { groupMsgs: [] };
75
+ });
76
+ };
77
+ });
78
+
79
+ exports.getGroupHistoryLegacyFactory = getGroupHistoryLegacyFactory;
@@ -0,0 +1,53 @@
1
+ 'use strict';
2
+
3
+ var ZaloApiError = require('../../Errors/ZaloApiError.cjs');
4
+ var utils = require('../../utils.cjs');
5
+
6
+ const getGroupInfoV2Factory = utils.apiFactory()((api, ctx, utils) => {
7
+ const v2ServiceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/getgi/v2`);
8
+ const v1ServiceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/getgi`);
9
+ /**
10
+ * Lấy thông tin nhóm và danh sách thành viên theo trang qua `/api/group/getgi/v2` hoặc `/api/group/getgi` (command 11162)
11
+ *
12
+ * @param groupId ID của nhóm
13
+ * @param pageOrOptions Số trang `mpage` (mặc định: `1`) hoặc cấu hình `GetGroupInfoV2Options`
14
+ * @throws {ZaloApiError}
15
+ */
16
+ return async function getGroupInfoV2(groupId, pageOrOptions = 1) {
17
+ if (!groupId) {
18
+ throw new ZaloApiError.ZaloApiError("Missing groupId");
19
+ }
20
+ const cleanGroupId = groupId.startsWith("g") ? groupId.slice(1) : groupId;
21
+ const options = typeof pageOrOptions === "number" ? { mpage: pageOrOptions } : pageOrOptions || {};
22
+ const mpage = options.mpage ?? 1;
23
+ const mcount = options.mcount ?? 100;
24
+ const avatarSize = options.avatarSize ?? 120;
25
+ const memberAvatarSize = options.memberAvatarSize ?? 120;
26
+ const useV1 = Boolean(options.useV1Endpoint);
27
+ const targetURL = useV1 ? v1ServiceURL : v2ServiceURL;
28
+ const params = useV1
29
+ ? {
30
+ grid: cleanGroupId,
31
+ avatar_size: avatarSize,
32
+ member_avatar_size: memberAvatarSize,
33
+ }
34
+ : {
35
+ grid: cleanGroupId,
36
+ avatar_size: avatarSize,
37
+ member_avatar_size: memberAvatarSize,
38
+ mpage,
39
+ mcount,
40
+ imei: ctx.imei,
41
+ };
42
+ const encryptedParams = utils.encodeAES(JSON.stringify(params));
43
+ if (!encryptedParams) {
44
+ throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
45
+ }
46
+ const response = await utils.request(utils.makeURL(targetURL, { params: encryptedParams }), {
47
+ method: "GET",
48
+ });
49
+ return utils.resolve(response);
50
+ };
51
+ });
52
+
53
+ exports.getGroupInfoV2Factory = getGroupInfoV2Factory;
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ var ZaloApiError = require('../../Errors/ZaloApiError.cjs');
4
+ var utils = require('../../utils.cjs');
5
+
6
+ const getGroupListV3Factory = utils.apiFactory()((api, ctx, utils) => {
7
+ const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/getlg/v3`);
8
+ /**
9
+ * Lấy danh sách nhóm theo trang kèm thông tin thành viên đại diện (`currentMems`) và gợi ý nhóm (`suggestGroup`) qua `/api/group/getlg/v3` (command 11161)
10
+ *
11
+ * @param pageOrOptions Số trang (mặc định: `1`) hoặc cấu hình `GetGroupListV3Options`
12
+ * @throws {ZaloApiError}
13
+ */
14
+ return async function getGroupListV3(pageOrOptions = 1) {
15
+ const options = typeof pageOrOptions === "number" ? { page: pageOrOptions } : pageOrOptions || {};
16
+ const params = {
17
+ page: options.page ?? 1,
18
+ count: options.count ?? 100,
19
+ avatar_size: 120,
20
+ member_avatar_size: 120,
21
+ imei: ctx.imei,
22
+ };
23
+ const encryptedParams = utils.encodeAES(JSON.stringify(params));
24
+ if (!encryptedParams) {
25
+ throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
26
+ }
27
+ const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
28
+ method: "GET",
29
+ });
30
+ return utils.resolve(response);
31
+ };
32
+ });
33
+
34
+ exports.getGroupListV3Factory = getGroupListV3Factory;
@@ -0,0 +1,82 @@
1
+ 'use strict';
2
+
3
+ var ZaloApiError = require('../../Errors/ZaloApiError.cjs');
4
+ var utils = require('../../utils.cjs');
5
+
6
+ const getGroupMessageStatusFactory = utils.apiFactory()((api, _ctx, utils$1) => {
7
+ const serviceURL = utils$1.makeURL(`${api.zpwServiceMap.group[0]}/api/group/getStatusMsg`);
8
+ /**
9
+ * Truy vấn trạng thái Đã nhận (`deliver`) và Đã xem (`seen`) tin nhắn của danh sách thành viên trong nhóm (command 12017)
10
+ *
11
+ * @param groupIdOrItems ID nhóm (hoặc mảng cấu hình `{ tId, ids }`)
12
+ * @param memberIds Danh sách UID thành viên cần kiểm tra (khi tham số đầu là `groupId`)
13
+ * @throws {ZaloApiError}
14
+ */
15
+ return async function getGroupMessageStatus(groupIdOrItems, memberIds = []) {
16
+ let queryData;
17
+ if (Array.isArray(groupIdOrItems)) {
18
+ queryData = groupIdOrItems.map((item) => ({
19
+ tId: item.tId.startsWith("g") ? item.tId.slice(1) : item.tId,
20
+ ids: item.ids.map(String),
21
+ }));
22
+ }
23
+ else {
24
+ if (!groupIdOrItems) {
25
+ throw new ZaloApiError.ZaloApiError("Missing groupId");
26
+ }
27
+ const cleanGroupId = groupIdOrItems.startsWith("g") ? groupIdOrItems.slice(1) : groupIdOrItems;
28
+ queryData = [
29
+ {
30
+ tId: cleanGroupId,
31
+ ids: memberIds.map(String),
32
+ },
33
+ ];
34
+ }
35
+ const params = {
36
+ param: JSON.stringify({
37
+ data: queryData,
38
+ }),
39
+ };
40
+ const encryptedParams = utils$1.encodeAES(JSON.stringify(params));
41
+ if (!encryptedParams) {
42
+ throw new ZaloApiError.ZaloApiError("Failed to encrypt params");
43
+ }
44
+ const response = await utils$1.request(serviceURL, {
45
+ method: "POST",
46
+ body: new URLSearchParams({
47
+ params: encryptedParams,
48
+ }),
49
+ });
50
+ return utils$1.resolve(response, (result) => {
51
+ let rawData = result.data;
52
+ if (typeof rawData === "string" && rawData.length > 0) {
53
+ try {
54
+ const parsed = JSON.parse(utils.preParseJsonIds(rawData));
55
+ if (parsed && typeof parsed === "object" && "data" in parsed && parsed.data) {
56
+ rawData = parsed.data;
57
+ }
58
+ else {
59
+ rawData = parsed;
60
+ }
61
+ }
62
+ catch {
63
+ // Giữ nguyên nếu không phải chuỗi JSON lồng
64
+ }
65
+ }
66
+ if (rawData && typeof rawData === "object") {
67
+ const obj = rawData;
68
+ if (Array.isArray(obj.statusInfos)) {
69
+ return obj;
70
+ }
71
+ if (obj.data && typeof obj.data === "object" && Array.isArray(obj.data.statusInfos)) {
72
+ return obj.data;
73
+ }
74
+ }
75
+ return {
76
+ statusInfos: Array.isArray(rawData) ? rawData : [],
77
+ };
78
+ });
79
+ };
80
+ });
81
+
82
+ exports.getGroupMessageStatusFactory = getGroupMessageStatusFactory;
package/dist/cjs/apis.cjs CHANGED
@@ -83,12 +83,16 @@ var getFullAvatar = require('./apis/profile/getFullAvatar.cjs');
83
83
  var getGroupBlockedMember = require('./apis/group/getGroupBlockedMember.cjs');
84
84
  var getGroupChatHistory = require('./apis/group/getGroupChatHistory.cjs');
85
85
  var getGroupCloudMessageJump = require('./apis/group/getGroupCloudMessageJump.cjs');
86
+ var getGroupHistoryLegacy = require('./apis/group/getGroupHistoryLegacy.cjs');
86
87
  var getGroupInfo = require('./apis/group/getGroupInfo.cjs');
88
+ var getGroupInfoV2 = require('./apis/group/getGroupInfoV2.cjs');
87
89
  var getGroupInviteBoxInfo = require('./apis/group/getGroupInviteBoxInfo.cjs');
88
90
  var getGroupInviteBoxList = require('./apis/group/getGroupInviteBoxList.cjs');
89
91
  var getGroupLinkDetail = require('./apis/group/getGroupLinkDetail.cjs');
90
92
  var getGroupLinkInfo = require('./apis/group/getGroupLinkInfo.cjs');
93
+ var getGroupListV3 = require('./apis/group/getGroupListV3.cjs');
91
94
  var getGroupMembersInfo = require('./apis/group/getGroupMembersInfo.cjs');
95
+ var getGroupMessageStatus = require('./apis/group/getGroupMessageStatus.cjs');
92
96
  var getHiddenConversations = require('./apis/chat/getHiddenConversations.cjs');
93
97
  var getLabels = require('./apis/business/getLabels.cjs');
94
98
  var getLastReadContactTab = require('./apis/friend/getLastReadContactTab.cjs');
@@ -419,12 +423,16 @@ class API {
419
423
  get getGroupBlockedMember() { return api.getGroupBlockedMember; },
420
424
  get getGroupChatHistory() { return api.getGroupChatHistory; },
421
425
  get getGroupCloudMessageJump() { return api.getGroupCloudMessageJump; },
426
+ get getGroupHistoryLegacy() { return api.getGroupHistoryLegacy; },
422
427
  get getGroupInfo() { return api.getGroupInfo; },
428
+ get getGroupInfoV2() { return api.getGroupInfoV2; },
423
429
  get getGroupInviteBoxInfo() { return api.getGroupInviteBoxInfo; },
424
430
  get getGroupInviteBoxList() { return api.getGroupInviteBoxList; },
425
431
  get getGroupLinkDetail() { return api.getGroupLinkDetail; },
426
432
  get getGroupLinkInfo() { return api.getGroupLinkInfo; },
433
+ get getGroupListV3() { return api.getGroupListV3; },
427
434
  get getGroupMembersInfo() { return api.getGroupMembersInfo; },
435
+ get getGroupMessageStatus() { return api.getGroupMessageStatus; },
428
436
  get getPendingGroupMembers() { return api.getPendingGroupMembers; },
429
437
  get getQuotaCommunity() { return api.getQuotaCommunity; },
430
438
  get getRelatedFriendGroup() { return api.getRelatedFriendGroup; },
@@ -774,9 +782,15 @@ class API {
774
782
  get getGroupCloudMessageJump() {
775
783
  return (this._cache.getGroupCloudMessageJump ??= getGroupCloudMessageJump.getGroupCloudMessageJumpFactory(this.ctx, this));
776
784
  }
785
+ get getGroupHistoryLegacy() {
786
+ return (this._cache.getGroupHistoryLegacy ??= getGroupHistoryLegacy.getGroupHistoryLegacyFactory(this.ctx, this));
787
+ }
777
788
  get getGroupInfo() {
778
789
  return (this._cache.getGroupInfo ??= getGroupInfo.getGroupInfoFactory(this.ctx, this));
779
790
  }
791
+ get getGroupInfoV2() {
792
+ return (this._cache.getGroupInfoV2 ??= getGroupInfoV2.getGroupInfoV2Factory(this.ctx, this));
793
+ }
780
794
  get getGroupInviteBoxInfo() {
781
795
  return (this._cache.getGroupInviteBoxInfo ??= getGroupInviteBoxInfo.getGroupInviteBoxInfoFactory(this.ctx, this));
782
796
  }
@@ -789,9 +803,15 @@ class API {
789
803
  get getGroupLinkInfo() {
790
804
  return (this._cache.getGroupLinkInfo ??= getGroupLinkInfo.getGroupLinkInfoFactory(this.ctx, this));
791
805
  }
806
+ get getGroupListV3() {
807
+ return (this._cache.getGroupListV3 ??= getGroupListV3.getGroupListV3Factory(this.ctx, this));
808
+ }
792
809
  get getGroupMembersInfo() {
793
810
  return (this._cache.getGroupMembersInfo ??= getGroupMembersInfo.getGroupMembersInfoFactory(this.ctx, this));
794
811
  }
812
+ get getGroupMessageStatus() {
813
+ return (this._cache.getGroupMessageStatus ??= getGroupMessageStatus.getGroupMessageStatusFactory(this.ctx, this));
814
+ }
795
815
  get getHiddenConversations() {
796
816
  return (this._cache.getHiddenConversations ??= getHiddenConversations.getHiddenConversationsFactory(this.ctx, this));
797
817
  }
@@ -66,6 +66,19 @@ const ZALO_ENDPOINTS = {
66
66
  LIST: "/api/recentsearch/list",
67
67
  UPDATE: "/api/recentsearch/update",
68
68
  },
69
+ GROUP: {
70
+ GET_LIST_V3: "/api/group/getlg/v3",
71
+ GET_LIST_V4: "/api/group/getlg/v4",
72
+ GET_INFO_V1: "/api/group/getgi",
73
+ GET_INFO_V2: "/api/group/getgi/v2",
74
+ GET_MULTI_INFO_V1: "/api/group/getmg",
75
+ GET_MULTI_INFO_V2: "/api/group/getmg-v2",
76
+ GET_STATUS_MSG: "/api/group/getStatusMsg",
77
+ HISTORY_LEGACY: "/api/group/history",
78
+ CLOUD_MSG_RECENT_V2: "/api/cm/getrecentv2",
79
+ CLOUD_MSG_OLD_V2: "/api/cm/getoldv2",
80
+ CLOUD_MSG_JUMP_V2: "/api/cm/rgetv2",
81
+ },
69
82
  };
70
83
 
71
84
  exports.ZALO_ENDPOINTS = ZALO_ENDPOINTS;
@@ -12,7 +12,7 @@ const ZALO_PROTOCOL = {
12
12
  API_VERSION: 689,
13
13
  DEFAULT_API_VERSION: 689,
14
14
  /** Phiên bản SDK hiện tại */
15
- SDK_VERSION: "2.3.1",
15
+ SDK_VERSION: "2.3.3",
16
16
  /** Mã zpw_type đặc thù dành riêng cho phân hệ Gọi Thoại & Video (binary C++ ZaloCall) */
17
17
  VOICECALL_API_TYPE: 24,
18
18
  /** Phiên bản mã hóa ZCID (ParamDecryptor) */
@@ -36,13 +36,7 @@ var zalo = require('./zalo.cjs');
36
36
  var types = require('./realtime/types.cjs');
37
37
  require('events');
38
38
  require('ws');
39
- require('crypto-js');
40
- require('node:crypto');
41
- require('node:fs');
42
- require('node:path');
43
- require('spark-md5');
44
- require('tough-cookie');
45
- require('./context.cjs');
39
+ var utils = require('./utils.cjs');
46
40
  var loginQR = require('./apis/loginQR.cjs');
47
41
  var getFriendRecommendations = require('./apis/friend/getFriendRecommendations.cjs');
48
42
  var reviewPendingMemberRequest = require('./apis/group/reviewPendingMemberRequest.cjs');
@@ -171,6 +165,7 @@ Object.defineProperty(exports, "CloseReason", {
171
165
  enumerable: true,
172
166
  get: function () { return types.CloseReason; }
173
167
  });
168
+ exports.preParseJsonIds = utils.preParseJsonIds;
174
169
  Object.defineProperty(exports, "LoginQRCallbackEventType", {
175
170
  enumerable: true,
176
171
  get: function () { return loginQR.LoginQRCallbackEventType; }
@@ -452,6 +452,67 @@ function getFriendEventType(act) {
452
452
  return FriendEvent.FriendEventType.PIN_CREATE;
453
453
  return FriendEvent.FriendEventType.UNKNOWN;
454
454
  }
455
+ const DEFAULT_BIGINT_ID_FIELDS = [
456
+ "owner_id",
457
+ "group_id",
458
+ "uidFrom",
459
+ "uidTo",
460
+ "uid",
461
+ "ownerId",
462
+ "destId",
463
+ "srcId",
464
+ "fromUid",
465
+ "threadId",
466
+ "globalMsgId",
467
+ "global_msg_id",
468
+ "globalDelMsgId",
469
+ "msgId",
470
+ "refMessageId",
471
+ "cliMsgId",
472
+ "client_msg_id",
473
+ "actionId",
474
+ "lastActionIdOther",
475
+ "lastActionId",
476
+ "resetLastActionId",
477
+ "lastId",
478
+ "ids",
479
+ "topicId",
480
+ "reminderId",
481
+ "eventId",
482
+ ];
483
+ /**
484
+ * Tiền xử lý chuỗi JSON trước khi `JSON.parse` (tương đương `preParse(e, t)` trong `app.asar` của Zalo PC).
485
+ * Bọc dấu ngoặc kép quanh các trường định danh 64-bit (`owner_id`, `group_id`, hoặc các số nguyên >= 16 chữ số
486
+ * vượt quá `Number.MAX_SAFE_INTEGER`) để tránh mất 3 chữ số cuối của UID/MsgId do làm tròn IEEE-754.
487
+ */
488
+ function preParseJsonIds(jsonStr, alwaysStringFields = ["owner_id", "group_id"], bigIntSafeFields = DEFAULT_BIGINT_ID_FIELDS) {
489
+ if (!jsonStr || typeof jsonStr !== "string")
490
+ return jsonStr;
491
+ const alwaysSet = new Set(alwaysStringFields);
492
+ const allFields = Array.from(new Set([...alwaysStringFields, ...bigIntSafeFields]));
493
+ if (allFields.length === 0)
494
+ return jsonStr;
495
+ const escapedKeys = allFields.map((k) => k.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
496
+ const keyValueRegex = new RegExp(`"(${escapedKeys})"(\\s*:\\s*)(\\d+|\\[\\s*\\d+(?:\\s*,\\s*\\d+)*\\s*\\])`, "g");
497
+ return jsonStr.replace(keyValueRegex, (fullMatch, key, sep, rawVal) => {
498
+ const forceString = alwaysSet.has(key);
499
+ if (rawVal.startsWith("[")) {
500
+ const inner = rawVal.slice(1, -1);
501
+ const parts = inner.split(",").map((part) => {
502
+ const trimmed = part.trim();
503
+ if (forceString || trimmed.length >= 16 || Number(trimmed) > Number.MAX_SAFE_INTEGER) {
504
+ return `"${trimmed}"`;
505
+ }
506
+ return trimmed;
507
+ });
508
+ return `"${key}"${sep}[${parts.join(",")}]`;
509
+ }
510
+ if (forceString || rawVal.length >= 16 || Number(rawVal) > Number.MAX_SAFE_INTEGER) {
511
+ return `"${key}"${sep}"${rawVal}"`;
512
+ }
513
+ return fullMatch;
514
+ });
515
+ }
455
516
  async function handleZaloResponse(ctx, response, isEncrypted = true) {
456
517
  const result = {
457
518
  data: null,
@@ -481,7 +542,8 @@ async function handleZaloResponse(ctx, response, isEncrypted = true) {
481
542
  result.data = {};
482
543
  return result;
483
544
  }
484
- const decodedData = isEncrypted ? JSON.parse(decodedStr) : jsonData;
545
+ const safeJsonStr = isEncrypted ? preParseJsonIds(decodedStr) : null;
546
+ const decodedData = isEncrypted ? JSON.parse(safeJsonStr) : jsonData;
485
547
  if (decodedData.error_code != 0) {
486
548
  result.error = {
487
549
  message: decodedData.error_message,
@@ -554,6 +616,7 @@ exports.decryptResp = aes.decryptResp;
554
616
  exports.encodeAES = aes.encodeAES;
555
617
  exports.encryptPin = aes.encryptPin;
556
618
  exports.validatePin = aes.validatePin;
619
+ exports.DEFAULT_BIGINT_ID_FIELDS = DEFAULT_BIGINT_ID_FIELDS;
557
620
  exports.apiFactory = apiFactory;
558
621
  exports.formatTime = formatTime;
559
622
  exports.generateZaloUUID = generateZaloUUID;
@@ -579,6 +642,7 @@ exports.isBun = isBun;
579
642
  exports.logger = logger;
580
643
  exports.makeURL = makeURL;
581
644
  exports.normalizeHolderName = normalizeHolderName;
645
+ exports.preParseJsonIds = preParseJsonIds;
582
646
  exports.removeUndefinedKeys = removeUndefinedKeys;
583
647
  exports.request = request;
584
648
  exports.resolveResponse = resolveResponse;
@@ -64,4 +64,17 @@ export declare const ZALO_ENDPOINTS: {
64
64
  readonly LIST: "/api/recentsearch/list";
65
65
  readonly UPDATE: "/api/recentsearch/update";
66
66
  };
67
+ readonly GROUP: {
68
+ readonly GET_LIST_V3: "/api/group/getlg/v3";
69
+ readonly GET_LIST_V4: "/api/group/getlg/v4";
70
+ readonly GET_INFO_V1: "/api/group/getgi";
71
+ readonly GET_INFO_V2: "/api/group/getgi/v2";
72
+ readonly GET_MULTI_INFO_V1: "/api/group/getmg";
73
+ readonly GET_MULTI_INFO_V2: "/api/group/getmg-v2";
74
+ readonly GET_STATUS_MSG: "/api/group/getStatusMsg";
75
+ readonly HISTORY_LEGACY: "/api/group/history";
76
+ readonly CLOUD_MSG_RECENT_V2: "/api/cm/getrecentv2";
77
+ readonly CLOUD_MSG_OLD_V2: "/api/cm/getoldv2";
78
+ readonly CLOUD_MSG_JUMP_V2: "/api/cm/rgetv2";
79
+ };
67
80
  };
@@ -64,4 +64,17 @@ export const ZALO_ENDPOINTS = {
64
64
  LIST: "/api/recentsearch/list",
65
65
  UPDATE: "/api/recentsearch/update",
66
66
  },
67
+ GROUP: {
68
+ GET_LIST_V3: "/api/group/getlg/v3",
69
+ GET_LIST_V4: "/api/group/getlg/v4",
70
+ GET_INFO_V1: "/api/group/getgi",
71
+ GET_INFO_V2: "/api/group/getgi/v2",
72
+ GET_MULTI_INFO_V1: "/api/group/getmg",
73
+ GET_MULTI_INFO_V2: "/api/group/getmg-v2",
74
+ GET_STATUS_MSG: "/api/group/getStatusMsg",
75
+ HISTORY_LEGACY: "/api/group/history",
76
+ CLOUD_MSG_RECENT_V2: "/api/cm/getrecentv2",
77
+ CLOUD_MSG_OLD_V2: "/api/cm/getoldv2",
78
+ CLOUD_MSG_JUMP_V2: "/api/cm/rgetv2",
79
+ },
67
80
  };
@@ -10,7 +10,7 @@ export declare const ZALO_PROTOCOL: {
10
10
  readonly API_VERSION: 689;
11
11
  readonly DEFAULT_API_VERSION: 689;
12
12
  /** Phiên bản SDK hiện tại */
13
- readonly SDK_VERSION: "2.3.1";
13
+ readonly SDK_VERSION: "2.3.3";
14
14
  /** Mã zpw_type đặc thù dành riêng cho phân hệ Gọi Thoại & Video (binary C++ ZaloCall) */
15
15
  readonly VOICECALL_API_TYPE: 24;
16
16
  /** Phiên bản mã hóa ZCID (ParamDecryptor) */
@@ -10,7 +10,7 @@ export const ZALO_PROTOCOL = {
10
10
  API_VERSION: 689,
11
11
  DEFAULT_API_VERSION: 689,
12
12
  /** Phiên bản SDK hiện tại */
13
- SDK_VERSION: "2.3.1",
13
+ SDK_VERSION: "2.3.3",
14
14
  /** Mã zpw_type đặc thù dành riêng cho phân hệ Gọi Thoại & Video (binary C++ ZaloCall) */
15
15
  VOICECALL_API_TYPE: 24,
16
16
  /** Phiên bản mã hóa ZCID (ParamDecryptor) */