@d0v3riz/baileys 6.7.8 → 6.7.12

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/README.md +1022 -635
  2. package/lib/Defaults/baileys-version.json +1 -1
  3. package/lib/Defaults/index.js +1 -0
  4. package/lib/Socket/business.d.ts +6 -7
  5. package/lib/Socket/chats.d.ts +6 -6
  6. package/lib/Socket/chats.js +34 -68
  7. package/lib/Socket/groups.d.ts +5 -6
  8. package/lib/Socket/index.d.ts +6 -7
  9. package/lib/Socket/messages-recv.d.ts +6 -7
  10. package/lib/Socket/messages-recv.js +72 -23
  11. package/lib/Socket/messages-send.d.ts +6 -6
  12. package/lib/Socket/messages-send.js +32 -51
  13. package/lib/Socket/socket.js +8 -0
  14. package/lib/Socket/usync.d.ts +38 -0
  15. package/lib/Socket/usync.js +70 -0
  16. package/lib/Types/Socket.d.ts +2 -0
  17. package/lib/Types/USync.d.ts +25 -0
  18. package/lib/Types/USync.js +2 -0
  19. package/lib/Utils/decode-wa-message.d.ts +16 -0
  20. package/lib/Utils/decode-wa-message.js +17 -1
  21. package/lib/Utils/messages.js +8 -6
  22. package/lib/Utils/process-message.js +16 -0
  23. package/lib/Utils/signal.d.ts +2 -1
  24. package/lib/Utils/signal.js +11 -21
  25. package/lib/Utils/validate-connection.js +6 -2
  26. package/lib/WABinary/encode.js +1 -1
  27. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +9 -0
  28. package/lib/WAUSync/Protocols/USyncContactProtocol.js +32 -0
  29. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +22 -0
  30. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +57 -0
  31. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +12 -0
  32. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +30 -0
  33. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +12 -0
  34. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +42 -0
  35. package/lib/WAUSync/Protocols/index.d.ts +4 -0
  36. package/lib/WAUSync/Protocols/index.js +20 -0
  37. package/lib/WAUSync/USyncQuery.d.ts +26 -0
  38. package/lib/WAUSync/USyncQuery.js +79 -0
  39. package/lib/WAUSync/USyncUser.d.ts +10 -0
  40. package/lib/WAUSync/USyncUser.js +22 -0
  41. package/lib/WAUSync/index.d.ts +3 -0
  42. package/lib/WAUSync/index.js +19 -0
  43. package/lib/index.d.ts +1 -0
  44. package/lib/index.js +1 -0
  45. package/package.json +1 -1
  46. package/WASignalGroup/readme.md +0 -6
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": [2, 3000, 1015901307]
2
+ "version": [2, 3000, 1019707846]
3
3
  }
@@ -59,6 +59,7 @@ exports.DEFAULT_CONNECTION_CONFIG = {
59
59
  patch: false,
60
60
  snapshot: false,
61
61
  },
62
+ countryCode: 'US',
62
63
  getMessage: async () => undefined,
63
64
  cachedGroupMetadata: async () => undefined,
64
65
  makeSignalRepository: libsignal_1.makeLibSignalRepository
@@ -18,7 +18,7 @@ export declare const makeBusinessSocket: (config: SocketConfig) => {
18
18
  deleted: number;
19
19
  }>;
20
20
  productUpdate: (productId: string, update: ProductUpdate) => Promise<import("../Types").Product>;
21
- sendMessageAck: ({ tag, attrs, content }: BinaryNode) => Promise<void>;
21
+ sendMessageAck: ({ tag, attrs, content }: BinaryNode, errorCode?: number | undefined) => Promise<void>;
22
22
  sendRetryRequest: (node: BinaryNode, forceIncludeKeys?: boolean) => Promise<void>;
23
23
  rejectCall: (callId: string, callFrom: string) => Promise<void>;
24
24
  fetchMessageHistory: (count: number, oldestMsgKey: import("../Types").WAProto.IMessageKey, oldestMsgTimestamp: number | import("long").Long) => Promise<string>;
@@ -83,14 +83,12 @@ export declare const makeBusinessSocket: (config: SocketConfig) => {
83
83
  presenceSubscribe: (toJid: string, tcToken?: Buffer | undefined) => Promise<void>;
84
84
  profilePictureUrl: (jid: string, type?: "image" | "preview", timeoutMs?: number | undefined) => Promise<string | undefined>;
85
85
  onWhatsApp: (...jids: string[]) => Promise<{
86
- exists: boolean;
87
86
  jid: string;
88
- }[]>;
87
+ exists: unknown;
88
+ }[] | undefined>;
89
89
  fetchBlocklist: () => Promise<string[]>;
