@bellaxchuu/flowred 0.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +214 -0
  3. package/WAProto/GenerateStatics.sh +3 -0
  4. package/WAProto/WAProto.proto +6902 -0
  5. package/WAProto/fix-imports.js +85 -0
  6. package/WAProto/index.js +242946 -0
  7. package/engine-requirements.js +10 -0
  8. package/lib/Defaults/index.js +190 -0
  9. package/lib/Defaults/phonenumber-mcc.json +223 -0
  10. package/lib/Signal/Group/ciphertext-message.js +15 -0
  11. package/lib/Signal/Group/group-session-builder.js +92 -0
  12. package/lib/Signal/Group/group_cipher.js +89 -0
  13. package/lib/Signal/Group/index.js +136 -0
  14. package/lib/Signal/Group/keyhelper.js +73 -0
  15. package/lib/Signal/Group/sender-chain-key.js +32 -0
  16. package/lib/Signal/Group/sender-key-distribution-message.js +66 -0
  17. package/lib/Signal/Group/sender-key-message.js +69 -0
  18. package/lib/Signal/Group/sender-key-name.js +50 -0
  19. package/lib/Signal/Group/sender-key-record.js +44 -0
  20. package/lib/Signal/Group/sender-key-state.js +97 -0
  21. package/lib/Signal/Group/sender-message-key.js +30 -0
  22. package/lib/Signal/libsignal.js +490 -0
  23. package/lib/Signal/lid-mapping.js +262 -0
  24. package/lib/Socket/Client/index.js +30 -0
  25. package/lib/Socket/Client/types.js +13 -0
  26. package/lib/Socket/Client/websocket.js +62 -0
  27. package/lib/Socket/aigroups.js +240 -0
  28. package/lib/Socket/business.js +422 -0
  29. package/lib/Socket/chats.js +1816 -0
  30. package/lib/Socket/communities.js +549 -0
  31. package/lib/Socket/graphql.js +656 -0
  32. package/lib/Socket/groups.js +764 -0
  33. package/lib/Socket/index.js +39 -0
  34. package/lib/Socket/interactive-handler.js +522 -0
  35. package/lib/Socket/interop.js +549 -0
  36. package/lib/Socket/luxu.js +387 -0
  37. package/lib/Socket/managed-account.js +183 -0
  38. package/lib/Socket/messages-recv.js +2440 -0
  39. package/lib/Socket/messages-send.js +1853 -0
  40. package/lib/Socket/mex.js +60 -0
  41. package/lib/Socket/newsletter.js +820 -0
  42. package/lib/Socket/privacy.js +449 -0
  43. package/lib/Socket/registration.js +427 -0
  44. package/lib/Socket/socket.js +1092 -0
  45. package/lib/Socket/text-router.js +83 -0
  46. package/lib/Socket/username.js +243 -0
  47. package/lib/Store/index.js +36 -0
  48. package/lib/Store/keyed-db.js +108 -0
  49. package/lib/Store/make-cache-manager-store.js +90 -0
  50. package/lib/Store/make-in-memory-store.js +604 -0
  51. package/lib/Store/make-ordered-dictionary.js +81 -0
  52. package/lib/Store/object-repository.js +29 -0
  53. package/lib/Types/Auth.js +38 -0
  54. package/lib/Types/Bussines.js +2 -0
  55. package/lib/Types/Call.js +2 -0
  56. package/lib/Types/Chat.js +4 -0
  57. package/lib/Types/Contact.js +2 -0
  58. package/lib/Types/Events.js +2 -0
  59. package/lib/Types/GroupMetadata.js +2 -0
  60. package/lib/Types/Label.js +27 -0
  61. package/lib/Types/LabelAssociation.js +9 -0
  62. package/lib/Types/Message.js +95 -0
  63. package/lib/Types/Mex.js +112 -0
  64. package/lib/Types/Newsletter.js +121 -0
  65. package/lib/Types/Product.js +2 -0
  66. package/lib/Types/Signal.js +2 -0
  67. package/lib/Types/Socket.js +2 -0
  68. package/lib/Types/State.js +70 -0
  69. package/lib/Types/USync.js +2 -0
  70. package/lib/Types/index.js +55 -0
  71. package/lib/Utils/auth-utils.js +306 -0
  72. package/lib/Utils/browser-utils.js +114 -0
  73. package/lib/Utils/business.js +247 -0
  74. package/lib/Utils/chat-utils.js +1208 -0
  75. package/lib/Utils/command-loader.js +100 -0
  76. package/lib/Utils/companion-reg-client-utils.js +42 -0
  77. package/lib/Utils/consumer-application.js +107 -0
  78. package/lib/Utils/crypto.js +155 -0
  79. package/lib/Utils/curve25519-js.js +275 -0
  80. package/lib/Utils/decode-wa-message.js +560 -0
  81. package/lib/Utils/event-buffer.js +607 -0
  82. package/lib/Utils/generics.js +563 -0
  83. package/lib/Utils/group-history.js +60 -0
  84. package/lib/Utils/history.js +244 -0
  85. package/lib/Utils/identity-change-handler.js +52 -0
  86. package/lib/Utils/index.js +57 -0
  87. package/lib/Utils/jid-display-normalization.js +218 -0
  88. package/lib/Utils/link-preview.js +143 -0
  89. package/lib/Utils/logger.js +9 -0
  90. package/lib/Utils/lt-hash.js +39 -0
  91. package/lib/Utils/make-mutex.js +36 -0
  92. package/lib/Utils/message-composer.js +479 -0
  93. package/lib/Utils/message-retry-manager.js +270 -0
  94. package/lib/Utils/messages-media.js +896 -0
  95. package/lib/Utils/messages.js +2904 -0
  96. package/lib/Utils/meta-ai-msmsg.js +262 -0
  97. package/lib/Utils/native-bridge.js +82 -0
  98. package/lib/Utils/noise-handler.js +196 -0
  99. package/lib/Utils/offline-node-processor.js +42 -0
  100. package/lib/Utils/pre-key-manager.js +107 -0
  101. package/lib/Utils/process-message.js +1048 -0
  102. package/lib/Utils/reporting-utils.js +262 -0
  103. package/lib/Utils/session-pool.js +94 -0
  104. package/lib/Utils/signal.js +224 -0
  105. package/lib/Utils/stanza-ack.js +40 -0
  106. package/lib/Utils/sticker.js +145 -0
  107. package/lib/Utils/sync-action-utils.js +54 -0
  108. package/lib/Utils/tc-token-utils.js +161 -0
  109. package/lib/Utils/use-multi-file-auth-state.js +121 -0
  110. package/lib/Utils/validate-connection.js +219 -0
  111. package/lib/Utils/view-once-cache.js +79 -0
  112. package/lib/Utils/voip-rekey.js +22 -0
  113. package/lib/WABinary/constants.js +1304 -0
  114. package/lib/WABinary/decode.js +343 -0
  115. package/lib/WABinary/encode.js +228 -0
  116. package/lib/WABinary/generic-utils.js +240 -0
  117. package/lib/WABinary/index.js +33 -0
  118. package/lib/WABinary/jid-utils.js +361 -0
  119. package/lib/WABinary/types.js +2 -0
  120. package/lib/WAM/BinaryInfo.js +13 -0
  121. package/lib/WAM/constants.js +39486 -0
  122. package/lib/WAM/encode.js +142 -0
  123. package/lib/WAM/index.js +31 -0
  124. package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +55 -0
  125. package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +43 -0
  126. package/lib/WAUSync/Protocols/USyncContactProtocol.js +54 -0
  127. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +57 -0
  128. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +30 -0
  129. package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +59 -0
  130. package/lib/WAUSync/Protocols/USyncLIDProtocol.js +31 -0
  131. package/lib/WAUSync/Protocols/USyncPictureProtocol.js +32 -0
  132. package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +29 -0
  133. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +39 -0
  134. package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +38 -0
  135. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +27 -0
  136. package/lib/WAUSync/Protocols/index.js +39 -0
  137. package/lib/WAUSync/USyncQuery.js +133 -0
  138. package/lib/WAUSync/USyncUser.js +50 -0
  139. package/lib/WAUSync/index.js +31 -0
  140. package/lib/antiban.js +4637 -0
  141. package/lib/index.js +45 -0
  142. package/package.json +107 -0
