@softtynet/zca-js 2.3.6 → 2.3.7

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 (51) hide show
  1. package/README.md +25 -2
  2. package/dist/apis/business/blockOA.d.ts +2 -0
  3. package/dist/apis/business/blockOA.js +28 -0
  4. package/dist/apis/business/convertOAIds.d.ts +4 -0
  5. package/dist/apis/business/convertOAIds.js +26 -0
  6. package/dist/apis/business/getOAProfile.d.ts +13 -0
  7. package/dist/apis/business/getOAProfile.js +64 -0
  8. package/dist/apis/business/unblockOA.d.ts +2 -0
  9. package/dist/apis/business/unblockOA.js +28 -0
  10. package/dist/apis/chat/preloadConversations.d.ts +3 -2
  11. package/dist/apis/chat/preloadConversations.js +14 -0
  12. package/dist/apis/sync/getSyncData.js +1 -1
  13. package/dist/apis.d.ts +12 -0
  14. package/dist/apis.js +20 -0
  15. package/dist/cjs/apis/business/blockOA.cjs +33 -0
  16. package/dist/cjs/apis/business/convertOAIds.cjs +31 -0
  17. package/dist/cjs/apis/business/getOAProfile.cjs +69 -0
  18. package/dist/cjs/apis/business/unblockOA.cjs +33 -0
  19. package/dist/cjs/apis/chat/preloadConversations.cjs +14 -0
  20. package/dist/cjs/apis/sync/getSyncData.cjs +20 -1
  21. package/dist/cjs/apis.cjs +20 -0
  22. package/dist/cjs/constants/defaults.cjs +2 -2
  23. package/dist/cjs/constants/protocol.cjs +1 -1
  24. package/dist/cjs/index.cjs +10 -0
  25. package/dist/cjs/models/Message.cjs +16 -1
  26. package/dist/cjs/models/OAMessage.cjs +375 -0
  27. package/dist/cjs/realtime/handlers/control.handler.cjs +9 -1
  28. package/dist/cjs/realtime/handlers/message.handler.cjs +103 -37
  29. package/dist/cjs/realtime/listener.cjs +39 -18
  30. package/dist/cjs/utils.cjs +21 -2
  31. package/dist/cjs/zalo.cjs +21 -2
  32. package/dist/constants/defaults.d.ts +2 -2
  33. package/dist/constants/defaults.js +2 -2
  34. package/dist/constants/protocol.d.ts +1 -1
  35. package/dist/constants/protocol.js +1 -1
  36. package/dist/index.d.ts +4 -0
  37. package/dist/models/Message.d.ts +12 -1
  38. package/dist/models/Message.js +16 -1
  39. package/dist/models/OAMessage.d.ts +221 -0
  40. package/dist/models/OAMessage.js +363 -0
  41. package/dist/models/index.d.ts +1 -0
  42. package/dist/models/index.js +1 -0
  43. package/dist/realtime/handlers/control.handler.js +9 -1
  44. package/dist/realtime/handlers/message.handler.js +103 -37
  45. package/dist/realtime/listener.d.ts +9 -3
  46. package/dist/realtime/listener.js +39 -18
  47. package/dist/realtime/types.d.ts +15 -1
  48. package/dist/utils.js +1 -1
  49. package/dist/zalo.d.ts +1 -1
  50. package/dist/zalo.js +1 -1
  51. package/package.json +2 -1
@@ -314,18 +314,19 @@ export class Listener extends EventEmitter {
314
314
  }