90
- fetchStatus: (jid: string) => Promise<{
91
- status: string | undefined;
92
- setAt: Date;
93
- } | undefined>;
90
+ fetchStatus: (...jids: string[]) => Promise<import("..").USyncQueryResultList[] | undefined>;
91
+ fetchDisappearingDuration: (...jids: string[]) => Promise<import("..").USyncQueryResultList[] | undefined>;
94
92
  updateProfilePicture: (jid: string, content: import("../Types").WAMediaUpload) => Promise<void>;
95
93
  removeProfilePicture: (jid: string) => Promise<void>;
96
94
  updateProfileStatus: (status: string) => Promise<void>;
@@ -117,6 +115,7 @@ export declare const makeBusinessSocket: (config: SocketConfig) => {
117
115
  id: string;
118
116
  fromMe?: boolean | undefined;
119
117
  }[], star: boolean) => Promise<void>;
118
+ executeUSyncQuery: (usyncQuery: import("..").USyncQuery) => Promise<import("..").USyncQueryResult | undefined>;
120
119
  type: "md";
121
120
  ws: import("./Client").WebSocketClient;
122
121
  ev: import("../Types").BaileysEventEmitter & {
@@ -5,6 +5,7 @@ import { proto } from '../../WAProto';
5
5
  import { ChatModification, MessageUpsertType, SocketConfig, WABusinessProfile, WAMediaUpload, WAPatchCreate, WAPresence, WAPrivacyCallValue, WAPrivacyGroupAddValue, WAPrivacyOnlineValue, WAPrivacyValue, WAReadReceiptsValue } from '../Types';
6
6
  import { LabelActionBody } from '../Types/Label';
7
7
  import { BinaryNode } from '../WABinary';
8
+ import { USyncQuery } from '../WAUSync';
8
9
  export declare const makeChatsSocket: (config: SocketConfig) => {
9
10
  processingMutex: {
10
11
  mutex<T>(code: () => T | Promise<T>): Promise<T>;
@@ -18,14 +19,12 @@ export declare const makeChatsSocket: (config: SocketConfig) => {
18
19
  presenceSubscribe: (toJid: string, tcToken?: Buffer) => Promise<void>;
19
20
  profilePictureUrl: (jid: string, type?: 'preview' | 'image', timeoutMs?: number) => Promise<string | undefined>;
20
21
  onWhatsApp: (...jids: string[]) => Promise<{
21
- exists: boolean;
22
22
  jid: string;
23
- }[]>;
23
+ exists: unknown;
24
+ }[] | undefined>;
24
25
  fetchBlocklist: () => Promise<string[]>;
25
- fetchStatus: (jid: string) => Promise<{
26
- status: string | undefined;
27
- setAt: Date;
28
- } | undefined>;
26
+ fetchStatus: (...jids: string[]) => Promise<import("../WAUSync").USyncQueryResultList[] | undefined>;
27
+ fetchDisappearingDuration: (...jids: string[]) => Promise<import("../WAUSync").USyncQueryResultList[] | undefined>;
29
28
  updateProfilePicture: (jid: string, content: WAMediaUpload) => Promise<void>;
30
29
  removeProfilePicture: (jid: string) => Promise<void>;
31
30
  updateProfileStatus: (status: string) => Promise<void>;
@@ -52,6 +51,7 @@ export declare const makeChatsSocket: (config: SocketConfig) => {
52
51
  id: string;
53
52
  fromMe?: boolean;
54
53
  }[], star: boolean) => Promise<void>;
54
+ executeUSyncQuery: (usyncQuery: USyncQuery) => Promise<import("../WAUSync").USyncQueryResult | undefined>;
55
55
  type: "md";
56
56
  ws: import("./Client").WebSocketClient;
57
57
  ev: import("../Types").BaileysEventEmitter & {
@@ -13,11 +13,12 @@ const Utils_1 = require("../Utils");
13
13
  const make_mutex_1 = require("../Utils/make-mutex");
14
14
  const process_message_1 = __importDefault(require("../Utils/process-message"));
15
15
  const WABinary_1 = require("../WABinary");
16
- const socket_1 = require("./socket");
16
+ const WAUSync_1 = require("../WAUSync");
17
+ const usync_1 = require("./usync");
17
18
  const MAX_SYNC_ATTEMPTS = 2;
18
19
  const makeChatsSocket = (config) => {
19
20
  const { logger, markOnlineOnConnect, fireInitQueries, appStateMacVerification, shouldIgnoreJid, shouldSyncHistoryMessage, } = config;
20
- const sock = (0, socket_1.makeSocket)(config);
21
+ const sock = (0, usync_1.makeUSyncSocket)(config);
21
22
  const { ev, ws, authState, generateMessageTag, sendNode, query, onUnexpectedError, } = sock;
22
23
  let privacySettings;
23
24
  let needToFlushWithAppStateSync = false;
@@ -111,74 +112,38 @@ const makeChatsSocket = (config) => {
111
112
  }]
112
113
  });
113
114
  };
