zalo-toolkit 1.1.7 → 1.1.9

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 (46) hide show
  1. package/dist/Errors/ZaloApiError.d.ts +5 -0
  2. package/dist/Errors/ZaloApiError.js +9 -1
  3. package/dist/apis/listen.d.ts +2 -2
  4. package/dist/apis/listen.js +31 -20
  5. package/dist/cjs/Errors/ZaloApiError.cjs +9 -1
  6. package/dist/cjs/apis/addUnreadMark.cjs +1 -1
  7. package/dist/cjs/apis/createReminder.cjs +1 -1
  8. package/dist/cjs/apis/deleteChat.cjs +1 -1
  9. package/dist/cjs/apis/deleteMessage.cjs +1 -1
  10. package/dist/cjs/apis/editReminder.cjs +1 -1
  11. package/dist/cjs/apis/getAvatarUrlProfile.cjs +1 -1
  12. package/dist/cjs/apis/getListBoard.cjs +1 -1
  13. package/dist/cjs/apis/getListReminder.cjs +1 -1
  14. package/dist/cjs/apis/listen.cjs +31 -20
  15. package/dist/cjs/apis/removeReminder.cjs +1 -1
  16. package/dist/cjs/apis/removeUnreadMark.cjs +1 -1
  17. package/dist/cjs/apis/sendBankCard.cjs +1 -1
  18. package/dist/cjs/apis/sendCard.cjs +1 -1
  19. package/dist/cjs/apis/sendDeliveredEvent.cjs +1 -1
  20. package/dist/cjs/apis/sendLink.cjs +1 -1
  21. package/dist/cjs/apis/sendMessage.cjs +1 -1
  22. package/dist/cjs/apis/sendReport.cjs +1 -1
  23. package/dist/cjs/apis/sendSeenEvent.cjs +1 -1
  24. package/dist/cjs/apis/sendSticker.cjs +1 -1
  25. package/dist/cjs/apis/sendTypingEvent.cjs +1 -1
  26. package/dist/cjs/apis/sendVideo.cjs +1 -1
  27. package/dist/cjs/apis/sendVoice.cjs +1 -1
  28. package/dist/cjs/apis/setHiddenConversations.cjs +1 -1
  29. package/dist/cjs/apis/setMute.cjs +1 -1
  30. package/dist/cjs/apis/setPinnedConversations.cjs +1 -1
  31. package/dist/cjs/apis/undo.cjs +1 -1
  32. package/dist/cjs/apis/updateAutoDeleteChat.cjs +1 -1
  33. package/dist/cjs/apis/uploadAttachment.cjs +1 -1
  34. package/dist/cjs/models/Listen.cjs +20 -0
  35. package/dist/cjs/models/Message.cjs +2 -3
  36. package/dist/cjs/socket/config-socket.cjs +104 -6
  37. package/dist/cjs/utils.cjs +0 -7
  38. package/dist/context.d.ts +2 -0
  39. package/dist/models/Listen.d.ts +21 -0
  40. package/dist/models/Listen.js +18 -0
  41. package/dist/models/Message.js +2 -3
  42. package/dist/socket/config-socket.d.ts +15 -4
  43. package/dist/socket/config-socket.js +105 -7
  44. package/dist/utils.d.ts +0 -2
  45. package/dist/utils.js +0 -6
  46. package/package.json +1 -1
@@ -1,4 +1,9 @@
1
1
  export declare class ZaloApiError extends Error {
2
2
  code: number | null;
3
3
  constructor(message: string, code?: number);
4
+ toJSON(): {
5
+ name: string;
6
+ message: string;
7
+ code: number | null;
8
+ };
4
9
  }
@@ -1,7 +1,15 @@
1
1
  export class ZaloApiError extends Error {
2
2
  constructor(message, code) {
3
3
  super(message);
4
- this.name = "ZcaApiError";
4
+ this.name = 'ZcaApiError';
5
5
  this.code = code || null;
6
+ this.message = message;
7
+ }
8
+ toJSON() {
9
+ return {
10
+ name: this.name,
11
+ message: this.message,
12
+ code: this.code,
13
+ };
6
14
  }
7
15
  }
@@ -112,13 +112,13 @@ export declare class Listener extends EventEmitter<ListenerEvents> {
112
112
  start(): void;
113
113
  stop(): void;
114
114
  getSocketUrl(shouldRotate?: boolean, forceFirstEndpoint?: boolean): string;
115
- sendWs(payload: WsPayload, requireId?: boolean): void;
115
+ sendWs(payload: WsPayload, requireId?: boolean): Promise<void>;
116
116
  shouldPingHttp(): boolean;
117
117
  ping(shouldTimeout?: boolean): void;
118
118
  pingActive(): void;
119
119
  pong(data: any): void;
120
120
  handleError(errorCode: number): void;
121
- getSocketState(): 0 | 2 | 1 | 3 | -1;
121
+ getSocketState(): 0 | 1 | 3 | 2 | -1;
122
122
  reset(): void;
123
123
  afterClose(): void;
124
124
  _onClose: (event: WebSocket.CloseEvent) => void;
@@ -187,6 +187,14 @@ export class Listener extends EventEmitter {
187
187
  this.ping();
188
188
  }, 3 * 60 * 1000);
189
189
  }
190
+ const supportedEncryptTypes = [2, 1, 3];
191
+ if (supportedEncryptTypes.includes(parsed.encrypt)) {
192
+ const parsedData = (await decodeEventData(parsed, this.cipherKey)).data;
193
+ if (cmd === MessageCommand.Authen) {
194
+ this.configSocket.doAfterAuth(parsedData);
195
+ return;
196
+ }
197
+ }
190
198
  if (version == 1 && cmd == 501) {
191
199
  const parsedData = (await decodeEventData(parsed, this.cipherKey)).data;
192
200
  const { msgs, queueStatus } = parsedData;
@@ -210,9 +218,9 @@ export class Listener extends EventEmitter {
210
218
  }
211
219
  const lastMsg = last(msgs);
212
220
  const timestamp = lastMsg ? Number(lastMsg.ts) : Date.now();
213
- this.onUndoMessageCallback(listUndo);
214
- this.onMessageCallback(listMessages);
215
- this.onUpdateQueueStatusCallback(queueStatus, timestamp);
221
+ await this.onUndoMessageCallback(listUndo);
222
+ await this.onMessageCallback(listMessages);
223
+ await this.onUpdateQueueStatusCallback(queueStatus, timestamp);
216
224
  }
