@badzz88/baileys 8.5.3 → 8.5.4
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 +1 -1
- package/WAProto/WAProto.proto +1256 -75
- package/WAProto/index.d.ts +36042 -19649
- package/WAProto/index.js +181990 -135645
- package/engine-requirements.js +7 -15
- package/lib/Defaults/index.js +22 -17
- package/lib/Signal/Group/group_cipher.js +5 -5
- package/lib/Signal/Group/keyhelper.js +4 -4
- package/lib/Signal/Group/sender-chain-key.js +2 -2
- package/lib/Signal/Group/sender-key-distribution-message.js +1 -1
- package/lib/Signal/Group/sender-key-message.js +3 -3
- package/lib/Signal/Group/sender-key-record.js +1 -1
- package/lib/Signal/Group/sender-message-key.js +5 -5
- package/lib/Signal/libsignal.js +39 -59
- package/lib/Signal/lid-mapping.js +28 -10
- package/lib/Socket/aigroups.js +5 -5
- package/lib/Socket/business.js +3 -11
- package/lib/Socket/chats.js +668 -319
- package/lib/Socket/communities.js +85 -89
- package/lib/Socket/graphql.js +435 -228
- package/lib/Socket/groups.js +132 -211
- package/lib/Socket/index.js +9 -7
- package/lib/Socket/interactive-handler.js +117 -60
- package/lib/Socket/interop.js +56 -175
- package/lib/Socket/managed-account.js +79 -48
- package/lib/Socket/messages-recv.js +898 -340
- package/lib/Socket/messages-send.js +462 -160
- package/lib/Socket/mex.js +40 -53
- package/lib/Socket/newsletter.js +291 -295
- package/lib/Socket/privacy.js +77 -265
- package/lib/Socket/registration.js +164 -157
- package/lib/Socket/socket.js +181 -199
- package/lib/Socket/username.js +144 -227
- package/lib/Store/make-cache-manager-store.js +2 -2
- package/lib/Store/make-in-memory-store.js +25 -141
- package/lib/Types/Auth.js +3 -3
- package/lib/Types/Label.js +1 -1
- package/lib/Types/LabelAssociation.js +1 -1
- package/lib/Types/Newsletter.js +96 -65
- package/lib/Types/State.js +4 -4
- package/lib/Types/index.js +1 -1
- package/lib/Utils/auth-utils.js +52 -57
- package/lib/Utils/browser-utils.js +1 -1
- package/lib/Utils/business.js +2 -6
- package/lib/Utils/chat-utils.js +102 -38
- package/lib/Utils/crypto.js +54 -84
- package/lib/Utils/decode-wa-message.js +316 -83
- package/lib/Utils/event-buffer.js +37 -61
- package/lib/Utils/generics.js +157 -103
- package/lib/Utils/group-history.js +3 -12
- package/lib/Utils/history.js +15 -15
- package/lib/Utils/index.js +1 -5
- package/lib/Utils/link-preview.js +3 -8
- package/lib/Utils/lt-hash.js +2 -35
- package/lib/Utils/make-mutex.js +1 -1
- package/lib/Utils/message-inspect.js +393 -0
- package/lib/Utils/message-retry-manager.js +27 -92
- package/lib/Utils/messages-media.js +159 -130
- package/lib/Utils/messages.js +144 -566
- package/lib/Utils/meta-ai-msmsg.js +62 -202
- package/lib/Utils/noise-handler.js +19 -21
- package/lib/Utils/offline-node-processor.js +3 -8
- package/lib/Utils/pre-key-manager.js +13 -23
- package/lib/Utils/process-message.js +197 -106
- package/lib/Utils/reporting-utils.js +2 -2
- package/lib/Utils/signal.js +28 -63
- package/lib/Utils/stanza-ack.js +39 -12
- package/lib/Utils/sync-action-utils.js +4 -7
- package/lib/Utils/tc-token-utils.js +20 -25
- package/lib/Utils/use-multi-file-auth-state.js +30 -14
- package/lib/Utils/validate-connection.js +59 -19
- package/lib/WABinary/decode.js +50 -16
- package/lib/WABinary/encode.js +54 -224
- package/lib/WABinary/generic-utils.js +7 -97
- package/lib/WABinary/jid-utils.js +27 -14
- package/lib/WAM/encode.js +7 -7
- package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +58 -1
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +7 -1
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +13 -5
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +1 -4
- package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +20 -7
- package/lib/WAUSync/Protocols/USyncNewsletterProtocol.js +865 -0
- package/lib/WAUSync/Protocols/USyncPictureProtocol.js +1 -1
- package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +2 -2
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +7 -2
- package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +1 -1
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +2 -1
- package/lib/WAUSync/Protocols/index.js +1 -0
- package/lib/WAUSync/USyncBackoff.js +26 -0
- package/lib/WAUSync/USyncQuery.js +77 -6
- package/lib/WAUSync/USyncUser.js +16 -8
- package/lib/WAUSync/index.js +1 -0
- package/lib/antiban.js +608 -854
- package/lib/index.js +1 -1
- package/package.json +16 -20
- package/lib/Socket/luxu.js +0 -387
- package/lib/Socket/text-router.js +0 -83
- package/lib/Store/keyed-db.js +0 -108
- package/lib/Types/Mex.js +0 -112
- package/lib/Utils/command-loader.d.ts +0 -31
- package/lib/Utils/command-loader.js +0 -100
- package/lib/Utils/companion-reg-client-utils.js +0 -42
- package/lib/Utils/curve25519-js.js +0 -275
- package/lib/Utils/native-bridge.js +0 -82
- package/lib/Utils/session-pool.d.ts +0 -16
- package/lib/Utils/session-pool.js +0 -94
- package/lib/Utils/sticker.d.ts +0 -17
- package/lib/Utils/sticker.js +0 -145
- package/lib/Utils/view-once-cache.d.ts +0 -9
- package/lib/Utils/view-once-cache.js +0 -79
package/lib/Utils/generics.js
CHANGED
|
@@ -41,11 +41,9 @@ exports.bindWaitForEvent = bindWaitForEvent
|
|
|
41
41
|
exports.trimUndefined = trimUndefined
|
|
42
42
|
exports.bytesToCrockford = bytesToCrockford
|
|
43
43
|
exports.encodeNewsletterMessage = encodeNewsletterMessage
|
|
44
|
-
exports.generateIOSMessageID = void 0
|
|
45
|
-
exports.generateAndroMessageID = void 0
|
|
46
44
|
const boom_1 = require('@hapi/boom')
|
|
47
45
|
const crypto_1 = require('crypto')
|
|
48
|
-
const
|
|
46
|
+
const rb = require('whatsapp-rust-bridge')
|
|
49
47
|
const DEFAULTS_1 = require('../Defaults')
|
|
50
48
|
const index_js_1 = require('../../WAProto/index.js')
|
|
51
49
|
const baileysVersion = DEFAULTS_1.VERSION
|
|
@@ -53,14 +51,14 @@ const Types_1 = require('../Types')
|
|
|
53
51
|
const WABinary_1 = require('../WABinary')
|
|
54
52
|
const crypto_2 = require('./crypto')
|
|
55
53
|
exports.BufferJSON = {
|
|
56
|
-
|
|
54
|
+
|
|
57
55
|
replacer: (k, value) => {
|
|
58
56
|
if (Buffer.isBuffer(value) || value instanceof Uint8Array || value?.type === 'Buffer') {
|
|
59
57
|
return { type: 'Buffer', data: Buffer.from(value?.data || value).toString('base64') }
|
|
60
58
|
}
|
|
61
59
|
return value
|
|
62
60
|
},
|
|
63
|
-
|
|
61
|
+
|
|
64
62
|
reviver: (_, value) => {
|
|
65
63
|
if (typeof value === 'object' && value !== null && value.type === 'Buffer' && typeof value.data === 'string') {
|
|
66
64
|
return Buffer.from(value.data, 'base64')
|
|
@@ -81,7 +79,7 @@ const getKeyAuthor = (key, meId = 'me') =>
|
|
|
81
79
|
(key?.fromMe ? meId : key?.participantAlt || key?.remoteJidAlt || key?.participant || key?.remoteJid) || ''
|
|
82
80
|
exports.getKeyAuthor = getKeyAuthor
|
|
83
81
|
const isStringNullOrEmpty = value =>
|
|
84
|
-
|
|
82
|
+
|
|
85
83
|
value == null || value === ''
|
|
86
84
|
exports.isStringNullOrEmpty = isStringNullOrEmpty
|
|
87
85
|
const writeRandomPadMax16 = msg => {
|
|
@@ -102,7 +100,7 @@ const unpadRandomMax16 = e => {
|
|
|
102
100
|
return new Uint8Array(t.buffer, t.byteOffset, t.length - r)
|
|
103
101
|
}
|
|
104
102
|
exports.unpadRandomMax16 = unpadRandomMax16
|
|
105
|
-
|
|
103
|
+
|
|
106
104
|
const generateParticipantHashV2 = participants => {
|
|
107
105
|
participants.sort()
|
|
108
106
|
const sha256Hash = (0, crypto_2.sha256)(Buffer.from(participants.join(''))).toString('base64')
|
|
@@ -127,7 +125,7 @@ const encodeBigEndian = (e, t = 4) => {
|
|
|
127
125
|
exports.encodeBigEndian = encodeBigEndian
|
|
128
126
|
const toNumber = t => (typeof t === 'object' && t ? ('toNumber' in t ? t.toNumber() : t.low) : t || 0)
|
|
129
127
|
exports.toNumber = toNumber
|
|
130
|
-
|
|
128
|
+
|
|
131
129
|
const unixTimestampSeconds = (date = new Date()) => Math.floor(date.getTime() / 1000)
|
|
132
130
|
exports.unixTimestampSeconds = unixTimestampSeconds
|
|
133
131
|
const debouncedTimeout = (intervalMs = 1000, task) => {
|
|
@@ -177,7 +175,7 @@ async function promiseTimeout(ms, promise) {
|
|
|
177
175
|
return new Promise(promise)
|
|
178
176
|
}
|
|
179
177
|
const stack = new Error().stack
|
|
180
|
-
|
|
178
|
+
|
|
181
179
|
const { delay, cancel } = (0, exports.delayCancellable)(ms)
|
|
182
180
|
const p = new Promise((resolve, reject) => {
|
|
183
181
|
delay
|
|
@@ -196,38 +194,26 @@ async function promiseTimeout(ms, promise) {
|
|
|
196
194
|
}).finally(cancel)
|
|
197
195
|
return p
|
|
198
196
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const generateMessageIDV2 =
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
const generateMessageIDV2 = userId => {
|
|
200
|
+
const data = Buffer.alloc(8 + 20 + 16)
|
|
201
|
+
data.writeBigUInt64BE(BigInt(Math.floor(Date.now() / 1000)))
|
|
202
|
+
if (userId) {
|
|
203
|
+
const id = (0, WABinary_1.jidDecode)(userId)
|
|
204
|
+
if (id?.user) {
|
|
205
|
+
data.write(id.user, 8)
|
|
206
|
+
data.write('@c.us', 8 + id.user.length)
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
const random = (0, crypto_1.randomBytes)(16)
|
|
210
|
+
random.copy(data, 28)
|
|
211
|
+
const hash = Buffer.from(rb.sha256(data))
|
|
212
|
+
return '3EB0' + hash.toString('hex').toUpperCase().substring(0, 18)
|
|
213
|
+
}
|
|
216
214
|
exports.generateMessageIDV2 = generateMessageIDV2
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
const random = (0, crypto_1.randomBytes)(9.5); // 19 hex chars = 9.5 bytes
|
|
220
|
-
return (prefix + random.toString('hex')).toUpperCase().substring(0, 21);
|
|
221
|
-
};
|
|
222
|
-
exports.generateIOSMessageID = generateIOSMessageID
|
|
223
|
-
const generateAndroMessageID = () => {
|
|
224
|
-
const prefix = '3A';
|
|
225
|
-
const random = (0, crypto_1.randomBytes)(16); // 32 hex chars = 16 bytes
|
|
226
|
-
return (random.toString('hex')).toUpperCase().substring(0, 21);
|
|
227
|
-
};
|
|
228
|
-
exports.generateAndroMessageID = generateAndroMessageID
|
|
229
|
-
// generate a random ID to attach to a message
|
|
230
|
-
const generateMessageID = () => 'XZCYYX-' + (0, crypto_1.randomBytes)(18).toString('hex').toUpperCase()
|
|
215
|
+
|
|
216
|
+
const generateMessageID = () => '3EB0' + (0, crypto_1.randomBytes)(18).toString('hex').toUpperCase()
|
|
231
217
|
exports.generateMessageID = generateMessageID
|
|
232
218
|
function bindWaitForEvent(ev, event) {
|
|
233
219
|
return async (check, timeoutMs) => {
|
|
@@ -257,30 +243,33 @@ function bindWaitForEvent(ev, event) {
|
|
|
257
243
|
}
|
|
258
244
|
const bindWaitForConnectionUpdate = ev => bindWaitForEvent(ev, 'connection.update')
|
|
259
245
|
exports.bindWaitForConnectionUpdate = bindWaitForConnectionUpdate
|
|
260
|
-
|
|
261
|
-
* utility that fetches latest baileys version from the master branch.
|
|
262
|
-
* Use to ensure your WA connection is always on the latest version
|
|
263
|
-
*/
|
|
246
|
+
|
|
264
247
|
const fetchLatestBaileysVersion = async (options = {}) => {
|
|
265
248
|
const URL = 'https://raw.githubusercontent.com/WhiskeySockets/Baileys/master/src/Defaults/index.ts'
|
|
266
249
|
try {
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
const controller = new AbortController()
|
|
253
|
+
const timer = setTimeout(() => controller.abort(), options.timeout ?? 5000)
|
|
267
254
|
const response = await fetch(URL, {
|
|
268
255
|
dispatcher: options.dispatcher,
|
|
269
256
|
method: 'GET',
|
|
270
|
-
headers: options.headers
|
|
257
|
+
headers: options.headers,
|
|
258
|
+
signal: controller.signal
|
|
271
259
|
})
|
|
260
|
+
clearTimeout(timer)
|
|
272
261
|
if (!response.ok) {
|
|
273
262
|
throw new boom_1.Boom(`Failed to fetch latest Baileys version: ${response.statusText}`, {
|
|
274
263
|
statusCode: response.status
|
|
275
264
|
})
|
|
276
265
|
}
|
|
277
266
|
const text = await response.text()
|
|
278
|
-
|
|
267
|
+
|
|
279
268
|
const lines = text.split('\n')
|
|
280
|
-
const versionLine = lines[6]
|
|
269
|
+
const versionLine = lines[6]
|
|
281
270
|
const versionMatch = versionLine.match(/const version = \[(\d+),\s*(\d+),\s*(\d+)\]/)
|
|
282
271
|
if (versionMatch) {
|
|
283
|
-
const version = [parseInt(versionMatch[1]), parseInt(versionMatch[2]), parseInt(versionMatch[3])]
|
|
272
|
+
const version = [parseInt(versionMatch[1], 10), parseInt(versionMatch[2], 10), parseInt(versionMatch[3], 10)]
|
|
284
273
|
return {
|
|
285
274
|
version,
|
|
286
275
|
isLatest: true
|
|
@@ -297,24 +286,25 @@ const fetchLatestBaileysVersion = async (options = {}) => {
|
|
|
297
286
|
}
|
|
298
287
|
}
|
|
299
288
|
exports.fetchLatestBaileysVersion = fetchLatestBaileysVersion
|
|
300
|
-
|
|
301
|
-
* A utility that fetches the latest web version of whatsapp.
|
|
302
|
-
* Use to ensure your WA connection is always on the latest version
|
|
303
|
-
*/
|
|
289
|
+
|
|
304
290
|
const fetchLatestWaWebVersion = async (options = {}) => {
|
|
305
291
|
try {
|
|
306
|
-
|
|
292
|
+
|
|
307
293
|
const defaultHeaders = {
|
|
308
294
|
'sec-fetch-site': 'none',
|
|
309
295
|
'user-agent':
|
|
310
296
|
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'
|
|
311
297
|
}
|
|
312
298
|
const headers = { ...defaultHeaders, ...options.headers }
|
|
299
|
+
const controller = new AbortController()
|
|
300
|
+
const timer = setTimeout(() => controller.abort(), options.timeout ?? 5000)
|
|
313
301
|
const response = await fetch('https://web.whatsapp.com/sw.js', {
|
|
314
302
|
...options,
|
|
315
303
|
method: 'GET',
|
|
316
|
-
headers
|
|
304
|
+
headers,
|
|
305
|
+
signal: controller.signal
|
|
317
306
|
})
|
|
307
|
+
clearTimeout(timer)
|
|
318
308
|
if (!response.ok) {
|
|
319
309
|
throw new boom_1.Boom(`Failed to fetch sw.js: ${response.statusText}`, { statusCode: response.status })
|
|
320
310
|
}
|
|
@@ -344,7 +334,7 @@ const fetchLatestWaWebVersion = async (options = {}) => {
|
|
|
344
334
|
}
|
|
345
335
|
}
|
|
346
336
|
exports.fetchLatestWaWebVersion = fetchLatestWaWebVersion
|
|
347
|
-
|
|
337
|
+
|
|
348
338
|
const generateMdTagPrefix = () => {
|
|
349
339
|
const bytes = (0, crypto_1.randomBytes)(4)
|
|
350
340
|
return `${bytes.readUInt16BE()}.${bytes.readUInt16BE(2)}-`
|
|
@@ -353,13 +343,11 @@ exports.generateMdTagPrefix = generateMdTagPrefix
|
|
|
353
343
|
const STATUS_MAP = {
|
|
354
344
|
sender: index_js_1.proto.WebMessageInfo.Status.SERVER_ACK,
|
|
355
345
|
played: index_js_1.proto.WebMessageInfo.Status.PLAYED,
|
|
346
|
+
'played-self': index_js_1.proto.WebMessageInfo.Status.PLAYED,
|
|
356
347
|
read: index_js_1.proto.WebMessageInfo.Status.READ,
|
|
357
348
|
'read-self': index_js_1.proto.WebMessageInfo.Status.READ
|
|
358
349
|
}
|
|
359
|
-
|
|
360
|
-
* Given a type of receipt, returns what the new status of the message should be
|
|
361
|
-
* @param type type from receipt
|
|
362
|
-
*/
|
|
350
|
+
|
|
363
351
|
const getStatusFromReceiptType = type => {
|
|
364
352
|
const status = STATUS_MAP[type]
|
|
365
353
|
if (typeof type === 'undefined') {
|
|
@@ -371,10 +359,7 @@ exports.getStatusFromReceiptType = getStatusFromReceiptType
|
|
|
371
359
|
const CODE_MAP = {
|
|
372
360
|
conflict: Types_1.DisconnectReason.connectionReplaced
|
|
373
361
|
}
|
|
374
|
-
|
|
375
|
-
* Stream errors generally provide a reason, map that to a baileys DisconnectReason
|
|
376
|
-
* @param reason the string reason given, eg. "conflict"
|
|
377
|
-
*/
|
|
362
|
+
|
|
378
363
|
const getErrorCodeFromStreamError = node => {
|
|
379
364
|
const [reasonNode] = (0, WABinary_1.getAllBinaryNodeChildren)(node)
|
|
380
365
|
let reason = reasonNode?.tag || 'unknown'
|
|
@@ -396,11 +381,31 @@ const getCallStatusFromNode = ({ tag, attrs }) => {
|
|
|
396
381
|
status = 'offer'
|
|
397
382
|
break
|
|
398
383
|
case 'terminate':
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
384
|
+
|
|
385
|
+
switch (attrs.reason) {
|
|
386
|
+
case 'timeout':
|
|
387
|
+
case 'Timeout':
|
|
388
|
+
status = 'timeout'
|
|
389
|
+
break
|
|
390
|
+
case 'RejectDoNotDisturb':
|
|
391
|
+
status = 'reject_do_not_disturb'
|
|
392
|
+
break
|
|
393
|
+
case 'MicPermissionDenied':
|
|
394
|
+
status = 'mic_permission_denied'
|
|
395
|
+
break
|
|
396
|
+
case 'CameraPermissionDenied':
|
|
397
|
+
status = 'camera_permission_denied'
|
|
398
|
+
break
|
|
399
|
+
case 'RemoteBusy':
|
|
400
|
+
status = 'remote_busy'
|
|
401
|
+
break
|
|
402
|
+
case 'RemoteOffline':
|
|
403
|
+
status = 'remote_offline'
|
|
404
|
+
break
|
|
405
|
+
default:
|
|
406
|
+
|
|
407
|
+
status = 'terminate'
|
|
408
|
+
break
|
|
404
409
|
}
|
|
405
410
|
break
|
|
406
411
|
case 'reject':
|
|
@@ -409,6 +414,76 @@ const getCallStatusFromNode = ({ tag, attrs }) => {
|
|
|
409
414
|
case 'accept':
|
|
410
415
|
status = 'accept'
|
|
411
416
|
break
|
|
417
|
+
case 'preaccept':
|
|
418
|
+
status = 'preaccept'
|
|
419
|
+
break
|
|
420
|
+
case 'accept_ack':
|
|
421
|
+
status = 'accept_ack'
|
|
422
|
+
break
|
|
423
|
+
case 'enc-rekey':
|
|
424
|
+
case 'enc_rekey':
|
|
425
|
+
status = 'enc_rekey'
|
|
426
|
+
break
|
|
427
|
+
case 'peer_state':
|
|
428
|
+
status = 'peer_state'
|
|
429
|
+
break
|
|
430
|
+
case 'group_info':
|
|
431
|
+
status = 'group_info'
|
|
432
|
+
break
|
|
433
|
+
case 'video_state':
|
|
434
|
+
status = 'video_state'
|
|
435
|
+
break
|
|
436
|
+
case 'video_state_ack':
|
|
437
|
+
status = 'video_state_ack'
|
|
438
|
+
break
|
|
439
|
+
case 'flow_control':
|
|
440
|
+
status = 'flow_control'
|
|
441
|
+
break
|
|
442
|
+
case 'relaylatency':
|
|
443
|
+
status = 'relaylatency'
|
|
444
|
+
break
|
|
445
|
+
case 'mute_v2':
|
|
446
|
+
status = 'mute'
|
|
447
|
+
break
|
|
448
|
+
case 'waiting_room_request':
|
|
449
|
+
status = 'waiting_room_request'
|
|
450
|
+
break
|
|
451
|
+
case 'signal':
|
|
452
|
+
|
|
453
|
+
switch (attrs.type) {
|
|
454
|
+
case '13':
|
|
455
|
+
status = 'preaccept'
|
|
456
|
+
break
|
|
457
|
+
case '15':
|
|
458
|
+
status = 'video_state'
|
|
459
|
+
break
|
|
460
|
+
case '17':
|
|
461
|
+
status = 'group_info'
|
|
462
|
+
break
|
|
463
|
+
case '20':
|
|
464
|
+
status = 'video_state_ack'
|
|
465
|
+
break
|
|
466
|
+
case '21':
|
|
467
|
+
status = 'flow_control'
|
|
468
|
+
break
|
|
469
|
+
case '23':
|
|
470
|
+
status = 'accept_ack'
|
|
471
|
+
break
|
|
472
|
+
case '1002':
|
|
473
|
+
case '1007':
|
|
474
|
+
status = 'peer_state'
|
|
475
|
+
break
|
|
476
|
+
case '1008':
|
|
477
|
+
status = 'enc_rekey'
|
|
478
|
+
break
|
|
479
|
+
case '12':
|
|
480
|
+
status = 'mute'
|
|
481
|
+
break
|
|
482
|
+
default:
|
|
483
|
+
status = 'ringing'
|
|
484
|
+
break
|
|
485
|
+
}
|
|
486
|
+
break
|
|
412
487
|
default:
|
|
413
488
|
status = 'ringing'
|
|
414
489
|
break
|
|
@@ -425,25 +500,22 @@ const getCodeFromWSError = error => {
|
|
|
425
500
|
statusCode = code
|
|
426
501
|
}
|
|
427
502
|
} else if (
|
|
428
|
-
|
|
503
|
+
|
|
429
504
|
error?.code?.startsWith('E') ||
|
|
430
505
|
error?.message?.includes('timed out')
|
|
431
506
|
) {
|
|
432
|
-
|
|
507
|
+
|
|
433
508
|
statusCode = 408
|
|
434
509
|
}
|
|
435
510
|
return statusCode
|
|
436
511
|
}
|
|
437
512
|
exports.getCodeFromWSError = getCodeFromWSError
|
|
438
|
-
|
|
439
|
-
* Is the given platform WA business
|
|
440
|
-
* @param platform AuthenticationCreds.platform
|
|
441
|
-
*/
|
|
513
|
+
|
|
442
514
|
const isWABusinessPlatform = platform => {
|
|
443
515
|
return platform === 'smbi' || platform === 'smba'
|
|
444
516
|
}
|
|
445
517
|
exports.isWABusinessPlatform = isWABusinessPlatform
|
|
446
|
-
|
|
518
|
+
|
|
447
519
|
function trimUndefined(obj) {
|
|
448
520
|
for (const key in obj) {
|
|
449
521
|
if (typeof obj[key] === 'undefined') {
|
|
@@ -474,51 +546,40 @@ function encodeNewsletterMessage(message) {
|
|
|
474
546
|
return index_js_1.proto.Message.encode(message).finish()
|
|
475
547
|
}
|
|
476
548
|
|
|
477
|
-
|
|
478
|
-
* Add human-like jitter to a base delay
|
|
479
|
-
* @param baseMs base delay in milliseconds
|
|
480
|
-
* @param varianceFraction fraction of baseMs to use as variance (0–1), default 0.3
|
|
481
|
-
*/
|
|
549
|
+
|
|
482
550
|
const jitterDelay = (baseMs, varianceFraction = 0.3) => {
|
|
483
551
|
const variance = baseMs * varianceFraction
|
|
484
552
|
return baseMs + (Math.random() * 2 - 1) * variance
|
|
485
553
|
}
|
|
486
554
|
exports.jitterDelay = jitterDelay
|
|
487
555
|
|
|
488
|
-
|
|
489
|
-
* Compute exponential backoff delay for a given attempt number (0-based)
|
|
490
|
-
* @param attempt attempt index (0 = first retry)
|
|
491
|
-
* @param baseMs starting delay in ms (default 500)
|
|
492
|
-
* @param maxMs maximum delay cap in ms (default 30000)
|
|
493
|
-
*/
|
|
556
|
+
|
|
494
557
|
const exponentialBackoff = (attempt, baseMs = 500, maxMs = 30000) => {
|
|
495
558
|
return Math.min(baseMs * Math.pow(2, attempt), maxMs)
|
|
496
559
|
}
|
|
497
560
|
exports.exponentialBackoff = exponentialBackoff
|
|
498
561
|
|
|
499
|
-
|
|
562
|
+
|
|
500
563
|
const bytesToHex = buf => Buffer.from(buf).toString('hex')
|
|
501
564
|
exports.bytesToHex = bytesToHex
|
|
502
565
|
|
|
503
|
-
|
|
566
|
+
|
|
504
567
|
const hexToBytes = hex => Buffer.from(hex, 'hex')
|
|
505
568
|
exports.hexToBytes = hexToBytes
|
|
506
569
|
|
|
507
|
-
|
|
570
|
+
|
|
508
571
|
const bytesToBase64Url = buf => Buffer.from(buf).toString('base64url')
|
|
509
572
|
exports.bytesToBase64Url = bytesToBase64Url
|
|
510
573
|
|
|
511
|
-
|
|
574
|
+
|
|
512
575
|
const sha256Hex = data => (0, crypto_1.createHash)('sha256').update(data).digest('hex')
|
|
513
576
|
exports.sha256Hex = sha256Hex
|
|
514
577
|
|
|
515
|
-
|
|
578
|
+
|
|
516
579
|
const hmacSha256 = (data, key) => (0, crypto_1.createHmac)('sha256', key).update(data).digest()
|
|
517
580
|
exports.hmacSha256 = hmacSha256
|
|
518
581
|
|
|
519
|
-
|
|
520
|
-
* Normalize and deduplicate an array of JIDs
|
|
521
|
-
*/
|
|
582
|
+
|
|
522
583
|
const normalizeJidBatch = (jids, normalizer) => {
|
|
523
584
|
const seen = new Set()
|
|
524
585
|
const result = []
|
|
@@ -534,18 +595,11 @@ const normalizeJidBatch = (jids, normalizer) => {
|
|
|
534
595
|
}
|
|
535
596
|
exports.normalizeJidBatch = normalizeJidBatch
|
|
536
597
|
|
|
537
|
-
|
|
538
|
-
* Sleep for a given number of milliseconds, returns a cancellable promise
|
|
539
|
-
*/
|
|
598
|
+
|
|
540
599
|
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
|
|
541
600
|
exports.sleep = sleep
|
|
542
601
|
|
|
543
|
-
|
|
544
|
-
* Run an async function with retry using exponential backoff
|
|
545
|
-
* @param fn async function to retry
|
|
546
|
-
* @param maxAttempts maximum number of attempts
|
|
547
|
-
* @param baseDelayMs base delay between retries
|
|
548
|
-
*/
|
|
602
|
+
|
|
549
603
|
const withRetry = async (fn, maxAttempts = 3, baseDelayMs = 500) => {
|
|
550
604
|
let lastErr
|
|
551
605
|
for (let i = 0; i < maxAttempts; i++) {
|
|
@@ -4,13 +4,7 @@ exports.processGroupHistory = exports.decodeGroupHistory = void 0
|
|
|
4
4
|
const zlib_1 = require('zlib')
|
|
5
5
|
const index_js_1 = require('../../WAProto/index.js')
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
* Decode a GroupHistory protobuf blob (community/group history container).
|
|
9
|
-
* @param buffer raw bytes, optionally zlib-compressed
|
|
10
|
-
* @param options.inflate try zlib.inflateSync first, falling back to raw bytes (default true)
|
|
11
|
-
* @param options.withMessageBytes decode the GroupHistoryWithMessageBytes variant,
|
|
12
|
-
* expanding each entry's messageBytes into a WebMessageInfo (default false)
|
|
13
|
-
*/
|
|
7
|
+
|
|
14
8
|
const decodeGroupHistory = (buffer, options = {}) => {
|
|
15
9
|
const { inflate = true, withMessageBytes = false } = options
|
|
16
10
|
if (!Buffer.isBuffer(buffer) && !(buffer instanceof Uint8Array)) {
|
|
@@ -21,7 +15,7 @@ const decodeGroupHistory = (buffer, options = {}) => {
|
|
|
21
15
|
try {
|
|
22
16
|
data = zlib_1.inflateSync(data)
|
|
23
17
|
} catch {
|
|
24
|
-
|
|
18
|
+
|
|
25
19
|
}
|
|
26
20
|
}
|
|
27
21
|
if (withMessageBytes) {
|
|
@@ -44,10 +38,7 @@ const decodeGroupHistory = (buffer, options = {}) => {
|
|
|
44
38
|
}
|
|
45
39
|
exports.decodeGroupHistory = decodeGroupHistory
|
|
46
40
|
|
|
47
|
-
|
|
48
|
-
* Normalize a decoded GroupHistory into stable message buckets.
|
|
49
|
-
* @param groupHistory a decoded proto.GroupHistory (or the withMessageBytes shape)
|
|
50
|
-
*/
|
|
41
|
+
|
|
51
42
|
const processGroupHistory = groupHistory => {
|
|
52
43
|
const gh = groupHistory || {}
|
|
53
44
|
return {
|
package/lib/Utils/history.js
CHANGED
|
@@ -17,8 +17,8 @@ const inflatePromise = (0, util_1.promisify)(zlib_1.inflate)
|
|
|
17
17
|
const extractPnFromMessages = messages => {
|
|
18
18
|
for (const msgItem of messages) {
|
|
19
19
|
const message = msgItem.message
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
|
|
21
|
+
|
|
22
22
|
if (!message?.key?.fromMe || !message.userReceipt?.length) {
|
|
23
23
|
continue
|
|
24
24
|
}
|
|
@@ -36,7 +36,7 @@ const downloadHistory = async (msg, options) => {
|
|
|
36
36
|
bufferArray.push(chunk)
|
|
37
37
|
}
|
|
38
38
|
let buffer = Buffer.concat(bufferArray)
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
buffer = await inflatePromise(buffer)
|
|
41
41
|
const syncData = index_js_1.proto.HistorySync.decode(buffer)
|
|
42
42
|
return syncData
|
|
@@ -53,13 +53,13 @@ const processHistoryMessage = (item, logger) => {
|
|
|
53
53
|
let globalSettings = undefined
|
|
54
54
|
let statusV3Messages = undefined
|
|
55
55
|
logger?.trace({ progress: item.progress }, 'processing history of type ' + item.syncType?.toString())
|
|
56
|
-
|
|
56
|
+
|
|
57
57
|
for (const m of item.phoneNumberToLidMappings || []) {
|
|
58
58
|
if (m.lidJid && m.pnJid) {
|
|
59
59
|
lidPnMappings.push({ lid: m.lidJid, pn: m.pnJid })
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
-
|
|
62
|
+
|
|
63
63
|
for (const c of item.inlineContacts || []) {
|
|
64
64
|
if (c.lidJid && c.pnJid) {
|
|
65
65
|
lidPnMappings.push({ lid: c.lidJid, pn: c.pnJid })
|
|
@@ -77,7 +77,7 @@ const processHistoryMessage = (item, logger) => {
|
|
|
77
77
|
})
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
-
|
|
80
|
+
|
|
81
81
|
for (const rec of item.callLogRecords || []) {
|
|
82
82
|
callLogRecords.push({
|
|
83
83
|
...rec,
|
|
@@ -89,7 +89,7 @@ const processHistoryMessage = (item, logger) => {
|
|
|
89
89
|
timestamp: rec.startTime ? (0, generics_1.toNumber)(rec.startTime) : undefined
|
|
90
90
|
})
|
|
91
91
|
}
|
|
92
|
-
|
|
92
|
+
|
|
93
93
|
const stickerKeys = new Set()
|
|
94
94
|
for (const s of item.recentStickers || []) {
|
|
95
95
|
const stickerKey = s.fileSha256 ? Buffer.from(s.fileSha256).toString('base64') : undefined
|
|
@@ -103,12 +103,12 @@ const processHistoryMessage = (item, logger) => {
|
|
|
103
103
|
case index_js_1.proto.HistorySync.HistorySyncType.RECENT:
|
|
104
104
|
case index_js_1.proto.HistorySync.HistorySyncType.FULL:
|
|
105
105
|
case index_js_1.proto.HistorySync.HistorySyncType.ON_DEMAND:
|
|
106
|
-
|
|
106
|
+
|
|
107
107
|
if (item.globalSettings) {
|
|
108
108
|
const gs = item.globalSettings
|
|
109
109
|
globalSettings = {
|
|
110
110
|
...gs,
|
|
111
|
-
|
|
111
|
+
|
|
112
112
|
autoDownloadSettings: {
|
|
113
113
|
photos: gs.autoDownloadPhotos,
|
|
114
114
|
audio: gs.autoDownloadAudio,
|
|
@@ -139,7 +139,7 @@ const processHistoryMessage = (item, logger) => {
|
|
|
139
139
|
: undefined
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
|
-
|
|
142
|
+
|
|
143
143
|
if (item.statusV3Messages?.length) {
|
|
144
144
|
const now = Math.floor(Date.now() / 1000)
|
|
145
145
|
statusV3Messages = item.statusV3Messages.filter(s => {
|
|
@@ -165,7 +165,7 @@ const processHistoryMessage = (item, logger) => {
|
|
|
165
165
|
} else if (isPn && chat.lidJid) {
|
|
166
166
|
lidPnMappings.push({ lid: chat.lidJid, pn: chatId })
|
|
167
167
|
} else if (isLid && !chat.pnJid) {
|
|
168
|
-
|
|
168
|
+
|
|
169
169
|
const pnFromReceipt = extractPnFromMessages(chat.messages || [])
|
|
170
170
|
if (pnFromReceipt) {
|
|
171
171
|
lidPnMappings.push({ lid: chatId, pn: pnFromReceipt })
|
|
@@ -177,7 +177,7 @@ const processHistoryMessage = (item, logger) => {
|
|
|
177
177
|
const message = item.message
|
|
178
178
|
messages.push(message)
|
|
179
179
|
if (!chat.messages?.length) {
|
|
180
|
-
|
|
180
|
+
|
|
181
181
|
chat.messages = [{ message }]
|
|
182
182
|
}
|
|
183
183
|
if (!message.key.fromMe && !chat.lastMessageRecvTimestamp) {
|
|
@@ -194,13 +194,13 @@ const processHistoryMessage = (item, logger) => {
|
|
|
194
194
|
})
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
|
-
|
|
197
|
+
|
|
198
198
|
if (chat.id && (0, WABinary_1.isJidGroup)(chat.id)) {
|
|
199
|
-
|
|
199
|
+
|
|
200
200
|
}
|
|
201
201
|
chats.push({ ...chat })
|
|
202
202
|
}
|
|
203
|
-
|
|
203
|
+
|
|
204
204
|
for (const pp of item.pastParticipants || []) {
|
|
205
205
|
pastParticipants.push(pp)
|
|
206
206
|
}
|
package/lib/Utils/index.js
CHANGED
|
@@ -28,6 +28,7 @@ var __exportStar =
|
|
|
28
28
|
Object.defineProperty(exports, '__esModule', { value: true })
|
|
29
29
|
__exportStar(require('./generics'), exports)
|
|
30
30
|
__exportStar(require('./decode-wa-message'), exports)
|
|
31
|
+
__exportStar(require('./message-inspect'), exports)
|
|
31
32
|
__exportStar(require('./messages'), exports)
|
|
32
33
|
__exportStar(require('./messages-media'), exports)
|
|
33
34
|
__exportStar(require('./validate-connection'), exports)
|
|
@@ -50,8 +51,3 @@ __exportStar(require('./message-composer'), exports)
|
|
|
50
51
|
__exportStar(require('./group-history'), exports)
|
|
51
52
|
__exportStar(require('./consumer-application'), exports)
|
|
52
53
|
__exportStar(require('./voip-rekey'), exports)
|
|
53
|
-
__exportStar(require('./companion-reg-client-utils'), exports)
|
|
54
|
-
__exportStar(require('./view-once-cache'), exports)
|
|
55
|
-
__exportStar(require('./sticker'), exports)
|
|
56
|
-
__exportStar(require('./command-loader'), exports)
|
|
57
|
-
__exportStar(require('./session-pool'), exports)
|
|
@@ -55,18 +55,13 @@ exports.getUrlInfo = void 0
|
|
|
55
55
|
const messages_1 = require('./messages')
|
|
56
56
|
const messages_media_1 = require('./messages-media')
|
|
57
57
|
const THUMBNAIL_WIDTH_PX = 192
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
const getCompressedJpegThumbnail = async (url, { thumbnailWidth, fetchOpts }) => {
|
|
60
60
|
const stream = await (0, messages_media_1.getHttpStream)(url, fetchOpts)
|
|
61
61
|
const result = await (0, messages_media_1.extractImageThumb)(stream, thumbnailWidth)
|
|
62
62
|
return result
|
|
63
63
|
}
|
|
64
|
-
|
|
65
|
-
* Given a piece of text, checks for any URL present, generates link preview for the same and returns it
|
|
66
|
-
* Return undefined if the fetch failed or no URL was found
|
|
67
|
-
* @param text first matched URL in text
|
|
68
|
-
* @returns the URL info required to generate link preview
|
|
69
|
-
*/
|
|
64
|
+
|
|
70
65
|
const getUrlInfo = async (
|
|
71
66
|
text,
|
|
72
67
|
opts = {
|
|
@@ -75,7 +70,7 @@ const getUrlInfo = async (
|
|
|
75
70
|
}
|
|
76
71
|
) => {
|
|
77
72
|
try {
|
|
78
|
-
|
|
73
|
+
|
|
79
74
|
const retries = 0
|
|
80
75
|
const maxRetry = 5
|
|
81
76
|
const { getLinkPreview } = await Promise.resolve().then(() => __importStar(require('link-preview-js')))
|
package/lib/Utils/lt-hash.js
CHANGED
|
@@ -1,39 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
Object.defineProperty(exports, '__esModule', { value: true })
|
|
3
3
|
exports.LT_HASH_ANTI_TAMPERING = void 0
|
|
4
|
-
const
|
|
4
|
+
const whatsapp_rust_bridge_1 = require('whatsapp-rust-bridge')
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
* LT Hash ("lthash16") is a summation-based homomorphic hash algorithm that
|
|
8
|
-
* maintains the integrity of a piece of data over a series of mutations. You
|
|
9
|
-
* can add/remove mutations and it'll return a hash equal to if the same
|
|
10
|
-
* series of mutations was made sequentially.
|
|
11
|
-
*
|
|
12
|
-
* WhatsApp expands each element to 128 bytes via HKDF (info = "WhatsApp Patch
|
|
13
|
-
* Integrity"), treats that as 64 little-endian uint16 lanes, and combines
|
|
14
|
-
* elements by adding/subtracting lane-wise mod 2^16 -- this is a pure HKDF +
|
|
15
|
-
* integer-arithmetic algorithm, no elliptic-curve math involved. Pure-JS,
|
|
16
|
-
* built on the already-validated `hkdf` implementation.
|
|
17
|
-
*/
|
|
18
|
-
const LTHASH_INFO = 'WhatsApp Patch Integrity'
|
|
19
|
-
const LTHASH_SIZE = 128 // bytes = 64 uint16 lanes
|
|
20
|
-
|
|
21
|
-
const expand = element => (0, crypto_1.hkdf)(element, LTHASH_SIZE, { info: LTHASH_INFO })
|
|
22
|
-
|
|
23
|
-
const applyDelta = (result, element, sign) => {
|
|
24
|
-
const expanded = expand(element)
|
|
25
|
-
for (let i = 0; i < LTHASH_SIZE; i += 2) {
|
|
26
|
-
const lane = result.readUInt16LE(i)
|
|
27
|
-
const delta = expanded.readUInt16LE(i)
|
|
28
|
-
result.writeUInt16LE((lane + sign * delta) & 0xffff, i)
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
exports.LT_HASH_ANTI_TAMPERING = {
|
|
33
|
-
subtractThenAdd: (base, subtract = [], add = []) => {
|
|
34
|
-
const result = Buffer.from(base)
|
|
35
|
-
for (const element of subtract) applyDelta(result, element, -1)
|
|
36
|
-
for (const element of add) applyDelta(result, element, 1)
|
|
37
|
-
return result
|
|
38
|
-
}
|
|
39
|
-
}
|
|
6
|
+
exports.LT_HASH_ANTI_TAMPERING = new whatsapp_rust_bridge_1.LTHashAntiTampering()
|