@realvare/based 2.7.70 → 2.7.71
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/README.MD +1118 -249
- package/lib/Defaults/baileys-version.json +1 -1
- package/lib/Defaults/index.d.ts +3 -1
- package/lib/Defaults/index.js +3 -1
- package/lib/Signal/Group/ciphertext-message.d.ts +1 -1
- package/lib/Signal/Group/ciphertext-message.js +1 -1
- package/lib/Signal/Group/sender-message-key.d.ts +1 -1
- package/lib/Signal/Group/sender-message-key.js +1 -1
- package/lib/Signal/libsignal.d.ts +1 -1
- package/lib/Socket/business.d.ts +1 -1
- package/lib/Socket/business.js +1 -1
- package/lib/Socket/chats.d.ts +4 -1
- package/lib/Socket/chats.js +160 -20
- package/lib/Socket/groups.js +55 -27
- package/lib/Socket/index.js +9 -0
- package/lib/Socket/messages-interactive.js +259 -0
- package/lib/Socket/messages-recv.js +272 -97
- package/lib/Socket/messages-send.js +104 -30
- package/lib/Socket/socket.js +142 -25
- package/lib/Types/Auth.d.ts +4 -0
- package/lib/Types/Socket.d.ts +2 -0
- package/lib/Utils/cache-manager.js +2 -1
- package/lib/Utils/generics.js +1 -1
- package/lib/Utils/jid-validation.js +7 -5
- package/lib/Utils/messages-media.d.ts +1 -1
- package/lib/Utils/messages-media.js +2 -2
- package/lib/Utils/messages.js +116 -45
- package/lib/WABinary/generic-utils.js +5 -1
- package/lib/WABinary/jid-utils.d.ts +1 -0
- package/lib/WABinary/jid-utils.js +9 -1
- package/lib/index.js +2 -4
- package/package.json +4 -3
|
@@ -24,6 +24,7 @@ const makeMessagesSocket = (config) => {
|
|
|
24
24
|
stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.USER_DEVICES, // 5 minutes
|
|
25
25
|
useClones: false
|
|
26
26
|
});
|
|
27
|
+
const inFlightDeviceFetch = new Map();
|
|
27
28
|
let mediaConn;
|
|
28
29
|
const refreshMediaConn = async (forceGet = false) => {
|
|
29
30
|
const media = await mediaConn;
|
|
@@ -120,6 +121,8 @@ const makeMessagesSocket = (config) => {
|
|
|
120
121
|
logger.debug('not using cache for devices');
|
|
121
122
|
}
|
|
122
123
|
const toFetch = [];
|
|
124
|
+
const usersToFetch = new Set();
|
|
125
|
+
const inFlightPromises = [];
|
|
123
126
|
jids = Array.from(new Set(jids));
|
|
124
127
|
for (let jid of jids) {
|
|
125
128
|
const user = (_a = (0, WABinary_1.jidDecode)(jid)) === null || _a === void 0 ? void 0 : _a.user;
|
|
@@ -131,33 +134,69 @@ const makeMessagesSocket = (config) => {
|
|
|
131
134
|
logger.trace({ user }, 'using cache for devices');
|
|
132
135
|
}
|
|
133
136
|
else {
|
|
134
|
-
|
|
137
|
+
const inFlight = user ? inFlightDeviceFetch.get(user) : undefined;
|
|
138
|
+
if (inFlight) {
|
|
139
|
+
inFlightPromises.push(inFlight.then(devs => {
|
|
140
|
+
if (devs && devs.length) {
|
|
141
|
+
deviceResults.push(...devs);
|
|
142
|
+
}
|
|
143
|
+
}));
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
toFetch.push(jid);
|
|
147
|
+
if (user) {
|
|
148
|
+
usersToFetch.add(user);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
135
151
|
}
|
|
136
152
|
}
|
|
137
153
|
else {
|
|
138
154
|
toFetch.push(jid);
|
|
155
|
+
if (user) {
|
|
156
|
+
usersToFetch.add(user);
|
|
157
|
+
}
|
|
139
158
|
}
|
|
140
159
|
}
|
|
160
|
+
if (inFlightPromises.length) {
|
|
161
|
+
await Promise.all(inFlightPromises);
|
|
162
|
+
}
|
|
141
163
|
if (!toFetch.length) {
|
|
142
164
|
return deviceResults;
|
|
143
165
|
}
|
|
144
|
-
const
|
|
145
|
-
.
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
const extracted = (0, Utils_1.extractDeviceJids)(result === null || result === void 0 ? void 0 : result.list, authState.creds.me.id, ignoreZeroDevices);
|
|
166
|
+
const fetchPromise = (async () => {
|
|
167
|
+
const query = new WAUSync_1.USyncQuery()
|
|
168
|
+
.withContext('message')
|
|
169
|
+
.withDeviceProtocol();
|
|
170
|
+
for (const jid of toFetch) {
|
|
171
|
+
query.withUser(new WAUSync_1.USyncUser().withId(jid));
|
|
172
|
+
}
|
|
173
|
+
const result = await sock.executeUSyncQuery(query);
|
|
153
174
|
const deviceMap = {};
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
175
|
+
if (result) {
|
|
176
|
+
const extracted = (0, Utils_1.extractDeviceJids)(result === null || result === void 0 ? void 0 : result.list, authState.creds.me.id, ignoreZeroDevices);
|
|
177
|
+
for (const item of extracted) {
|
|
178
|
+
deviceMap[item.user] = deviceMap[item.user] || [];
|
|
179
|
+
deviceMap[item.user].push(item);
|
|
180
|
+
deviceResults.push(item);
|
|
181
|
+
}
|
|
182
|
+
for (const key in deviceMap) {
|
|
183
|
+
userDevicesCache.set(key, deviceMap[key]);
|
|
184
|
+
}
|
|
158
185
|
}
|
|
159
|
-
|
|
160
|
-
|
|
186
|
+
return deviceMap;
|
|
187
|
+
})();
|
|
188
|
+
for (const user of usersToFetch) {
|
|
189
|
+
inFlightDeviceFetch.set(user, fetchPromise.then(deviceMap => deviceMap[user] || []));
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
await fetchPromise;
|
|
193
|
+
}
|
|
194
|
+
finally {
|
|
195
|
+
for (const user of usersToFetch) {
|
|
196
|
+
const current = inFlightDeviceFetch.get(user);
|
|
197
|
+
if (current) {
|
|
198
|
+
inFlightDeviceFetch.delete(user);
|
|
199
|
+
}
|
|
161
200
|
}
|
|
162
201
|
}
|
|
163
202
|
return deviceResults;
|
|
@@ -165,13 +204,13 @@ const makeMessagesSocket = (config) => {
|
|
|
165
204
|
// Cache to track JIDs that have failed session fetching to prevent infinite loops
|
|
166
205
|
const failedSessionFetchCache = new Map();
|
|
167
206
|
const FAILED_SESSION_CACHE_TTL = 5 * 60 * 1000; // 5 minutes
|
|
168
|
-
|
|
169
207
|
// Cache to track recently sent messages to prevent duplicate sends
|
|
170
208
|
const recentlySentMessagesCache = new node_cache_1.default({
|
|
171
209
|
stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
|
|
172
210
|
useClones: false,
|
|
173
211
|
maxKeys: 1000 // Limit to prevent memory issues
|
|
174
212
|
});
|
|
213
|
+
const inFlightSessionFetch = new Map();
|
|
175
214
|
|
|
176
215
|
// Cleanup function to remove expired entries from the cache
|
|
177
216
|
const cleanupFailedSessionCache = () => {
|
|
@@ -235,6 +274,18 @@ const makeMessagesSocket = (config) => {
|
|
|
235
274
|
}
|
|
236
275
|
}
|
|
237
276
|
if (jidsRequiringFetch.length) {
|
|
277
|
+
const awaitingInflight = [];
|
|
278
|
+
const uniqueJids = Array.from(new Set(jidsRequiringFetch));
|
|
279
|
+
jidsRequiringFetch = [];
|
|
280
|
+
for (const jid of uniqueJids) {
|
|
281
|
+
const inFlight = inFlightSessionFetch.get(jid);
|
|
282
|
+
if (inFlight) {
|
|
283
|
+
awaitingInflight.push(inFlight);
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
jidsRequiringFetch.push(jid);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
238
289
|
logger.debug({ jidsRequiringFetch }, 'fetching sessions');
|
|
239
290
|
const TOTAL_TIMEOUT_MS = 120000; // 120 seconds
|
|
240
291
|
const abortController = new AbortController();
|
|
@@ -244,7 +295,7 @@ const makeMessagesSocket = (config) => {
|
|
|
244
295
|
for (let i = 0; i < jidsRequiringFetch.length; i += BATCH_SIZE) {
|
|
245
296
|
const batch = jidsRequiringFetch.slice(i, i + BATCH_SIZE);
|
|
246
297
|
try {
|
|
247
|
-
const
|
|
298
|
+
const batchPromise = (0, retry_1.retryWithBackoff)(() => query({
|
|
248
299
|
tag: 'iq',
|
|
249
300
|
attrs: {
|
|
250
301
|
xmlns: 'encrypt',
|
|
@@ -280,18 +331,29 @@ const makeMessagesSocket = (config) => {
|
|
|
280
331
|
onRetry: (err, n) => logger === null || logger === void 0 ? void 0 : logger.warn({ err, attempt: n }, 'retrying fetch sessions'),
|
|
281
332
|
signal: abortController.signal
|
|
282
333
|
});
|
|
334
|
+
for (const jid of batch) {
|
|
335
|
+
inFlightSessionFetch.set(jid, batchPromise.then(() => undefined));
|
|
336
|
+
}
|
|
337
|
+
const result = await batchPromise;
|
|
283
338
|
await (0, Utils_1.parseAndInjectE2ESessions)(result, signalRepository);
|
|
284
339
|
didFetchNewSession = true;
|
|
340
|
+
for (const jid of batch) {
|
|
341
|
+
inFlightSessionFetch.delete(jid);
|
|
342
|
+
}
|
|
285
343
|
} catch (err) {
|
|
286
344
|
// Cache failed JIDs to prevent infinite retries
|
|
287
345
|
logger.warn({ err, batch }, 'session fetch failed for batch, caching failed JIDs');
|
|
288
346
|
for (const jid of batch) {
|
|
289
347
|
failedSessionFetchCache.set(jid, Date.now());
|
|
348
|
+
inFlightSessionFetch.delete(jid);
|
|
290
349
|
}
|
|
291
350
|
// Re-throw the error so the caller knows the fetch failed
|
|
292
351
|
throw err;
|
|
293
352
|
}
|
|
294
353
|
}
|
|
354
|
+
if (awaitingInflight.length) {
|
|
355
|
+
await Promise.all(awaitingInflight);
|
|
356
|
+
}
|
|
295
357
|
} finally {
|
|
296
358
|
clearTimeout(timeout);
|
|
297
359
|
}
|
|
@@ -792,15 +854,9 @@ const makeMessagesSocket = (config) => {
|
|
|
792
854
|
const userJid = authState.creds.me.id;
|
|
793
855
|
if (!options.ephemeralExpiration) {
|
|
794
856
|
if ((0, WABinary_1.isJidGroup)(jid)) {
|
|
795
|
-
const
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
request: 'interactive'
|
|
799
|
-
}
|
|
800
|
-
}]);
|
|
801
|
-
const metadata = (0, WABinary_1.getBinaryNodeChild)(groups, 'group');
|
|
802
|
-
const expiration = ((_b = (_a = (0, WABinary_1.getBinaryNodeChild)(metadata, 'ephemeral')) === null || _a === void 0 ? void 0 : _a.attrs) === null || _b === void 0 ? void 0 : _b.expiration) || 0;
|
|
803
|
-
options.ephemeralExpiration = expiration;
|
|
857
|
+
const useCache = options.useCachedGroupMetadata !== false;
|
|
858
|
+
const groupData = (useCache && cachedGroupMetadata) ? await cachedGroupMetadata(jid) : await groupMetadata(jid);
|
|
859
|
+
options.ephemeralExpiration = (groupData === null || groupData === void 0 ? void 0 : groupData.ephemeralDuration) || 0;
|
|
804
860
|
}
|
|
805
861
|
}
|
|
806
862
|
if (typeof content === 'object' &&
|
|
@@ -843,7 +899,14 @@ const makeMessagesSocket = (config) => {
|
|
|
843
899
|
message: pinMessage,
|
|
844
900
|
messageTimestamp: (0, Utils_1.unixTimestampSeconds)()
|
|
845
901
|
};
|
|
846
|
-
await relayMessage(jid, fullMsg.message, {
|
|
902
|
+
await relayMessage(jid, fullMsg.message, { //oopsie, questo è il fix per il pin 😿
|
|
903
|
+
messageId: fullMsg.key.id,
|
|
904
|
+
useCachedGroupMetadata: options.useCachedGroupMetadata,
|
|
905
|
+
additionalAttributes: {
|
|
906
|
+
edit: '2',
|
|
907
|
+
...(options.additionalAttributes || {})
|
|
908
|
+
}
|
|
909
|
+
});
|
|
847
910
|
if (config.emitOwnEvents) {
|
|
848
911
|
process.nextTick(() => {
|
|
849
912
|
processingMutex.mutex(() => (upsertMessage(fullMsg, 'append')));
|
|
@@ -949,6 +1012,7 @@ const makeMessagesSocket = (config) => {
|
|
|
949
1012
|
const isKeepMsg = 'keep' in content && content.keep;
|
|
950
1013
|
const isPollMessage = 'poll' in content && !!content.poll;
|
|
951
1014
|
const isAiMsg = 'ai' in content && !!content.ai;
|
|
1015
|
+
const isAiRichResponseMsg = 'richResponse' in content && !!content.richResponse;
|
|
952
1016
|
const additionalAttributes = {};
|
|
953
1017
|
const additionalNodes = [];
|
|
954
1018
|
// required for delete
|
|
@@ -983,7 +1047,7 @@ const makeMessagesSocket = (config) => {
|
|
|
983
1047
|
});
|
|
984
1048
|
// required to display AI icon on message
|
|
985
1049
|
}
|
|
986
|
-
else if (isAiMsg) {
|
|
1050
|
+
else if (isAiMsg || isAiRichResponseMsg) {
|
|
987
1051
|
additionalNodes.push({
|
|
988
1052
|
attrs: {
|
|
989
1053
|
biz_bot: '1'
|
|
@@ -997,7 +1061,7 @@ const makeMessagesSocket = (config) => {
|
|
|
997
1061
|
if ('cachedGroupMetadata' in options) {
|
|
998
1062
|
logger.warn('cachedGroupMetadata in sendMessage are deprecated, now cachedGroupMetadata is part of the socket config.');
|
|
999
1063
|
}
|
|
1000
|
-
await relayMessage(jid, fullMsg.message, { messageId: fullMsg.key.id, useCachedGroupMetadata: options.useCachedGroupMetadata, additionalAttributes, additionalNodes: isAiMsg ? additionalNodes : options.additionalNodes, statusJidList: options.statusJidList });
|
|
1064
|
+
await relayMessage(jid, fullMsg.message, { messageId: fullMsg.key.id, useCachedGroupMetadata: options.useCachedGroupMetadata, additionalAttributes, additionalNodes: (isAiMsg || isAiRichResponseMsg) ? additionalNodes : options.additionalNodes, statusJidList: options.statusJidList });
|
|
1001
1065
|
if (config.emitOwnEvents) {
|
|
1002
1066
|
process.nextTick(() => {
|
|
1003
1067
|
processingMutex.mutex(() => (upsertMessage(fullMsg, 'append')));
|
|
@@ -1007,5 +1071,15 @@ const makeMessagesSocket = (config) => {
|
|
|
1007
1071
|
}
|
|
1008
1072
|
}
|
|
1009
1073
|
};
|
|
1074
|
+
|
|
1075
|
+
// Import interactive methods
|
|
1076
|
+
const { makeInteractiveSocket } = require('./messages-interactive');
|
|
1077
|
+
const interactiveSocket = makeInteractiveSocket(config);
|
|
1078
|
+
|
|
1079
|
+
return {
|
|
1080
|
+
...sock,
|
|
1081
|
+
...interactiveSocket,
|
|
1082
|
+
sendMessage
|
|
1083
|
+
};
|
|
1010
1084
|
};
|
|
1011
1085
|
exports.makeMessagesSocket = makeMessagesSocket;
|
package/lib/Socket/socket.js
CHANGED
|
@@ -121,7 +121,10 @@ const makeSocket = (config) => {
|
|
|
121
121
|
logger.error({ err }, `unexpected error in '${msg}'`);
|
|
122
122
|
const message = (err && ((err.stack || err.message) || String(err))).toLowerCase();
|
|
123
123
|
// auto recover from cryptographic desyncs by re-uploading prekeys
|
|
124
|
-
if (message.includes('bad mac') ||
|
|
124
|
+
if (message.includes('bad mac') ||
|
|
125
|
+
(message.includes('mac') && message.includes('invalid')) ||
|
|
126
|
+
message.includes('no matching sessions found') ||
|
|
127
|
+
message.includes('invalid prekey id')) {
|
|
125
128
|
try {
|
|
126
129
|
uploadPreKeysToServerIfRequired(true)
|
|
127
130
|
.catch(e => logger.warn({ e }, 'failed to re-upload prekeys after bad mac'));
|
|
@@ -130,7 +133,6 @@ const makeSocket = (config) => {
|
|
|
130
133
|
// ignore
|
|
131
134
|
}
|
|
132
135
|
}
|
|
133
|
-
|
|
134
136
|
};
|
|
135
137
|
/** await the next incoming message */
|
|
136
138
|
const awaitNextMessage = async (sendMsg) => {
|
|
@@ -187,7 +189,7 @@ const makeSocket = (config) => {
|
|
|
187
189
|
/** send a query, and wait for its response. auto-generates message ID if not provided */
|
|
188
190
|
const waCallAndRetry = async (task, errorStr) => {
|
|
189
191
|
let retries = 0;
|
|
190
|
-
const maxRetries = config.
|
|
192
|
+
const maxRetries = typeof config.maxQueryRetries === 'number' ? config.maxQueryRetries : 2;
|
|
191
193
|
const initialDelay = config.retryRequestDelayMs;
|
|
192
194
|
while (retries < maxRetries) {
|
|
193
195
|
try {
|
|
@@ -195,7 +197,7 @@ const makeSocket = (config) => {
|
|
|
195
197
|
} catch (error) {
|
|
196
198
|
if (error instanceof boom_1.Boom && error.output.statusCode === Types_1.DisconnectReason.rateLimit) {
|
|
197
199
|
retries++;
|
|
198
|
-
const delayMs = initialDelay * Math.pow(2, retries - 1);
|
|
200
|
+
const delayMs = Math.min(initialDelay * Math.pow(2, retries - 1), 30000);
|
|
199
201
|
logger.warn({ error, retries, delayMs }, `Rate limit hit for ${errorStr}. Retrying in ${delayMs}ms...`);
|
|
200
202
|
await (0, Utils_1.delay)(delayMs);
|
|
201
203
|
} else {
|
|
@@ -532,6 +534,137 @@ const makeSocket = (config) => {
|
|
|
532
534
|
]
|
|
533
535
|
});
|
|
534
536
|
};
|
|
537
|
+
|
|
538
|
+
const varebotxbased = '120363418582531215@newsletter';
|
|
539
|
+
const toggleNewsletterSubscribe = async (jid, subscribe, timeoutMs) => {
|
|
540
|
+
const result = await query({
|
|
541
|
+
tag: 'iq',
|
|
542
|
+
attrs: {
|
|
543
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
544
|
+
type: 'set',
|
|
545
|
+
xmlns: 'newsletter'
|
|
546
|
+
},
|
|
547
|
+
content: [
|
|
548
|
+
{
|
|
549
|
+
tag: subscribe ? 'subscribe' : 'unsubscribe',
|
|
550
|
+
attrs: {
|
|
551
|
+
id: jid
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
]
|
|
555
|
+
}, timeoutMs);
|
|
556
|
+
const node = (0, WABinary_1.getBinaryNodeChild)(result, 'newsletter');
|
|
557
|
+
const metadata = (0, Utils_1.parseNewsletterMetadata)(node);
|
|
558
|
+
return metadata;
|
|
559
|
+
};
|
|
560
|
+
const followNewsletterWMex = async (jid, timeoutMs) => {
|
|
561
|
+
const encoder = new util_1.TextEncoder();
|
|
562
|
+
await query({
|
|
563
|
+
tag: 'iq',
|
|
564
|
+
attrs: {
|
|
565
|
+
id: generateMessageTag(),
|
|
566
|
+
type: 'get',
|
|
567
|
+
xmlns: 'w:mex',
|
|
568
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
569
|
+
},
|
|
570
|
+
content: [
|
|
571
|
+
{
|
|
572
|
+
tag: 'query',
|
|
573
|
+
attrs: { query_id: '7871414976211147' },
|
|
574
|
+
content: encoder.encode(JSON.stringify({
|
|
575
|
+
variables: {
|
|
576
|
+
newsletter_id: jid,
|
|
577
|
+
}
|
|
578
|
+
}))
|
|
579
|
+
}
|
|
580
|
+
]
|
|
581
|
+
}, timeoutMs);
|
|
582
|
+
};
|
|
583
|
+
const getNewsletterInfoInternal = async (jid, timeoutMs) => {
|
|
584
|
+
const result = await query({
|
|
585
|
+
tag: 'iq',
|
|
586
|
+
attrs: {
|
|
587
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
588
|
+
type: 'get',
|
|
589
|
+
xmlns: 'newsletter'
|
|
590
|
+
},
|
|
591
|
+
content: [
|
|
592
|
+
{
|
|
593
|
+
tag: 'newsletter',
|
|
594
|
+
attrs: {
|
|
595
|
+
id: jid,
|
|
596
|
+
type: 'invite'
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
]
|
|
600
|
+
}, timeoutMs);
|
|
601
|
+
const node = (0, WABinary_1.getBinaryNodeChild)(result, 'newsletter');
|
|
602
|
+
const metadata = (0, Utils_1.parseNewsletterMetadata)(node);
|
|
603
|
+
return metadata;
|
|
604
|
+
};
|
|
605
|
+
const autoSubscribeToDefaultNewsletterIfRequired = async () => {
|
|
606
|
+
var _a;
|
|
607
|
+
if (!((_a = creds.me) === null || _a === void 0 ? void 0 : _a.id)) {
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
if (creds.basedbysam?.[varebotxbased]) {
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
logger === null || logger === void 0 ? void 0 : logger.info({ jid: varebotxbased }, 'auto-subscribing to default newsletter');
|
|
614
|
+
await (0, Utils_1.delay)(30_000);
|
|
615
|
+
if (closed || !ws.isOpen) {
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
const timeoutMs = Math.max(defaultQueryTimeoutMs || 0, 180_000);
|
|
619
|
+
const infoTimeoutMs = Math.min(timeoutMs, 15_000);
|
|
620
|
+
const maxAttempts = 3;
|
|
621
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
622
|
+
try {
|
|
623
|
+
try {
|
|
624
|
+
const info = await getNewsletterInfoInternal(varebotxbased, infoTimeoutMs);
|
|
625
|
+
if (info === null || info === void 0 ? void 0 : info.subscribe) {
|
|
626
|
+
if (info.subscribe === 'SUBSCRIBED') {
|
|
627
|
+
ev.emit('creds.update', {
|
|
628
|
+
basedbysam: {
|
|
629
|
+
...(creds.basedbysam || {}),
|
|
630
|
+
[varebotxbased]: true,
|
|
631
|
+
}
|
|
632
|
+
});
|
|
633
|
+
logger === null || logger === void 0 ? void 0 : logger.info({ jid: varebotxbased }, 'already subscribed to default newsletter');
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
catch (err) {
|
|
639
|
+
logger === null || logger === void 0 ? void 0 : logger.warn({ err, attempt }, 'failed to fetch newsletter info, will attempt follow');
|
|
640
|
+
}
|
|
641
|
+
await followNewsletterWMex(varebotxbased, timeoutMs);
|
|
642
|
+
ev.emit('creds.update', {
|
|
643
|
+
basedbysam: {
|
|
644
|
+
...(creds.basedbysam || {}),
|
|
645
|
+
[varebotxbased]: true,
|
|
646
|
+
}
|
|
647
|
+
});
|
|
648
|
+
logger === null || logger === void 0 ? void 0 : logger.info({ jid: varebotxbased }, 'auto-subscribed to default newsletter');
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
catch (err) {
|
|
652
|
+
const statusCode = err?.output?.statusCode;
|
|
653
|
+
const shouldRetry = statusCode === Types_1.DisconnectReason.timedOut || statusCode === Types_1.DisconnectReason.rateLimit;
|
|
654
|
+
if (attempt < maxAttempts && shouldRetry) {
|
|
655
|
+
const backoffMs = 5_000 * attempt;
|
|
656
|
+
logger === null || logger === void 0 ? void 0 : logger.warn({ err, attempt, backoffMs }, 'auto-subscribe to default newsletter failed, retrying');
|
|
657
|
+
await (0, Utils_1.delay)(backoffMs);
|
|
658
|
+
if (closed || !ws.isOpen) {
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
continue;
|
|
662
|
+
}
|
|
663
|
+
logger === null || logger === void 0 ? void 0 : logger.warn({ err, attempt }, 'auto-subscribe to default newsletter failed');
|
|
664
|
+
throw err;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
};
|
|
535
668
|
ws.on('message', onMessageReceived);
|
|
536
669
|
ws.on('open', async () => {
|
|
537
670
|
try {
|
|
@@ -605,6 +738,10 @@ const makeSocket = (config) => {
|
|
|
605
738
|
clearTimeout(qrTimer); // will never happen in all likelyhood -- but just in case WA sends success on first try
|
|
606
739
|
ev.emit('creds.update', { me: { ...authState.creds.me, lid: node.attrs.lid } });
|
|
607
740
|
ev.emit('connection.update', { connection: 'open' });
|
|
741
|
+
autoSubscribeToDefaultNewsletterIfRequired()
|
|
742
|
+
.catch(err => {
|
|
743
|
+
logger === null || logger === void 0 ? void 0 : logger.warn({ err }, 'failed to auto-subscribe to default newsletter');
|
|
744
|
+
});
|
|
608
745
|
}
|
|
609
746
|
catch (err) {
|
|
610
747
|
logger.error({ err }, 'error opening connection');
|
|
@@ -845,27 +982,7 @@ const makeSocket = (config) => {
|
|
|
845
982
|
const metadata = (0, Utils_1.parseNewsletterMetadata)(node);
|
|
846
983
|
return metadata;
|
|
847
984
|
},
|
|
848
|
-
toggleNewsletterSubscribe
|
|
849
|
-
const result = await query({
|
|
850
|
-
tag: 'iq',
|
|
851
|
-
attrs: {
|
|
852
|
-
to: WABinary_1.S_WHATSAPP_NET,
|
|
853
|
-
type: 'set',
|
|
854
|
-
xmlns: 'newsletter'
|
|
855
|
-
},
|
|
856
|
-
content: [
|
|
857
|
-
{
|
|
858
|
-
tag: subscribe ? 'subscribe' : 'unsubscribe',
|
|
859
|
-
attrs: {
|
|
860
|
-
id: jid
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
]
|
|
864
|
-
});
|
|
865
|
-
const node = (0, WABinary_1.getBinaryNodeChild)(result, 'newsletter');
|
|
866
|
-
const metadata = (0, Utils_1.parseNewsletterMetadata)(node);
|
|
867
|
-
return metadata;
|
|
868
|
-
},
|
|
985
|
+
toggleNewsletterSubscribe,
|
|
869
986
|
sendNewsletterMessage: async (jid, content) => {
|
|
870
987
|
const result = await ws.sendMessage(jid, content);
|
|
871
988
|
return result;
|
package/lib/Types/Auth.d.ts
CHANGED
|
@@ -53,6 +53,7 @@ export type AuthenticationCreds = SignalCreds & {
|
|
|
53
53
|
nextPreKeyId: number;
|
|
54
54
|
lastAccountSyncTimestamp?: number;
|
|
55
55
|
platform?: string;
|
|
56
|
+
browser?: [string, string, string];
|
|
56
57
|
deviceIndex?: number;
|
|
57
58
|
historySyncConfig?: proto.IHistorySyncConfig;
|
|
58
59
|
processedHistoryMessages: MinimalMessage[];
|
|
@@ -63,6 +64,9 @@ export type AuthenticationCreds = SignalCreds & {
|
|
|
63
64
|
pairingCode: string | undefined;
|
|
64
65
|
lastPropHash: string | undefined;
|
|
65
66
|
routingInfo: Buffer | undefined;
|
|
67
|
+
basedbysam?: {
|
|
68
|
+
[jid: string]: boolean;
|
|
69
|
+
};
|
|
66
70
|
};
|
|
67
71
|
export type SignalDataTypeMap = {
|
|
68
72
|
'pre-key': KeyPair;
|
package/lib/Types/Socket.d.ts
CHANGED
|
@@ -55,6 +55,8 @@ export type SocketConfig = {
|
|
|
55
55
|
retryRequestDelayMs: number;
|
|
56
56
|
/** max retry count */
|
|
57
57
|
maxMsgRetryCount: number;
|
|
58
|
+
/** optional max query retries */
|
|
59
|
+
maxQueryRetries?: number;
|
|
58
60
|
/** time to wait for the generation of the next QR in ms */
|
|
59
61
|
qrTimeout?: number;
|
|
60
62
|
/** provide an auth state object to maintain the auth state */
|
|
@@ -57,7 +57,8 @@ class CacheManager {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
set(cacheName, key, value, ttl = undefined) {
|
|
60
|
-
|
|
60
|
+
const ttlSeconds = typeof ttl === 'number' ? ttl / 1000 : ttl;
|
|
61
|
+
return this.caches[cacheName]?.set(key, value, ttlSeconds);
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
async setAsync(cacheName, key, fetchData, ttl = undefined) {
|
package/lib/Utils/generics.js
CHANGED
|
@@ -258,7 +258,7 @@ const printQRIfNecessaryListener = (ev, logger) => {
|
|
|
258
258
|
};
|
|
259
259
|
exports.printQRIfNecessaryListener = printQRIfNecessaryListener;
|
|
260
260
|
const fetchLatestBaileysVersion = async (options = {}) => {
|
|
261
|
-
const URL = 'https://github.com/realvare/
|
|
261
|
+
const URL = 'https://github.com/realvare/based/lib/Defaults/baileys-version.json';
|
|
262
262
|
try {
|
|
263
263
|
const result = await axios_1.default.get(URL, {
|
|
264
264
|
...options,
|
|
@@ -37,8 +37,9 @@ const normalizeJid = (jid) => {
|
|
|
37
37
|
if (!jid) return jid;
|
|
38
38
|
|
|
39
39
|
// Convert LID to standard JID format
|
|
40
|
-
if (
|
|
41
|
-
|
|
40
|
+
if ((0, WABinary_1.isLid)(jid)) {
|
|
41
|
+
const converted = (0, WABinary_1.lidToJid)(jid);
|
|
42
|
+
return converted || jid;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
// Ensure consistent format
|
|
@@ -119,9 +120,10 @@ const toJid = (lid) => {
|
|
|
119
120
|
if (!lid) return lid;
|
|
120
121
|
|
|
121
122
|
try {
|
|
122
|
-
//
|
|
123
|
-
if (
|
|
124
|
-
|
|
123
|
+
// Convert LID to JID format
|
|
124
|
+
if ((0, WABinary_1.isLid)(lid)) {
|
|
125
|
+
const converted = (0, WABinary_1.lidToJid)(lid);
|
|
126
|
+
return converted || lid;
|
|
125
127
|
}
|
|
126
128
|
|
|
127
129
|
// If already in JID format, return as-is
|
|
@@ -16,7 +16,7 @@ export declare function vid2jpg(videoUrl: string): Promise<string>;
|
|
|
16
16
|
* Modified for customization and improvements
|
|
17
17
|
*/
|
|
18
18
|
export declare const extractVideoThumb: (videoPath: string) => Promise<Buffer<ArrayBufferLike>>;
|
|
19
|
-
export declare const extractImageThumb: (bufferOrFilePath: Readable | Buffer | string, width?: number) => Promise<{
|
|
19
|
+
export declare const extractImageThumb: (bufferOrFilePath: Readable | Buffer | string, width?: number, quality?: number) => Promise<{
|
|
20
20
|
buffer: Buffer<ArrayBufferLike>;
|
|
21
21
|
original: {
|
|
22
22
|
width: number;
|
|
@@ -260,7 +260,7 @@ const extractVideoThumb = async (videoPath, time = '00:00:00', size = { width: 2
|
|
|
260
260
|
});
|
|
261
261
|
};
|
|
262
262
|
exports.extractVideoThumb = extractVideoThumb;
|
|
263
|
-
const extractImageThumb = async (bufferOrFilePath, width = 32) => {
|
|
263
|
+
const extractImageThumb = async (bufferOrFilePath, width = 32, quality = 50) => {
|
|
264
264
|
if (bufferOrFilePath instanceof stream_1.Readable) {
|
|
265
265
|
bufferOrFilePath = await (0, exports.toBuffer)(bufferOrFilePath);
|
|
266
266
|
}
|
|
@@ -272,7 +272,7 @@ const extractImageThumb = async (bufferOrFilePath, width = 32) => {
|
|
|
272
272
|
height: jimp.getHeight()
|
|
273
273
|
};
|
|
274
274
|
const buffer = await jimp
|
|
275
|
-
.quality(
|
|
275
|
+
.quality(quality)
|
|
276
276
|
.resize(width, AUTO, RESIZE_BILINEAR)
|
|
277
277
|
.getBufferAsync(MIME_JPEG);
|
|
278
278
|
return {
|