114
- /** helper function to run a generic IQ query */
115
- const interactiveQuery = async (userNodes, queryNode) => {
116
- const result = await query({
117
- tag: 'iq',
118
- attrs: {
119
- to: WABinary_1.S_WHATSAPP_NET,
120
- type: 'get',
121
- xmlns: 'usync',
122
- },
123
- content: [
124
- {
125
- tag: 'usync',
126
- attrs: {
127
- sid: generateMessageTag(),
128
- mode: 'query',
129
- last: 'true',
130
- index: '0',
131
- context: 'interactive',
132
- },
133
- content: [
134
- {
135
- tag: 'query',
136
- attrs: {},
137
- content: [queryNode]
138
- },
139
- {
140
- tag: 'list',
141
- attrs: {},
142
- content: userNodes
143
- }
144
- ]
145
- }
146
- ],
147
- });
148
- const usyncNode = (0, WABinary_1.getBinaryNodeChild)(result, 'usync');
149
- const listNode = (0, WABinary_1.getBinaryNodeChild)(usyncNode, 'list');
150
- const users = (0, WABinary_1.getBinaryNodeChildren)(listNode, 'user');
151
- return users;
152
- };
153
115
  const onWhatsApp = async (...jids) => {
154
- const query = { tag: 'contact', attrs: {} };
155
- const list = jids.map((jid) => {
156
- // insures only 1 + is there
157
- const content = `+${jid.replace('+', '')}`;
158
- return {
159
- tag: 'user',
160
- attrs: {},
161
- content: [{
162
- tag: 'contact',
163
- attrs: {},
164
- content,
165
- }],
166
- };
167
- });
168
- const results = await interactiveQuery(list, query);
169
- return results.map(user => {
170
- const contact = (0, WABinary_1.getBinaryNodeChild)(user, 'contact');
171
- return { exists: (contact === null || contact === void 0 ? void 0 : contact.attrs.type) === 'in', jid: user.attrs.jid };
172
- }).filter(item => item.exists);
173
- };
174
- const fetchStatus = async (jid) => {
175
- const [result] = await interactiveQuery([{ tag: 'user', attrs: { jid } }], { tag: 'status', attrs: {} });
116
+ const usyncQuery = new WAUSync_1.USyncQuery()
117
+ .withContactProtocol();
118
+ for (const jid of jids) {
119
+ const phone = `+${jid.replace('+', '').split('@')[0].split(':')[0]}`;
120
+ usyncQuery.withUser(new WAUSync_1.USyncUser().withPhone(phone));
121
+ }
122
+ const results = await sock.executeUSyncQuery(usyncQuery);
123
+ if (results) {
124
+ return results.list.filter((a) => !!a.contact).map(({ contact, id }) => ({ jid: id, exists: contact }));
125
+ }
126
+ };
127
+ const fetchStatus = async (...jids) => {
128
+ const usyncQuery = new WAUSync_1.USyncQuery()
129
+ .withStatusProtocol();
130
+ for (const jid of jids) {
131
+ usyncQuery.withUser(new WAUSync_1.USyncUser().withId(jid));
132
+ }
133
+ const result = await sock.executeUSyncQuery(usyncQuery);
176
134
  if (result) {
177
- const status = (0, WABinary_1.getBinaryNodeChild)(result, 'status');
178
- return {
179
- status: status === null || status === void 0 ? void 0 : status.content.toString(),
180
- setAt: new Date(+((status === null || status === void 0 ? void 0 : status.attrs.t) || 0) * 1000)
181
- };
135
+ return result.list;
136
+ }
137
+ };
138
+ const fetchDisappearingDuration = async (...jids) => {
139
+ const usyncQuery = new WAUSync_1.USyncQuery()
140
+ .withDisappearingModeProtocol();
141
+ for (const jid of jids) {
142
+ usyncQuery.withUser(new WAUSync_1.USyncUser().withId(jid));
143
+ }
144
+ const result = await sock.executeUSyncQuery(usyncQuery);
145
+ if (result) {
146
+ return result.list;
182
147
  }
183
148
  };
184
149
  /** update the profile picture for yourself or a group */
