@ubedsockets/baileys 1.6.6 → 1.6.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.
- package/WAProto/GenerateStatics.sh +4 -3
- package/WAProto/WAProto.proto +511 -1215
- package/WAProto/index.js +131318 -59331
- package/lib/Defaults/index.js +92 -76
- package/lib/Signal/Group/ciphertext-message.js +5 -2
- package/lib/Signal/Group/group-session-builder.js +41 -7
- package/lib/Signal/Group/group_cipher.js +51 -37
- package/lib/Signal/Group/index.js +57 -12
- package/lib/Signal/Group/keyhelper.js +44 -7
- package/lib/Signal/Group/sender-chain-key.js +15 -7
- package/lib/Signal/Group/sender-key-distribution-message.js +11 -8
- package/lib/Signal/Group/sender-key-message.js +12 -9
- package/lib/Signal/Group/sender-key-name.js +5 -2
- package/lib/Signal/Group/sender-key-record.js +21 -9
- package/lib/Signal/Group/sender-key-state.js +42 -27
- package/lib/Signal/Group/sender-message-key.js +7 -4
- package/lib/Signal/libsignal.js +90 -347
- package/lib/Socket/Client/index.js +18 -3
- package/lib/Socket/Client/types.js +6 -4
- package/lib/Socket/Client/websocket.js +78 -21
- package/lib/Socket/business.js +43 -162
- package/lib/Socket/chats.js +249 -571
- package/lib/Socket/groups.js +99 -114
- package/lib/Socket/index.js +9 -11
- package/lib/Socket/messages-recv.js +559 -1277
- package/lib/Socket/messages-send.js +669 -674
- package/lib/Socket/newsletter.js +286 -149
- package/lib/Socket/socket.js +235 -548
- package/lib/Types/Auth.js +2 -2
- package/lib/Types/Call.js +2 -2
- package/lib/Types/Chat.js +4 -8
- package/lib/Types/Contact.js +2 -2
- package/lib/Types/Events.js +2 -2
- package/lib/Types/GroupMetadata.js +2 -2
- package/lib/Types/Label.js +5 -3
- package/lib/Types/LabelAssociation.js +5 -3
- package/lib/Types/Message.js +7 -11
- package/lib/Types/Product.js +2 -2
- package/lib/Types/Signal.js +2 -2
- package/lib/Types/Socket.js +2 -3
- package/lib/Types/State.js +2 -56
- package/lib/Types/USync.js +2 -2
- package/lib/Types/index.js +31 -15
- package/lib/Utils/auth-utils.js +136 -239
- package/lib/Utils/business.js +69 -66
- package/lib/Utils/chat-utils.js +238 -380
- package/lib/Utils/crypto.js +127 -56
- package/lib/Utils/decode-wa-message.js +63 -173
- package/lib/Utils/event-buffer.js +70 -174
- package/lib/Utils/generics.js +207 -159
- package/lib/Utils/history.js +53 -93
- package/lib/Utils/index.js +33 -22
- package/lib/Utils/link-preview.js +58 -17
- package/lib/Utils/logger.js +7 -3
- package/lib/Utils/lt-hash.js +46 -3
- package/lib/Utils/make-mutex.js +34 -24
- package/lib/Utils/messages-media.js +744 -483
- package/lib/Utils/messages.js +621 -411
- package/lib/Utils/noise-handler.js +99 -149
- package/lib/Utils/process-message.js +150 -459
- package/lib/Utils/signal.js +73 -112
- package/lib/Utils/use-multi-file-auth-state.js +27 -23
- package/lib/Utils/validate-connection.js +104 -74
- package/lib/WABinary/constants.js +11 -9
- package/lib/WABinary/decode.js +52 -49
- package/lib/WABinary/encode.js +49 -19
- package/lib/WABinary/generic-utils.js +43 -46
- package/lib/WABinary/index.js +21 -6
- package/lib/WABinary/jid-utils.js +45 -72
- package/lib/WABinary/types.js +2 -2
- package/lib/WAM/BinaryInfo.js +5 -2
- package/lib/WAM/constants.js +11958 -19461
- package/lib/WAM/encode.js +22 -17
- package/lib/WAM/index.js +19 -4
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +13 -33
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +14 -11
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +11 -8
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +13 -9
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +22 -20
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +8 -13
- package/lib/WAUSync/Protocols/index.js +20 -6
- package/lib/WAUSync/USyncQuery.js +35 -44
- package/lib/WAUSync/USyncUser.js +5 -10
- package/lib/WAUSync/index.js +19 -4
- package/lib/index.js +70 -11
- package/package.json +60 -100
- package/engine-requirements.js +0 -10
package/lib/Socket/chats.js
CHANGED
|
@@ -1,56 +1,37 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.makeChatsSocket = void 0;
|
|
7
|
+
const boom_1 = require("@hapi/boom");
|
|
8
|
+
const node_cache_1 = __importDefault(require("@cacheable/node-cache"));
|
|
9
|
+
const WAProto_1 = require("../../WAProto");
|
|
10
|
+
const Defaults_1 = require("../Defaults");
|
|
11
|
+
const Types_1 = require("../Types");
|
|
12
|
+
const Utils_1 = require("../Utils");
|
|
13
|
+
const make_mutex_1 = require("../Utils/make-mutex");
|
|
14
|
+
const process_message_1 = __importDefault(require("../Utils/process-message"));
|
|
15
|
+
const WABinary_1 = require("../WABinary");
|
|
16
|
+
const WAUSync_1 = require("../WAUSync");
|
|
17
|
+
const usync_1 = require("./usync");
|
|
18
|
+
const MAX_SYNC_ATTEMPTS = 2;
|
|
19
|
+
const makeChatsSocket = (config) => {
|
|
20
|
+
const { logger, markOnlineOnConnect, fireInitQueries, appStateMacVerification, shouldIgnoreJid, shouldSyncHistoryMessage, } = config;
|
|
21
|
+
const sock = (0, usync_1.makeUSyncSocket)(config);
|
|
22
|
+
const { ev, ws, authState, generateMessageTag, sendNode, query, onUnexpectedError, } = sock;
|
|
19
23
|
let privacySettings;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const messageMutex = makeMutex();
|
|
32
|
-
/** this mutex ensures that receipts are processed in order */
|
|
33
|
-
const receiptMutex = makeMutex();
|
|
34
|
-
/** this mutex ensures that app state patches are processed in order */
|
|
35
|
-
const appStatePatchMutex = makeMutex();
|
|
36
|
-
/** this mutex ensures that notifications are processed in order */
|
|
37
|
-
const notificationMutex = makeMutex();
|
|
38
|
-
// Timeout for AwaitingInitialSync state
|
|
39
|
-
let awaitingSyncTimeout;
|
|
40
|
-
// In-memory history sync completion tracking (resets on reconnection)
|
|
41
|
-
const historySyncStatus = {
|
|
42
|
-
initialBootstrapComplete: false,
|
|
43
|
-
recentSyncComplete: false
|
|
44
|
-
};
|
|
45
|
-
let historySyncPausedTimeout;
|
|
46
|
-
// Collections blocked on missing app state sync keys (mirrors WA Web's "Blocked" state).
|
|
47
|
-
// When a key arrives via APP_STATE_SYNC_KEY_SHARE, these are re-synced.
|
|
48
|
-
const blockedCollections = new Set();
|
|
49
|
-
const placeholderResendCache = config.placeholderResendCache ||
|
|
50
|
-
new NodeCache({
|
|
51
|
-
stdTTL: DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
|
|
52
|
-
useClones: false
|
|
53
|
-
});
|
|
24
|
+
let needToFlushWithAppStateSync = false;
|
|
25
|
+
let pendingAppStateSync = false;
|
|
26
|
+
/** this mutex ensures that the notifications (receipts, messages etc.) are processed in order */
|
|
27
|
+
const processingMutex = (0, make_mutex_1.makeMutex)();
|
|
28
|
+
const placeholderResendCache = config.placeholderResendCache || new node_cache_1.default({
|
|
29
|
+
stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
|
|
30
|
+
useClones: false
|
|
31
|
+
});
|
|
32
|
+
if (!config.placeholderResendCache) {
|
|
33
|
+
config.placeholderResendCache = placeholderResendCache;
|
|
34
|
+
}
|
|
54
35
|
/** helper function to fetch the given app state sync key */
|
|
55
36
|
const getAppStateSyncKey = async (keyId) => {
|
|
56
37
|
const { [keyId]: key } = await authState.keys.get('app-state-sync-key', [keyId]);
|
|
@@ -62,12 +43,14 @@ export const makeChatsSocket = (config) => {
|
|
|
62
43
|
tag: 'iq',
|
|
63
44
|
attrs: {
|
|
64
45
|
xmlns: 'privacy',
|
|
65
|
-
to: S_WHATSAPP_NET,
|
|
46
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
66
47
|
type: 'get'
|
|
67
48
|
},
|
|
68
|
-
content: [
|
|
49
|
+
content: [
|
|
50
|
+
{ tag: 'privacy', attrs: {} }
|
|
51
|
+
]
|
|
69
52
|
});
|
|
70
|
-
privacySettings = reduceBinaryNodeToDictionary(content
|
|
53
|
+
privacySettings = (0, WABinary_1.reduceBinaryNodeToDictionary)(content === null || content === void 0 ? void 0 : content[0], 'category');
|
|
71
54
|
}
|
|
72
55
|
return privacySettings;
|
|
73
56
|
};
|
|
@@ -77,11 +60,10 @@ export const makeChatsSocket = (config) => {
|
|
|
77
60
|
tag: 'iq',
|
|
78
61
|
attrs: {
|
|
79
62
|
xmlns: 'privacy',
|
|
80
|
-
to: S_WHATSAPP_NET,
|
|
63
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
81
64
|
type: 'set'
|
|
82
65
|
},
|
|
83
|
-
content: [
|
|
84
|
-
{
|
|
66
|
+
content: [{
|
|
85
67
|
tag: 'privacy',
|
|
86
68
|
attrs: {},
|
|
87
69
|
content: [
|
|
@@ -90,8 +72,7 @@ export const makeChatsSocket = (config) => {
|
|
|
90
72
|
attrs: { name, value }
|
|
91
73
|
}
|
|
92
74
|
]
|
|
93
|
-
}
|
|
94
|
-
]
|
|
75
|
+
}]
|
|
95
76
|
});
|
|
96
77
|
};
|
|
97
78
|
const updateMessagesPrivacy = async (value) => {
|
|
@@ -123,17 +104,15 @@ export const makeChatsSocket = (config) => {
|
|
|
123
104
|
tag: 'iq',
|
|
124
105
|
attrs: {
|
|
125
106
|
xmlns: 'disappearing_mode',
|
|
126
|
-
to: S_WHATSAPP_NET,
|
|
107
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
127
108
|
type: 'set'
|
|
128
109
|
},
|
|
129
|
-
content: [
|
|
130
|
-
{
|
|
110
|
+
content: [{
|
|
131
111
|
tag: 'disappearing_mode',
|
|
132
112
|
attrs: {
|
|
133
113
|
duration: duration.toString()
|
|
134
114
|
}
|
|
135
|
-
}
|
|
136
|
-
]
|
|
115
|
+
}]
|
|
137
116
|
});
|
|
138
117
|
};
|
|
139
118
|
const getBotListV2 = async () => {
|
|
@@ -141,23 +120,21 @@ export const makeChatsSocket = (config) => {
|
|
|
141
120
|
tag: 'iq',
|
|
142
121
|
attrs: {
|
|
143
122
|
xmlns: 'bot',
|
|
144
|
-
to: S_WHATSAPP_NET,
|
|
123
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
145
124
|
type: 'get'
|
|
146
125
|
},
|
|
147
|
-
content: [
|
|
148
|
-
{
|
|
126
|
+
content: [{
|
|
149
127
|
tag: 'bot',
|
|
150
128
|
attrs: {
|
|
151
129
|
v: '2'
|
|
152
130
|
}
|
|
153
|
-
}
|
|
154
|
-
]
|
|
131
|
+
}]
|
|
155
132
|
});
|
|
156
|
-
const botNode = getBinaryNodeChild(resp, 'bot');
|
|
133
|
+
const botNode = (0, WABinary_1.getBinaryNodeChild)(resp, 'bot');
|
|
157
134
|
const botList = [];
|
|
158
|
-
for (const section of getBinaryNodeChildren(botNode, 'section')) {
|
|
135
|
+
for (const section of (0, WABinary_1.getBinaryNodeChildren)(botNode, 'section')) {
|
|
159
136
|
if (section.attrs.type === 'all') {
|
|
160
|
-
for (const bot of getBinaryNodeChildren(section, 'bot')) {
|
|
137
|
+
for (const bot of (0, WABinary_1.getBinaryNodeChildren)(section, 'bot')) {
|
|
161
138
|
botList.push({
|
|
162
139
|
jid: bot.attrs.jid,
|
|
163
140
|
personaId: bot.attrs['persona_id']
|
|
@@ -167,10 +144,24 @@ export const makeChatsSocket = (config) => {
|
|
|
167
144
|
}
|
|
168
145
|
return botList;
|
|
169
146
|
};
|
|
147
|
+
const onWhatsApp = async (...jids) => {
|
|
148
|
+
const usyncQuery = new WAUSync_1.USyncQuery()
|
|
149
|
+
.withContactProtocol()
|
|
150
|
+
.withLIDProtocol();
|
|
151
|
+
for (const jid of jids) {
|
|
152
|
+
const phone = `+${jid.replace('+', '').split('@')[0].split(':')[0]}`;
|
|
153
|
+
usyncQuery.withUser(new WAUSync_1.USyncUser().withPhone(phone));
|
|
154
|
+
}
|
|
155
|
+
const results = await sock.executeUSyncQuery(usyncQuery);
|
|
156
|
+
if (results) {
|
|
157
|
+
return results.list.filter((a) => !!a.contact).map(({ contact, id, lid }) => ({ jid: id, exists: contact, lid }));
|
|
158
|
+
}
|
|
159
|
+
};
|
|
170
160
|
const fetchStatus = async (...jids) => {
|
|
171
|
-
const usyncQuery = new USyncQuery()
|
|
161
|
+
const usyncQuery = new WAUSync_1.USyncQuery()
|
|
162
|
+
.withStatusProtocol();
|
|
172
163
|
for (const jid of jids) {
|
|
173
|
-
usyncQuery.withUser(new USyncUser().withId(jid));
|
|
164
|
+
usyncQuery.withUser(new WAUSync_1.USyncUser().withId(jid));
|
|
174
165
|
}
|
|
175
166
|
const result = await sock.executeUSyncQuery(usyncQuery);
|
|
176
167
|
if (result) {
|
|
@@ -178,9 +169,10 @@ export const makeChatsSocket = (config) => {
|
|
|
178
169
|
}
|
|
179
170
|
};
|
|
180
171
|
const fetchDisappearingDuration = async (...jids) => {
|
|
181
|
-
const usyncQuery = new USyncQuery()
|
|
172
|
+
const usyncQuery = new WAUSync_1.USyncQuery()
|
|
173
|
+
.withDisappearingModeProtocol();
|
|
182
174
|
for (const jid of jids) {
|
|
183
|
-
usyncQuery.withUser(new USyncUser().withId(jid));
|
|
175
|
+
usyncQuery.withUser(new WAUSync_1.USyncUser().withId(jid));
|
|
184
176
|
}
|
|
185
177
|
const result = await sock.executeUSyncQuery(usyncQuery);
|
|
186
178
|
if (result) {
|
|
@@ -188,25 +180,22 @@ export const makeChatsSocket = (config) => {
|
|
|
188
180
|
}
|
|
189
181
|
};
|
|
190
182
|
/** update the profile picture for yourself or a group */
|
|
191
|
-
const updateProfilePicture = async (jid, content
|
|
183
|
+
const updateProfilePicture = async (jid, content) => {
|
|
192
184
|
let targetJid;
|
|
193
185
|
if (!jid) {
|
|
194
|
-
throw new Boom('Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update');
|
|
186
|
+
throw new boom_1.Boom('Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update');
|
|
195
187
|
}
|
|
196
|
-
if (jidNormalizedUser(jid) !== jidNormalizedUser(authState.creds.me.id)) {
|
|
197
|
-
targetJid = jidNormalizedUser(jid); // in case it is someone other than us
|
|
188
|
+
if ((0, WABinary_1.jidNormalizedUser)(jid) !== (0, WABinary_1.jidNormalizedUser)(authState.creds.me.id)) {
|
|
189
|
+
targetJid = (0, WABinary_1.jidNormalizedUser)(jid); // in case it is someone other than us
|
|
198
190
|
}
|
|
199
|
-
|
|
200
|
-
targetJid = undefined;
|
|
201
|
-
}
|
|
202
|
-
const { img } = await generateProfilePicture(content, dimensions);
|
|
191
|
+
const { img } = await (0, Utils_1.generateProfilePicture)(content);
|
|
203
192
|
await query({
|
|
204
193
|
tag: 'iq',
|
|
205
194
|
attrs: {
|
|
206
|
-
|
|
195
|
+
target: targetJid,
|
|
196
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
207
197
|
type: 'set',
|
|
208
|
-
xmlns: 'w:profile:picture'
|
|
209
|
-
...(targetJid ? { target: targetJid } : {})
|
|
198
|
+
xmlns: 'w:profile:picture'
|
|
210
199
|
},
|
|
211
200
|
content: [
|
|
212
201
|
{
|
|
@@ -221,21 +210,18 @@ export const makeChatsSocket = (config) => {
|
|
|
221
210
|
const removeProfilePicture = async (jid) => {
|
|
222
211
|
let targetJid;
|
|
223
212
|
if (!jid) {
|
|
224
|
-
throw new Boom('Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update');
|
|
213
|
+
throw new boom_1.Boom('Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update');
|
|
225
214
|
}
|
|
226
|
-
if (jidNormalizedUser(jid) !== jidNormalizedUser(authState.creds.me.id)) {
|
|
227
|
-
targetJid = jidNormalizedUser(jid); // in case it is someone other than us
|
|
228
|
-
}
|
|
229
|
-
else {
|
|
230
|
-
targetJid = undefined;
|
|
215
|
+
if ((0, WABinary_1.jidNormalizedUser)(jid) !== (0, WABinary_1.jidNormalizedUser)(authState.creds.me.id)) {
|
|
216
|
+
targetJid = (0, WABinary_1.jidNormalizedUser)(jid); // in case it is someone other than us
|
|
231
217
|
}
|
|
232
218
|
await query({
|
|
233
219
|
tag: 'iq',
|
|
234
220
|
attrs: {
|
|
235
|
-
|
|
221
|
+
target: targetJid,
|
|
222
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
236
223
|
type: 'set',
|
|
237
|
-
xmlns: 'w:profile:picture'
|
|
238
|
-
...(targetJid ? { target: targetJid } : {})
|
|
224
|
+
xmlns: 'w:profile:picture'
|
|
239
225
|
}
|
|
240
226
|
});
|
|
241
227
|
};
|
|
@@ -244,7 +230,7 @@ export const makeChatsSocket = (config) => {
|
|
|
244
230
|
await query({
|
|
245
231
|
tag: 'iq',
|
|
246
232
|
attrs: {
|
|
247
|
-
to: S_WHATSAPP_NET,
|
|
233
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
248
234
|
type: 'set',
|
|
249
235
|
xmlns: 'status'
|
|
250
236
|
},
|
|
@@ -265,66 +251,35 @@ export const makeChatsSocket = (config) => {
|
|
|
265
251
|
tag: 'iq',
|
|
266
252
|
attrs: {
|
|
267
253
|
xmlns: 'blocklist',
|
|
268
|
-
to: S_WHATSAPP_NET,
|
|
254
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
269
255
|
type: 'get'
|
|
270
256
|
}
|
|
271
257
|
});
|
|
272
|
-
const listNode = getBinaryNodeChild(result, 'list');
|
|
273
|
-
return getBinaryNodeChildren(listNode, 'item')
|
|
258
|
+
const listNode = (0, WABinary_1.getBinaryNodeChild)(result, 'list');
|
|
259
|
+
return (0, WABinary_1.getBinaryNodeChildren)(listNode, 'item')
|
|
260
|
+
.map(n => n.attrs.jid);
|
|
274
261
|
};
|
|
275
262
|
const updateBlockStatus = async (jid, action) => {
|
|
276
|
-
const normalizedJid = jidNormalizedUser(jid);
|
|
277
|
-
let lid;
|
|
278
|
-
let pn_jid;
|
|
279
|
-
if (isLidUser(normalizedJid) || isHostedLidUser(normalizedJid)) {
|
|
280
|
-
lid = normalizedJid;
|
|
281
|
-
if (action === 'block') {
|
|
282
|
-
const pn = await signalRepository.lidMapping.getPNForLID(normalizedJid);
|
|
283
|
-
if (!pn) {
|
|
284
|
-
throw new Boom(`Unable to resolve PN JID for LID: ${jid}`, { statusCode: 400 });
|
|
285
|
-
}
|
|
286
|
-
pn_jid = jidNormalizedUser(pn);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
else if (isPnUser(normalizedJid) || isHostedPnUser(normalizedJid)) {
|
|
290
|
-
const mapped = await signalRepository.lidMapping.getLIDForPN(normalizedJid);
|
|
291
|
-
if (!mapped) {
|
|
292
|
-
throw new Boom(`Unable to resolve LID for PN JID: ${jid}`, { statusCode: 400 });
|
|
293
|
-
}
|
|
294
|
-
lid = mapped;
|
|
295
|
-
if (action === 'block') {
|
|
296
|
-
pn_jid = jidNormalizedUser(normalizedJid);
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
else {
|
|
300
|
-
throw new Boom(`Invalid jid: ${jid}`, { statusCode: 400 });
|
|
301
|
-
}
|
|
302
|
-
const itemAttrs = {
|
|
303
|
-
action,
|
|
304
|
-
jid: lid
|
|
305
|
-
};
|
|
306
|
-
if (action === 'block') {
|
|
307
|
-
if (!pn_jid) {
|
|
308
|
-
throw new Boom(`pn_jid required for block: ${jid}`, { statusCode: 400 });
|
|
309
|
-
}
|
|
310
|
-
itemAttrs.pn_jid = pn_jid;
|
|
311
|
-
}
|
|
312
263
|
await query({
|
|
313
264
|
tag: 'iq',
|
|
314
265
|
attrs: {
|
|
315
266
|
xmlns: 'blocklist',
|
|
316
|
-
to: S_WHATSAPP_NET,
|
|
267
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
317
268
|
type: 'set'
|
|
318
269
|
},
|
|
319
270
|
content: [
|
|
320
271
|
{
|
|
321
272
|
tag: 'item',
|
|
322
|
-
attrs:
|
|
273
|
+
attrs: {
|
|
274
|
+
action,
|
|
275
|
+
jid
|
|
276
|
+
}
|
|
323
277
|
}
|
|
324
278
|
]
|
|
325
279
|
});
|
|
326
280
|
};
|
|
327
281
|
const getBusinessProfile = async (jid) => {
|
|
282
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
328
283
|
const results = await query({
|
|
329
284
|
tag: 'iq',
|
|
330
285
|
attrs: {
|
|
@@ -332,42 +287,38 @@ export const makeChatsSocket = (config) => {
|
|
|
332
287
|
xmlns: 'w:biz',
|
|
333
288
|
type: 'get'
|
|
334
289
|
},
|
|
335
|
-
content: [
|
|
336
|
-
{
|
|
290
|
+
content: [{
|
|
337
291
|
tag: 'business_profile',
|
|
338
292
|
attrs: { v: '244' },
|
|
339
|
-
content: [
|
|
340
|
-
{
|
|
293
|
+
content: [{
|
|
341
294
|
tag: 'profile',
|
|
342
295
|
attrs: { jid }
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
]
|
|
296
|
+
}]
|
|
297
|
+
}]
|
|
347
298
|
});
|
|
348
|
-
const profileNode = getBinaryNodeChild(results, 'business_profile');
|
|
349
|
-
const profiles = getBinaryNodeChild(profileNode, 'profile');
|
|
299
|
+
const profileNode = (0, WABinary_1.getBinaryNodeChild)(results, 'business_profile');
|
|
300
|
+
const profiles = (0, WABinary_1.getBinaryNodeChild)(profileNode, 'profile');
|
|
350
301
|
if (profiles) {
|
|
351
|
-
const address = getBinaryNodeChild(profiles, 'address');
|
|
352
|
-
const description = getBinaryNodeChild(profiles, 'description');
|
|
353
|
-
const website = getBinaryNodeChild(profiles, 'website');
|
|
354
|
-
const email = getBinaryNodeChild(profiles, 'email');
|
|
355
|
-
const category = getBinaryNodeChild(getBinaryNodeChild(profiles, 'categories'), 'category');
|
|
356
|
-
const businessHours = getBinaryNodeChild(profiles, 'business_hours');
|
|
302
|
+
const address = (0, WABinary_1.getBinaryNodeChild)(profiles, 'address');
|
|
303
|
+
const description = (0, WABinary_1.getBinaryNodeChild)(profiles, 'description');
|
|
304
|
+
const website = (0, WABinary_1.getBinaryNodeChild)(profiles, 'website');
|
|
305
|
+
const email = (0, WABinary_1.getBinaryNodeChild)(profiles, 'email');
|
|
306
|
+
const category = (0, WABinary_1.getBinaryNodeChild)((0, WABinary_1.getBinaryNodeChild)(profiles, 'categories'), 'category');
|
|
307
|
+
const businessHours = (0, WABinary_1.getBinaryNodeChild)(profiles, 'business_hours');
|
|
357
308
|
const businessHoursConfig = businessHours
|
|
358
|
-
? getBinaryNodeChildren(businessHours, 'business_hours_config')
|
|
309
|
+
? (0, WABinary_1.getBinaryNodeChildren)(businessHours, 'business_hours_config')
|
|
359
310
|
: undefined;
|
|
360
|
-
const websiteStr = website
|
|
311
|
+
const websiteStr = (_a = website === null || website === void 0 ? void 0 : website.content) === null || _a === void 0 ? void 0 : _a.toString();
|
|
361
312
|
return {
|
|
362
|
-
wid: profiles.attrs
|
|
363
|
-
address: address
|
|
364
|
-
description: description
|
|
313
|
+
wid: (_b = profiles.attrs) === null || _b === void 0 ? void 0 : _b.jid,
|
|
314
|
+
address: (_c = address === null || address === void 0 ? void 0 : address.content) === null || _c === void 0 ? void 0 : _c.toString(),
|
|
315
|
+
description: ((_d = description === null || description === void 0 ? void 0 : description.content) === null || _d === void 0 ? void 0 : _d.toString()) || '',
|
|
365
316
|
website: websiteStr ? [websiteStr] : [],
|
|
366
|
-
email: email
|
|
367
|
-
category: category
|
|
368
|
-
business_hours: {
|
|
369
|
-
timezone: businessHours
|
|
370
|
-
business_config: businessHoursConfig
|
|
317
|
+
email: (_e = email === null || email === void 0 ? void 0 : email.content) === null || _e === void 0 ? void 0 : _e.toString(),
|
|
318
|
+
category: (_f = category === null || category === void 0 ? void 0 : category.content) === null || _f === void 0 ? void 0 : _f.toString(),
|
|
319
|
+
'business_hours': {
|
|
320
|
+
timezone: (_g = businessHours === null || businessHours === void 0 ? void 0 : businessHours.attrs) === null || _g === void 0 ? void 0 : _g.timezone,
|
|
321
|
+
'business_config': businessHoursConfig === null || businessHoursConfig === void 0 ? void 0 : businessHoursConfig.map(({ attrs }) => attrs)
|
|
371
322
|
}
|
|
372
323
|
};
|
|
373
324
|
}
|
|
@@ -377,17 +328,17 @@ export const makeChatsSocket = (config) => {
|
|
|
377
328
|
await sendNode({
|
|
378
329
|
tag: 'iq',
|
|
379
330
|
attrs: {
|
|
380
|
-
to: S_WHATSAPP_NET,
|
|
331
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
381
332
|
type: 'set',
|
|
382
333
|
xmlns: 'urn:xmpp:whatsapp:dirty',
|
|
383
|
-
id: generateMessageTag()
|
|
334
|
+
id: generateMessageTag(),
|
|
384
335
|
},
|
|
385
336
|
content: [
|
|
386
337
|
{
|
|
387
338
|
tag: 'clean',
|
|
388
339
|
attrs: {
|
|
389
340
|
type,
|
|
390
|
-
...(fromTimestamp ? { timestamp: fromTimestamp.toString() } : null)
|
|
341
|
+
...(fromTimestamp ? { timestamp: fromTimestamp.toString() } : null),
|
|
391
342
|
}
|
|
392
343
|
}
|
|
393
344
|
]
|
|
@@ -396,31 +347,20 @@ export const makeChatsSocket = (config) => {
|
|
|
396
347
|
const newAppStateChunkHandler = (isInitialSync) => {
|
|
397
348
|
return {
|
|
398
349
|
onMutation(mutation) {
|
|
399
|
-
processSyncAction(mutation, ev, authState.creds.me, isInitialSync ? { accountSettings: authState.creds.accountSettings } : undefined, logger);
|
|
350
|
+
(0, Utils_1.processSyncAction)(mutation, ev, authState.creds.me, isInitialSync ? { accountSettings: authState.creds.accountSettings } : undefined, logger);
|
|
400
351
|
}
|
|
401
352
|
};
|
|
402
353
|
};
|
|
403
354
|
const resyncAppState = ev.createBufferedFunction(async (collections, isInitialSync) => {
|
|
404
|
-
const appStateSyncKeyCache = new Map();
|
|
405
|
-
const getCachedAppStateSyncKey = async (keyId) => {
|
|
406
|
-
if (appStateSyncKeyCache.has(keyId)) {
|
|
407
|
-
return appStateSyncKeyCache.get(keyId) ?? undefined;
|
|
408
|
-
}
|
|
409
|
-
const key = await getAppStateSyncKey(keyId);
|
|
410
|
-
appStateSyncKeyCache.set(keyId, key ?? null);
|
|
411
|
-
return key;
|
|
412
|
-
};
|
|
413
355
|
// we use this to determine which events to fire
|
|
414
356
|
// otherwise when we resync from scratch -- all notifications will fire
|
|
415
357
|
const initialVersionMap = {};
|
|
416
358
|
const globalMutationMap = {};
|
|
417
359
|
await authState.keys.transaction(async () => {
|
|
360
|
+
var _a;
|
|
418
361
|
const collectionsToHandle = new Set(collections);
|
|
419
362
|
// in case something goes wrong -- ensure we don't enter a loop that cannot be exited from
|
|
420
363
|
const attemptsMap = {};
|
|
421
|
-
// collections that failed and need a full snapshot on retry
|
|
422
|
-
// mirrors WA Web's ErrorFatal -> force snapshot behavior
|
|
423
|
-
const forceSnapshotCollections = new Set();
|
|
424
364
|
// keep executing till all collections are done
|
|
425
365
|
// sometimes a single patch request will not return all the patches (God knows why)
|
|
426
366
|
// so we fetch till they're all done (this is determined by the "has_more_patches" flag)
|
|
@@ -431,34 +371,29 @@ export const makeChatsSocket = (config) => {
|
|
|
431
371
|
const result = await authState.keys.get('app-state-sync-version', [name]);
|
|
432
372
|
let state = result[name];
|
|
433
373
|
if (state) {
|
|
434
|
-
state = ensureLTHashStateVersion(state);
|
|
435
374
|
if (typeof initialVersionMap[name] === 'undefined') {
|
|
436
375
|
initialVersionMap[name] = state.version;
|
|
437
376
|
}
|
|
438
377
|
}
|
|
439
378
|
else {
|
|
440
|
-
state = newLTHashState();
|
|
379
|
+
state = (0, Utils_1.newLTHashState)();
|
|
441
380
|
}
|
|
442
381
|
states[name] = state;
|
|
443
|
-
|
|
444
|
-
if (shouldForceSnapshot) {
|
|
445
|
-
forceSnapshotCollections.delete(name);
|
|
446
|
-
}
|
|
447
|
-
logger.info(`resyncing ${name} from v${state.version}${shouldForceSnapshot ? ' (forcing snapshot)' : ''}`);
|
|
382
|
+
logger.info(`resyncing ${name} from v${state.version}`);
|
|
448
383
|
nodes.push({
|
|
449
384
|
tag: 'collection',
|
|
450
385
|
attrs: {
|
|
451
386
|
name,
|
|
452
387
|
version: state.version.toString(),
|
|
453
|
-
// return snapshot if
|
|
454
|
-
return_snapshot: (
|
|
388
|
+
// return snapshot if being synced from scratch
|
|
389
|
+
'return_snapshot': (!state.version).toString()
|
|
455
390
|
}
|
|
456
391
|
});
|
|
457
392
|
}
|
|
458
393
|
const result = await query({
|
|
459
394
|
tag: 'iq',
|
|
460
395
|
attrs: {
|
|
461
|
-
to: S_WHATSAPP_NET,
|
|
396
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
462
397
|
xmlns: 'w:sync:app:state',
|
|
463
398
|
type: 'set'
|
|
464
399
|
},
|
|
@@ -471,13 +406,13 @@ export const makeChatsSocket = (config) => {
|
|
|
471
406
|
]
|
|
472
407
|
});
|
|
473
408
|
// extract from binary node
|
|
474
|
-
const decoded = await extractSyncdPatches(result, config
|
|
409
|
+
const decoded = await (0, Utils_1.extractSyncdPatches)(result, config === null || config === void 0 ? void 0 : config.options);
|
|
475
410
|
for (const key in decoded) {
|
|
476
411
|
const name = key;
|
|
477
412
|
const { patches, hasMorePatches, snapshot } = decoded[name];
|
|
478
413
|
try {
|
|
479
414
|
if (snapshot) {
|
|
480
|
-
const { state: newState, mutationMap } = await decodeSyncdSnapshot(name, snapshot,
|
|
415
|
+
const { state: newState, mutationMap } = await (0, Utils_1.decodeSyncdSnapshot)(name, snapshot, getAppStateSyncKey, initialVersionMap[name], appStateMacVerification.snapshot);
|
|
481
416
|
states[name] = newState;
|
|
482
417
|
Object.assign(globalMutationMap, mutationMap);
|
|
483
418
|
logger.info(`restored state of ${name} from snapshot to v${newState.version} with mutations`);
|
|
@@ -485,7 +420,7 @@ export const makeChatsSocket = (config) => {
|
|
|
485
420
|
}
|
|
486
421
|
// only process if there are syncd patches
|
|
487
422
|
if (patches.length) {
|
|
488
|
-
const { state: newState, mutationMap } = await decodePatches(name, patches, states[name],
|
|
423
|
+
const { state: newState, mutationMap } = await (0, Utils_1.decodePatches)(name, patches, states[name], getAppStateSyncKey, config.options, initialVersionMap[name], logger, appStateMacVerification.patch);
|
|
489
424
|
await authState.keys.set({ 'app-state-sync-version': { [name]: newState } });
|
|
490
425
|
logger.info(`synced ${name} to v${newState.version}`);
|
|
491
426
|
initialVersionMap[name] = newState.version;
|
|
@@ -494,47 +429,28 @@ export const makeChatsSocket = (config) => {
|
|
|
494
429
|
if (hasMorePatches) {
|
|
495
430
|
logger.info(`${name} has more patches...`);
|
|
496
431
|
}
|
|
497
|
-
else {
|
|
498
|
-
// collection is done with sync
|
|
432
|
+
else { // collection is done with sync
|
|
499
433
|
collectionsToHandle.delete(name);
|
|
500
434
|
}
|
|
501
435
|
}
|
|
502
436
|
catch (error) {
|
|
437
|
+
// if retry attempts overshoot
|
|
438
|
+
// or key not found
|
|
439
|
+
const isIrrecoverableError = attemptsMap[name] >= MAX_SYNC_ATTEMPTS
|
|
440
|
+
|| ((_a = error.output) === null || _a === void 0 ? void 0 : _a.statusCode) === 404
|
|
441
|
+
|| error.name === 'TypeError';
|
|
442
|
+
logger.info({ name, error: error.stack }, `failed to sync state from version${isIrrecoverableError ? '' : ', removing and trying from scratch'}`);
|
|
443
|
+
await authState.keys.set({ 'app-state-sync-version': { [name]: null } });
|
|
444
|
+
// increment number of retries
|
|
503
445
|
attemptsMap[name] = (attemptsMap[name] || 0) + 1;
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
attempt: attemptsMap[name],
|
|
507
|
-
version: states[name].version,
|
|
508
|
-
statusCode: error.output?.statusCode,
|
|
509
|
-
errorType: error.name,
|
|
510
|
-
error: error.stack
|
|
511
|
-
};
|
|
512
|
-
if (isMissingKeyError(error) && attemptsMap[name] >= MAX_SYNC_ATTEMPTS) {
|
|
513
|
-
// WA Web treats missing keys as "Blocked" — park the collection
|
|
514
|
-
// until the key arrives via APP_STATE_SYNC_KEY_SHARE.
|
|
515
|
-
logger.warn(logData, `${name} blocked on missing key from v${states[name].version}, parking after ${attemptsMap[name]} attempts`);
|
|
516
|
-
blockedCollections.add(name);
|
|
517
|
-
collectionsToHandle.delete(name);
|
|
518
|
-
}
|
|
519
|
-
else if (isMissingKeyError(error)) {
|
|
520
|
-
// Retry with a snapshot which may use a different key.
|
|
521
|
-
logger.info(logData, `${name} blocked on missing key from v${states[name].version}, retrying with snapshot`);
|
|
522
|
-
forceSnapshotCollections.add(name);
|
|
523
|
-
}
|
|
524
|
-
else if (isAppStateSyncIrrecoverable(error, attemptsMap[name])) {
|
|
525
|
-
logger.warn(logData, `failed to sync ${name} from v${states[name].version}, giving up`);
|
|
446
|
+
if (isIrrecoverableError) {
|
|
447
|
+
// stop retrying
|
|
526
448
|
collectionsToHandle.delete(name);
|
|
527
449
|
}
|
|
528
|
-
else {
|
|
529
|
-
logger.info(logData, `failed to sync ${name} from v${states[name].version}, forcing snapshot retry`);
|
|
530
|
-
// force a full snapshot on retry to recover from
|
|
531
|
-
// corrupted local state (e.g. LTHash MAC mismatch)
|
|
532
|
-
forceSnapshotCollections.add(name);
|
|
533
|
-
}
|
|
534
450
|
}
|
|
535
451
|
}
|
|
536
452
|
}
|
|
537
|
-
}
|
|
453
|
+
});
|
|
538
454
|
const { onMutation } = newAppStateChunkHandler(isInitialSync);
|
|
539
455
|
for (const key in globalMutationMap) {
|
|
540
456
|
onMutation(globalMutationMap[key]);
|
|
@@ -546,67 +462,31 @@ export const makeChatsSocket = (config) => {
|
|
|
546
462
|
* type = "image for the high res picture"
|
|
547
463
|
*/
|
|
548
464
|
const profilePictureUrl = async (jid, type = 'preview', timeoutMs) => {
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
// and never for own profile pic (Chat model for self has no tcToken).
|
|
552
|
-
// Including tctoken for own JID causes the server to never respond.
|
|
553
|
-
const normalizedJid = jidNormalizedUser(jid);
|
|
554
|
-
const isUserJid = isPnUser(normalizedJid) || isLidUser(normalizedJid);
|
|
555
|
-
const me = authState.creds.me;
|
|
556
|
-
const isSelf = me && (normalizedJid === jidNormalizedUser(me.id) || (me.lid && normalizedJid === jidNormalizedUser(me.lid)));
|
|
557
|
-
let content = baseContent;
|
|
558
|
-
if (serverProps.profilePicPrivacyToken && isUserJid && !isSelf) {
|
|
559
|
-
content = await buildTcTokenFromJid({
|
|
560
|
-
authState,
|
|
561
|
-
jid: normalizedJid,
|
|
562
|
-
baseContent,
|
|
563
|
-
getLIDForPN
|
|
564
|
-
});
|
|
565
|
-
}
|
|
566
|
-
jid = jidNormalizedUser(jid);
|
|
465
|
+
var _a;
|
|
466
|
+
jid = (0, WABinary_1.jidNormalizedUser)(jid);
|
|
567
467
|
const result = await query({
|
|
568
468
|
tag: 'iq',
|
|
569
469
|
attrs: {
|
|
570
470
|
target: jid,
|
|
571
|
-
to: S_WHATSAPP_NET,
|
|
471
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
572
472
|
type: 'get',
|
|
573
473
|
xmlns: 'w:profile:picture'
|
|
574
474
|
},
|
|
575
|
-
content
|
|
576
|
-
}, timeoutMs);
|
|
577
|
-
const child = getBinaryNodeChild(result, 'picture');
|
|
578
|
-
return child?.attrs?.url;
|
|
579
|
-
};
|
|
580
|
-
const createCallLink = async (type, event, timeoutMs) => {
|
|
581
|
-
const result = await query({
|
|
582
|
-
tag: 'call',
|
|
583
|
-
attrs: {
|
|
584
|
-
id: generateMessageTag(),
|
|
585
|
-
to: '@call'
|
|
586
|
-
},
|
|
587
475
|
content: [
|
|
588
|
-
{
|
|
589
|
-
tag: 'link_create',
|
|
590
|
-
attrs: { media: type },
|
|
591
|
-
content: event ? [{ tag: 'event', attrs: { start_time: String(event.startTime) } }] : undefined
|
|
592
|
-
}
|
|
476
|
+
{ tag: 'picture', attrs: { type, query: 'url' } }
|
|
593
477
|
]
|
|
594
478
|
}, timeoutMs);
|
|
595
|
-
const child = getBinaryNodeChild(result, '
|
|
596
|
-
return child
|
|
479
|
+
const child = (0, WABinary_1.getBinaryNodeChild)(result, 'picture');
|
|
480
|
+
return (_a = child === null || child === void 0 ? void 0 : child.attrs) === null || _a === void 0 ? void 0 : _a.url;
|
|
597
481
|
};
|
|
598
482
|
const sendPresenceUpdate = async (type, toJid) => {
|
|
599
483
|
const me = authState.creds.me;
|
|
600
|
-
|
|
601
|
-
if (isAvailableType || type === 'unavailable') {
|
|
484
|
+
if (type === 'available' || type === 'unavailable') {
|
|
602
485
|
if (!me.name) {
|
|
603
486
|
logger.warn('no name present, ignoring presence update request...');
|
|
604
487
|
return;
|
|
605
488
|
}
|
|
606
|
-
ev.emit('connection.update', { isOnline:
|
|
607
|
-
if (isAvailableType) {
|
|
608
|
-
void sendUnifiedSession();
|
|
609
|
-
}
|
|
489
|
+
ev.emit('connection.update', { isOnline: type === 'available' });
|
|
610
490
|
await sendNode({
|
|
611
491
|
tag: 'presence',
|
|
612
492
|
attrs: {
|
|
@@ -616,13 +496,13 @@ export const makeChatsSocket = (config) => {
|
|
|
616
496
|
});
|
|
617
497
|
}
|
|
618
498
|
else {
|
|
619
|
-
const { server } = jidDecode(toJid);
|
|
499
|
+
const { server } = (0, WABinary_1.jidDecode)(toJid);
|
|
620
500
|
const isLid = server === 'lid';
|
|
621
501
|
await sendNode({
|
|
622
502
|
tag: 'chatstate',
|
|
623
503
|
attrs: {
|
|
624
504
|
from: isLid ? me.lid : me.id,
|
|
625
|
-
to: toJid
|
|
505
|
+
to: toJid,
|
|
626
506
|
},
|
|
627
507
|
content: [
|
|
628
508
|
{
|
|
@@ -637,35 +517,35 @@ export const makeChatsSocket = (config) => {
|
|
|
637
517
|
* @param toJid the jid to subscribe to
|
|
638
518
|
* @param tcToken token for subscription, use if present
|
|
639
519
|
*/
|
|
640
|
-
const presenceSubscribe =
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
};
|
|
520
|
+
const presenceSubscribe = (toJid, tcToken) => (sendNode({
|
|
521
|
+
tag: 'presence',
|
|
522
|
+
attrs: {
|
|
523
|
+
to: toJid,
|
|
524
|
+
id: generateMessageTag(),
|
|
525
|
+
type: 'subscribe'
|
|
526
|
+
},
|
|
527
|
+
content: tcToken
|
|
528
|
+
? [
|
|
529
|
+
{
|
|
530
|
+
tag: 'tctoken',
|
|
531
|
+
attrs: {},
|
|
532
|
+
content: tcToken
|
|
533
|
+
}
|
|
534
|
+
]
|
|
535
|
+
: undefined
|
|
536
|
+
}));
|
|
657
537
|
const handlePresenceUpdate = ({ tag, attrs, content }) => {
|
|
538
|
+
var _a;
|
|
658
539
|
let presence;
|
|
659
540
|
const jid = attrs.from;
|
|
660
541
|
const participant = attrs.participant || attrs.from;
|
|
661
|
-
if (shouldIgnoreJid(jid) && jid
|
|
542
|
+
if (shouldIgnoreJid(jid) && jid != '@s.whatsapp.net') {
|
|
662
543
|
return;
|
|
663
544
|
}
|
|
664
545
|
if (tag === 'presence') {
|
|
665
546
|
presence = {
|
|
666
547
|
lastKnownPresence: attrs.type === 'unavailable' ? 'unavailable' : 'available',
|
|
667
|
-
lastSeen: attrs.last && attrs.last !== 'deny' ? +attrs.last : undefined
|
|
668
|
-
groupOnlineCount: attrs.count ? +attrs.count : undefined
|
|
548
|
+
lastSeen: attrs.last && attrs.last !== 'deny' ? +attrs.last : undefined
|
|
669
549
|
};
|
|
670
550
|
}
|
|
671
551
|
else if (Array.isArray(content)) {
|
|
@@ -674,7 +554,7 @@ export const makeChatsSocket = (config) => {
|
|
|
674
554
|
if (type === 'paused') {
|
|
675
555
|
type = 'available';
|
|
676
556
|
}
|
|
677
|
-
if (firstChild.attrs
|
|
557
|
+
if (((_a = firstChild.attrs) === null || _a === void 0 ? void 0 : _a.media) === 'audio') {
|
|
678
558
|
type = 'recording';
|
|
679
559
|
}
|
|
680
560
|
presence = { lastKnownPresence: type };
|
|
@@ -690,22 +570,22 @@ export const makeChatsSocket = (config) => {
|
|
|
690
570
|
const name = patchCreate.type;
|
|
691
571
|
const myAppStateKeyId = authState.creds.myAppStateKeyId;
|
|
692
572
|
if (!myAppStateKeyId) {
|
|
693
|
-
throw new Boom('App state key not present!', { statusCode: 400 });
|
|
573
|
+
throw new boom_1.Boom('App state key not present!', { statusCode: 400 });
|
|
694
574
|
}
|
|
695
575
|
let initial;
|
|
696
576
|
let encodeResult;
|
|
697
|
-
await
|
|
577
|
+
await processingMutex.mutex(async () => {
|
|
698
578
|
await authState.keys.transaction(async () => {
|
|
699
579
|
logger.debug({ patch: patchCreate }, 'applying app patch');
|
|
700
580
|
await resyncAppState([name], false);
|
|
701
581
|
const { [name]: currentSyncVersion } = await authState.keys.get('app-state-sync-version', [name]);
|
|
702
|
-
initial = currentSyncVersion
|
|
703
|
-
encodeResult = await encodeSyncdPatch(patchCreate, myAppStateKeyId, initial, getAppStateSyncKey);
|
|
582
|
+
initial = currentSyncVersion || (0, Utils_1.newLTHashState)();
|
|
583
|
+
encodeResult = await (0, Utils_1.encodeSyncdPatch)(patchCreate, myAppStateKeyId, initial, getAppStateSyncKey);
|
|
704
584
|
const { patch, state } = encodeResult;
|
|
705
585
|
const node = {
|
|
706
586
|
tag: 'iq',
|
|
707
587
|
attrs: {
|
|
708
|
-
to: S_WHATSAPP_NET,
|
|
588
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
709
589
|
type: 'set',
|
|
710
590
|
xmlns: 'w:sync:app:state'
|
|
711
591
|
},
|
|
@@ -719,13 +599,13 @@ export const makeChatsSocket = (config) => {
|
|
|
719
599
|
attrs: {
|
|
720
600
|
name,
|
|
721
601
|
version: (state.version - 1).toString(),
|
|
722
|
-
return_snapshot: 'false'
|
|
602
|
+
'return_snapshot': 'false'
|
|
723
603
|
},
|
|
724
604
|
content: [
|
|
725
605
|
{
|
|
726
606
|
tag: 'patch',
|
|
727
607
|
attrs: {},
|
|
728
|
-
content: proto.SyncdPatch.encode(patch).finish()
|
|
608
|
+
content: WAProto_1.proto.SyncdPatch.encode(patch).finish()
|
|
729
609
|
}
|
|
730
610
|
]
|
|
731
611
|
}
|
|
@@ -735,78 +615,54 @@ export const makeChatsSocket = (config) => {
|
|
|
735
615
|
};
|
|
736
616
|
await query(node);
|
|
737
617
|
await authState.keys.set({ 'app-state-sync-version': { [name]: state } });
|
|
738
|
-
}
|
|
618
|
+
});
|
|
739
619
|
});
|
|
740
620
|
if (config.emitOwnEvents) {
|
|
741
621
|
const { onMutation } = newAppStateChunkHandler(false);
|
|
742
|
-
const { mutationMap } = await decodePatches(name, [{ ...encodeResult.patch, version: { version: encodeResult.state.version } }], initial, getAppStateSyncKey, config.options, undefined, logger);
|
|
622
|
+
const { mutationMap } = await (0, Utils_1.decodePatches)(name, [{ ...encodeResult.patch, version: { version: encodeResult.state.version }, }], initial, getAppStateSyncKey, config.options, undefined, logger);
|
|
743
623
|
for (const key in mutationMap) {
|
|
744
624
|
onMutation(mutationMap[key]);
|
|
745
625
|
}
|
|
746
626
|
}
|
|
747
627
|
};
|
|
748
|
-
/**
|
|
628
|
+
/** sending non-abt props may fix QR scan fail if server expects */
|
|
749
629
|
const fetchProps = async () => {
|
|
630
|
+
var _a, _b, _c;
|
|
750
631
|
const resultNode = await query({
|
|
751
632
|
tag: 'iq',
|
|
752
633
|
attrs: {
|
|
753
|
-
to: S_WHATSAPP_NET,
|
|
754
|
-
xmlns: '
|
|
755
|
-
type: 'get'
|
|
634
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
635
|
+
xmlns: 'w',
|
|
636
|
+
type: 'get',
|
|
756
637
|
},
|
|
757
638
|
content: [
|
|
758
|
-
{
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
...(authState?.creds?.lastPropHash ? { hash: authState.creds.lastPropHash } : {})
|
|
763
|
-
}
|
|
764
|
-
}
|
|
639
|
+
{ tag: 'props', attrs: {
|
|
640
|
+
protocol: '2',
|
|
641
|
+
hash: ((_a = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _a === void 0 ? void 0 : _a.lastPropHash) || ''
|
|
642
|
+
} }
|
|
765
643
|
]
|
|
766
644
|
});
|
|
767
|
-
const propsNode = getBinaryNodeChild(resultNode, 'props');
|
|
645
|
+
const propsNode = (0, WABinary_1.getBinaryNodeChild)(resultNode, 'props');
|
|
768
646
|
let props = {};
|
|
769
647
|
if (propsNode) {
|
|
770
|
-
if (propsNode.attrs
|
|
771
|
-
|
|
772
|
-
authState.creds.lastPropHash = propsNode?.attrs?.hash;
|
|
648
|
+
if ((_b = propsNode.attrs) === null || _b === void 0 ? void 0 : _b.hash) { // on some clients, the hash is returning as undefined
|
|
649
|
+
authState.creds.lastPropHash = (_c = propsNode === null || propsNode === void 0 ? void 0 : propsNode.attrs) === null || _c === void 0 ? void 0 : _c.hash;
|
|
773
650
|
ev.emit('creds.update', authState.creds);
|
|
774
651
|
}
|
|
775
|
-
props = reduceBinaryNodeToDictionary(propsNode, 'prop');
|
|
652
|
+
props = (0, WABinary_1.reduceBinaryNodeToDictionary)(propsNode, 'prop');
|
|
776
653
|
}
|
|
777
|
-
|
|
778
|
-
const privacyTokenProp = props['10518'] ?? props['privacy_token_sending_on_all_1_on_1_messages'];
|
|
779
|
-
if (privacyTokenProp !== undefined) {
|
|
780
|
-
serverProps.privacyTokenOn1to1 = privacyTokenProp === 'true' || privacyTokenProp === '1';
|
|
781
|
-
}
|
|
782
|
-
const profilePicProp = props['9666'] ?? props['profile_scraping_privacy_token_in_photo_iq'];
|
|
783
|
-
if (profilePicProp !== undefined) {
|
|
784
|
-
serverProps.profilePicPrivacyToken = profilePicProp === 'true' || profilePicProp === '1';
|
|
785
|
-
}
|
|
786
|
-
const lidIssueProp = props['14303'] ?? props['lid_trusted_token_issue_to_lid'];
|
|
787
|
-
if (lidIssueProp !== undefined) {
|
|
788
|
-
serverProps.lidTrustedTokenIssueToLid = lidIssueProp === 'true' || lidIssueProp === '1';
|
|
789
|
-
}
|
|
790
|
-
logger.debug({ serverProps }, 'fetched props');
|
|
654
|
+
logger.debug('fetched props');
|
|
791
655
|
return props;
|
|
792
656
|
};
|
|
793
657
|
/**
|
|
794
658
|
* modify a chat -- mark unread, read etc.
|
|
795
659
|
* lastMessages must be sorted in reverse chronologically
|
|
796
660
|
* requires the last messages till the last message received; required for archive & unread
|
|
797
|
-
|
|
661
|
+
*/
|
|
798
662
|
const chatModify = (mod, jid) => {
|
|
799
|
-
const patch = chatModificationToAppPatch(mod, jid);
|
|
663
|
+
const patch = (0, Utils_1.chatModificationToAppPatch)(mod, jid);
|
|
800
664
|
return appPatch(patch);
|
|
801
665
|
};
|
|
802
|
-
/**
|
|
803
|
-
* Enable/Disable link preview privacy, not related to baileys link preview generation
|
|
804
|
-
*/
|
|
805
|
-
const updateDisableLinkPreviewsPrivacy = (isPreviewsDisabled) => {
|
|
806
|
-
return chatModify({
|
|
807
|
-
disableLinkPreviews: { isPreviewsDisabled }
|
|
808
|
-
}, '');
|
|
809
|
-
};
|
|
810
666
|
/**
|
|
811
667
|
* Star or Unstar a message
|
|
812
668
|
*/
|
|
@@ -818,32 +674,6 @@ export const makeChatsSocket = (config) => {
|
|
|
818
674
|
}
|
|
819
675
|
}, jid);
|
|
820
676
|
};
|
|
821
|
-
/**
|
|
822
|
-
* Add or Edit Contact
|
|
823
|
-
*/
|
|
824
|
-
const addOrEditContact = (jid, contact) => {
|
|
825
|
-
return chatModify({
|
|
826
|
-
contact
|
|
827
|
-
}, jid);
|
|
828
|
-
};
|
|
829
|
-
/**
|
|
830
|
-
* Remove Contact
|
|
831
|
-
*/
|
|
832
|
-
const removeContact = (jid) => {
|
|
833
|
-
return chatModify({
|
|
834
|
-
contact: null
|
|
835
|
-
}, jid);
|
|
836
|
-
};
|
|
837
|
-
/**
|
|
838
|
-
* Adds label
|
|
839
|
-
*/
|
|
840
|
-
const addLabel = (jid, labels) => {
|
|
841
|
-
return chatModify({
|
|
842
|
-
addLabel: {
|
|
843
|
-
...labels
|
|
844
|
-
}
|
|
845
|
-
}, jid);
|
|
846
|
-
};
|
|
847
677
|
/**
|
|
848
678
|
* Adds label for the chats
|
|
849
679
|
*/
|
|
@@ -886,127 +716,49 @@ export const makeChatsSocket = (config) => {
|
|
|
886
716
|
}
|
|
887
717
|
}, jid);
|
|
888
718
|
};
|
|
889
|
-
/**
|
|
890
|
-
* Add or Edit Quick Reply
|
|
891
|
-
*/
|
|
892
|
-
const addOrEditQuickReply = (quickReply) => {
|
|
893
|
-
return chatModify({
|
|
894
|
-
quickReply
|
|
895
|
-
}, '');
|
|
896
|
-
};
|
|
897
|
-
/**
|
|
898
|
-
* Remove Quick Reply
|
|
899
|
-
*/
|
|
900
|
-
const removeQuickReply = (timestamp) => {
|
|
901
|
-
return chatModify({
|
|
902
|
-
quickReply: { timestamp, deleted: true }
|
|
903
|
-
}, '');
|
|
904
|
-
};
|
|
905
719
|
/**
|
|
906
720
|
* queries need to be fired on connection open
|
|
907
721
|
* help ensure parity with WA Web
|
|
908
722
|
* */
|
|
909
723
|
const executeInitQueries = async () => {
|
|
910
|
-
await Promise.all([
|
|
724
|
+
await Promise.all([
|
|
725
|
+
fetchProps(),
|
|
726
|
+
fetchBlocklist(),
|
|
727
|
+
fetchPrivacySettings(),
|
|
728
|
+
]);
|
|
911
729
|
};
|
|
912
730
|
const upsertMessage = ev.createBufferedFunction(async (msg, type) => {
|
|
731
|
+
var _a, _b, _c;
|
|
913
732
|
ev.emit('messages.upsert', { messages: [msg], type });
|
|
914
733
|
if (!!msg.pushName) {
|
|
915
|
-
let jid = msg.key.fromMe ? authState.creds.me.id : msg.key.participant || msg.key.remoteJid;
|
|
916
|
-
jid = jidNormalizedUser(jid);
|
|
734
|
+
let jid = msg.key.fromMe ? authState.creds.me.id : (msg.key.participant || msg.key.remoteJid);
|
|
735
|
+
jid = (0, WABinary_1.jidNormalizedUser)(jid);
|
|
917
736
|
if (!msg.key.fromMe) {
|
|
918
737
|
ev.emit('contacts.update', [{ id: jid, notify: msg.pushName, verifiedName: msg.verifiedBizName }]);
|
|
919
738
|
}
|
|
920
739
|
// update our pushname too
|
|
921
|
-
if (msg.key.fromMe && msg.pushName && authState.creds.me
|
|
740
|
+
if (msg.key.fromMe && msg.pushName && ((_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.name) !== msg.pushName) {
|
|
922
741
|
ev.emit('creds.update', { me: { ...authState.creds.me, name: msg.pushName } });
|
|
923
742
|
}
|
|
924
743
|
}
|
|
925
|
-
const historyMsg = getHistoryMsg(msg.message);
|
|
744
|
+
const historyMsg = (0, Utils_1.getHistoryMsg)(msg.message);
|
|
926
745
|
const shouldProcessHistoryMsg = historyMsg
|
|
927
|
-
? shouldSyncHistoryMessage(historyMsg)
|
|
928
|
-
PROCESSABLE_HISTORY_TYPES.includes(historyMsg.syncType)
|
|
746
|
+
? (shouldSyncHistoryMessage(historyMsg)
|
|
747
|
+
&& Defaults_1.PROCESSABLE_HISTORY_TYPES.includes(historyMsg.syncType))
|
|
929
748
|
: false;
|
|
930
|
-
if (historyMsg &&
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
if (syncType === proto.HistorySync.HistorySyncType.INITIAL_BOOTSTRAP &&
|
|
934
|
-
!historySyncStatus.initialBootstrapComplete) {
|
|
935
|
-
historySyncStatus.initialBootstrapComplete = true;
|
|
936
|
-
ev.emit('messaging-history.status', {
|
|
937
|
-
syncType,
|
|
938
|
-
status: 'complete',
|
|
939
|
-
explicit: true
|
|
940
|
-
});
|
|
941
|
-
}
|
|
942
|
-
// RECENT with progress === 100 — explicit completion
|
|
943
|
-
if (syncType === proto.HistorySync.HistorySyncType.RECENT &&
|
|
944
|
-
historyMsg.progress === 100 &&
|
|
945
|
-
!historySyncStatus.recentSyncComplete) {
|
|
946
|
-
historySyncStatus.recentSyncComplete = true;
|
|
947
|
-
clearTimeout(historySyncPausedTimeout);
|
|
948
|
-
historySyncPausedTimeout = undefined;
|
|
949
|
-
ev.emit('messaging-history.status', {
|
|
950
|
-
syncType,
|
|
951
|
-
status: 'complete',
|
|
952
|
-
explicit: true
|
|
953
|
-
});
|
|
954
|
-
}
|
|
955
|
-
// Reset 120s paused timeout on any RECENT chunk (like WA Web's handleChunkProgress)
|
|
956
|
-
if (syncType === proto.HistorySync.HistorySyncType.RECENT && !historySyncStatus.recentSyncComplete) {
|
|
957
|
-
clearTimeout(historySyncPausedTimeout);
|
|
958
|
-
historySyncPausedTimeout = setTimeout(() => {
|
|
959
|
-
if (!historySyncStatus.recentSyncComplete) {
|
|
960
|
-
historySyncStatus.recentSyncComplete = true;
|
|
961
|
-
ev.emit('messaging-history.status', {
|
|
962
|
-
syncType: proto.HistorySync.HistorySyncType.RECENT,
|
|
963
|
-
status: 'paused',
|
|
964
|
-
explicit: false
|
|
965
|
-
});
|
|
966
|
-
}
|
|
967
|
-
historySyncPausedTimeout = undefined;
|
|
968
|
-
}, HISTORY_SYNC_PAUSED_TIMEOUT_MS);
|
|
969
|
-
}
|
|
749
|
+
if (historyMsg && !authState.creds.myAppStateKeyId) {
|
|
750
|
+
logger.warn('skipping app state sync, as myAppStateKeyId is not set');
|
|
751
|
+
pendingAppStateSync = true;
|
|
970
752
|
}
|
|
971
|
-
// State machine: decide on sync and flush
|
|
972
|
-
if (historyMsg && syncState === SyncState.AwaitingInitialSync) {
|
|
973
|
-
if (awaitingSyncTimeout) {
|
|
974
|
-
clearTimeout(awaitingSyncTimeout);
|
|
975
|
-
awaitingSyncTimeout = undefined;
|
|
976
|
-
}
|
|
977
|
-
if (shouldProcessHistoryMsg) {
|
|
978
|
-
syncState = SyncState.Syncing;
|
|
979
|
-
logger.info('Transitioned to Syncing state');
|
|
980
|
-
// Let doAppStateSync handle the final flush after it's done
|
|
981
|
-
}
|
|
982
|
-
else {
|
|
983
|
-
syncState = SyncState.Online;
|
|
984
|
-
logger.info('History sync skipped, transitioning to Online state and flushing buffer');
|
|
985
|
-
ev.flush();
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
const doAppStateSync = async () => {
|
|
989
|
-
if (syncState === SyncState.Syncing) {
|
|
990
|
-
// All collections will be synced, so clear any blocked ones
|
|
991
|
-
blockedCollections.clear();
|
|
992
|
-
logger.info('Doing app state sync');
|
|
993
|
-
await resyncAppState(ALL_WA_PATCH_NAMES, true);
|
|
994
|
-
// Sync is complete, go online and flush everything
|
|
995
|
-
syncState = SyncState.Online;
|
|
996
|
-
logger.info('App state sync complete, transitioning to Online state and flushing buffer');
|
|
997
|
-
ev.flush();
|
|
998
|
-
const accountSyncCounter = (authState.creds.accountSyncCounter || 0) + 1;
|
|
999
|
-
ev.emit('creds.update', { accountSyncCounter });
|
|
1000
|
-
}
|
|
1001
|
-
};
|
|
1002
753
|
await Promise.all([
|
|
1003
754
|
(async () => {
|
|
1004
|
-
if (
|
|
755
|
+
if (historyMsg
|
|
756
|
+
&& authState.creds.myAppStateKeyId) {
|
|
757
|
+
pendingAppStateSync = false;
|
|
1005
758
|
await doAppStateSync();
|
|
1006
759
|
}
|
|
1007
760
|
})(),
|
|
1008
|
-
|
|
1009
|
-
signalRepository,
|
|
761
|
+
(0, process_message_1.default)(msg, {
|
|
1010
762
|
shouldProcessHistoryMsg,
|
|
1011
763
|
placeholderResendCache,
|
|
1012
764
|
ev,
|
|
@@ -1014,19 +766,31 @@ export const makeChatsSocket = (config) => {
|
|
|
1014
766
|
keyStore: authState.keys,
|
|
1015
767
|
logger,
|
|
1016
768
|
options: config.options,
|
|
1017
|
-
getMessage
|
|
769
|
+
getMessage: config.getMessage,
|
|
1018
770
|
})
|
|
1019
771
|
]);
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
logger.info('App state sync key arrived, triggering app state sync');
|
|
772
|
+
if (((_c = (_b = msg.message) === null || _b === void 0 ? void 0 : _b.protocolMessage) === null || _c === void 0 ? void 0 : _c.appStateSyncKeyShare)
|
|
773
|
+
&& pendingAppStateSync) {
|
|
1023
774
|
await doAppStateSync();
|
|
775
|
+
pendingAppStateSync = false;
|
|
776
|
+
}
|
|
777
|
+
async function doAppStateSync() {
|
|
778
|
+
if (!authState.creds.accountSyncCounter) {
|
|
779
|
+
logger.info('doing initial app state sync');
|
|
780
|
+
await resyncAppState(Types_1.ALL_WA_PATCH_NAMES, true);
|
|
781
|
+
const accountSyncCounter = (authState.creds.accountSyncCounter || 0) + 1;
|
|
782
|
+
ev.emit('creds.update', { accountSyncCounter });
|
|
783
|
+
if (needToFlushWithAppStateSync) {
|
|
784
|
+
logger.debug('flushing with app state sync');
|
|
785
|
+
ev.flush();
|
|
786
|
+
}
|
|
787
|
+
}
|
|
1024
788
|
}
|
|
1025
789
|
});
|
|
1026
790
|
ws.on('CB:presence', handlePresenceUpdate);
|
|
1027
791
|
ws.on('CB:chatstate', handlePresenceUpdate);
|
|
1028
792
|
ws.on('CB:ib,,dirty', async (node) => {
|
|
1029
|
-
const { attrs } = getBinaryNodeChild(node, 'dirty');
|
|
793
|
+
const { attrs } = (0, WABinary_1.getBinaryNodeChild)(node, 'dirty');
|
|
1030
794
|
const type = attrs.type;
|
|
1031
795
|
switch (type) {
|
|
1032
796
|
case 'account_sync':
|
|
@@ -1048,122 +812,42 @@ export const makeChatsSocket = (config) => {
|
|
|
1048
812
|
}
|
|
1049
813
|
});
|
|
1050
814
|
ev.on('connection.update', ({ connection, receivedPendingNotifications }) => {
|
|
1051
|
-
|
|
1052
|
-
blockedCollections.clear();
|
|
1053
|
-
clearTimeout(historySyncPausedTimeout);
|
|
1054
|
-
historySyncPausedTimeout = undefined;
|
|
1055
|
-
}
|
|
815
|
+
var _a;
|
|
1056
816
|
if (connection === 'open') {
|
|
1057
817
|
if (fireInitQueries) {
|
|
1058
|
-
executeInitQueries()
|
|
818
|
+
executeInitQueries()
|
|
819
|
+
.catch(error => onUnexpectedError(error, 'init queries'));
|
|
1059
820
|
}
|
|
1060
|
-
sendPresenceUpdate(markOnlineOnConnect ? 'available' : 'unavailable')
|
|
821
|
+
sendPresenceUpdate(markOnlineOnConnect ? 'available' : 'unavailable')
|
|
822
|
+
.catch(error => onUnexpectedError(error, 'presence update requests'));
|
|
1061
823
|
}
|
|
1062
|
-
if (
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
historySyncPausedTimeout = undefined;
|
|
1069
|
-
syncState = SyncState.AwaitingInitialSync;
|
|
1070
|
-
logger.info('Connection is now AwaitingInitialSync, buffering events');
|
|
1071
|
-
ev.buffer();
|
|
1072
|
-
const willSyncHistory = shouldSyncHistoryMessage(proto.Message.HistorySyncNotification.create({
|
|
1073
|
-
syncType: proto.HistorySync.HistorySyncType.RECENT
|
|
1074
|
-
}));
|
|
1075
|
-
if (!willSyncHistory) {
|
|
1076
|
-
logger.info('History sync is disabled by config, not waiting for notification. Transitioning to Online.');
|
|
1077
|
-
syncState = SyncState.Online;
|
|
1078
|
-
setTimeout(() => ev.flush(), 0);
|
|
1079
|
-
return;
|
|
1080
|
-
}
|
|
1081
|
-
// On reconnection (accountSyncCounter > 0), the server does not push
|
|
1082
|
-
// history sync notifications — the device already has its data.
|
|
1083
|
-
// Skip the 20s wait and go online immediately.
|
|
1084
|
-
if (authState.creds.accountSyncCounter > 0) {
|
|
1085
|
-
logger.info('Reconnection with existing sync data, skipping history sync wait. Transitioning to Online.');
|
|
1086
|
-
syncState = SyncState.Online;
|
|
1087
|
-
setTimeout(() => ev.flush(), 0);
|
|
1088
|
-
return;
|
|
1089
|
-
}
|
|
1090
|
-
logger.info('First connection, awaiting history sync notification with a 20s timeout.');
|
|
1091
|
-
if (awaitingSyncTimeout) {
|
|
1092
|
-
clearTimeout(awaitingSyncTimeout);
|
|
1093
|
-
}
|
|
1094
|
-
awaitingSyncTimeout = setTimeout(() => {
|
|
1095
|
-
if (syncState === SyncState.AwaitingInitialSync) {
|
|
1096
|
-
logger.warn('Timeout in AwaitingInitialSync, forcing state to Online and flushing buffer');
|
|
1097
|
-
syncState = SyncState.Online;
|
|
1098
|
-
ev.flush();
|
|
1099
|
-
// Increment so subsequent reconnections skip the 20s wait.
|
|
1100
|
-
// Late-arriving history is still processed via processMessage
|
|
1101
|
-
// regardless of the state machine phase.
|
|
1102
|
-
const accountSyncCounter = (authState.creds.accountSyncCounter || 0) + 1;
|
|
1103
|
-
ev.emit('creds.update', { accountSyncCounter });
|
|
1104
|
-
}
|
|
1105
|
-
}, 20000);
|
|
1106
|
-
});
|
|
1107
|
-
// When an app state sync key arrives (myAppStateKeyId is set) and there are
|
|
1108
|
-
// collections blocked on a missing key, trigger a re-sync for just those collections.
|
|
1109
|
-
// This mirrors WA Web's Blocked → retry-on-key-arrival behavior.
|
|
1110
|
-
ev.on('creds.update', ({ myAppStateKeyId }) => {
|
|
1111
|
-
if (!myAppStateKeyId || blockedCollections.size === 0) {
|
|
1112
|
-
return;
|
|
1113
|
-
}
|
|
1114
|
-
// If we're in the middle of a full sync, doAppStateSync handles all collections
|
|
1115
|
-
if (syncState === SyncState.Syncing) {
|
|
1116
|
-
blockedCollections.clear();
|
|
1117
|
-
return;
|
|
1118
|
-
}
|
|
1119
|
-
const collections = [...blockedCollections];
|
|
1120
|
-
blockedCollections.clear();
|
|
1121
|
-
logger.info({ collections }, 'app state sync key arrived, re-syncing blocked collections');
|
|
1122
|
-
resyncAppState(collections, false).catch(error => onUnexpectedError(error, 'blocked collections resync'));
|
|
1123
|
-
});
|
|
1124
|
-
ev.on('lid-mapping.update', async ({ lid, pn }) => {
|
|
1125
|
-
try {
|
|
1126
|
-
await signalRepository.lidMapping.storeLIDPNMappings([{ lid, pn }]);
|
|
1127
|
-
}
|
|
1128
|
-
catch (error) {
|
|
1129
|
-
logger.warn({ lid, pn, error }, 'Failed to store LID-PN mapping');
|
|
824
|
+
if (receivedPendingNotifications && // if we don't have the app state key
|
|
825
|
+
// we keep buffering events until we finally have
|
|
826
|
+
// the key and can sync the messages
|
|
827
|
+
!((_a = authState.creds) === null || _a === void 0 ? void 0 : _a.myAppStateKeyId)) {
|
|
828
|
+
ev.buffer();
|
|
829
|
+
needToFlushWithAppStateSync = true;
|
|
1130
830
|
}
|
|
1131
831
|
});
|
|
1132
|
-
registerSocketEndHandler(() => {
|
|
1133
|
-
if (awaitingSyncTimeout) {
|
|
1134
|
-
clearTimeout(awaitingSyncTimeout);
|
|
1135
|
-
awaitingSyncTimeout = undefined;
|
|
1136
|
-
}
|
|
1137
|
-
if (!config.placeholderResendCache && placeholderResendCache.close) {
|
|
1138
|
-
placeholderResendCache.close();
|
|
1139
|
-
}
|
|
1140
|
-
syncState = SyncState.Connecting;
|
|
1141
|
-
privacySettings = undefined;
|
|
1142
|
-
});
|
|
1143
832
|
return {
|
|
1144
833
|
...sock,
|
|
1145
|
-
serverProps,
|
|
1146
|
-
createCallLink,
|
|
1147
834
|
getBotListV2,
|
|
1148
|
-
|
|
1149
|
-
receiptMutex,
|
|
1150
|
-
appStatePatchMutex,
|
|
1151
|
-
notificationMutex,
|
|
835
|
+
processingMutex,
|
|
1152
836
|
fetchPrivacySettings,
|
|
1153
837
|
upsertMessage,
|
|
1154
838
|
appPatch,
|
|
1155
839
|
sendPresenceUpdate,
|
|
1156
840
|
presenceSubscribe,
|
|
1157
841
|
profilePictureUrl,
|
|
842
|
+
onWhatsApp,
|
|
1158
843
|
fetchBlocklist,
|
|
1159
|
-
fetchStatus,
|
|
1160
844
|
fetchDisappearingDuration,
|
|
845
|
+
fetchStatus,
|
|
1161
846
|
updateProfilePicture,
|
|
1162
847
|
removeProfilePicture,
|
|
1163
848
|
updateProfileStatus,
|
|
1164
849
|
updateProfileName,
|
|
1165
850
|
updateBlockStatus,
|
|
1166
|
-
updateDisableLinkPreviewsPrivacy,
|
|
1167
851
|
updateCallPrivacy,
|
|
1168
852
|
updateMessagesPrivacy,
|
|
1169
853
|
updateLastSeenPrivacy,
|
|
@@ -1177,17 +861,11 @@ export const makeChatsSocket = (config) => {
|
|
|
1177
861
|
resyncAppState,
|
|
1178
862
|
chatModify,
|
|
1179
863
|
cleanDirtyBits,
|
|
1180
|
-
addOrEditContact,
|
|
1181
|
-
removeContact,
|
|
1182
|
-
placeholderResendCache,
|
|
1183
|
-
addLabel,
|
|
1184
864
|
addChatLabel,
|
|
1185
865
|
removeChatLabel,
|
|
1186
866
|
addMessageLabel,
|
|
1187
867
|
removeMessageLabel,
|
|
1188
|
-
star
|
|
1189
|
-
addOrEditQuickReply,
|
|
1190
|
-
removeQuickReply
|
|
868
|
+
star
|
|
1191
869
|
};
|
|
1192
870
|
};
|
|
1193
|
-
|
|
871
|
+
exports.makeChatsSocket = makeChatsSocket;
|