315
315
  sendWs(payload, requireId = true) {
316
316
  if (this.ws && (this.ws.readyState === undefined || this.ws.readyState === WebSocket.OPEN)) {
317
- if (requireId)
318
- payload.data["req_id"] = `req_${this.id++}`;
317
+ if (requireId) {
318
+ const reqId = `req_${this.id++}`;
319
+ payload.data["req_id"] = reqId;
320
+ payload.data["reqId"] = reqId;
321
+ }
319
322
  const encodedData = new TextEncoder().encode(JSON.stringify(payload.data));
320
323
  const dataLength = encodedData.length;
321
- const data = new DataView(Buffer.alloc(4 + dataLength).buffer);
322
- data.setUint8(0, payload.version);
323
- data.setInt32(1, payload.cmd, true);
324
- data.setInt8(3, payload.subCmd);
325
- encodedData.forEach((e, i) => {
326
- data.setUint8(4 + i, e);
327
- });
328
- this.ws.send(data);
324
+ const buf = Buffer.alloc(4 + dataLength);
325
+ buf.writeUInt8(payload.version, 0);
326
+ buf.writeUInt16LE(payload.cmd, 1);
327
+ buf.writeInt8(payload.subCmd, 3);
328
+ Buffer.from(encodedData).copy(buf, 4);
329
+ this.ws.send(buf);
329
330
  }
330
331
  }
331
332
  /**
@@ -360,16 +361,36 @@ export class Listener extends EventEmitter {
360
361
  this.sendWs(payload);
361
362
  }
362
363
  /**
363
- * Kích hoạt và kéo hàng đợi sự kiện điều khiển / VoIP (`cmd 603` CTRL_PULL_CTRL và `cmd 604` CTRL_PULL_VOIP).
364
- * Giúp nhận ngay các cuộc gọi đến đang đổ chuông ngay cả khi vừa mở kết nối WebSocket.
364
+ * Kéo danh sách tin nhắn cụ thể theo `queueId` và mảng `ids` (`cmd 570` GET_MSG)
365
+ * khi nhận tín hiệu `cmd 533` (`HAS_MSG`) từ Zalo WebSocket (thường dùng cho tin nhắn OA / ZNS / Missed Queue).
366
+ * Tự động chia batch tối đa 20 ID mỗi gói theo đúng cấu hình `max_msg_get = 20` trên Zalo Desktop.
367
+ */
368
+ requestMessagesByIds(queueId, ids, lastId = "0") {
369
+ if (!queueId || !Array.isArray(ids) || ids.length === 0)
370
+ return;
371
+ const maxBatchSize = 20;
372
+ for (let i = 0; i < ids.length; i += maxBatchSize) {
373
+ const chunk = ids.slice(i, i + maxBatchSize);
374
+ const reqId = `req_${this.id++}`;
375
+ this.sendWs({
376
+ version: 1,
377
+ cmd: 570,
378
+ subCmd: 0,
379
+ data: {
380
+ queueId,
381
+ ids: chunk,
382
+ lastId,
383
+ reqId,
384
+ req_id: reqId,
385
+ },
386
+ }, false);
387
+ }
388
+ }
389
+ /**
390
+ * Kích hoạt và kéo hàng đợi sự kiện điều khiển / VoIP (`cmd 603` CTRL_PULL_CTRL).
391
+ * Giúp nhận ngay các cuộc gọi đến đang đổ chuông và sự kiện điều khiển ngay cả khi vừa mở kết nối WebSocket.
365
392
  */
