@sixcore/baileys 1.0.0 → 1.0.2

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 (228) hide show
  1. package/WAProto/index.js +14270 -302
  2. package/jessica.js +91 -0
  3. package/lib/Defaults/baileys-version.json +1 -1
  4. package/lib/Defaults/index.js +117 -79
  5. package/lib/Defaults/phonenumber-mcc.json +223 -0
  6. package/lib/Signal/Group/ciphertext-message.d.ts +9 -0
  7. package/lib/Signal/Group/ciphertext-message.js +15 -0
  8. package/lib/Signal/Group/group-session-builder.d.ts +14 -0
  9. package/lib/Signal/Group/group-session-builder.js +64 -0
  10. package/lib/Signal/Group/group_cipher.d.ts +17 -0
  11. package/lib/Signal/Group/group_cipher.js +96 -0
  12. package/lib/Signal/Group/index.d.ts +11 -0
  13. package/lib/Signal/Group/index.js +57 -0
  14. package/lib/Signal/Group/keyhelper.d.ts +10 -0
  15. package/lib/Signal/Group/keyhelper.js +55 -0
  16. package/lib/Signal/Group/queue-job.d.ts +1 -0
  17. package/lib/Signal/Group/queue-job.js +57 -0
  18. package/lib/Signal/Group/sender-chain-key.d.ts +13 -0
  19. package/lib/Signal/Group/sender-chain-key.js +34 -0
  20. package/lib/Signal/Group/sender-key-distribution-message.d.ts +16 -0
  21. package/lib/Signal/Group/sender-key-distribution-message.js +66 -0
  22. package/lib/Signal/Group/sender-key-message.d.ts +18 -0
  23. package/lib/Signal/Group/sender-key-message.js +69 -0
  24. package/lib/Signal/Group/sender-key-name.d.ts +17 -0
  25. package/lib/Signal/Group/sender-key-name.js +51 -0
  26. package/lib/Signal/Group/sender-key-record.d.ts +30 -0
  27. package/lib/Signal/Group/sender-key-record.js +53 -0
  28. package/lib/Signal/Group/sender-key-state.d.ts +38 -0
  29. package/lib/Signal/Group/sender-key-state.js +99 -0
  30. package/lib/Signal/Group/sender-message-key.d.ts +11 -0
  31. package/{WASignalGroup/sender_message_key.js → lib/Signal/Group/sender-message-key.js} +6 -16
  32. package/lib/Signal/libsignal.js +51 -29
  33. package/lib/Socket/business.d.ts +43 -42
  34. package/lib/Socket/chats.d.ts +222 -36
  35. package/lib/Socket/chats.js +173 -153
  36. package/lib/Socket/dugong.d.ts +254 -0
  37. package/lib/Socket/dugong.js +484 -0
  38. package/lib/Socket/groups.d.ts +7 -7
  39. package/lib/Socket/groups.js +37 -35
  40. package/lib/Socket/index.d.ts +52 -51
  41. package/lib/Socket/index.js +1 -0
  42. package/lib/Socket/messages-recv.d.ts +37 -34
  43. package/lib/Socket/messages-recv.js +175 -37
  44. package/lib/Socket/messages-send.d.ts +12 -18
  45. package/lib/Socket/messages-send.js +396 -574
  46. package/lib/Socket/newsletter.d.ts +28 -26
  47. package/lib/Socket/newsletter.js +132 -121
  48. package/lib/Socket/registration.d.ts +52 -49
  49. package/lib/Socket/registration.js +7 -7
  50. package/lib/Socket/socket.d.ts +0 -1
  51. package/lib/Socket/socket.js +49 -27
  52. package/lib/Socket/usync.d.ts +10 -11
  53. package/lib/Store/make-cache-manager-store.d.ts +1 -2
  54. package/lib/Store/make-in-memory-store.d.ts +2 -2
  55. package/lib/Store/make-in-memory-store.js +1 -5
  56. package/lib/Store/make-ordered-dictionary.js +2 -2
  57. package/lib/Types/Auth.d.ts +1 -0
  58. package/lib/Types/Call.d.ts +1 -1
  59. package/lib/Types/Chat.d.ts +7 -12
  60. package/lib/Types/Events.d.ts +2 -17
  61. package/lib/Types/GroupMetadata.d.ts +2 -3
  62. package/lib/Types/Label.d.ts +0 -11
  63. package/lib/Types/Label.js +1 -1
  64. package/lib/Types/LabelAssociation.js +1 -1
  65. package/lib/Types/Message.d.ts +10 -170
  66. package/lib/Types/Newsletter.d.ts +97 -86
  67. package/lib/Types/Newsletter.js +38 -32
  68. package/lib/Types/Socket.d.ts +2 -7
  69. package/lib/Types/index.d.ts +0 -9
  70. package/lib/Types/index.js +1 -1
  71. package/lib/Utils/auth-utils.js +14 -35
  72. package/lib/Utils/business.d.ts +1 -1
  73. package/lib/Utils/business.js +2 -2
  74. package/lib/Utils/chat-utils.d.ts +12 -11
  75. package/lib/Utils/chat-utils.js +36 -52
  76. package/lib/Utils/crypto.d.ts +16 -15
  77. package/lib/Utils/crypto.js +26 -74
  78. package/lib/Utils/decode-wa-message.d.ts +0 -17
  79. package/lib/Utils/decode-wa-message.js +17 -53
  80. package/lib/Utils/event-buffer.js +7 -10
  81. package/lib/Utils/generics.d.ts +17 -13
  82. package/lib/Utils/generics.js +79 -58
  83. package/lib/Utils/history.d.ts +2 -6
  84. package/lib/Utils/history.js +6 -4
  85. package/lib/Utils/logger.d.ts +3 -1
  86. package/lib/Utils/lt-hash.js +12 -12
  87. package/lib/Utils/make-mutex.d.ts +2 -2
  88. package/lib/Utils/messages-media.d.ts +28 -25
  89. package/lib/Utils/messages-media.js +733 -557
  90. package/lib/Utils/messages.js +68 -473
  91. package/lib/Utils/noise-handler.d.ts +5 -4
  92. package/lib/Utils/noise-handler.js +14 -19
  93. package/lib/Utils/process-message.d.ts +5 -5
  94. package/lib/Utils/process-message.js +23 -75
  95. package/lib/Utils/signal.d.ts +1 -2
  96. package/lib/Utils/signal.js +26 -32
  97. package/lib/Utils/use-multi-file-auth-state.d.ts +1 -0
  98. package/lib/Utils/use-multi-file-auth-state.js +66 -242
  99. package/lib/Utils/validate-connection.d.ts +1 -1
  100. package/lib/Utils/validate-connection.js +88 -64
  101. package/lib/WABinary/constants.d.ts +27 -24
  102. package/lib/WABinary/decode.d.ts +2 -1
  103. package/lib/WABinary/decode.js +11 -23
  104. package/lib/WABinary/encode.d.ts +2 -1
  105. package/lib/WABinary/encode.js +147 -134
  106. package/lib/WABinary/generic-utils.d.ts +5 -2
  107. package/lib/WABinary/generic-utils.js +125 -37
  108. package/lib/WABinary/jid-utils.d.ts +1 -1
  109. package/lib/WAM/BinaryInfo.d.ts +11 -2
  110. package/lib/WAM/encode.d.ts +2 -1
  111. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +3 -3
  112. package/lib/WAUSync/USyncUser.d.ts +2 -0
  113. package/lib/index.d.ts +12 -0
  114. package/lib/index.js +64 -1
  115. package/package.json +113 -51
  116. package/WAProto/GenerateStatics.sh +0 -4
  117. package/WAProto/WAProto.proto +0 -4357
  118. package/WAProto/index.d.ts +0 -50383
  119. package/WASignalGroup/GroupProtocol.js +0 -1697
  120. package/WASignalGroup/ciphertext_message.js +0 -16
  121. package/WASignalGroup/generate-proto.sh +0 -1
  122. package/WASignalGroup/group.proto +0 -42
  123. package/WASignalGroup/group_cipher.js +0 -120
  124. package/WASignalGroup/group_session_builder.js +0 -46
  125. package/WASignalGroup/index.js +0 -5
  126. package/WASignalGroup/keyhelper.js +0 -21
  127. package/WASignalGroup/protobufs.js +0 -3
  128. package/WASignalGroup/queue_job.js +0 -69
  129. package/WASignalGroup/sender_chain_key.js +0 -50
  130. package/WASignalGroup/sender_key_distribution_message.js +0 -78
  131. package/WASignalGroup/sender_key_message.js +0 -92
  132. package/WASignalGroup/sender_key_name.js +0 -70
  133. package/WASignalGroup/sender_key_record.js +0 -56
  134. package/WASignalGroup/sender_key_state.js +0 -129
  135. package/lib/Utils/use-single-file-auth-state.d.ts +0 -12
  136. package/lib/Utils/use-single-file-auth-state.js +0 -75
  137. package/src/Defaults/baileys-version.json +0 -3
  138. package/src/Defaults/index.ts +0 -133
  139. package/src/Signal/Group/ciphertext-message.ts +0 -9
  140. package/src/Signal/Group/group-session-builder.ts +0 -56
  141. package/src/Signal/Group/group_cipher.ts +0 -117
  142. package/src/Signal/Group/index.ts +0 -11
  143. package/src/Signal/Group/keyhelper.ts +0 -28
  144. package/src/Signal/Group/sender-chain-key.ts +0 -34
  145. package/src/Signal/Group/sender-key-distribution-message.ts +0 -95
  146. package/src/Signal/Group/sender-key-message.ts +0 -96
  147. package/src/Signal/Group/sender-key-name.ts +0 -66
  148. package/src/Signal/Group/sender-key-record.ts +0 -69
  149. package/src/Signal/Group/sender-key-state.ts +0 -134
  150. package/src/Signal/Group/sender-message-key.ts +0 -36
  151. package/src/Signal/libsignal.ts +0 -447
  152. package/src/Signal/lid-mapping.ts +0 -209
  153. package/src/Socket/Client/index.ts +0 -2
  154. package/src/Socket/Client/types.ts +0 -22
  155. package/src/Socket/Client/websocket.ts +0 -56
  156. package/src/Socket/business.ts +0 -421
  157. package/src/Socket/chats.ts +0 -1223
  158. package/src/Socket/communities.ts +0 -477
  159. package/src/Socket/groups.ts +0 -361
  160. package/src/Socket/index.ts +0 -22
  161. package/src/Socket/messages-recv.ts +0 -1563
  162. package/src/Socket/messages-send.ts +0 -1210
  163. package/src/Socket/mex.ts +0 -58
  164. package/src/Socket/newsletter.ts +0 -229
  165. package/src/Socket/socket.ts +0 -1072
  166. package/src/Types/Auth.ts +0 -115
  167. package/src/Types/Bussines.ts +0 -20
  168. package/src/Types/Call.ts +0 -14
  169. package/src/Types/Chat.ts +0 -138
  170. package/src/Types/Contact.ts +0 -24
  171. package/src/Types/Events.ts +0 -132
  172. package/src/Types/GroupMetadata.ts +0 -70
  173. package/src/Types/Label.ts +0 -48
  174. package/src/Types/LabelAssociation.ts +0 -35
  175. package/src/Types/Message.ts +0 -424
  176. package/src/Types/Newsletter.ts +0 -98
  177. package/src/Types/Product.ts +0 -85
  178. package/src/Types/Signal.ts +0 -76
  179. package/src/Types/Socket.ts +0 -150
  180. package/src/Types/State.ts +0 -43
  181. package/src/Types/USync.ts +0 -27
  182. package/src/Types/globals.d.ts +0 -8
  183. package/src/Types/index.ts +0 -67
  184. package/src/Utils/auth-utils.ts +0 -331
  185. package/src/Utils/browser-utils.ts +0 -31
  186. package/src/Utils/business.ts +0 -286
  187. package/src/Utils/chat-utils.ts +0 -933
  188. package/src/Utils/crypto.ts +0 -184
  189. package/src/Utils/decode-wa-message.ts +0 -355
  190. package/src/Utils/event-buffer.ts +0 -662
  191. package/src/Utils/generics.ts +0 -470
  192. package/src/Utils/history.ts +0 -114
  193. package/src/Utils/index.ts +0 -18
  194. package/src/Utils/link-preview.ts +0 -111
  195. package/src/Utils/logger.ts +0 -13
  196. package/src/Utils/lt-hash.ts +0 -65
  197. package/src/Utils/make-mutex.ts +0 -45
  198. package/src/Utils/message-retry-manager.ts +0 -229
  199. package/src/Utils/messages-media.ts +0 -820
  200. package/src/Utils/messages.ts +0 -1137
  201. package/src/Utils/noise-handler.ts +0 -192
  202. package/src/Utils/pre-key-manager.ts +0 -126
  203. package/src/Utils/process-message.ts +0 -622
  204. package/src/Utils/signal.ts +0 -214
  205. package/src/Utils/use-multi-file-auth-state.ts +0 -136
  206. package/src/Utils/validate-connection.ts +0 -253
  207. package/src/WABinary/constants.ts +0 -1305
  208. package/src/WABinary/decode.ts +0 -281
  209. package/src/WABinary/encode.ts +0 -253
  210. package/src/WABinary/generic-utils.ts +0 -127
  211. package/src/WABinary/index.ts +0 -5
  212. package/src/WABinary/jid-utils.ts +0 -128
  213. package/src/WABinary/types.ts +0 -17
  214. package/src/WAM/BinaryInfo.ts +0 -12
  215. package/src/WAM/constants.ts +0 -22889
  216. package/src/WAM/encode.ts +0 -169
  217. package/src/WAM/index.ts +0 -3
  218. package/src/WAUSync/Protocols/USyncContactProtocol.ts +0 -32
  219. package/src/WAUSync/Protocols/USyncDeviceProtocol.ts +0 -78
  220. package/src/WAUSync/Protocols/USyncDisappearingModeProtocol.ts +0 -35
  221. package/src/WAUSync/Protocols/USyncStatusProtocol.ts +0 -44
  222. package/src/WAUSync/Protocols/UsyncBotProfileProtocol.ts +0 -76
  223. package/src/WAUSync/Protocols/UsyncLIDProtocol.ts +0 -33
  224. package/src/WAUSync/Protocols/index.ts +0 -4
  225. package/src/WAUSync/USyncQuery.ts +0 -133
  226. package/src/WAUSync/USyncUser.ts +0 -32
  227. package/src/WAUSync/index.ts +0 -3
  228. package/src/index.ts +0 -13