@@ -852,6 +817,7 @@ const makeChatsSocket = (config) => {
852
817
  onWhatsApp,
853
818
  fetchBlocklist,
854
819
  fetchStatus,
820
+ fetchDisappearingDuration,
855
821
  updateProfilePicture,
856
822
  removeProfilePicture,
857
823
  updateProfileStatus,
@@ -57,14 +57,12 @@ export declare const makeGroupsSocket: (config: SocketConfig) => {
57
57
  presenceSubscribe: (toJid: string, tcToken?: Buffer | undefined) => Promise<void>;
58
58
  profilePictureUrl: (jid: string, type?: "image" | "preview", timeoutMs?: number | undefined) => Promise<string | undefined>;
59
59
  onWhatsApp: (...jids: string[]) => Promise<{
60
- exists: boolean;
61
60
  jid: string;
62
- }[]>;
61
+ exists: unknown;
62
+ }[] | undefined>;
63
63
  fetchBlocklist: () => Promise<string[]>;
64
- fetchStatus: (jid: string) => Promise<{
65
- status: string | undefined;
66
- setAt: Date;
67
- } | undefined>;
64
+ fetchStatus: (...jids: string[]) => Promise<import("..").USyncQueryResultList[] | undefined>;
65
+ fetchDisappearingDuration: (...jids: string[]) => Promise<import("..").USyncQueryResultList[] | undefined>;
68
66
  updateProfilePicture: (jid: string, content: import("../Types").WAMediaUpload) => Promise<void>;
69
67
  removeProfilePicture: (jid: string) => Promise<void>;
70
68
  updateProfileStatus: (status: string) => Promise<void>;
@@ -91,6 +89,7 @@ export declare const makeGroupsSocket: (config: SocketConfig) => {
91
89
  id: string;
92
90
  fromMe?: boolean | undefined;
93
91
  }[], star: boolean) => Promise<void>;
92
+ executeUSyncQuery: (usyncQuery: import("..").USyncQuery) => Promise<import("..").USyncQueryResult | undefined>;
94
93
  type: "md";
95
94
  ws: import("./Client").WebSocketClient;
96
95
  ev: import("../Types").BaileysEventEmitter & {
@@ -17,7 +17,7 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
17
17
  deleted: number;
18
18
  }>;
19
19
  productUpdate: (productId: string, update: import("../Types").ProductUpdate) => Promise<import("../Types").Product>;
20
- sendMessageAck: ({ tag, attrs, content }: import("..").BinaryNode) => Promise<void>;
20
+ sendMessageAck: ({ tag, attrs, content }: import("..").BinaryNode, errorCode?: number | undefined) => Promise<void>;
21
21
  sendRetryRequest: (node: import("..").BinaryNode, forceIncludeKeys?: boolean) => Promise<void>;
22
22
  rejectCall: (callId: string, callFrom: string) => Promise<void>;
23
23
  fetchMessageHistory: (count: number, oldestMsgKey: import("../Types").WAProto.IMessageKey, oldestMsgTimestamp: number | import("long").Long) => Promise<string>;
@@ -82,14 +82,12 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
82
82
  presenceSubscribe: (toJid: string, tcToken?: Buffer | undefined) => Promise<void>;
83
83
  profilePictureUrl: (jid: string, type?: "image" | "preview", timeoutMs?: number | undefined) => Promise<string | undefined>;
84
84
  onWhatsApp: (...jids: string[]) => Promise<{
85
- exists: boolean;
86
85
  jid: string;
87
- }[]>;
86
+ exists: unknown;
87
+ }[] | undefined>;
88
88
  fetchBlocklist: () => Promise<string[]>;
89
- fetchStatus: (jid: string) => Promise<{
90
- status: string | undefined;
91
- setAt: Date;
92
- } | undefined>;
89
+ fetchStatus: (...jids: string[]) => Promise<import("..").USyncQueryResultList[] | undefined>;
90
+ fetchDisappearingDuration: (...jids: string[]) => Promise<import("..").USyncQueryResultList[] | undefined>;
93
91
  updateProfilePicture: (jid: string, content: import("../Types").WAMediaUpload) => Promise<void>;
94
92
  removeProfilePicture: (jid: string) => Promise<void>;
95
93
  updateProfileStatus: (status: string) => Promise<void>;
@@ -116,6 +114,7 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
116
114
  id: string;
117
115
  fromMe?: boolean | undefined;
118
116
  }[], star: boolean) => Promise<void>;
117
+ executeUSyncQuery: (usyncQuery: import("..").USyncQuery) => Promise<import("..").USyncQueryResult | undefined>;
119
118
  type: "md";
120
119
  ws: import("./Client").WebSocketClient;