217
225
  if (version == 1 && cmd == 521) {
218
226
  const parsedData = (await decodeEventData(parsed, this.cipherKey)).data;
@@ -237,13 +245,13 @@ export class Listener extends EventEmitter {
237
245
  }
238
246
  const lastMsg = last(groupMsgs);
239
247
  const timestamp = lastMsg ? Number(lastMsg.ts) : Date.now();
240
- this.onUndoMessageCallback(listUndo);
241
- this.onMessageCallback(listMessages);
242
- this.onUpdateQueueStatusCallback(queueStatus, timestamp);
248
+ await this.onUndoMessageCallback(listUndo);
249
+ await this.onMessageCallback(listMessages);
250
+ await this.onUpdateQueueStatusCallback(queueStatus, timestamp);
243
251
  }
244
252
  if ([510, 511, 610, 611, 603, 604].includes(cmd)) {
245
253
  const parsedData = (await decodeEventData(parsed, this.cipherKey)).data;
246
- this.configSocket.onGotOffline(cmd, subCmd, { data: parsedData });
254
+ await this.configSocket.onGotOffline(cmd, subCmd, { data: parsedData });
247
255
  }
248
256
  if (version == 1 && [601, 603, 604].includes(cmd)) {
249
257
  const parsedData = (await decodeEventData(parsed, this.cipherKey)).data;
@@ -342,8 +350,8 @@ export class Listener extends EventEmitter {
342
350
  }
343
351
  const lastMsg = reacts.length > 0 ? last(reacts) : reactGroups.length > 0 ? last(reactGroups) : null;
344
352
  const timestamp = lastMsg ? Number(lastMsg.ts) : Date.now();
345
- this.onReactionCallback(listReactions);
346
- this.onUpdateQueueStatusCallback(queueStatus, timestamp);
353
+ await this.onReactionCallback(listReactions);
354
+ await this.onUpdateQueueStatusCallback(queueStatus, timestamp);
347
355
  }
348
356
  if (cmd == 510) {
349
357
  const parsedData = (await decodeEventData(parsed, this.cipherKey)).data;
@@ -362,9 +370,9 @@ export class Listener extends EventEmitter {
362
370
  });
363
371
  const lastMsg = last(msgs);
364
372
  const timestamp = lastMsg ? Number(lastMsg.ts) : Date.now();
365
- this.onUpdateQueueStatusCallback(queueStatus, timestamp);
366
- this.onOldMessageCallback(responseMsgs);
367
- this.onUndoMessageCallback(responseUndos);
373
+ await this.onUndoMessageCallback(responseUndos);
374
+ await this.onOldMessageCallback(responseMsgs);
375
+ await this.onUpdateQueueStatusCallback(queueStatus, timestamp);
368
376
  this.emit('old_messages', responseMsgs);
369
377
  }
370
378
  if (cmd == 511) {
@@ -384,9 +392,9 @@ export class Listener extends EventEmitter {
384
392
  }
385
393
  const lastMsg = last(groupMsgs);
386
394
  const timestamp = lastMsg ? Number(lastMsg.ts) : Date.now();
387
- this.onUpdateQueueStatusCallback(queueStatus, timestamp);
388
- this.onOldMessageCallback(responseMsgs);
389
- this.onUndoMessageCallback(responseUndos);
395
+ await this.onUndoMessageCallback(responseUndos);
396
+ await this.onOldMessageCallback(responseMsgs);
397
+ await this.onUpdateQueueStatusCallback(queueStatus, timestamp);
390
398
  this.emit('old_messages', responseMsgs);
391
399
  }
