@softtynet/zca-js 2.1.16 → 2.1.18

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.
@@ -267,25 +267,49 @@ function getPlatformFromUA(userAgent) {
267
267
  */
268
268
  function getChromeVersionFromUA(userAgent) {
269
269
  if (!userAgent)
270
- return "130"; // Không có UA → dùng version ổn định
270
+ return "133"; // Không có UA → dùng version ổn định hiện đại
271
271
  const match = userAgent.match(/Chrome\/(\d+)/);
272
- return match ? match[1] : "130"; // Không phải Chrome → fallback về "130"
272
+ return match ? match[1] : "133"; // Không phải Chrome → fallback về "133"
273
+ }
274
+ /**
275
+ * Chuẩn hóa chuỗi Accept-Language dựa theo thiết lập ngôn ngữ ngữ cảnh.
276
+ *
277
+ * @param language Mã ngôn ngữ ("vi", "en", ...)
278
+ * @returns Chuỗi Accept-Language chuẩn theo hành vi trình duyệt
279
+ */
280
+ function getBrowserLanguage(language) {
281
+ if (language === "en") {
282
+ return "en-US,en;q=0.9,vi;q=0.8";
283
+ }
284
+ return "vi-VN,vi;q=0.9,en-US;q=0.8,en;q=0.7";
285
+ }
286
+ /**
287
+ * Sinh bộ header Sec-CH-UA nhất quán theo User-Agent (chỉ khi là Chromium/Chrome).
288
+ *
289
+ * Nếu User-Agent là Firefox/Safari, hàm sẽ trả về object rỗng nhằm tránh
290
+ * tạo ra dị thường Browser Mismatch.
291
+ *
292
+ * @param userAgent Chuỗi User-Agent của client
293
+ * @returns Record chứa các header sec-ch-ua-* hoặc object rỗng
294
+ */
295
+ function getSecChUaHeaders(userAgent) {
296
+ if (!userAgent || !/Chrome\//i.test(userAgent))
297
+ return {};
298
+ const platform = getPlatformFromUA(userAgent);
299
+ const chromeVer = getChromeVersionFromUA(userAgent);
300
+ return {
301
+ "sec-ch-ua": `"Not=A?Brand";v="99", "Google Chrome";v="${chromeVer}", "Chromium";v="${chromeVer}"`,
302
+ "sec-ch-ua-mobile": "?0",
303
+ "sec-ch-ua-platform": `"${platform}"`,
304
+ };
273
305
  }
274
306
  async function getDefaultHeaders(ctx, origin = "https://chat.zalo.me") {
275
307
  if (!ctx.cookie)
276
308
  throw new ZaloApiError.ZaloApiError("Cookie is not available");
277
309
  if (!ctx.userAgent)
278
310
  throw new ZaloApiError.ZaloApiError("User agent is not available");
279
- return {
280
- Accept: "application/json, text/plain, */*",
281
- "Accept-Encoding": "gzip, deflate, br, zstd",
282
- "Accept-Language": "en-US,en;q=0.9",
283
- "content-type": "application/x-www-form-urlencoded",
284
- Cookie: await ctx.cookie.getCookieString(origin),
285
- Origin: "https://chat.zalo.me",
286
- Referer: "https://chat.zalo.me/",
287
- "User-Agent": ctx.userAgent,
288
- };
311
+ const secChUa = getSecChUaHeaders(ctx.userAgent);
312
+ return Object.assign({ accept: "*/*", "accept-encoding": "gzip, deflate, br, zstd", "accept-language": getBrowserLanguage(ctx.language), "content-type": "application/x-www-form-urlencoded", cookie: await ctx.cookie.getCookieString(origin), origin: "https://chat.zalo.me", priority: "u=1, i", referer: "https://chat.zalo.me/", "user-agent": ctx.userAgent, "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-fetch-site": "same-site" }, secChUa);
289
313
  }
290
314
  async function request(ctx, url, options, raw = false) {
291
315
  var _a, _b;
@@ -300,11 +324,17 @@ async function request(ctx, url, options, raw = false) {
300
324
  else
301
325
  options = { headers: defaultHeaders };
302
326
  }
303
- const _options = Object.assign(Object.assign({}, (options !== null && options !== void 0 ? options : {})), (isBun ? {
304
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
305
- // @ts-ignore
306
- proxy: (_b = (_a = ctx.options.agent) === null || _a === void 0 ? void 0 : _a.proxy) === null || _b === void 0 ? void 0 : _b.href
307
- } : { agent: ctx.options.agent }));
327
+ const _options = Object.assign(Object.assign({}, (options !== null && options !== void 0 ? options : {})), (isBun
328
+ ? {
329
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
330
+ // @ts-ignore
331
+ proxy: (_b = (_a = ctx.options.agent) === null || _a === void 0 ? void 0 : _a.proxy) === null || _b === void 0 ? void 0 : _b.href,
332
+ }
333
+ : {
334
+ agent: ctx.options.agent,
335
+ // Hỗ trợ Undici Dispatcher cho Node.js 18+ native fetch
336
+ dispatcher: ctx.options.agent,
337
+ }));
308
338
  const response = await ctx.options.polyfill(url, _options);
309
339
  const setCookieRaw = response.headers.get("set-cookie");
310
340
  if (setCookieRaw && !raw) {
@@ -712,6 +742,7 @@ exports.encodeAES = encodeAES;
712
742
  exports.encryptPin = encryptPin;
713
743
  exports.formatTime = formatTime;
714
744
  exports.generateZaloUUID = generateZaloUUID;
745
+ exports.getBrowserLanguage = getBrowserLanguage;
715
746
  exports.getChromeVersionFromUA = getChromeVersionFromUA;
716
747
  exports.getClientMessageType = getClientMessageType;
717
748
  exports.getDefaultHeaders = getDefaultHeaders;
@@ -725,6 +756,7 @@ exports.getGroupEventType = getGroupEventType;
725
756
  exports.getImageMetaData = getImageMetaData;
726
757
  exports.getMd5LargeFileObject = getMd5LargeFileObject;
727
758
  exports.getPlatformFromUA = getPlatformFromUA;
759
+ exports.getSecChUaHeaders = getSecChUaHeaders;
728
760
  exports.getSignKey = getSignKey;
729
761
  exports.handleZaloResponse = handleZaloResponse;
730
762
  exports.hasOwn = hasOwn;
package/dist/cjs/zalo.cjs CHANGED
@@ -78,7 +78,8 @@ class Zalo {
78
78
  if (!options)
79
79
  options = {};
80
80
  if (!options.userAgent)
81
- options.userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0";
81
+ options.userAgent =
82
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36";
82
83
  if (!options.language)
83
84
  options.language = "vi";
84
85
  const ctx = context.createContext(this.options.apiType, this.options.apiVersion);
package/dist/context.js CHANGED
@@ -10,7 +10,7 @@ class CallbacksMap extends Map {
10
10
  return super.set(key, value);
11
11
  }
12
12
  }
13
- export const createContext = (apiType = 30, apiVersion = 671) => ({
13
+ export const createContext = (apiType = 30, apiVersion = 689) => ({
14
14
  API_TYPE: apiType,
15
15
  API_VERSION: apiVersion,
16
16
  uploadCallbacks: new CallbacksMap(),
package/dist/index.d.ts CHANGED
@@ -31,6 +31,8 @@ export type { DeleteChatLastMessage, DeleteChatResponse } from "./apis/deleteCha
31
31
  export type { DeleteGroupInviteBoxResponse } from "./apis/deleteGroupInviteBox.js";
32
32
  export type { DeleteMessageDestination, DeleteMessageResponse } from "./apis/deleteMessage.js";
33
33
  export type { DeleteProductCatalogPayload, DeleteProductCatalogResponse } from "./apis/deleteProductCatalog.js";
34
+ export type { DecryptGidsResponse } from "./apis/decryptGids.js";
35
+ export type { DownloadTransferSyncOptions } from "./apis/downloadTransferSync.js";
34
36
  export type { DisableGroupLinkResponse } from "./apis/disableGroupLink.js";
35
37
  export type { DisperseGroupResponse } from "./apis/disperseGroup.js";
36
38
  export type { EditNoteOptions, EditNoteResponse } from "./apis/editNote.js";
@@ -103,6 +105,7 @@ export type { RemoveQuickMessageResponse } from "./apis/removeQuickMessage.js";
103
105
  export type { RemoveReminderResponse } from "./apis/removeReminder.js";
104
106
  export type { RemoveUnreadMarkResponse } from "./apis/removeUnreadMark.js";
105
107
  export type { RemoveUserFromGroupResponse } from "./apis/removeUserFromGroup.js";
108
+ export type { RequestSyncFromPhoneResponse } from "./apis/requestSyncFromPhone.js";
106
109
  export type { ResetHiddenConversPinResponse } from "./apis/resetHiddenConversPin.js";
107
110
  export type { ReuseAvatarResponse } from "./apis/reuseAvatar.js";
108
111
  export type { ReviewPendingMemberRequestPayload, ReviewPendingMemberRequestResponse } from "./apis/reviewPendingMemberRequest.js";
package/dist/utils.d.ts CHANGED
@@ -81,15 +81,36 @@ export declare function getPlatformFromUA(userAgent: string | undefined): string
81
81
  * @returns Phiên bản Chrome major dạng string, ví dụ: "130", "133"
82
82
  */
83
83
  export declare function getChromeVersionFromUA(userAgent: string | undefined): string;
84
+ /**
85
+ * Chuẩn hóa chuỗi Accept-Language dựa theo thiết lập ngôn ngữ ngữ cảnh.
86
+ *
87
+ * @param language Mã ngôn ngữ ("vi", "en", ...)
88
+ * @returns Chuỗi Accept-Language chuẩn theo hành vi trình duyệt
89
+ */
90
+ export declare function getBrowserLanguage(language: string | undefined): string;
91
+ /**
92
+ * Sinh bộ header Sec-CH-UA nhất quán theo User-Agent (chỉ khi là Chromium/Chrome).
93
+ *
94
+ * Nếu User-Agent là Firefox/Safari, hàm sẽ trả về object rỗng nhằm tránh
95
+ * tạo ra dị thường Browser Mismatch.
96
+ *
97
+ * @param userAgent Chuỗi User-Agent của client
98
+ * @returns Record chứa các header sec-ch-ua-* hoặc object rỗng
99
+ */
100
+ export declare function getSecChUaHeaders(userAgent: string | undefined): Record<string, string>;
84
101
  export declare function getDefaultHeaders(ctx: ContextBase, origin?: string): Promise<{
85
- Accept: string;
86
- "Accept-Encoding": string;
87
- "Accept-Language": string;
102
+ accept: string;
103
+ "accept-encoding": string;
104
+ "accept-language": string;
88
105
  "content-type": string;
89
- Cookie: string;
90
- Origin: string;
91
- Referer: string;
92
- "User-Agent": string;
106
+ cookie: string;
107
+ origin: string;
108
+ priority: string;
109
+ referer: string;
110
+ "user-agent": string;
111
+ "sec-fetch-dest": string;
112
+ "sec-fetch-mode": string;
113
+ "sec-fetch-site": string;
93
114
  }>;
94
115
  export declare function request(ctx: ContextBase, url: string, options?: RequestInit, raw?: boolean): Promise<Response>;
95
116
  export declare function getImageMetaData(ctx: ContextBase, filePath: string): Promise<{
package/dist/utils.js CHANGED
@@ -263,25 +263,49 @@ export function getPlatformFromUA(userAgent) {
263
263
  */
264
264
  export function getChromeVersionFromUA(userAgent) {
265
265
  if (!userAgent)
266
- return "130"; // Không có UA → dùng version ổn định
266
+ return "133"; // Không có UA → dùng version ổn định hiện đại
267
267
  const match = userAgent.match(/Chrome\/(\d+)/);
268
- return match ? match[1] : "130"; // Không phải Chrome → fallback về "130"
268
+ return match ? match[1] : "133"; // Không phải Chrome → fallback về "133"
269
+ }
270
+ /**
271
+ * Chuẩn hóa chuỗi Accept-Language dựa theo thiết lập ngôn ngữ ngữ cảnh.
272
+ *
273
+ * @param language Mã ngôn ngữ ("vi", "en", ...)
274
+ * @returns Chuỗi Accept-Language chuẩn theo hành vi trình duyệt
275
+ */
276
+ export function getBrowserLanguage(language) {
277
+ if (language === "en") {
278
+ return "en-US,en;q=0.9,vi;q=0.8";
279
+ }
280
+ return "vi-VN,vi;q=0.9,en-US;q=0.8,en;q=0.7";
281
+ }
282
+ /**
283
+ * Sinh bộ header Sec-CH-UA nhất quán theo User-Agent (chỉ khi là Chromium/Chrome).
284
+ *
285
+ * Nếu User-Agent là Firefox/Safari, hàm sẽ trả về object rỗng nhằm tránh
286
+ * tạo ra dị thường Browser Mismatch.
287
+ *
288
+ * @param userAgent Chuỗi User-Agent của client
289
+ * @returns Record chứa các header sec-ch-ua-* hoặc object rỗng
290
+ */
291
+ export function getSecChUaHeaders(userAgent) {
292
+ if (!userAgent || !/Chrome\//i.test(userAgent))
293
+ return {};
294
+ const platform = getPlatformFromUA(userAgent);
295
+ const chromeVer = getChromeVersionFromUA(userAgent);
296
+ return {
297
+ "sec-ch-ua": `"Not=A?Brand";v="99", "Google Chrome";v="${chromeVer}", "Chromium";v="${chromeVer}"`,
298
+ "sec-ch-ua-mobile": "?0",
299
+ "sec-ch-ua-platform": `"${platform}"`,
300
+ };
269
301
  }
270
302
  export async function getDefaultHeaders(ctx, origin = "https://chat.zalo.me") {
271
303
  if (!ctx.cookie)
272
304
  throw new ZaloApiError("Cookie is not available");
273
305
  if (!ctx.userAgent)
274
306
  throw new ZaloApiError("User agent is not available");
275
- return {
276
- Accept: "application/json, text/plain, */*",
277
- "Accept-Encoding": "gzip, deflate, br, zstd",
278
- "Accept-Language": "en-US,en;q=0.9",
279
- "content-type": "application/x-www-form-urlencoded",
280
- Cookie: await ctx.cookie.getCookieString(origin),
281
- Origin: "https://chat.zalo.me",
282
- Referer: "https://chat.zalo.me/",
283
- "User-Agent": ctx.userAgent,
284
- };
307
+ const secChUa = getSecChUaHeaders(ctx.userAgent);
308
+ return Object.assign({ accept: "*/*", "accept-encoding": "gzip, deflate, br, zstd", "accept-language": getBrowserLanguage(ctx.language), "content-type": "application/x-www-form-urlencoded", cookie: await ctx.cookie.getCookieString(origin), origin: "https://chat.zalo.me", priority: "u=1, i", referer: "https://chat.zalo.me/", "user-agent": ctx.userAgent, "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-fetch-site": "same-site" }, secChUa);
285
309
  }
286
310
  export async function request(ctx, url, options, raw = false) {
287
311
  var _a, _b;
@@ -296,11 +320,17 @@ export async function request(ctx, url, options, raw = false) {
296
320
  else
297
321
  options = { headers: defaultHeaders };
298
322
  }
299
- const _options = Object.assign(Object.assign({}, (options !== null && options !== void 0 ? options : {})), (isBun ? {
300
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
301
- // @ts-ignore
302
- proxy: (_b = (_a = ctx.options.agent) === null || _a === void 0 ? void 0 : _a.proxy) === null || _b === void 0 ? void 0 : _b.href
303
- } : { agent: ctx.options.agent }));
323
+ const _options = Object.assign(Object.assign({}, (options !== null && options !== void 0 ? options : {})), (isBun
324
+ ? {
325
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
326
+ // @ts-ignore
327
+ proxy: (_b = (_a = ctx.options.agent) === null || _a === void 0 ? void 0 : _a.proxy) === null || _b === void 0 ? void 0 : _b.href,
328
+ }
329
+ : {
330
+ agent: ctx.options.agent,
331
+ // Hỗ trợ Undici Dispatcher cho Node.js 18+ native fetch
332
+ dispatcher: ctx.options.agent,
333
+ }));
304
334
  const response = await ctx.options.polyfill(url, _options);
305
335
  const setCookieRaw = response.headers.get("set-cookie");
306
336
  if (setCookieRaw && !raw) {
package/dist/zalo.js CHANGED
@@ -75,7 +75,8 @@ export class Zalo {
75
75
  if (!options)
76
76
  options = {};
77
77
  if (!options.userAgent)
78
- options.userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0";
78
+ options.userAgent =
79
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36";
79
80
  if (!options.language)
80
81
  options.language = "vi";
81
82
  const ctx = createContext(this.options.apiType, this.options.apiVersion);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softtynet/zca-js",
3
- "version": "2.1.16",
3
+ "version": "2.1.18",
4
4
  "description": "Unofficial Zalo API for JavaScript",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",