366
393
  requestOfflineVoipControls() {
367
- this.sendWs({
368
- version: 1,
369
- cmd: 604,
370
- subCmd: 0,
371
- data: { first: true, lastId: 1, preIds: [] },
372
- });
373
394
  this.sendWs({
374
395
  version: 1,
375
396
  cmd: 603,
@@ -1,11 +1,23 @@
1
1
  import type { FriendEvent } from "../models/FriendEvent.js";
2
2
  import type { GroupEvent } from "../models/GroupEvent.js";
3
- import type { Message, Reaction, Undo, Typing, ThreadType } from "../models/index.js";
3
+ import type { Message, Reaction, Undo, Typing, ThreadType, UserMessage } from "../models/index.js";
4
4
  import type { SeenMessage } from "../models/SeenMessage.js";
5
5
  import type { DeliveredMessage } from "../models/DeliveredMessage.js";
6
6
  import type { ClearUnread } from "../models/ClearUnread.js";
7
7
  import type { SyncEvent } from "../models/SyncEvent.js";
8
8
  import type { CallEvent } from "../models/CallEvent.js";
9
+ import type { OAEvent } from "../models/OAMessage.js";
10
+ export type HasMsgQueueId = {
11
+ cmd: number;
12
+ subCmd: number;
13
+ queueName?: string;
14
+ [key: string]: unknown;
15
+ };
16
+ export type HasMsgIdItem = {
17
+ actionId: string;
18
+ msgId?: string;
19
+ [key: string]: unknown;
20
+ };
9
21
  export type UploadEventData = {
10
22
  fileUrl: string;
11
23
  fileId: string;
@@ -45,6 +57,7 @@ export interface ListenerEvents {
45
57
  error: [error: unknown];
46
58
  typing: [typing: Typing];
47
59
  message: [message: Message];
60
+ oa_message: [message: UserMessage];
48
61
  old_messages: [messages: Message[], type: ThreadType, hasMore?: boolean];
49
62
  seen_messages: [messages: SeenMessage[]];
50
63
  delivered_messages: [messages: DeliveredMessage[]];
@@ -57,6 +70,7 @@ export interface ListenerEvents {
57
70
  group_event: [data: GroupEvent];
58
71
  sync_event: [data: SyncEvent];
59
72
  call_event: [data: CallEvent];
73
+ oa_event: [data: OAEvent];
60
74
  voice2text_event: [data: Voice2TextEvent];
61
75
  cipher_key: [key: string];
62
76
  ping: [];
package/dist/utils.js CHANGED
@@ -3,7 +3,7 @@ import crypto from "node:crypto";
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
5
  import SparkMD5 from "spark-md5";
6
- import toughCookie from "tough-cookie";
6
+ import * as toughCookie from "tough-cookie";
7
7
  import { isContextSession } from "./context.js";
8
8
  import { ZaloApiError, ZaloApiMissingImageMetadataGetter } from "./Errors/index.js";
9
9
  import { FriendEventType } from "./models/FriendEvent.js";
package/dist/zalo.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { type LoginQRCallback } from "./apis/loginQR.js";
2
2
  import { type Options } from "./context.js";
3
- import toughCookie from "tough-cookie";
3
+ import * as toughCookie from "tough-cookie";
4
4
  import { API } from "./apis.js";
5
5
  export type Cookie = {
6
6
  domain: string;
package/dist/zalo.js CHANGED
@@ -2,7 +2,7 @@ import { loginQR, LoginQRCallbackEventType } from "./apis/loginQR.js";
2
2
  import { getServerInfo, login } from "./apis/login.js";
3
3
  import { createContext, isContextSession, } from "./context.js";
4
4
  import { generateZaloUUID, logger, ZALO_DEFAULTS, ZALO_DOMAINS } from "./utils.js";
5
- import toughCookie from "tough-cookie";
5
+ import * as toughCookie from "tough-cookie";
6
6
  import { ZaloApiError } from "./Errors/ZaloApiError.js";
7
7
  import { checkUpdate } from "./update.js";
8
8
  import { API } from "./apis.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softtynet/zca-js",
3
- "version": "2.3.6",
3
+ "version": "2.3.7",
4
4
  "description": "Zalo API client library for Node.js and Bun, maintained by Softtynet.",
5
5
  "main": "dist/cjs/index.cjs",
6
6
  "module": "dist/index.js",
@@ -30,6 +30,7 @@
30
30
  "test:verify": "npm run typecheck && npx --yes tsx test/verify_upgrades.ts",
31
31
  "test:live": "npx --yes tsx test/verify_live.ts",
32
32
  "test:call-studio": "npm run build && npx --yes tsx test/call_studio_server.ts",
33
+ "test:oa-studio": "npm run build && npx --yes tsx test/oa_studio_server.ts",
33
34
  "docs:gen": "node scripts/generateDocs.js",
34
35
  "docs:dev": "node scripts/generateDocs.js && vitepress dev docs",
35
36
  "docs:build": "node scripts/generateDocs.js && vitepress build docs",