392
400
  if (cmd == 518) {
@@ -397,8 +405,8 @@ export class Listener extends EventEmitter {
397
405
  const listMessage = [...parseMsgs, ...parseGroupMsgs];
398
406
  const lastMsg = last(listMessage);
399
407
  const timestamp = lastMsg ? Number(lastMsg.ts) : Date.now();
400
- this.onUpdateQueueStatusCallback(queueStatus, timestamp);
401
- this.onOldMessageCallback(listMessage);
408
+ await this.onOldMessageCallback(listMessage);
409
+ await this.onUpdateQueueStatusCallback(queueStatus, timestamp);
402
410
  this.emit('old_messages', listMessage);
403
411
  }
404
412
  if (cmd == 602 && subCmd == 0) {
@@ -480,7 +488,7 @@ export class Listener extends EventEmitter {
480
488
  }
481
489
  return makeURL(this.ctx, this.listUrlSocket[index], { t: Date.now() });
482
490
  }
483
- sendWs(payload, requireId = true) {
491
+ async sendWs(payload, requireId = true) {
484
492
  if (this.ws && this.getSocketState() === WebSocket.OPEN) {
485
493
  if (requireId)
486
494
  payload.data['req_id'] = `req_${this.id++}`;
@@ -493,6 +501,7 @@ export class Listener extends EventEmitter {
493
501
  encodedData.forEach((e, i) => {
494
502
  data.setUint8(4 + i, e);
495
503
  });
504
+ await Promise.resolve();
496
505
  this.ws.send(data);
497
506
  }
498
507
  }
@@ -656,9 +665,11 @@ export class Listener extends EventEmitter {
656
665
  const retryConfig = this.retries[errorCode];
657
666
  if (retryConfig) {
658
667
  let { times, count, max } = retryConfig;
659
- if (max != null && count >= max) {
668
+ // if (max != null && count >= max) {
669
+ // return null;
670
+ // }
671
+ if (count >= 3)
660
672
  return null;
661
- }
662
673
  this.retries[errorCode].count = ((_a = this.retries[errorCode].count) !== null && _a !== void 0 ? _a : 0) + 1;
663
674
  if (typeof times === 'number') {
664
675
  return times;
@@ -3,8 +3,16 @@
3
3
  class ZaloApiError extends Error {
4
4
  constructor(message, code) {
5
5
  super(message);
6
- this.name = "ZcaApiError";
6
+ this.name = 'ZcaApiError';
7
7
  this.code = code || null;
8
+ this.message = message;
9
+ }
10
+ toJSON() {
11
+ return {
12
+ name: this.name,
13
+ message: this.message,
14
+ code: this.code,
15
+ };
8
16
  }
9
17
  }
10
18
 
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  const addUnreadMarkFactory = utils.apiFactory()((api, ctx, utils) => {
16
16
  const serviceURL = utils.makeURL(`${api.zpwServiceMap.conversation[0]}/api/conv/addUnreadMark`);
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  var Reminder = require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  const createReminderFactory = utils.apiFactory()((api, ctx, utils) => {
16
16
  const serviceURL = {
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  const deleteChatFactory = utils.apiFactory()((api, ctx, utils) => {
16
16
  const serviceURL = {
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  const deleteMessageFactory = utils.apiFactory()((api, ctx, utils) => {
16
16
  const serviceURL = {
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  const editReminderFactory = utils.apiFactory()((api, ctx, utils) => {
16
16
  const serviceURL = {
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  const getAvatarUrlProfileFactory = utils.apiFactory()((api, _ctx, utils) => {
16
16
  const serviceURL = utils.makeURL(`${api.zpwServiceMap.profile[0]}/api/social/profile/avatar-url`);
@@ -7,10 +7,10 @@ require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  const getListBoardFactory = utils.apiFactory()((api, ctx, utils) => {
16
16
  const serviceURL = utils.makeURL(`${api.zpwServiceMap.group_board[0]}/api/board/list`);
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  const getListReminderFactory = utils.apiFactory()((api, ctx, utils) => {
16
16
  const serviceURL = {
@@ -190,6 +190,14 @@ class Listener extends stream.EventEmitter {
190
190
  this.ping();
191
191
  }, 3 * 60 * 1000);
192
192
  }
193
+ const supportedEncryptTypes = [2, 1, 3];
194
+ if (supportedEncryptTypes.includes(parsed.encrypt)) {
195
+ const parsedData = (await utils.decodeEventData(parsed, this.cipherKey)).data;
196
+ if (cmd === Listen.MessageCommand.Authen) {
197
+ this.configSocket.doAfterAuth(parsedData);
198
+ return;
199
+ }
200
+ }
193
201
  if (version == 1 && cmd == 501) {
194
202
  const parsedData = (await utils.decodeEventData(parsed, this.cipherKey)).data;
195
203
  const { msgs, queueStatus } = parsedData;
@@ -213,9 +221,9 @@ class Listener extends stream.EventEmitter {
213
221
  }
214
222
  const lastMsg = lodash.last(msgs);
215
223
  const timestamp = lastMsg ? Number(lastMsg.ts) : Date.now();
216
- this.onUndoMessageCallback(listUndo);
217
- this.onMessageCallback(listMessages);
218
- this.onUpdateQueueStatusCallback(queueStatus, timestamp);
224
+ await this.onUndoMessageCallback(listUndo);
225
+ await this.onMessageCallback(listMessages);
226
+ await this.onUpdateQueueStatusCallback(queueStatus, timestamp);
219
227
  }
220
228
  if (version == 1 && cmd == 521) {
221
229
  const parsedData = (await utils.decodeEventData(parsed, this.cipherKey)).data;
@@ -240,13 +248,13 @@ class Listener extends stream.EventEmitter {
240
248
  }
241
249
  const lastMsg = lodash.last(groupMsgs);
242
250
  const timestamp = lastMsg ? Number(lastMsg.ts) : Date.now();
243
- this.onUndoMessageCallback(listUndo);
244
- this.onMessageCallback(listMessages);
245
- this.onUpdateQueueStatusCallback(queueStatus, timestamp);
251
+ await this.onUndoMessageCallback(listUndo);
252
+ await this.onMessageCallback(listMessages);
253
+ await this.onUpdateQueueStatusCallback(queueStatus, timestamp);
246
254
  }
247
255
  if ([510, 511, 610, 611, 603, 604].includes(cmd)) {
248
256
  const parsedData = (await utils.decodeEventData(parsed, this.cipherKey)).data;
249
- this.configSocket.onGotOffline(cmd, subCmd, { data: parsedData });
257
+ await this.configSocket.onGotOffline(cmd, subCmd, { data: parsedData });
250
258
  }
251
259
  if (version == 1 && [601, 603, 604].includes(cmd)) {
252
260
  const parsedData = (await utils.decodeEventData(parsed, this.cipherKey)).data;
@@ -345,8 +353,8 @@ class Listener extends stream.EventEmitter {
345
353
  }
346
354
  const lastMsg = reacts.length > 0 ? lodash.last(reacts) : reactGroups.length > 0 ? lodash.last(reactGroups) : null;
347
355
  const timestamp = lastMsg ? Number(lastMsg.ts) : Date.now();
348
- this.onReactionCallback(listReactions);
349
- this.onUpdateQueueStatusCallback(queueStatus, timestamp);
356
+ await this.onReactionCallback(listReactions);
357
+ await this.onUpdateQueueStatusCallback(queueStatus, timestamp);
350
358
  }
351
359
  if (cmd == 510) {
352
360
  const parsedData = (await utils.decodeEventData(parsed, this.cipherKey)).data;
@@ -365,9 +373,9 @@ class Listener extends stream.EventEmitter {
365
373
  });
366
374
  const lastMsg = lodash.last(msgs);
367
375
  const timestamp = lastMsg ? Number(lastMsg.ts) : Date.now();
368
- this.onUpdateQueueStatusCallback(queueStatus, timestamp);
369
- this.onOldMessageCallback(responseMsgs);
370
- this.onUndoMessageCallback(responseUndos);
376
+ await this.onUndoMessageCallback(responseUndos);
377
+ await this.onOldMessageCallback(responseMsgs);
378
+ await this.onUpdateQueueStatusCallback(queueStatus, timestamp);
371
379
  this.emit('old_messages', responseMsgs);
372
380
  }
373
381
  if (cmd == 511) {
@@ -387,9 +395,9 @@ class Listener extends stream.EventEmitter {
387
395
  }
388
396
  const lastMsg = lodash.last(groupMsgs);
389
397
  const timestamp = lastMsg ? Number(lastMsg.ts) : Date.now();
390
- this.onUpdateQueueStatusCallback(queueStatus, timestamp);
391
- this.onOldMessageCallback(responseMsgs);
392
- this.onUndoMessageCallback(responseUndos);
398
+ await this.onUndoMessageCallback(responseUndos);
399
+ await this.onOldMessageCallback(responseMsgs);
400
+ await this.onUpdateQueueStatusCallback(queueStatus, timestamp);
393
401
  this.emit('old_messages', responseMsgs);
394
402
  }
395
403
  if (cmd == 518) {
@@ -400,8 +408,8 @@ class Listener extends stream.EventEmitter {
400
408
  const listMessage = [...parseMsgs, ...parseGroupMsgs];
401
409
  const lastMsg = lodash.last(listMessage);
402
410
  const timestamp = lastMsg ? Number(lastMsg.ts) : Date.now();
403
- this.onUpdateQueueStatusCallback(queueStatus, timestamp);
404
- this.onOldMessageCallback(listMessage);
411
+ await this.onOldMessageCallback(listMessage);
412
+ await this.onUpdateQueueStatusCallback(queueStatus, timestamp);
405
413
  this.emit('old_messages', listMessage);
406
414
  }
407
415
  if (cmd == 602 && subCmd == 0) {
@@ -483,7 +491,7 @@ class Listener extends stream.EventEmitter {
483
491
  }
484
492
  return utils.makeURL(this.ctx, this.listUrlSocket[index], { t: Date.now() });
485
493
  }
486
- sendWs(payload, requireId = true) {
494
+ async sendWs(payload, requireId = true) {
487
495
  if (this.ws && this.getSocketState() === WebSocket.OPEN) {
488
496
  if (requireId)
489
497
  payload.data['req_id'] = `req_${this.id++}`;
@@ -496,6 +504,7 @@ class Listener extends stream.EventEmitter {
496
504
  encodedData.forEach((e, i) => {
497
505
  data.setUint8(4 + i, e);
498
506
  });
507
+ await Promise.resolve();
499
508
  this.ws.send(data);
500
509
  }
501
510
  }
@@ -659,9 +668,11 @@ class Listener extends stream.EventEmitter {
659
668
  const retryConfig = this.retries[errorCode];
660
669
  if (retryConfig) {
661
670
  let { times, count, max } = retryConfig;
662
- if (max != null && count >= max) {
671
+ // if (max != null && count >= max) {
672
+ // return null;
673
+ // }
674
+ if (count >= 3)
663
675
  return null;
664
- }
665
676
  this.retries[errorCode].count = ((_a = this.retries[errorCode].count) !== null && _a !== void 0 ? _a : 0) + 1;
666
677
  if (typeof times === 'number') {
667
678
  return times;
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  const removeReminderFactory = utils.apiFactory()((api, ctx, utils) => {
16
16
  const serviceURL = {
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  const removeUnreadMarkFactory = utils.apiFactory()((api, ctx, utils) => {
16
16
  const serviceURL = utils.makeURL(`${api.zpwServiceMap.conversation[0]}/api/conv/removeUnreadMark`);
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  const sendBankCardFactory = utils.apiFactory()((api, ctx, utils) => {
16
16
  const serviceURL = utils.makeURL(`${api.zpwServiceMap.zimsg[0]}/api/transfer/card`);
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  const sendCardFactory = utils.apiFactory()((api, ctx, utils) => {
16
16
  const serviceURL = {
@@ -8,10 +8,10 @@ var Enum = require('../models/Enum.cjs');
8
8
  require('../models/FriendEvent.cjs');
9
9
  require('../models/Group.cjs');
10
10
  require('../models/GroupEvent.cjs');
11
- var utils = require('../utils.cjs');
12
11
  require('../models/Reaction.cjs');
13
12
  require('../models/Reminder.cjs');
14
13
  require('../models/ZBusiness.cjs');
14
+ var utils = require('../utils.cjs');
15
15
 
16
16
  const sendDeliveredEventFactory = utils.apiFactory()((api, ctx, utils) => {
17
17
  const serviceURL = {
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  const sendLinkFactory = utils.apiFactory()((api, ctx, utils) => {
16
16
  const serviceURL = {
@@ -8,10 +8,10 @@ var Enum = require('../models/Enum.cjs');
8
8
  require('../models/FriendEvent.cjs');
9
9
  require('../models/Group.cjs');
10
10
  require('../models/GroupEvent.cjs');
11
- var utils = require('../utils.cjs');
12
11
  require('../models/Reaction.cjs');
13
12
  require('../models/Reminder.cjs');
14
13
  require('../models/ZBusiness.cjs');
14
+ var utils = require('../utils.cjs');
15
15
 
16
16
  const attachmentUrlType = {
17
17
  image: 'photo_original/send?',
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  exports.ReportReason = void 0;
16
16
  (function (ReportReason) {
@@ -8,10 +8,10 @@ var Enum = require('../models/Enum.cjs');
8
8
  require('../models/FriendEvent.cjs');
9
9
  require('../models/Group.cjs');
10
10
  require('../models/GroupEvent.cjs');
11
- var utils = require('../utils.cjs');
12
11
  require('../models/Reaction.cjs');
13
12
  require('../models/Reminder.cjs');
14
13
  require('../models/ZBusiness.cjs');
14
+ var utils = require('../utils.cjs');
15
15
 
16
16
  const sendSeenEventFactory = utils.apiFactory()((api, ctx, utils) => {
17
17
  const serviceURL = {
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  const sendStickerFactory = utils.apiFactory()((api, ctx, utils$1) => {
16
16
  const serviceURL = {
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  const sendTypingEventFactory = utils.apiFactory()((api, ctx, utils) => {
16
16
  const serviceURL = {
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  const sendVideoFactory = utils.apiFactory()((api, ctx, utils) => {
16
16
  const serviceURL = {
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  const sendVoiceFactory = utils.apiFactory()((api, ctx, utils) => {
16
16
  const serviceURL = {
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  const setHiddenConversationsFactory = utils.apiFactory()((api, ctx, utils) => {
16
16
  const serviceURL = utils.makeURL(`${api.zpwServiceMap.conversation[0]}/api/hiddenconvers/add-remove`);
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  exports.MuteDuration = void 0;
16
16
  (function (MuteDuration) {
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  const setPinnedConversationsFactory = utils.apiFactory()((api, _, utils) => {
16
16
  const serviceURL = utils.makeURL(`${api.zpwServiceMap.conversation[0]}/api/pinconvers/updatev2`);
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  const undoFactory = utils.apiFactory()((api, ctx, utils) => {
16
16
  const URLType = {
@@ -7,10 +7,10 @@ var Enum = require('../models/Enum.cjs');
7
7
  require('../models/FriendEvent.cjs');
8
8
  require('../models/Group.cjs');
9
9
  require('../models/GroupEvent.cjs');
10
- var utils = require('../utils.cjs');
11
10
  require('../models/Reaction.cjs');
12
11
  require('../models/Reminder.cjs');
13
12
  require('../models/ZBusiness.cjs');
13
+ var utils = require('../utils.cjs');
14
14
 
15
15
  exports.ChatTTL = void 0;
16
16
  (function (ChatTTL) {
@@ -9,10 +9,10 @@ var Enum = require('../models/Enum.cjs');
9
9
  require('../models/FriendEvent.cjs');
10
10
  require('../models/Group.cjs');
11
11
  require('../models/GroupEvent.cjs');
12
- var utils = require('../utils.cjs');
13
12
  require('../models/Reaction.cjs');
14
13
  require('../models/Reminder.cjs');
15
14
  require('../models/ZBusiness.cjs');
15
+ var utils = require('../utils.cjs');
16
16
 
17
17
  const urlType = {
18
18
  image: 'photo_original/upload',
@@ -159,8 +159,28 @@ const SignalCommands = {
159
159
  },
160
160
  };
161
161
  const MAX_CHUNK_WS = 5;
162
+ const OfflineCommands = {
163
+ MSG_11_PC: 513,
164
+ MSG_11_WEB: 515,
165
+ MSG_GROUP: 514,
166
+ SESSION_PC: 516,
167
+ SESSION_WEB: 517,
168
+ ACK_DELIVER_11: 518,
169
+ ACK_DELIVER_GROUP: 519,
170
+ };
171
+ const E2EE_QUEUE_OFFLINE_REQUEST_PRIORITY = {
172
+ [OfflineCommands.MSG_11_PC]: 0,
173
+ [OfflineCommands.MSG_11_WEB]: 0,
174
+ [OfflineCommands.SESSION_PC]: 1,
175
+ [OfflineCommands.SESSION_WEB]: 1,
176
+ [OfflineCommands.MSG_GROUP]: 2,
177
+ [OfflineCommands.ACK_DELIVER_11]: 3,
178
+ [OfflineCommands.ACK_DELIVER_GROUP]: 3,
179
+ };
162
180
 
163
181
  exports.DEFAULT_RETRY_DELAYS = DEFAULT_RETRY_DELAYS;
182
+ exports.E2EE_QUEUE_OFFLINE_REQUEST_PRIORITY = E2EE_QUEUE_OFFLINE_REQUEST_PRIORITY;
164
183
  exports.MAX_CHUNK_WS = MAX_CHUNK_WS;
165
184
  exports.MessageTypes = MessageTypes;
185
+ exports.OfflineCommands = OfflineCommands;
166
186
  exports.SignalCommands = SignalCommands;
@@ -1,6 +1,5 @@
1
1
  'use strict';
2
2
 
3
- var utils = require('../utils.cjs');
4
3
  var Enum = require('./Enum.cjs');
5
4
 
6
5
  class UserMessage {
@@ -10,7 +9,7 @@ class UserMessage {
10
9
  this.threadId = data.uidFrom == '0' ? data.idTo : data.uidFrom;
11
10
  this.isSelf = data.uidFrom == '0';
12
11
  if (queueStatus)
13
- this.queueStatus = utils.handleQueueStatus(queueStatus);
12
+ this.queueStatus = queueStatus;
14
13
  if (data.idTo == '0')
15
14
  data.idTo = uid;
16
15
  if (data.uidFrom == '0')
@@ -27,7 +26,7 @@ class GroupMessage {
27
26
  this.threadId = data.idTo;
28
27
  this.isSelf = data.uidFrom == '0';
29
28
  if (queueStatus)
30
- this.queueStatus = utils.handleQueueStatus(queueStatus);
29
+ this.queueStatus = queueStatus;
31
30
  if (data.uidFrom == '0')
32
31
  data.uidFrom = uid;
33
32
  if (data.quote) {
@@ -3,6 +3,7 @@
3
3
  var Listen = require('../models/Listen.cjs');
4
4
  var WebSocket = require('ws');
5
5
  var utils = require('../utils.cjs');
6
+ var lodash = require('lodash');
6
7
 
7
8
  class ConfigSocket {
8
9
  constructor(ws, features, ctx, listen) {
@@ -15,13 +16,14 @@ class ConfigSocket {
15
16
  this.features = features;
16
17
  this.ctx = ctx;
17
18
  this.listen = listen;
19
+ this.settingSocket = features.socket;
18
20
  }
19
21
  getLastActionIdsForSocket(socketKey) {
20
22
  const defaultResult = { lastId: 1, preIds: [] };
21
- if (utils.hasOwn(this.pollId, socketKey)) {
22
- const { lastId } = this.pollId[socketKey];
23
- const preIds = this.pollId[socketKey].control.getLastActionIdsArray(lastId).slice(0, 10);
24
- return { lastId, preIds };
23
+ if (utils.hasOwn(this.ctx.queueStatus, socketKey)) {
24
+ const { lastId } = this.ctx.queueStatus[socketKey];
25
+ // const preIds = this.ctx.queueStatus[socketKey].ids.slice(0, 10);
26
+ return { lastId, preIds: [] };
25
27
  }
26
28
  return defaultResult;
27
29
  }
@@ -32,7 +34,7 @@ class ConfigSocket {
32
34
  getSocketState() {
33
35
  return this.emitter ? this.emitter.readyState : -1;
34
36
  }
35
- sendWs(payload) {
37
+ async sendWs(payload) {
36
38
  if (this.emitter && this.getSocketState() === WebSocket.WebSocket.OPEN) {
37
39
  const encodedData = new TextEncoder().encode(JSON.stringify(payload.data));
38
40
  const dataLength = encodedData.length;
@@ -43,6 +45,7 @@ class ConfigSocket {
43
45
  encodedData.forEach((e, i) => {
44
46
  data.setUint8(4 + i, e);
45
47
  });
48
+ await Promise.resolve();
46
49
  this.emitter.send(data);
47
50
  }
48
51
  }
@@ -69,7 +72,7 @@ class ConfigSocket {
69
72
  requestPayload.data.lastId = lastActionId !== undefined ? lastActionId : lastId;
70
73
  requestPayload.data.preIds = preIds;
71
74
  }
72
- this.sendWs(requestPayload);
75
+ await this.sendWs(requestPayload);
73
76
  }
74
77
  createOfflineWaiter() {
75
78
  const waiter = { resolve: null, reject: null, promise: null };
@@ -199,6 +202,101 @@ class ConfigSocket {
199
202
  this.offlineTimer = null;
200
203
  }
201
204
  }
205
+ reorderQueueCmdToRequestPushOffline(queueCommands) {
206
+ const normalQueues = [];
207
+ const e2eeQueues = [];
208
+ const e2eeCmds = [513, 515, 514, 516, 517, 518, 519];
209
+ queueCommands.forEach((queueCommand) => {
210
+ if (e2eeCmds.includes(queueCommand.cmd)) {
211
+ e2eeQueues.push(queueCommand);
212
+ }
213
+ else {
214
+ normalQueues.push(queueCommand);
215
+ }
216
+ });
217
+ e2eeQueues.sort((a, b) => {
218
+ return Listen.E2EE_QUEUE_OFFLINE_REQUEST_PRIORITY[a.cmd] - Listen.E2EE_QUEUE_OFFLINE_REQUEST_PRIORITY[b.cmd];
219
+ });
220
+ return [...normalQueues, ...e2eeQueues];
221
+ }
222
+ checkSwapToBUQueue(queueCmds, backupQueues) {
223
+ if (lodash.isEmpty(backupQueues)) {
224
+ return;
225
+ }
226
+ for (const queueCmd of queueCmds) {
227
+ const queueName = `${queueCmd.cmd}_${queueCmd.subCmd}`;
228
+ const backupQueueName = backupQueues[queueName];
229
+ if (!backupQueueName) {
230
+ continue;
231
+ }
232
+ const currentQueueState = this.getLastActionIdsForSocket(queueName);
233
+ const backupQueueState = this.getLastActionIdsForSocket(backupQueueName);
234
+ const shouldSwapQueue = currentQueueState.lastId === 1 && backupQueueState.lastId !== 1;
235
+ if (shouldSwapQueue) {
236
+ const [cmd, subCmd] = backupQueueName.split('_').map(Number);
237
+ queueCmd.cmd = cmd;
238
+ queueCmd.subCmd = subCmd;
239
+ queueCmd.queueName = backupQueueName;
240
+ }
241
+ }
242
+ }
243
+ doAfterAuth(data) {
244
+ this.onAuthenticated(data);
245
+ this.onAuthenticatedCtrl(data);
246
+ }
247
+ onAuthenticated(data) {
248
+ const qCmds = data === null || data === void 0 ? void 0 : data.qCmds;
249
+ if (!Array.isArray(qCmds) || qCmds.length === 0) {
250
+ return false;
251
+ }
252
+ this.offlineCmds.clear();
253
+ this.checkSwapToBUQueue(qCmds, data.bk_cmds);
254
+ const validCmds = qCmds.filter((item) => item.cmd && item.subCmd);
255
+ validCmds.map(({ cmd, subCmd }) => `${cmd}_${subCmd}`);
256
+ const reorderedCmds = this.reorderQueueCmdToRequestPushOffline(validCmds);
257
+ const total = reorderedCmds.length;
258
+ reorderedCmds.forEach((item, index) => {
259
+ item.priority = total - index;
260
+ // nếu muốn unique theo cả cmd + subCmd thì đổi key
261
+ this.offlineCmds.set(item.cmd, item);
262
+ });
263
+ this.signalGetOffline();
264
+ }
265
+ onAuthenticatedCtrl(data) {
266
+ const controlQueues = data === null || data === void 0 ? void 0 : data.ctrl_qCmds;
267
+ const backupQueues = data === null || data === void 0 ? void 0 : data.bk_cmds;
268
+ const hasValidControlQueues = Array.isArray(controlQueues) && controlQueues.length > 0;
269
+ if (!hasValidControlQueues) {
270
+ if (!this.settingSocket.enable_ctrl_socket) {
271
+ return false;
272
+ }
273
+ return false;
274
+ }
275
+ this.offlineCmds.clear();
276
+ // Swap to backup queue if needed
277
+ this.checkSwapToBUQueue(controlQueues, backupQueues);
278
+ controlQueues.forEach((queue) => {
279
+ if (queue.cmd && queue.subCmd) {
280
+ this.offlineCmds.set(queue.cmd, queue);
281
+ }
282
+ });
283
+ if (!this.settingSocket.enable_ctrl_socket) {
284
+ return true;
285
+ }
286
+ this.signalGetOffline();
287
+ return true;
288
+ }
289
+ signalGetOffline() {
290
+ this.emitter.emit(Listen.SocketEvent.ON_START_PULL_OFFLINE);
291
+ const offlineQueues = Array.from(this.offlineCmds.values());
292
+ offlineQueues.sort((a, b) => {
293
+ return b.priority - a.priority;
294
+ });
295
+ offlineQueues.forEach((queue) => {
296
+ this.doGetOffline(queue.cmd, queue.subCmd, true);
297
+ });
298
+ return true;
299
+ }
202
300
  }
203
301
 
204
302
  exports.ConfigSocket = ConfigSocket;
@@ -683,12 +683,6 @@ class FibonacciRetry {
683
683
  return baseDelay * randomFactor;
684
684
  }
685
685
  }
686
- function handleQueueStatus(queueStatus) {
687
- for (const key in queueStatus) {
688
- delete queueStatus[key].ids;
689
- }
690
- return queueStatus;
691
- }
692
686
  function looksLikeJson(str) {
693
687
  return /^[\[{].*[\]}]$/.test(str.trim());
694
688
  }
@@ -724,7 +718,6 @@ exports.getImageMetaData = getImageMetaData;
724
718
  exports.getMd5LargeFileObject = getMd5LargeFileObject;
725
719
  exports.getSecChUaPlatform = getSecChUaPlatform;
726
720
  exports.getSignKey = getSignKey;
727
- exports.handleQueueStatus = handleQueueStatus;
728
721
  exports.handleZaloResponse = handleZaloResponse;
729
722
  exports.hasOwn = hasOwn;
730
723
  exports.logger = logger;
package/dist/context.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { Agent } from 'http';
2
2
  import type { CookieJar } from 'tough-cookie';
3
+ import type { TypeQueueStatus } from './models/Message.js';
3
4
  type UploadEventData = {
4
5
  fileUrl: string;
5
6
  fileId: string;
@@ -155,6 +156,7 @@ export type AppContextBase = {
155
156
  };
156
157
  serverInfo: ServerInfo;
157
158
  extraVer: ExtraVer;
159
+ queueStatus: TypeQueueStatus;
158
160
  };
159
161
  export type ImageMetadataGetterResponse = {
160
162
  width: number;
@@ -184,3 +184,24 @@ export declare const SignalCommands: {
184
184
  };
185
185
  };
186
186
  export declare const MAX_CHUNK_WS = 5;
187
+ export interface TypeQueueCmd {
188
+ cmd: number;
189
+ subCmd: number;
190
+ queueName: string;
191
+ priority: number;
192
+ }
193
+ export interface TypeResponseAuth {
194
+ ctrl_qCmds: TypeQueueCmd[];
195
+ qCmds: TypeQueueCmd[];
196
+ bk_cmds: Record<string, string>;
197
+ }
198
+ export declare const OfflineCommands: {
199
+ readonly MSG_11_PC: 513;
200
+ readonly MSG_11_WEB: 515;
201
+ readonly MSG_GROUP: 514;
202
+ readonly SESSION_PC: 516;
203
+ readonly SESSION_WEB: 517;
204
+ readonly ACK_DELIVER_11: 518;
205
+ readonly ACK_DELIVER_GROUP: 519;
206
+ };
207
+ export declare const E2EE_QUEUE_OFFLINE_REQUEST_PRIORITY: Record<number, number>;
@@ -192,3 +192,21 @@ export const SignalCommands = {
192
192
  },
193
193
  };
194
194
  export const MAX_CHUNK_WS = 5;
195
+ export const OfflineCommands = {
196
+ MSG_11_PC: 513,
197
+ MSG_11_WEB: 515,
198
+ MSG_GROUP: 514,
199
+ SESSION_PC: 516,
200
+ SESSION_WEB: 517,
201
+ ACK_DELIVER_11: 518,
202
+ ACK_DELIVER_GROUP: 519,
203
+ };
204
+ export const E2EE_QUEUE_OFFLINE_REQUEST_PRIORITY = {
205
+ [OfflineCommands.MSG_11_PC]: 0,
206
+ [OfflineCommands.MSG_11_WEB]: 0,
207
+ [OfflineCommands.SESSION_PC]: 1,
208
+ [OfflineCommands.SESSION_WEB]: 1,
209
+ [OfflineCommands.MSG_GROUP]: 2,
210
+ [OfflineCommands.ACK_DELIVER_11]: 3,
211
+ [OfflineCommands.ACK_DELIVER_GROUP]: 3,
212
+ };
@@ -1,4 +1,3 @@
1
- import { handleQueueStatus } from '../utils.js';
2
1
  import { ThreadType } from './Enum.js';
3
2
  export class UserMessage {
4
3
  constructor(uid, data, queueStatus) {
@@ -7,7 +6,7 @@ export class UserMessage {
7
6
  this.threadId = data.uidFrom == '0' ? data.idTo : data.uidFrom;
8
7
  this.isSelf = data.uidFrom == '0';
9
8
  if (queueStatus)
10
- this.queueStatus = handleQueueStatus(queueStatus);
9
+ this.queueStatus = queueStatus;
11
10
  if (data.idTo == '0')
12
11
  data.idTo = uid;
13
12
  if (data.uidFrom == '0')
@@ -24,7 +23,7 @@ export class GroupMessage {
24
23
  this.threadId = data.idTo;
25
24
  this.isSelf = data.uidFrom == '0';
26
25
  if (queueStatus)
27
- this.queueStatus = handleQueueStatus(queueStatus);
26
+ this.queueStatus = queueStatus;
28
27
  if (data.uidFrom == '0')
29
28
  data.uidFrom = uid;
30
29
  if (data.quote) {
@@ -1,5 +1,6 @@
1
1
  import type { Listener, WsPayload } from '../apis/listen.js';
2
2
  import type { AppContextBase, ContextSession } from '../context.js';
3
+ import { type TypeQueueCmd, type TypeResponseAuth } from '../models/Listen.js';
3
4
  import { WebSocket } from 'ws';
4
5
  export declare class ConfigSocket {
5
6
  private emitter;
@@ -12,14 +13,18 @@ export declare class ConfigSocket {
12
13
  private pollId;
13
14
  private offlineTimer;
14
15
  private isDoneOffline;
16
+ private settingSocket;
15
17
  constructor(ws: WebSocket, features: AppContextBase['settings']['features'], ctx: ContextSession, listen: Listener);
16
18
  getLastActionIdsForSocket(socketKey: string): {
17
- lastId: any;
18
- preIds: any;
19
+ lastId: number;
20
+ preIds: never[];
21
+ } | {
22
+ lastId: string;
23
+ preIds: never[];
19
24
  };
20
25
  immediateDoNextOfflineReq(cmd: number): boolean;
21
- getSocketState(): 0 | 2 | 1 | 3 | -1;
22
- sendWs(payload: WsPayload): void;
26
+ getSocketState(): 0 | 1 | 3 | 2 | -1;
27
+ sendWs(payload: WsPayload): Promise<void>;
23
28
  doGetOffline(cmd: number, subCmd: number, first: boolean, lastActionId?: number): Promise<void>;
24
29
  createOfflineWaiter(): any;
25
30
  ackOfflineQueue(isGroup: boolean, data: any): Promise<unknown>;
@@ -35,4 +40,10 @@ export declare class ConfigSocket {
35
40
  handleSocketMsg(cmd: string, payload: any): boolean | undefined;
36
41
  onDoneOfflineQueue(queueId: string): void;
37
42
  onDoneOfflineAll(): void;
43
+ reorderQueueCmdToRequestPushOffline(queueCommands: TypeQueueCmd[]): TypeQueueCmd[];
44
+ checkSwapToBUQueue(queueCmds: TypeQueueCmd[], backupQueues: TypeResponseAuth['bk_cmds']): void;
45
+ doAfterAuth(data: TypeResponseAuth): void;
46
+ onAuthenticated(data: TypeResponseAuth): false | undefined;
47
+ onAuthenticatedCtrl(data: TypeResponseAuth): boolean;
48
+ signalGetOffline(): boolean;
38
49
  }
@@ -1,6 +1,7 @@
1
- import { EventTypes, MAX_CHUNK_WS, MessageCommand, MessageTypes, SignalCommands } from '../models/Listen.js';
1
+ import { E2EE_QUEUE_OFFLINE_REQUEST_PRIORITY, EventTypes, MAX_CHUNK_WS, MessageCommand, MessageTypes, SignalCommands, SocketEvent, } from '../models/Listen.js';
2
2
  import { WebSocket } from 'ws';
3
3
  import { hasOwn } from '../utils.js';
4
+ import { isEmpty } from 'lodash';
4
5
  export class ConfigSocket {
5
6
  constructor(ws, features, ctx, listen) {
6
7
  this.overflowTracker = {};
@@ -12,13 +13,14 @@ export class ConfigSocket {
12
13
  this.features = features;
13
14
  this.ctx = ctx;
14
15
  this.listen = listen;
16
+ this.settingSocket = features.socket;
15
17
  }
16
18
  getLastActionIdsForSocket(socketKey) {
17
19
  const defaultResult = { lastId: 1, preIds: [] };
18
- if (hasOwn(this.pollId, socketKey)) {
19
- const { lastId } = this.pollId[socketKey];
20
- const preIds = this.pollId[socketKey].control.getLastActionIdsArray(lastId).slice(0, 10);
21
- return { lastId, preIds };
20
+ if (hasOwn(this.ctx.queueStatus, socketKey)) {
21
+ const { lastId } = this.ctx.queueStatus[socketKey];
22
+ // const preIds = this.ctx.queueStatus[socketKey].ids.slice(0, 10);
23
+ return { lastId, preIds: [] };
22
24
  }
23
25
  return defaultResult;
24
26
  }
@@ -29,7 +31,7 @@ export class ConfigSocket {
29
31
  getSocketState() {
30
32
  return this.emitter ? this.emitter.readyState : -1;
31
33
  }
32
- sendWs(payload) {
34
+ async sendWs(payload) {
33
35
  if (this.emitter && this.getSocketState() === WebSocket.OPEN) {
34
36
  const encodedData = new TextEncoder().encode(JSON.stringify(payload.data));
35
37
  const dataLength = encodedData.length;
@@ -40,6 +42,7 @@ export class ConfigSocket {
40
42
  encodedData.forEach((e, i) => {
41
43
  data.setUint8(4 + i, e);
42
44
  });
45
+ await Promise.resolve();
43
46
  this.emitter.send(data);
44
47
  }
45
48
  }
@@ -66,7 +69,7 @@ export class ConfigSocket {
66
69
  requestPayload.data.lastId = lastActionId !== undefined ? lastActionId : lastId;
67
70
  requestPayload.data.preIds = preIds;
68
71
  }
69
- this.sendWs(requestPayload);
72
+ await this.sendWs(requestPayload);
70
73
  }
71
74
  createOfflineWaiter() {
72
75
  const waiter = { resolve: null, reject: null, promise: null };
@@ -200,4 +203,99 @@ export class ConfigSocket {
200
203
  this.offlineTimer = null;
201
204
  }
202
205
  }
206
+ reorderQueueCmdToRequestPushOffline(queueCommands) {
207
+ const normalQueues = [];
208
+ const e2eeQueues = [];
209
+ const e2eeCmds = [513, 515, 514, 516, 517, 518, 519];
210
+ queueCommands.forEach((queueCommand) => {
211
+ if (e2eeCmds.includes(queueCommand.cmd)) {
212
+ e2eeQueues.push(queueCommand);
213
+ }
214
+ else {
215
+ normalQueues.push(queueCommand);
216
+ }
217
+ });
218
+ e2eeQueues.sort((a, b) => {
219
+ return E2EE_QUEUE_OFFLINE_REQUEST_PRIORITY[a.cmd] - E2EE_QUEUE_OFFLINE_REQUEST_PRIORITY[b.cmd];
220
+ });
221
+ return [...normalQueues, ...e2eeQueues];
222
+ }
223
+ checkSwapToBUQueue(queueCmds, backupQueues) {
224
+ if (isEmpty(backupQueues)) {
225
+ return;
226
+ }
227
+ for (const queueCmd of queueCmds) {
228
+ const queueName = `${queueCmd.cmd}_${queueCmd.subCmd}`;
229
+ const backupQueueName = backupQueues[queueName];
230
+ if (!backupQueueName) {
231
+ continue;
232
+ }
233
+ const currentQueueState = this.getLastActionIdsForSocket(queueName);
234
+ const backupQueueState = this.getLastActionIdsForSocket(backupQueueName);
235
+ const shouldSwapQueue = currentQueueState.lastId === 1 && backupQueueState.lastId !== 1;
236
+ if (shouldSwapQueue) {
237
+ const [cmd, subCmd] = backupQueueName.split('_').map(Number);
238
+ queueCmd.cmd = cmd;
239
+ queueCmd.subCmd = subCmd;
240
+ queueCmd.queueName = backupQueueName;
241
+ }
242
+ }
243
+ }
244
+ doAfterAuth(data) {
245
+ this.onAuthenticated(data);
246
+ this.onAuthenticatedCtrl(data);
247
+ }
248
+ onAuthenticated(data) {
249
+ const qCmds = data === null || data === void 0 ? void 0 : data.qCmds;
250
+ if (!Array.isArray(qCmds) || qCmds.length === 0) {
251
+ return false;
252
+ }
253
+ this.offlineCmds.clear();
254
+ this.checkSwapToBUQueue(qCmds, data.bk_cmds);
255
+ const validCmds = qCmds.filter((item) => item.cmd && item.subCmd);
256
+ const verifyKeys = validCmds.map(({ cmd, subCmd }) => `${cmd}_${subCmd}`);
257
+ const reorderedCmds = this.reorderQueueCmdToRequestPushOffline(validCmds);
258
+ const total = reorderedCmds.length;
259
+ reorderedCmds.forEach((item, index) => {
260
+ item.priority = total - index;
261
+ // nếu muốn unique theo cả cmd + subCmd thì đổi key
262
+ this.offlineCmds.set(item.cmd, item);
263
+ });
264
+ this.signalGetOffline();
265
+ }
266
+ onAuthenticatedCtrl(data) {
267
+ const controlQueues = data === null || data === void 0 ? void 0 : data.ctrl_qCmds;
268
+ const backupQueues = data === null || data === void 0 ? void 0 : data.bk_cmds;
269
+ const hasValidControlQueues = Array.isArray(controlQueues) && controlQueues.length > 0;
270
+ if (!hasValidControlQueues) {
271
+ if (!this.settingSocket.enable_ctrl_socket) {
272
+ return false;
273
+ }
274
+ return false;
275
+ }
276
+ this.offlineCmds.clear();
277
+ // Swap to backup queue if needed
278
+ this.checkSwapToBUQueue(controlQueues, backupQueues);
279
+ controlQueues.forEach((queue) => {
280
+ if (queue.cmd && queue.subCmd) {
281
+ this.offlineCmds.set(queue.cmd, queue);
282
+ }
283
+ });
284
+ if (!this.settingSocket.enable_ctrl_socket) {
285
+ return true;
286
+ }
287
+ this.signalGetOffline();
288
+ return true;
289
+ }
290
+ signalGetOffline() {
291
+ this.emitter.emit(SocketEvent.ON_START_PULL_OFFLINE);
292
+ const offlineQueues = Array.from(this.offlineCmds.values());
293
+ offlineQueues.sort((a, b) => {
294
+ return b.priority - a.priority;
295
+ });
296
+ offlineQueues.forEach((queue) => {
297
+ this.doGetOffline(queue.cmd, queue.subCmd, true);
298
+ });
299
+ return true;
300
+ }
203
301
  }
package/dist/utils.d.ts CHANGED
@@ -4,7 +4,6 @@ import { type ContextBase, type ContextSession } from './context.js';
4
4
  import type { IFileUpload } from './core/interfaces/common.js';
5
5
  import { FriendEventType } from './models/FriendEvent.js';
6
6
  import { GroupEventType } from './models/GroupEvent.js';
7
- import type { TypeQueueStatus } from './models/Message.js';
8
7
  export declare function hasOwn(obj: Record<string, unknown>, key: string): key is keyof typeof obj;
9
8
  /**
10
9
  * Get signed key for API requests.
@@ -185,7 +184,6 @@ export declare class FibonacciRetry {
185
184
  */
186
185
  getNextRetry(count: number, multiplier: number, maxDelay?: number): number;
187
186
  }
188
- export declare function handleQueueStatus(queueStatus: TypeQueueStatus): TypeQueueStatus;
189
187
  export declare function looksLikeJson(str: string): boolean;
190
188
  export declare function safeJsonParse<T = any>(input: string): T | undefined;
191
189
  export {};
package/dist/utils.js CHANGED
@@ -740,12 +740,6 @@ export class FibonacciRetry {
740
740
  return baseDelay * randomFactor;
741
741
  }
742
742
  }
743
- export function handleQueueStatus(queueStatus) {
744
- for (const key in queueStatus) {
745
- delete queueStatus[key].ids;
746
- }
747
- return queueStatus;
748
- }
749
743
  export function looksLikeJson(str) {
750
744
  return /^[\[{].*[\]}]$/.test(str.trim());
751
745
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zalo-toolkit",
3
- "version": "1.1.7",
3
+ "version": "1.1.9",
4
4
  "description": "Unofficial Zalo API for JavaScript",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",