@@ -0,0 +1,563 @@
1
+ 'use strict'
2
+ Object.defineProperty(exports, '__esModule', { value: true })
3
+ exports.isWABusinessPlatform =
4
+ exports.getCodeFromWSError =
5
+ exports.getCallStatusFromNode =
6
+ exports.getErrorCodeFromStreamError =
7
+ exports.getStatusFromReceiptType =
8
+ exports.generateMdTagPrefix =
9
+ exports.fetchLatestWaWebVersion =
10
+ exports.fetchLatestBaileysVersion =
11
+ exports.bindWaitForConnectionUpdate =
12
+ exports.generateMessageID =
13
+ exports.generateMessageIDV2 =
14
+ exports.delayCancellable =
15
+ exports.delay =
16
+ exports.debouncedTimeout =
17
+ exports.unixTimestampSeconds =
18
+ exports.toNumber =
19
+ exports.encodeBigEndian =
20
+ exports.generateRegistrationId =
21
+ exports.encodeWAMessage =
22
+ exports.generateParticipantHashV2 =
23
+ exports.unpadRandomMax16 =
24
+ exports.writeRandomPadMax16 =
25
+ exports.isStringNullOrEmpty =
26
+ exports.getKeyAuthor =
27
+ exports.BufferJSON =
28
+ exports.jitterDelay =
29
+ exports.exponentialBackoff =
30
+ exports.bytesToHex =
31
+ exports.hexToBytes =
32
+ exports.bytesToBase64Url =
33
+ exports.sha256Hex =
34
+ exports.hmacSha256 =
35
+ exports.normalizeJidBatch =
36
+ exports.sleep =
37
+ exports.withRetry =
38
+ void 0
39
+ exports.promiseTimeout = promiseTimeout
40
+ exports.bindWaitForEvent = bindWaitForEvent
41
+ exports.trimUndefined = trimUndefined
42
+ exports.bytesToCrockford = bytesToCrockford
43
+ exports.encodeNewsletterMessage = encodeNewsletterMessage
44
+ exports.generateIOSMessageID = void 0
45
+ exports.generateAndroMessageID = void 0
46
+ const boom_1 = require('@hapi/boom')
47
+ const crypto_1 = require('crypto')
48
+ const Crypto_1 = require('./crypto')
49
+ const DEFAULTS_1 = require('../Defaults')
50
+ const index_js_1 = require('../../WAProto/index.js')
51
+ const baileysVersion = DEFAULTS_1.VERSION
52
+ const Types_1 = require('../Types')
53
+ const WABinary_1 = require('../WABinary')
54
+ const crypto_2 = require('./crypto')
55
+ exports.BufferJSON = {
56
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
+ replacer: (k, value) => {
58
+ if (Buffer.isBuffer(value) || value instanceof Uint8Array || value?.type === 'Buffer') {
59
+ return { type: 'Buffer', data: Buffer.from(value?.data || value).toString('base64') }
60
+ }
61
+ return value
62
+ },
63
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
64
+ reviver: (_, value) => {
65
+ if (typeof value === 'object' && value !== null && value.type === 'Buffer' && typeof value.data === 'string') {
66
+ return Buffer.from(value.data, 'base64')
67
+ }
68
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
69
+ const keys = Object.keys(value)
70
+ if (keys.length > 0 && keys.every(k => !isNaN(parseInt(k, 10)))) {
71
+ const values = Object.values(value)
72
+ if (values.every(v => typeof v === 'number')) {
73
+ return Buffer.from(values)
74
+ }
75
+ }
76
+ }
77
+ return value
78
+ }
79
+ }
80
+ const getKeyAuthor = (key, meId = 'me') =>
81
+ (key?.fromMe ? meId : key?.participantAlt || key?.remoteJidAlt || key?.participant || key?.remoteJid) || ''
82
+ exports.getKeyAuthor = getKeyAuthor
83
+ const isStringNullOrEmpty = value =>
84
+ // eslint-disable-next-line eqeqeq
85
+ value == null || value === ''
86
+ exports.isStringNullOrEmpty = isStringNullOrEmpty
87
+ const writeRandomPadMax16 = msg => {
88
+ const pad = (0, crypto_1.randomBytes)(1)
89
+ const padLength = (pad[0] & 0x0f) + 1
90
+ return Buffer.concat([msg, Buffer.alloc(padLength, padLength)])
91
+ }
92
+ exports.writeRandomPadMax16 = writeRandomPadMax16
93
+ const unpadRandomMax16 = e => {
94
+ const t = new Uint8Array(e)
95
+ if (0 === t.length) {
96
+ throw new Error('unpadPkcs7 given empty bytes')
97
+ }
98
+ var r = t[t.length - 1]
99
+ if (r > t.length) {
100
+ throw new Error(`unpad given ${t.length} bytes, but pad is ${r}`)
101
+ }
102
+ return new Uint8Array(t.buffer, t.byteOffset, t.length - r)
103
+ }
104
+ exports.unpadRandomMax16 = unpadRandomMax16
105
+ // code is inspired by whatsmeow
106
+ const generateParticipantHashV2 = participants => {
107
+ participants.sort()
108
+ const sha256Hash = (0, crypto_2.sha256)(Buffer.from(participants.join(''))).toString('base64')
109
+ return '2:' + sha256Hash.slice(0, 6)
110
+ }
111
+ exports.generateParticipantHashV2 = generateParticipantHashV2
112
+ const encodeWAMessage = message => (0, exports.writeRandomPadMax16)(index_js_1.proto.Message.encode(message).finish())
113
+ exports.encodeWAMessage = encodeWAMessage
114
+ const generateRegistrationId = () => {
115
+ return Uint16Array.from((0, crypto_1.randomBytes)(2))[0] & 16383
116
+ }
117
+ exports.generateRegistrationId = generateRegistrationId
118
+ const encodeBigEndian = (e, t = 4) => {
119
+ let r = e
120
+ const a = new Uint8Array(t)
121
+ for (let i = t - 1; i >= 0; i--) {
122
+ a[i] = 255 & r
123
+ r >>>= 8
124
+ }
125
+ return a
126
+ }
127
+ exports.encodeBigEndian = encodeBigEndian
128
+ const toNumber = t => (typeof t === 'object' && t ? ('toNumber' in t ? t.toNumber() : t.low) : t || 0)
129
+ exports.toNumber = toNumber
130
+ /** unix timestamp of a date in seconds */
131
+ const unixTimestampSeconds = (date = new Date()) => Math.floor(date.getTime() / 1000)
132
+ exports.unixTimestampSeconds = unixTimestampSeconds
133
+ const debouncedTimeout = (intervalMs = 1000, task) => {
134
+ let timeout
135
+ return {
136
+ start: (newIntervalMs, newTask) => {
137
+ task = newTask || task
138
+ intervalMs = newIntervalMs || intervalMs
139
+ timeout && clearTimeout(timeout)
140
+ timeout = setTimeout(() => task?.(), intervalMs)
141
+ },
142
+ cancel: () => {
143
+ timeout && clearTimeout(timeout)
144
+ timeout = undefined
145
+ },
146
+ setTask: newTask => (task = newTask),
147
+ setInterval: newInterval => (intervalMs = newInterval)
148
+ }
149
+ }
150
+ exports.debouncedTimeout = debouncedTimeout
151
+ const delay = ms => (0, exports.delayCancellable)(ms).delay
152
+ exports.delay = delay
153
+ const delayCancellable = ms => {
154
+ const stack = new Error().stack
155
+ let timeout
156
+ let reject
157
+ const delay = new Promise((resolve, _reject) => {
158
+ timeout = setTimeout(resolve, ms)
159
+ reject = _reject
160
+ })
161
+ const cancel = () => {
162
+ clearTimeout(timeout)
163
+ reject(
164
+ new boom_1.Boom('Cancelled', {
165
+ statusCode: 500,
166
+ data: {
167
+ stack
168
+ }
169
+ })
170
+ )
171
+ }
172
+ return { delay, cancel }
173
+ }
174
+ exports.delayCancellable = delayCancellable
175
+ async function promiseTimeout(ms, promise) {
176
+ if (!ms) {
177
+ return new Promise(promise)
178
+ }
179
+ const stack = new Error().stack
180
+ // Create a promise that rejects in <ms> milliseconds
181
+ const { delay, cancel } = (0, exports.delayCancellable)(ms)
182
+ const p = new Promise((resolve, reject) => {
183
+ delay
184
+ .then(() =>
185
+ reject(
186
+ new boom_1.Boom('Timed Out', {
187
+ statusCode: Types_1.DisconnectReason.timedOut,
188
+ data: {
189
+ stack
190
+ }
191
+ })
192
+ )
193
+ )
194
+ .catch(err => reject(err))
195
+ promise(resolve, reject)
196
+ }).finally(cancel)
197
+ return p
198
+ }
199
+ // inspired from whatsmeow code
200
+ // https://github.com/tulir/whatsmeow/blob/64bc969fbe78d31ae0dd443b8d4c80a5d026d07a/send.go#L42
201
+ const generateMessageIDV2 = (userId) => {
202
+ const data = Buffer.alloc(8 + 20 + 16);
203
+ data.writeBigUInt64BE(BigInt(Math.floor(Date.now() / 1000)));
204
+ if (userId) {
205
+ const id = (0, WABinary_1.jidDecode)(userId);
206
+ if (id?.user) {
207
+ data.write(id.user, 8);
208
+ data.write('@c.us', 8 + id.user.length);
209
+ }
210
+ }
211
+ const random = (0, crypto_1.randomBytes)(16);
212
+ random.copy(data, 28);
213
+ const hash = (0, crypto_1.createHash)('sha256').update(data).digest();
214
+ return 'XZCYYX-' + hash.toString('hex').toUpperCase().substring(0, 18);
215
+ };
216
+ exports.generateMessageIDV2 = generateMessageIDV2
217
+ const generateIOSMessageID = () => {
218
+ const prefix = '3A';
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()
231
+ exports.generateMessageID = generateMessageID
232
+ function bindWaitForEvent(ev, event) {
233
+ return async (check, timeoutMs) => {
234
+ let listener
235
+ let closeListener
236
+ await promiseTimeout(timeoutMs, (resolve, reject) => {
237
+ closeListener = ({ connection, lastDisconnect }) => {
238
+ if (connection === 'close') {
239
+ reject(
240
+ lastDisconnect?.error ||
241
+ new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed })
242
+ )
243
+ }
244
+ }
245
+ ev.on('connection.update', closeListener)
246
+ listener = async update => {
247
+ if (await check(update)) {
248
+ resolve()
249
+ }
250
+ }
251
+ ev.on(event, listener)
252
+ }).finally(() => {
253
+ ev.off(event, listener)
254
+ ev.off('connection.update', closeListener)
255
+ })
256
+ }
257
+ }
258
+ const bindWaitForConnectionUpdate = ev => bindWaitForEvent(ev, 'connection.update')
259
+ 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
+ */
264
+ const fetchLatestBaileysVersion = async (options = {}) => {
265
+ const URL = 'https://raw.githubusercontent.com/WhiskeySockets/Baileys/master/src/Defaults/index.ts'
266
+ try {
267
+ const response = await fetch(URL, {
268
+ dispatcher: options.dispatcher,
269
+ method: 'GET',
270
+ headers: options.headers
271
+ })
272
+ if (!response.ok) {
273
+ throw new boom_1.Boom(`Failed to fetch latest Baileys version: ${response.statusText}`, {
274
+ statusCode: response.status
275
+ })
276
+ }
277
+ const text = await response.text()
278
+ // Extract version from line 7 (const version = [...])
279
+ const lines = text.split('\n')
280
+ const versionLine = lines[6] // Line 7 (0-indexed)
281
+ const versionMatch = versionLine.match(/const version = \[(\d+),\s*(\d+),\s*(\d+)\]/)
282
+ if (versionMatch) {
283
+ const version = [parseInt(versionMatch[1]), parseInt(versionMatch[2]), parseInt(versionMatch[3])]
284
+ return {
285
+ version,
286
+ isLatest: true
287
+ }
288
+ } else {
289
+ throw new Error('Could not parse version from Defaults/index.ts')
290
+ }
291
+ } catch (error) {
292
+ return {
293
+ version: baileysVersion,
294
+ isLatest: false,
295
+ error
296
+ }
297
+ }
298
+ }
299
+ 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
+ */
304
+ const fetchLatestWaWebVersion = async (options = {}) => {
305
+ try {
306
+ // Absolute minimal headers required to bypass anti-bot detection
307
+ const defaultHeaders = {
308
+ 'sec-fetch-site': 'none',
309
+ 'user-agent':
310
+ 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'
311
+ }
312
+ const headers = { ...defaultHeaders, ...options.headers }
313
+ const response = await fetch('https://web.whatsapp.com/sw.js', {
314
+ ...options,
315
+ method: 'GET',
316
+ headers
317
+ })
318
+ if (!response.ok) {
319
+ throw new boom_1.Boom(`Failed to fetch sw.js: ${response.statusText}`, { statusCode: response.status })
320
+ }
321
+ const data = await response.text()
322
+ const regex = /\\?"client_revision\\?":\s*(\d+)/
323
+ const match = data.match(regex)
324
+ if (!match?.[1]) {
325
+ return {
326
+ version: baileysVersion,
327
+ isLatest: false,
328
+ error: {
329
+ message: 'Could not find client revision in the fetched content'
330
+ }
331
+ }
332
+ }
333
+ const clientRevision = match[1]
334
+ return {
335
+ version: [2, 3000, +clientRevision],
336
+ isLatest: true
337
+ }
338
+ } catch (error) {
339
+ return {
340
+ version: baileysVersion,
341
+ isLatest: false,
342
+ error
343
+ }
344
+ }
345
+ }
346
+ exports.fetchLatestWaWebVersion = fetchLatestWaWebVersion
347
+ /** unique message tag prefix for MD clients */
348
+ const generateMdTagPrefix = () => {
349
+ const bytes = (0, crypto_1.randomBytes)(4)
350
+ return `${bytes.readUInt16BE()}.${bytes.readUInt16BE(2)}-`
351
+ }
352
+ exports.generateMdTagPrefix = generateMdTagPrefix
353
+ const STATUS_MAP = {
354
+ sender: index_js_1.proto.WebMessageInfo.Status.SERVER_ACK,
355
+ played: index_js_1.proto.WebMessageInfo.Status.PLAYED,
356
+ read: index_js_1.proto.WebMessageInfo.Status.READ,
357
+ 'read-self': index_js_1.proto.WebMessageInfo.Status.READ
358
+ }
359
+ /**
360
+ * Given a type of receipt, returns what the new status of the message should be
361
+ * @param type type from receipt
362
+ */
363
+ const getStatusFromReceiptType = type => {
364
+ const status = STATUS_MAP[type]
365
+ if (typeof type === 'undefined') {
366
+ return index_js_1.proto.WebMessageInfo.Status.DELIVERY_ACK
367
+ }
368
+ return status
369
+ }
370
+ exports.getStatusFromReceiptType = getStatusFromReceiptType
371
+ const CODE_MAP = {
372
+ conflict: Types_1.DisconnectReason.connectionReplaced
373
+ }
374
+ /**
375
+ * Stream errors generally provide a reason, map that to a baileys DisconnectReason
376
+ * @param reason the string reason given, eg. "conflict"
377
+ */
378
+ const getErrorCodeFromStreamError = node => {
379
+ const [reasonNode] = (0, WABinary_1.getAllBinaryNodeChildren)(node)
380
+ let reason = reasonNode?.tag || 'unknown'
381
+ const statusCode = +(node.attrs.code || CODE_MAP[reason] || Types_1.DisconnectReason.badSession)
382
+ if (statusCode === Types_1.DisconnectReason.restartRequired) {
383
+ reason = 'restart required'
384
+ }
385
+ return {
386
+ reason,
387
+ statusCode
388
+ }
389
+ }
390
+ exports.getErrorCodeFromStreamError = getErrorCodeFromStreamError
391
+ const getCallStatusFromNode = ({ tag, attrs }) => {
392
+ let status
393
+ switch (tag) {
394
+ case 'offer':
395
+ case 'offer_notice':
396
+ status = 'offer'
397
+ break
398
+ case 'terminate':
399
+ if (attrs.reason === 'timeout') {
400
+ status = 'timeout'
401
+ } else {
402
+ //fired when accepted/rejected/timeout/caller hangs up
403
+ status = 'terminate'
404
+ }
405
+ break
406
+ case 'reject':
407
+ status = 'reject'
408
+ break
409
+ case 'accept':
410
+ status = 'accept'
411
+ break
412
+ default:
413
+ status = 'ringing'
414
+ break
415
+ }
416
+ return status
417
+ }
418
+ exports.getCallStatusFromNode = getCallStatusFromNode
419
+ const UNEXPECTED_SERVER_CODE_TEXT = 'Unexpected server response: '
420
+ const getCodeFromWSError = error => {
421
+ let statusCode = 500
422
+ if (error?.message?.includes(UNEXPECTED_SERVER_CODE_TEXT)) {
423
+ const code = +error?.message.slice(UNEXPECTED_SERVER_CODE_TEXT.length)
424
+ if (!Number.isNaN(code) && code >= 400) {
425
+ statusCode = code
426
+ }
427
+ } else if (
428
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
429
+ error?.code?.startsWith('E') ||
430
+ error?.message?.includes('timed out')
431
+ ) {
432
+ // handle ETIMEOUT, ENOTFOUND etc
433
+ statusCode = 408
434
+ }
435
+ return statusCode
436
+ }
437
+ exports.getCodeFromWSError = getCodeFromWSError
438
+ /**
439
+ * Is the given platform WA business
440
+ * @param platform AuthenticationCreds.platform
441
+ */
442
+ const isWABusinessPlatform = platform => {
443
+ return platform === 'smbi' || platform === 'smba'
444
+ }
445
+ exports.isWABusinessPlatform = isWABusinessPlatform
446
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
447
+ function trimUndefined(obj) {
448
+ for (const key in obj) {
449
+ if (typeof obj[key] === 'undefined') {
450
+ delete obj[key]
451
+ }
452
+ }
453
+ return obj
454
+ }
455
+ const CROCKFORD_CHARACTERS = '123456789ABCDEFGHJKLMNPQRSTVWXYZ'
456
+ function bytesToCrockford(buffer) {
457
+ let value = 0
458
+ let bitCount = 0
459
+ const crockford = []
460
+ for (const element of buffer) {
461
+ value = (value << 8) | (element & 0xff)
462
+ bitCount += 8
463
+ while (bitCount >= 5) {
464
+ crockford.push(CROCKFORD_CHARACTERS.charAt((value >>> (bitCount - 5)) & 31))
465
+ bitCount -= 5
466
+ }
467
+ }
468
+ if (bitCount > 0) {
469
+ crockford.push(CROCKFORD_CHARACTERS.charAt((value << (5 - bitCount)) & 31))
470
+ }
471
+ return crockford.join('')
472
+ }
473
+ function encodeNewsletterMessage(message) {
474
+ return index_js_1.proto.Message.encode(message).finish()
475
+ }
476
+
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
+ */
482
+ const jitterDelay = (baseMs, varianceFraction = 0.3) => {
483
+ const variance = baseMs * varianceFraction
484
+ return baseMs + (Math.random() * 2 - 1) * variance
485
+ }
486
+ exports.jitterDelay = jitterDelay
487
+
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
+ */
494
+ const exponentialBackoff = (attempt, baseMs = 500, maxMs = 30000) => {
495
+ return Math.min(baseMs * Math.pow(2, attempt), maxMs)
496
+ }
497
+ exports.exponentialBackoff = exponentialBackoff
498
+
499
+ /** Convert buffer/Uint8Array to hex string */
500
+ const bytesToHex = buf => Buffer.from(buf).toString('hex')
501
+ exports.bytesToHex = bytesToHex
502
+
503
+ /** Convert hex string to Buffer */
504
+ const hexToBytes = hex => Buffer.from(hex, 'hex')
505
+ exports.hexToBytes = hexToBytes
506
+
507
+ /** Convert buffer to base64url string */
508
+ const bytesToBase64Url = buf => Buffer.from(buf).toString('base64url')
509
+ exports.bytesToBase64Url = bytesToBase64Url
510
+
511
+ /** Compute SHA-256 hex digest of data */
512
+ const sha256Hex = data => (0, crypto_1.createHash)('sha256').update(data).digest('hex')
513
+ exports.sha256Hex = sha256Hex
514
+
515
+ /** Compute HMAC-SHA-256 of data with key, returns Buffer */
516
+ const hmacSha256 = (data, key) => (0, crypto_1.createHmac)('sha256', key).update(data).digest()
517
+ exports.hmacSha256 = hmacSha256
518
+
519
+ /**
520
+ * Normalize and deduplicate an array of JIDs
521
+ */
522
+ const normalizeJidBatch = (jids, normalizer) => {
523
+ const seen = new Set()
524
+ const result = []
525
+ for (const jid of jids) {
526
+ if (!jid) continue
527
+ const normalized = normalizer ? normalizer(jid) : jid
528
+ if (!seen.has(normalized)) {
529
+ seen.add(normalized)
530
+ result.push(normalized)
531
+ }
532
+ }
533
+ return result
534
+ }
535
+ exports.normalizeJidBatch = normalizeJidBatch
536
+
537
+ /**
538
+ * Sleep for a given number of milliseconds, returns a cancellable promise
539
+ */
540
+ const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
541
+ exports.sleep = sleep
542
+
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
+ */
549
+ const withRetry = async (fn, maxAttempts = 3, baseDelayMs = 500) => {
550
+ let lastErr
551
+ for (let i = 0; i < maxAttempts; i++) {
552
+ try {
553
+ return await fn()
554
+ } catch (err) {
555
+ lastErr = err
556
+ if (i < maxAttempts - 1) {
557
+ await sleep(exponentialBackoff(i, baseDelayMs))
558
+ }
559
+ }
560
+ }
561
+ throw lastErr
562
+ }
563
+ exports.withRetry = withRetry
@@ -0,0 +1,60 @@
1
+ 'use strict'
2
+ Object.defineProperty(exports, '__esModule', { value: true })
3
+ exports.processGroupHistory = exports.decodeGroupHistory = void 0
4
+ const zlib_1 = require('zlib')
5
+ const index_js_1 = require('../../WAProto/index.js')
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
+ */
14
+ const decodeGroupHistory = (buffer, options = {}) => {
15
+ const { inflate = true, withMessageBytes = false } = options
16
+ if (!Buffer.isBuffer(buffer) && !(buffer instanceof Uint8Array)) {
17
+ throw new TypeError('decodeGroupHistory: buffer must be Buffer or Uint8Array')
18
+ }
19
+ let data = Buffer.isBuffer(buffer) ? buffer : Buffer.from(buffer)
20
+ if (inflate) {
21
+ try {
22
+ data = zlib_1.inflateSync(data)
23
+ } catch {
24
+ // not zlib-compressed — use raw bytes
25
+ }
26
+ }
27
+ if (withMessageBytes) {
28
+ const decoded = index_js_1.proto.GroupHistoryWithMessageBytes.decode(data)
29
+ const expand = list =>
30
+ (list || []).map(entry =>
31
+ entry?.messageBytes ? index_js_1.proto.WebMessageInfo.decode(entry.messageBytes) : { key: entry?.key }
32
+ )
33
+ return {
34
+ messages: expand(decoded.messages),
35
+ commentMessages: expand(decoded.commentMessages),
36
+ outOfWindowPinnedMessages: expand(decoded.outOfWindowPinnedMessages),
37
+ uncountedAssociatedMessageLists: (decoded.uncountedAssociatedMessageLists || []).map(l => ({
38
+ parentMessage: l.parentMessage,
39
+ messages: expand(l.messages)
40
+ }))
41
+ }
42
+ }
43
+ return index_js_1.proto.GroupHistory.decode(data)
44
+ }
45
+ exports.decodeGroupHistory = decodeGroupHistory
46
+
47
+ /**
48
+ * Normalize a decoded GroupHistory into stable message buckets.
49
+ * @param groupHistory a decoded proto.GroupHistory (or the withMessageBytes shape)
50
+ */
51
+ const processGroupHistory = groupHistory => {
52
+ const gh = groupHistory || {}
53
+ return {
54
+ messages: gh.messages || [],
55
+ commentMessages: gh.commentMessages || [],
56
+ outOfWindowPinnedMessages: gh.outOfWindowPinnedMessages || [],
57
+ uncountedAssociatedMessageLists: gh.uncountedAssociatedMessageLists || []
58
+ }
59
+ }
60
+ exports.processGroupHistory = processGroupHistory