@@ -1,470 +0,0 @@
1
- import { Boom } from '@hapi/boom'
2
- import { createHash, randomBytes } from 'crypto'
3
- import { proto } from '../../WAProto/index.js'
4
- const baileysVersion = [2, 3000, 1027934701]
5
- import type {
6
- BaileysEventEmitter,
7
- BaileysEventMap,
8
- ConnectionState,
9
- WACallUpdateType,
10
- WAMessageKey,
11
- WAVersion
12
- } from '../Types'
13
- import { DisconnectReason } from '../Types'
14
- import { type BinaryNode, getAllBinaryNodeChildren, jidDecode } from '../WABinary'
15
- import { sha256 } from './crypto'
16
-
17
- export const BufferJSON = {
18
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
- replacer: (k: any, value: any) => {
20
- if (Buffer.isBuffer(value) || value instanceof Uint8Array || value?.type === 'Buffer') {
21
- return { type: 'Buffer', data: Buffer.from(value?.data || value).toString('base64') }
22
- }
23
-
24
- return value
25
- },
26
-
27
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
- reviver: (_: any, value: any) => {
29
- if (typeof value === 'object' && value !== null && value.type === 'Buffer' && typeof value.data === 'string') {
30
- return Buffer.from(value.data, 'base64')
31
- }
32
-
33
- if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
34
- const keys = Object.keys(value)
35
- if (keys.length > 0 && keys.every(k => !isNaN(parseInt(k, 10)))) {
36
- const values = Object.values(value)
37
- if (values.every(v => typeof v === 'number')) {
38
- return Buffer.from(values)
39
- }
40
- }
41
- }
42
-
43
- return value
44
- }
45
- }
46
-
47
- export const getKeyAuthor = (key: WAMessageKey | undefined | null, meId = 'me') =>
48
- (key?.fromMe ? meId : key?.participantAlt || key?.remoteJidAlt || key?.participant || key?.remoteJid) || ''
49
-
50
- export const writeRandomPadMax16 = (msg: Uint8Array) => {
51
- const pad = randomBytes(1)
52
- const padLength = (pad[0]! & 0x0f) + 1
53
-
54
- return Buffer.concat([msg, Buffer.alloc(padLength, padLength)])
55
- }
56
-
57
- export const unpadRandomMax16 = (e: Uint8Array | Buffer) => {
58
- const t = new Uint8Array(e)
59
- if (0 === t.length) {
60
- throw new Error('unpadPkcs7 given empty bytes')
61
- }
62
-
63
- var r = t[t.length - 1]!
64
- if (r > t.length) {
65
- throw new Error(`unpad given ${t.length} bytes, but pad is ${r}`)
66
- }
67
-
68
- return new Uint8Array(t.buffer, t.byteOffset, t.length - r)
69
- }
70
-
71
- // code is inspired by whatsmeow
72
- export const generateParticipantHashV2 = (participants: string[]): string => {
73
- participants.sort()
74
- const sha256Hash = sha256(Buffer.from(participants.join(''))).toString('base64')
75
- return '2:' + sha256Hash.slice(0, 6)
76
- }
77
-
78
- export const encodeWAMessage = (message: proto.IMessage) => writeRandomPadMax16(proto.Message.encode(message).finish())
79
-
80
- export const generateRegistrationId = (): number => {
81
- return Uint16Array.from(randomBytes(2))[0]! & 16383
82
- }
83
-
84
- export const encodeBigEndian = (e: number, t = 4) => {
85
- let r = e
86
- const a = new Uint8Array(t)
87
- for (let i = t - 1; i >= 0; i--) {
88
- a[i] = 255 & r
89
- r >>>= 8
90
- }
91
-
92
- return a
93
- }
94
-
95
- export const toNumber = (t: Long | number | null | undefined): number =>
96
- typeof t === 'object' && t ? ('toNumber' in t ? t.toNumber() : (t as Long).low) : t || 0
97
-
98
- /** unix timestamp of a date in seconds */
99
- export const unixTimestampSeconds = (date: Date = new Date()) => Math.floor(date.getTime() / 1000)
100
-
101
- export type DebouncedTimeout = ReturnType<typeof debouncedTimeout>
102
-
103
- export const debouncedTimeout = (intervalMs = 1000, task?: () => void) => {
104
- let timeout: NodeJS.Timeout | undefined
105
- return {
106
- start: (newIntervalMs?: number, newTask?: () => void) => {
107
- task = newTask || task
108
- intervalMs = newIntervalMs || intervalMs
109
- timeout && clearTimeout(timeout)
110
- timeout = setTimeout(() => task?.(), intervalMs)
111
- },
112
- cancel: () => {
113
- timeout && clearTimeout(timeout)
114
- timeout = undefined
115
- },
116
- setTask: (newTask: () => void) => (task = newTask),
117
- setInterval: (newInterval: number) => (intervalMs = newInterval)
118
- }
119
- }
120
-
121
- export const delay = (ms: number) => delayCancellable(ms).delay
122
-
123
- export const delayCancellable = (ms: number) => {
124
- const stack = new Error().stack
125
- let timeout: NodeJS.Timeout
126
- let reject: (error: any) => void
127
- const delay: Promise<void> = new Promise((resolve, _reject) => {
128
- timeout = setTimeout(resolve, ms)
129
- reject = _reject
130
- })
131
- const cancel = () => {
132
- clearTimeout(timeout)
133
- reject(
134
- new Boom('Cancelled', {
135
- statusCode: 500,
136
- data: {
137
- stack
138
- }
139
- })
140
- )
141
- }
142
-
143
- return { delay, cancel }
144
- }
145
-
146
- export async function promiseTimeout<T>(
147
- ms: number | undefined,
148
- promise: (resolve: (v: T) => void, reject: (error: any) => void) => void
149
- ) {
150
- if (!ms) {
151
- return new Promise(promise)
152
- }
153
-
154
- const stack = new Error().stack
155
- // Create a promise that rejects in <ms> milliseconds
156
- const { delay, cancel } = delayCancellable(ms)
157
- const p = new Promise((resolve, reject) => {
158
- delay
159
- .then(() =>
160
- reject(
161
- new Boom('Timed Out', {
162
- statusCode: DisconnectReason.timedOut,
163
- data: {
164
- stack
165
- }
166
- })
167
- )
168
- )
169
- .catch(err => reject(err))
170
-
171
- promise(resolve, reject)
172
- }).finally(cancel)
173
- return p as Promise<T>
174
- }
175
-
176
- // inspired from whatsmeow code
177
- // https://github.com/tulir/whatsmeow/blob/64bc969fbe78d31ae0dd443b8d4c80a5d026d07a/send.go#L42
178
- export const generateMessageIDV2 = (userId?: string): string => {
179
- const data = Buffer.alloc(8 + 20 + 16)
180
- data.writeBigUInt64BE(BigInt(Math.floor(Date.now() / 1000)))
181
-
182
- if (userId) {
183
- const id = jidDecode(userId)
184
- if (id?.user) {
185
- data.write(id.user, 8)
186
- data.write('@c.us', 8 + id.user.length)
187
- }
188
- }
189
-
190
- const random = randomBytes(16)
191
- random.copy(data, 28)
192
-
193
- const hash = createHash('sha256').update(data).digest()
194
- return '3EB0' + hash.toString('hex').toUpperCase().substring(0, 18)
195
- }
196
-
197
- // generate a random ID to attach to a message
198
- export const generateMessageID = () => '3EB0' + randomBytes(18).toString('hex').toUpperCase()
199
-
200
- export function bindWaitForEvent<T extends keyof BaileysEventMap>(ev: BaileysEventEmitter, event: T) {
201
- return async (check: (u: BaileysEventMap[T]) => Promise<boolean | undefined>, timeoutMs?: number) => {
202
- let listener: (item: BaileysEventMap[T]) => void
203
- let closeListener: (state: Partial<ConnectionState>) => void
204
- await promiseTimeout<void>(timeoutMs, (resolve, reject) => {
205
- closeListener = ({ connection, lastDisconnect }) => {
206
- if (connection === 'close') {
207
- reject(
208
- lastDisconnect?.error || new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed })
209
- )
210
- }
211
- }
212
-
213
- ev.on('connection.update', closeListener)
214
- listener = async update => {
215
- if (await check(update)) {
216
- resolve()
217
- }
218
- }
219
-
220
- ev.on(event, listener)
221
- }).finally(() => {
222
- ev.off(event, listener)
223
- ev.off('connection.update', closeListener)
224
- })
225
- }
226
- }
227
-
228
- export const bindWaitForConnectionUpdate = (ev: BaileysEventEmitter) => bindWaitForEvent(ev, 'connection.update')
229
-
230
- /**
231
- * utility that fetches latest baileys version from the master branch.
232
- * Use to ensure your WA connection is always on the latest version
233
- */
234
- export const fetchLatestBaileysVersion = async (options: RequestInit = {}) => {
235
- const URL = 'https://raw.githubusercontent.com/WhiskeySockets/Baileys/master/src/Defaults/index.ts'
236
- try {
237
- const response = await fetch(URL, {
238
- dispatcher: options.dispatcher,
239
- method: 'GET',
240
- headers: options.headers
241
- })
242
- if (!response.ok) {
243
- throw new Boom(`Failed to fetch latest Baileys version: ${response.statusText}`, { statusCode: response.status })
244
- }
245
-
246
- const text = await response.text()
247
- // Extract version from line 7 (const version = [...])
248
- const lines = text.split('\n')
249
- const versionLine = lines[6] // Line 7 (0-indexed)
250
- const versionMatch = versionLine!.match(/const version = \[(\d+),\s*(\d+),\s*(\d+)\]/)
251
-
252
- if (versionMatch) {
253
- const version = [parseInt(versionMatch[1]!), parseInt(versionMatch[2]!), parseInt(versionMatch[3]!)] as WAVersion
254
-
255
- return {
256
- version,
257
- isLatest: true
258
- }
259
- } else {
260
- throw new Error('Could not parse version from Defaults/index.ts')
261
- }
262
- } catch (error) {
263
- return {
264
- version: baileysVersion as WAVersion,
265
- isLatest: false,
266
- error
267
- }
268
- }
269
- }
270
-
271
- /**
272
- * A utility that fetches the latest web version of whatsapp.
273
- * Use to ensure your WA connection is always on the latest version
274
- */
275
- export const fetchLatestWaWebVersion = async (options: RequestInit = {}) => {
276
- try {
277
- // Absolute minimal headers required to bypass anti-bot detection
278
- const defaultHeaders = {
279
- 'sec-fetch-site': 'none',
280
- 'user-agent':
281
- 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'
282
- }
283
-
284
- const headers = { ...defaultHeaders, ...options.headers }
285
-
286
- const response = await fetch('https://web.whatsapp.com/sw.js', {
287
- ...options,
288
- method: 'GET',
289
- headers
290
- })
291
-
292
- if (!response.ok) {
293
- throw new Boom(`Failed to fetch sw.js: ${response.statusText}`, { statusCode: response.status })
294
- }
295
-
296
- const data = await response.text()
297
-
298
- const regex = /\\?"client_revision\\?":\s*(\d+)/
299
- const match = data.match(regex)
300
-
301
- if (!match?.[1]) {
302
- return {
303
- version: baileysVersion as WAVersion,
304
- isLatest: false,
305
- error: {
306
- message: 'Could not find client revision in the fetched content'
307
- }
308
- }
309
- }
310
-
311
- const clientRevision = match[1]
312
-
313
- return {
314
- version: [2, 3000, +clientRevision] as WAVersion,
315
- isLatest: true
316
- }
317
- } catch (error) {
318
- return {
319
- version: baileysVersion as WAVersion,
320
- isLatest: false,
321
- error
322
- }
323
- }
324
- }
325
-
326
- /** unique message tag prefix for MD clients */
327
- export const generateMdTagPrefix = () => {
328
- const bytes = randomBytes(4)
329
- return `${bytes.readUInt16BE()}.${bytes.readUInt16BE(2)}-`
330
- }
331
-
332
- const STATUS_MAP: { [_: string]: proto.WebMessageInfo.Status } = {
333
- sender: proto.WebMessageInfo.Status.SERVER_ACK,
334
- played: proto.WebMessageInfo.Status.PLAYED,
335
- read: proto.WebMessageInfo.Status.READ,
336
- 'read-self': proto.WebMessageInfo.Status.READ
337
- }
338
- /**
339
- * Given a type of receipt, returns what the new status of the message should be
340
- * @param type type from receipt
341
- */
342
- export const getStatusFromReceiptType = (type: string | undefined) => {
343
- const status = STATUS_MAP[type!]
344
- if (typeof type === 'undefined') {
345
- return proto.WebMessageInfo.Status.DELIVERY_ACK
346
- }
347
-
348
- return status
349
- }
350
-
351
- const CODE_MAP: { [_: string]: DisconnectReason } = {
352
- conflict: DisconnectReason.connectionReplaced
353
- }
354
-
355
- /**
356
- * Stream errors generally provide a reason, map that to a baileys DisconnectReason
357
- * @param reason the string reason given, eg. "conflict"
358
- */
359
- export const getErrorCodeFromStreamError = (node: BinaryNode) => {
360
- const [reasonNode] = getAllBinaryNodeChildren(node)
361
- let reason = reasonNode?.tag || 'unknown'
362
- const statusCode = +(node.attrs.code || CODE_MAP[reason] || DisconnectReason.badSession)
363
-
364
- if (statusCode === DisconnectReason.restartRequired) {
365
- reason = 'restart required'
366
- }
367
-
368
- return {
369
- reason,
370
- statusCode
371
- }
372
- }
373
-
374
- export const getCallStatusFromNode = ({ tag, attrs }: BinaryNode) => {
375
- let status: WACallUpdateType
376
- switch (tag) {
377
- case 'offer':
378
- case 'offer_notice':
379
- status = 'offer'
380
- break
381
- case 'terminate':
382
- if (attrs.reason === 'timeout') {
383
- status = 'timeout'
384
- } else {
385
- //fired when accepted/rejected/timeout/caller hangs up
386
- status = 'terminate'
387
- }
388
-
389
- break
390
- case 'reject':
391
- status = 'reject'
392
- break
393
- case 'accept':
394
- status = 'accept'
395
- break
396
- default:
397
- status = 'ringing'
398
- break
399
- }
400
-
401
- return status
402
- }
403
-
404
- const UNEXPECTED_SERVER_CODE_TEXT = 'Unexpected server response: '
405
-
406
- export const getCodeFromWSError = (error: Error) => {
407
- let statusCode = 500
408
- if (error?.message?.includes(UNEXPECTED_SERVER_CODE_TEXT)) {
409
- const code = +error?.message.slice(UNEXPECTED_SERVER_CODE_TEXT.length)
410
- if (!Number.isNaN(code) && code >= 400) {
411
- statusCode = code
412
- }
413
- } else if (
414
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
415
- (error as any)?.code?.startsWith('E') ||
416
- error?.message?.includes('timed out')
417
- ) {
418
- // handle ETIMEOUT, ENOTFOUND etc
419
- statusCode = 408
420
- }
421
-
422
- return statusCode
423
- }
424
-
425
- /**
426
- * Is the given platform WA business
427
- * @param platform AuthenticationCreds.platform
428
- */
429
- export const isWABusinessPlatform = (platform: string) => {
430
- return platform === 'smbi' || platform === 'smba'
431
- }
432
-
433
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
434
- export function trimUndefined(obj: { [_: string]: any }) {
435
- for (const key in obj) {
436
- if (typeof obj[key] === 'undefined') {
437
- delete obj[key]
438
- }
439
- }
440
-
441
- return obj
442
- }
443
-
444
- const CROCKFORD_CHARACTERS = '123456789ABCDEFGHJKLMNPQRSTVWXYZ'
445
-
446
- export function bytesToCrockford(buffer: Buffer): string {
447
- let value = 0
448
- let bitCount = 0
449
- const crockford: string[] = []
450
-
451
- for (const element of buffer) {
452
- value = (value << 8) | (element & 0xff)
453
- bitCount += 8
454
-
455
- while (bitCount >= 5) {
456
- crockford.push(CROCKFORD_CHARACTERS.charAt((value >>> (bitCount - 5)) & 31))
457
- bitCount -= 5
458
- }
459
- }
460
-
461
- if (bitCount > 0) {
462
- crockford.push(CROCKFORD_CHARACTERS.charAt((value << (5 - bitCount)) & 31))
463
- }
464
-
465
- return crockford.join('')
466
- }
467
-
468
- export function encodeNewsletterMessage(message: proto.IMessage): Uint8Array {
469
- return proto.Message.encode(message).finish()
470
- }
@@ -1,114 +0,0 @@
1
- import { promisify } from 'util'
2
- import { inflate } from 'zlib'
3
- import { proto } from '../../WAProto/index.js'
4
- import type { Chat, Contact, WAMessage } from '../Types'
5
- import { WAMessageStubType } from '../Types'
6
- import { toNumber } from './generics'
7
- import { normalizeMessageContent } from './messages'
8
- import { downloadContentFromMessage } from './messages-media'
9
-
10
- const inflatePromise = promisify(inflate)
11
-
12
- export const downloadHistory = async (msg: proto.Message.IHistorySyncNotification, options: RequestInit) => {
13
- const stream = await downloadContentFromMessage(msg, 'md-msg-hist', { options })
14
- const bufferArray: Buffer[] = []
15
- for await (const chunk of stream) {
16
- bufferArray.push(chunk)
17
- }
18
-
19
- let buffer: Buffer = Buffer.concat(bufferArray)
20
-
21
- // decompress buffer
22
- buffer = await inflatePromise(buffer)
23
-
24
- const syncData = proto.HistorySync.decode(buffer)
25
- return syncData
26
- }
27
-
28
- export const processHistoryMessage = (item: proto.IHistorySync) => {
29
- const messages: WAMessage[] = []
30
- const contacts: Contact[] = []
31
- const chats: Chat[] = []
32
-
33
- switch (item.syncType) {
34
- case proto.HistorySync.HistorySyncType.INITIAL_BOOTSTRAP:
35
- case proto.HistorySync.HistorySyncType.RECENT:
36
- case proto.HistorySync.HistorySyncType.FULL:
37
- case proto.HistorySync.HistorySyncType.ON_DEMAND:
38
- for (const chat of item.conversations! as Chat[]) {
39
- contacts.push({
40
- id: chat.id!,
41
- name: chat.name || undefined,
42
- lid: chat.lidJid || undefined,
43
- phoneNumber: chat.pnJid || undefined
44
- })
45
-
46
- const msgs = chat.messages || []
47
- delete chat.messages
48
-
49
- for (const item of msgs) {
50
- const message = item.message! as WAMessage
51
- messages.push(message)
52
-
53
- if (!chat.messages?.length) {
54
- // keep only the most recent message in the chat array
55
- chat.messages = [{ message }]
56
- }
57
-
58
- if (!message.key.fromMe && !chat.lastMessageRecvTimestamp) {
59
- chat.lastMessageRecvTimestamp = toNumber(message.messageTimestamp)
60
- }
61
-
62
- if (
63
- (message.messageStubType === WAMessageStubType.BIZ_PRIVACY_MODE_TO_BSP ||
64
- message.messageStubType === WAMessageStubType.BIZ_PRIVACY_MODE_TO_FB) &&
65
- message.messageStubParameters?.[0]
66
- ) {
67
- contacts.push({
68
- id: message.key.participant || message.key.remoteJid!,
69
- verifiedName: message.messageStubParameters?.[0]
70
- })
71
- }
72
- }
73
-
74
- chats.push({ ...chat })
75
- }
76
-
77
- break
78
- case proto.HistorySync.HistorySyncType.PUSH_NAME:
79
- for (const c of item.pushnames!) {
80
- contacts.push({ id: c.id!, notify: c.pushname! })
81
- }
82
-
83
- break
84
- }
85
-
86
- return {
87
- chats,
88
- contacts,
89
- messages,
90
- syncType: item.syncType,
91
- progress: item.progress
92
- }
93
- }
94
-
95
- export const downloadAndProcessHistorySyncNotification = async (
96
- msg: proto.Message.IHistorySyncNotification,
97
- options: RequestInit
98
- ) => {
99
- let historyMsg: proto.HistorySync
100
- if (msg.initialHistBootstrapInlinePayload) {
101
- historyMsg = proto.HistorySync.decode(await inflatePromise(msg.initialHistBootstrapInlinePayload))
102
- } else {
103
- historyMsg = await downloadHistory(msg, options)
104
- }
105
-
106
- return processHistoryMessage(historyMsg)
107
- }
108
-
109
- export const getHistoryMsg = (message: proto.IMessage) => {
110
- const normalizedContent = !!message ? normalizeMessageContent(message) : undefined
111
- const anyHistoryMsg = normalizedContent?.protocolMessage?.historySyncNotification!
112
-
113
- return anyHistoryMsg
114
- }
@@ -1,18 +0,0 @@
1
- export * from './generics'
2
- export * from './decode-wa-message'
3
- export * from './messages'
4
- export * from './messages-media'
5
- export * from './validate-connection'
6
- export * from './crypto'
7
- export * from './signal'
8
- export * from './noise-handler'
9
- export * from './history'
10
- export * from './chat-utils'
11
- export * from './lt-hash'
12
- export * from './auth-utils'
13
- export * from './use-multi-file-auth-state'
14
- export * from './link-preview'
15
- export * from './event-buffer'
16
- export * from './process-message'
17
- export * from './message-retry-manager'
18
- export * from './browser-utils'
@@ -1,111 +0,0 @@
1
- import type { WAMediaUploadFunction, WAUrlInfo } from '../Types'
2
- import type { ILogger } from './logger'
3
- import { prepareWAMessageMedia } from './messages'
4
- import { extractImageThumb, getHttpStream } from './messages-media'
5
-
6
- const THUMBNAIL_WIDTH_PX = 192
7
-
8
- /** Fetches an image and generates a thumbnail for it */
9
- const getCompressedJpegThumbnail = async (url: string, { thumbnailWidth, fetchOpts }: URLGenerationOptions) => {
10
- const stream = await getHttpStream(url, fetchOpts)
11
- const result = await extractImageThumb(stream, thumbnailWidth)
12
- return result
13
- }
14
-
15
- export type URLGenerationOptions = {
16
- thumbnailWidth: number
17
- fetchOpts: {
18
- /** Timeout in ms */
19
- timeout: number
20
- proxyUrl?: string
21
- headers?: HeadersInit
22
- }
23
- uploadImage?: WAMediaUploadFunction
24
- logger?: ILogger
25
- }
26
-
27
- /**
28
- * Given a piece of text, checks for any URL present, generates link preview for the same and returns it
29
- * Return undefined if the fetch failed or no URL was found
30
- * @param text first matched URL in text
31
- * @returns the URL info required to generate link preview
32
- */
33
- export const getUrlInfo = async (
34
- text: string,
35
- opts: URLGenerationOptions = {
36
- thumbnailWidth: THUMBNAIL_WIDTH_PX,
37
- fetchOpts: { timeout: 3000 }
38
- }
39
- ): Promise<WAUrlInfo | undefined> => {
40
- try {
41
- // retries
42
- const retries = 0
43
- const maxRetry = 5
44
-
45
- const { getLinkPreview } = await import('link-preview-js')
46
- let previewLink = text
47
- if (!text.startsWith('https://') && !text.startsWith('http://')) {
48
- previewLink = 'https://' + previewLink
49
- }
50
-
51
- const info = await getLinkPreview(previewLink, {
52
- ...opts.fetchOpts,
53
- followRedirects: 'follow',
54
- handleRedirects: (baseURL: string, forwardedURL: string) => {
55
- const urlObj = new URL(baseURL)
56
- const forwardedURLObj = new URL(forwardedURL)
57
- if (retries >= maxRetry) {
58
- return false
59
- }
60
-
61
- if (
62
- forwardedURLObj.hostname === urlObj.hostname ||
63
- forwardedURLObj.hostname === 'www.' + urlObj.hostname ||
64
- 'www.' + forwardedURLObj.hostname === urlObj.hostname
65
- ) {
66
- retries + 1
67
- return true
68
- } else {
69
- return false
70
- }
71
- },
72
- headers: opts.fetchOpts?.headers as {}
73
- })
74
- if (info && 'title' in info && info.title) {
75
- const [image] = info.images
76
-
77
- const urlInfo: WAUrlInfo = {
78
- 'canonical-url': info.url,
79
- 'matched-text': text,
80
- title: info.title,
81
- description: info.description,
82
- originalThumbnailUrl: image
83
- }
84
-
85
- if (opts.uploadImage) {
86
- const { imageMessage } = await prepareWAMessageMedia(
87
- { image: { url: image! } },
88
- {
89
- upload: opts.uploadImage,
90
- mediaTypeOverride: 'thumbnail-link',
91
- options: opts.fetchOpts
92
- }
93
- )
94
- urlInfo.jpegThumbnail = imageMessage?.jpegThumbnail ? Buffer.from(imageMessage.jpegThumbnail) : undefined
95
- urlInfo.highQualityThumbnail = imageMessage || undefined
96
- } else {
97
- try {
98
- urlInfo.jpegThumbnail = image ? (await getCompressedJpegThumbnail(image, opts)).buffer : undefined
99
- } catch (error: any) {
100
- opts.logger?.debug({ err: error.stack, url: previewLink }, 'error in generating thumbnail')
101
- }
102
- }
103
-
104
- return urlInfo
105
- }
106
- } catch (error: any) {
107
- if (!error.message.includes('receive a valid')) {
108
- throw error
109
- }
110
- }
111
- }