121
120
  ev: import("../Types").BaileysEventEmitter & {
@@ -5,7 +5,7 @@ import { proto } from '../../WAProto';
5
5
  import { MessageReceiptType, MessageRelayOptions, SocketConfig, WAMessageKey } from '../Types';
6
6
  import { BinaryNode } from '../WABinary';
7
7
  export declare const makeMessagesRecvSocket: (config: SocketConfig) => {
8
- sendMessageAck: ({ tag, attrs, content }: BinaryNode) => Promise<void>;
8
+ sendMessageAck: ({ tag, attrs, content }: BinaryNode, errorCode?: number) => Promise<void>;
9
9
  sendRetryRequest: (node: BinaryNode, forceIncludeKeys?: boolean) => Promise<void>;
10
10
  rejectCall: (callId: string, callFrom: string) => Promise<void>;
11
11
  fetchMessageHistory: (count: number, oldestMsgKey: WAMessageKey, oldestMsgTimestamp: number | Long) => Promise<string>;
@@ -70,14 +70,12 @@ export declare const makeMessagesRecvSocket: (config: SocketConfig) => {
70
70
  presenceSubscribe: (toJid: string, tcToken?: Buffer | undefined) => Promise<void>;
71
71
  profilePictureUrl: (jid: string, type?: "image" | "preview", timeoutMs?: number | undefined) => Promise<string | undefined>;
72
72
  onWhatsApp: (...jids: string[]) => Promise<{
73
- exists: boolean;
74
73
  jid: string;
75
- }[]>;
74
+ exists: unknown;
75
+ }[] | undefined>;
76
76
  fetchBlocklist: () => Promise<string[]>;
77
- fetchStatus: (jid: string) => Promise<{
78
- status: string | undefined;
79
- setAt: Date;
80
- } | undefined>;
77
+ fetchStatus: (...jids: string[]) => Promise<import("..").USyncQueryResultList[] | undefined>;
78
+ fetchDisappearingDuration: (...jids: string[]) => Promise<import("..").USyncQueryResultList[] | undefined>;
81
79
  updateProfilePicture: (jid: string, content: import("../Types").WAMediaUpload) => Promise<void>;
82
80
  removeProfilePicture: (jid: string) => Promise<void>;
83
81
  updateProfileStatus: (status: string) => Promise<void>;
@@ -104,6 +102,7 @@ export declare const makeMessagesRecvSocket: (config: SocketConfig) => {
104
102
  id: string;
105
103
  fromMe?: boolean | undefined;
106
104
  }[], star: boolean) => Promise<void>;
105
+ executeUSyncQuery: (usyncQuery: import("..").USyncQuery) => Promise<import("..").USyncQueryResult | undefined>;
107
106
  type: "md";
108
107
  ws: import("./Client").WebSocketClient;
109
108
  ev: import("../Types").BaileysEventEmitter & {
@@ -35,22 +35,25 @@ const makeMessagesRecvSocket = (config) => {
35
35
  useClones: false
36
36
  });
37
37
  let sendActiveReceipts = false;
38
- const sendMessageAck = async ({ tag, attrs, content }) => {
38
+ const sendMessageAck = async ({ tag, attrs, content }, errorCode) => {
39
39
  const stanza = {
40
40
  tag: 'ack',
41
41
  attrs: {
42
42
  id: attrs.id,
43
43
  to: attrs.from,
44
- class: tag,
44
+ class: tag
45
45
  }
46
46
  };
47
+ if (!!errorCode) {
48
+ stanza.attrs.error = errorCode.toString();
49
+ }
47
50
  if (!!attrs.participant) {
48
51
  stanza.attrs.participant = attrs.participant;
49
52
  }
50
53
  if (!!attrs.recipient) {
51
54
  stanza.attrs.recipient = attrs.recipient;
52
55
  }
53
- if (!!attrs.type && (tag !== 'message' || (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable'))) {
56
+ if (!!attrs.type && (tag !== 'message' || (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable') || errorCode !== 0)) {
54
57
  stanza.attrs.type = attrs.type;
55
58
  }
56
59
  if (tag === 'message' && (0, WABinary_1.getBinaryNodeChild)({ tag, attrs, content }, 'unavailable')) {
@@ -626,9 +629,13 @@ const makeMessagesRecvSocket = (config) => {
626
629
  try {
627
630
  await Promise.all([
628
631
  processingMutex.mutex(async () => {
632
+ var _a;
629
633
  await decrypt();
630
634
  // message failed to decrypt
631
635
  if (msg.messageStubType === WAProto_1.proto.WebMessageInfo.StubType.CIPHERTEXT) {
636
+ if (((_a = msg === null || msg === void 0 ? void 0 : msg.messageStubParameters) === null || _a === void 0 ? void 0 : _a[0]) === Utils_1.MISSING_KEYS_ERROR_TEXT) {
637
+ return sendMessageAck(node, Utils_1.NACK_REASONS.ParsingError);
638
+ }
632
639
  retryMutex.mutex(async () => {
633
640
  if (ws.isOpen) {
634
641
  if ((0, WABinary_1.getBinaryNodeChild)(node, 'unavailable')) {
@@ -671,12 +678,13 @@ const makeMessagesRecvSocket = (config) => {
671
678
  }
672
679
  }
673
680
  (0, Utils_2.cleanMessage)(msg, authState.creds.me.id);
681
+ await sendMessageAck(node);
674
682
  await upsertMessage(msg, node.attrs.offline ? 'append' : 'notify');
675
683
  })
676
684
  ]);
677
685
  }
678
- finally {
679
- await sendMessageAck(node);
686
+ catch (error) {
687
+ logger.error({ error, node }, 'error in handling message');
680
688
  }
681
689
  };
682
690
  const fetchMessageHistory = async (count, oldestMsgKey, oldestMsgTimestamp) => {
@@ -762,19 +770,19 @@ const makeMessagesRecvSocket = (config) => {
762
770
  };
763
771
  const handleBadAck = async ({ attrs }) => {
764
772
  const key = { remoteJid: attrs.from, fromMe: true, id: attrs.id };
765
- // current hypothesis is that if pash is sent in the ack
766
- // it means -- the message hasn't reached all devices yet
767
- // we'll retry sending the message here
768
- if (attrs.phash) {
769
- logger.info({ attrs }, 'received phash in ack, resending message...');
770
- const msg = await getMessage(key);
771
- if (msg) {
772
- await relayMessage(key.remoteJid, msg, { messageId: key.id, useUserDevicesCache: false });
773
- }
774
- else {
775
- logger.warn({ attrs }, 'could not send message again, as it was not found');
776
- }
777
- }
773
+ // WARNING: REFRAIN FROM ENABLING THIS FOR NOW. IT WILL CAUSE A LOOP
774
+ // // current hypothesis is that if pash is sent in the ack
775
+ // // it means -- the message hasn't reached all devices yet
776
+ // // we'll retry sending the message here
777
+ // if(attrs.phash) {
778
+ // logger.info({ attrs }, 'received phash in ack, resending message...')
779
+ // const msg = await getMessage(key)
780
+ // if(msg) {
781
+ // await relayMessage(key.remoteJid!, msg, { messageId: key.id!, useUserDevicesCache: false })
782
+ // } else {
783
+ // logger.warn({ attrs }, 'could not send message again, as it was not found')
784
+ // }
785
+ // }
778
786
  // error in acknowledgement,
779
787
  // device could not display the message
780
788
  if (attrs.error) {
@@ -799,22 +807,63 @@ const makeMessagesRecvSocket = (config) => {
799
807
  await execTask();
800
808
  ev.flush();
801
809
  function execTask() {
802
- return exec(node)
810
+ return exec(node, false)
803
811
  .catch(err => onUnexpectedError(err, identifier));
804
812
  }
805
813
  };
814
+ const makeOfflineNodeProcessor = () => {
815
+ const nodeProcessorMap = new Map([
816
+ ['message', handleMessage],
817
+ ['call', handleCall],
818
+ ['receipt', handleReceipt],
819
+ ['notification', handleNotification]
820
+ ]);
821
+ const nodes = [];
822
+ let isProcessing = false;
823
+ const enqueue = (type, node) => {
824
+ nodes.push({ type, node });
825
+ if (isProcessing) {
826
+ return;
827
+ }
828
+ isProcessing = true;
829
+ const promise = async () => {
830
+ while (nodes.length && ws.isOpen) {
831
+ const { type, node } = nodes.shift();
832
+ const nodeProcessor = nodeProcessorMap.get(type);
833
+ if (!nodeProcessor) {
834
+ onUnexpectedError(new Error(`unknown offline node type: ${type}`), 'processing offline node');
835
+ continue;
836
+ }
837
+ await nodeProcessor(node);
838
+ }
839
+ isProcessing = false;
840
+ };
841
+ promise().catch(error => onUnexpectedError(error, 'processing offline nodes'));
842
+ };
843
+ return { enqueue };
844
+ };
845
+ const offlineNodeProcessor = makeOfflineNodeProcessor();
846
+ const processNode = (type, node, identifier, exec) => {
847
+ const isOffline = !!node.attrs.offline;
848
+ if (isOffline) {
849
+ offlineNodeProcessor.enqueue(type, node);
850
+ }
851
+ else {
852
+ processNodeWithBuffer(node, identifier, exec);
853
+ }
854
+ };
806
855
  // recv a message
807
856
  ws.on('CB:message', (node) => {
808
- processNodeWithBuffer(node, 'processing message', handleMessage);
857
+ processNode('message', node, 'processing message', handleMessage);
809
858
  });
810
859
  ws.on('CB:call', async (node) => {
811
- processNodeWithBuffer(node, 'handling call', handleCall);
860
+ processNode('call', node, 'handling call', handleCall);
812
861
  });
813
862
  ws.on('CB:receipt', node => {
814
- processNodeWithBuffer(node, 'handling receipt', handleReceipt);
863
+ processNode('receipt', node, 'handling receipt', handleReceipt);
815
864
  });
816
865
  ws.on('CB:notification', async (node) => {
817
- processNodeWithBuffer(node, 'handling notification', handleNotification);
866
+ processNode('notification', node, 'handling notification', handleNotification);
818
867
  });
819
868
  ws.on('CB:ack,class:message', (node) => {
820
869
  handleBadAck(node)
@@ -4,6 +4,7 @@ import { Boom } from '@hapi/boom';
4
4
  import { proto } from '../../WAProto';
5
5
  import { AnyMessageContent, MediaConnInfo, MessageReceiptType, MessageRelayOptions, MiscMessageGenerationOptions, SocketConfig, WAMessageKey } from '../Types';
6
6
  import { BinaryNode, JidWithDevice } from '../WABinary';
7
+ import { USyncQuery } from '../WAUSync';
7
8
  export declare const makeMessagesSocket: (config: SocketConfig) => {
8
9
  getPrivacyTokens: (jids: string[]) => Promise<BinaryNode>;
9
10
  assertSessions: (jids: string[], force: boolean) => Promise<boolean>;
@@ -63,14 +64,12 @@ export declare const makeMessagesSocket: (config: SocketConfig) => {
63
64
  presenceSubscribe: (toJid: string, tcToken?: Buffer | undefined) => Promise<void>;
64
65
  profilePictureUrl: (jid: string, type?: "image" | "preview", timeoutMs?: number | undefined) => Promise<string | undefined>;
65
66
  onWhatsApp: (...jids: string[]) => Promise<{
66
- exists: boolean;
67
67
  jid: string;
68
- }[]>;
68
+ exists: unknown;
69
+ }[] | undefined>;
69
70
  fetchBlocklist: () => Promise<string[]>;
70
- fetchStatus: (jid: string) => Promise<{
71
- status: string | undefined;
72
- setAt: Date;
73
- } | undefined>;
71
+ fetchStatus: (...jids: string[]) => Promise<import("../WAUSync").USyncQueryResultList[] | undefined>;
72
+ fetchDisappearingDuration: (...jids: string[]) => Promise<import("../WAUSync").USyncQueryResultList[] | undefined>;
74
73
  updateProfilePicture: (jid: string, content: import("../Types").WAMediaUpload) => Promise<void>;
75
74
  removeProfilePicture: (jid: string) => Promise<void>;
76
75
  updateProfileStatus: (status: string) => Promise<void>;
@@ -97,6 +96,7 @@ export declare const makeMessagesSocket: (config: SocketConfig) => {
97
96
  id: string;
98
97
  fromMe?: boolean | undefined;
99
98
  }[], star: boolean) => Promise<void>;
99
+ executeUSyncQuery: (usyncQuery: USyncQuery) => Promise<import("../WAUSync").USyncQueryResult | undefined>;
100
100
  type: "md";
101
101
  ws: import("./Client").WebSocketClient;
102
102
  ev: import("../Types").BaileysEventEmitter & {
@@ -11,11 +11,12 @@ const Defaults_1 = require("../Defaults");
11
11
  const Utils_1 = require("../Utils");
12
12
  const link_preview_1 = require("../Utils/link-preview");
13
13
  const WABinary_1 = require("../WABinary");
14
+ const WAUSync_1 = require("../WAUSync");
14
15
  const groups_1 = require("./groups");
15
16
  const makeMessagesSocket = (config) => {
16
17
  const { logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: axiosOptions, patchMessageBeforeSending, cachedGroupMetadata, } = config;
17
18
  const sock = (0, groups_1.makeGroupsSocket)(config);
18
- const { ev, authState, processingMutex, signalRepository, upsertMessage, query, fetchPrivacySettings, generateMessageTag, sendNode, groupMetadata, groupToggleEphemeral, } = sock;
19
+ const { ev, authState, processingMutex, signalRepository, upsertMessage, query, fetchPrivacySettings, sendNode, groupMetadata, groupToggleEphemeral, } = sock;
19
20
  const userDevicesCache = config.userDevicesCache || new node_cache_1.default({
20
21
  stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.USER_DEVICES,
21
22
  useClones: false
@@ -115,66 +116,46 @@ const makeMessagesSocket = (config) => {
115
116
  if (!useCache) {
116
117
  logger.debug('not using cache for devices');
117
118
  }
118
- const users = [];
119
+ const toFetch = [];
119
120
  jids = Array.from(new Set(jids));
120
121
  for (let jid of jids) {
121
122
  const user = (_a = (0, WABinary_1.jidDecode)(jid)) === null || _a === void 0 ? void 0 : _a.user;
122
123
  jid = (0, WABinary_1.jidNormalizedUser)(jid);
123
- const devices = userDevicesCache.get(user);
124
- if (devices && useCache) {
125
- deviceResults.push(...devices);
126
- logger.trace({ user }, 'using cache for devices');
124
+ if (useCache) {
125
+ const devices = userDevicesCache.get(user);
126
+ if (devices) {
127
+ deviceResults.push(...devices);
128
+ logger.trace({ user }, 'using cache for devices');
129
+ }
130
+ else {
131
+ toFetch.push(jid);
132
+ }
127
133
  }
128
134
  else {
129
- users.push({ tag: 'user', attrs: { jid } });
135
+ toFetch.push(jid);
130
136
  }
131
137
  }
132
- if (!users.length) {
138
+ if (!toFetch.length) {
133
139
  return deviceResults;
134
140
  }
135
- const iq = {
136
- tag: 'iq',
137
- attrs: {
138
- to: WABinary_1.S_WHATSAPP_NET,
139
- type: 'get',
140
- xmlns: 'usync',
141
- },
142
- content: [
143
- {
144
- tag: 'usync',
145
- attrs: {
146
- sid: generateMessageTag(),
147
- mode: 'query',
148
- last: 'true',
149
- index: '0',
150
- context: 'message',
151
- },
152
- content: [
153
- {
154
- tag: 'query',
155
- attrs: {},
156
- content: [
157
- {
158
- tag: 'devices',
159
- attrs: { version: '2' }
160
- }
161
- ]
162
- },
163
- { tag: 'list', attrs: {}, content: users }
164
- ]
165
- },
166
- ],
167
- };
168
- const result = await query(iq);
169
- const extracted = (0, Utils_1.extractDeviceJids)(result, authState.creds.me.id, ignoreZeroDevices);
170
- const deviceMap = {};
171
- for (const item of extracted) {
172
- deviceMap[item.user] = deviceMap[item.user] || [];
173
- deviceMap[item.user].push(item);
174
- deviceResults.push(item);
175
- }
176
- for (const key in deviceMap) {
177
- userDevicesCache.set(key, deviceMap[key]);
141
+ const query = new WAUSync_1.USyncQuery()
142
+ .withContext('message')
143
+ .withDeviceProtocol();
144
+ for (const jid of toFetch) {
145
+ query.withUser(new WAUSync_1.USyncUser().withId(jid));
146
+ }
147
+ const result = await sock.executeUSyncQuery(query);
148
+ if (result) {
149
+ const extracted = (0, Utils_1.extractDeviceJids)(result === null || result === void 0 ? void 0 : result.list, authState.creds.me.id, ignoreZeroDevices);
150
+ const deviceMap = {};
151
+ for (const item of extracted) {
152
+ deviceMap[item.user] = deviceMap[item.user] || [];
153
+ deviceMap[item.user].push(item);
154
+ deviceResults.push(item);
155
+ }
156
+ for (const key in deviceMap) {
157
+ userDevicesCache.set(key, deviceMap[key]);
158
+ }
178
159
  }
179
160
  return deviceResults;
180
161
  };
@@ -526,6 +526,14 @@ const makeSocket = (config) => {
526
526
  ws.on('CB:ib,,downgrade_webclient', () => {
527
527
  end(new boom_1.Boom('Multi-device beta not joined', { statusCode: Types_1.DisconnectReason.multideviceMismatch }));
528
528
  });
529
+ ws.on('CB:ib,,offline_preview', (node) => {
530
+ logger.info('offline preview received', node);
531
+ sendNode({
532
+ tag: 'ib',
533
+ attrs: {},
534
+ content: [{ tag: 'offline_batch', attrs: { count: '100' } }]
535
+ });
536
+ });
529
537
  ws.on('CB:ib,,edge_routing', (node) => {
530
538
  const edgeRoutingNode = (0, WABinary_1.getBinaryNodeChild)(node, 'edge_routing');
531
539
  const routingInfo = (0, WABinary_1.getBinaryNodeChild)(edgeRoutingNode, 'routing_info');