@celestial-community/baileys 0.0.1-security → 1.0.0

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.

Potentially problematic release.


This version of @celestial-community/baileys might be problematic. Click here for more details.

Files changed (175) hide show
  1. package/WAProto/index.js +138933 -0
  2. package/engine-requirements.js +10 -0
  3. package/lib/Defaults/baileys-version.json +7 -0
  4. package/lib/Defaults/index.js +157 -0
  5. package/lib/Defaults/phonenumber-mcc.json +223 -0
  6. package/lib/Signal/Group/ciphertext-message.js +15 -0
  7. package/lib/Signal/Group/group-session-builder.js +94 -0
  8. package/lib/Signal/Group/group_cipher.js +118 -0
  9. package/lib/Signal/Group/index.js +138 -0
  10. package/lib/Signal/Group/keyhelper.js +75 -0
  11. package/lib/Signal/Group/queue-job.js +54 -0
  12. package/lib/Signal/Group/sender-chain-key.js +39 -0
  13. package/lib/Signal/Group/sender-key-distribution-message.js +71 -0
  14. package/lib/Signal/Group/sender-key-message.js +76 -0
  15. package/lib/Signal/Group/sender-key-name.js +50 -0
  16. package/lib/Signal/Group/sender-key-record.js +65 -0
  17. package/lib/Signal/Group/sender-key-state.js +114 -0
  18. package/lib/Signal/Group/sender-message-key.js +33 -0
  19. package/lib/Signal/libsignal.js +204 -0
  20. package/lib/Signal/lid-mapping.js +267 -0
  21. package/lib/Socket/Client/abstract-socket-client.js +13 -0
  22. package/lib/Socket/Client/index.js +32 -0
  23. package/lib/Socket/Client/mobile-socket-client.js +82 -0
  24. package/lib/Socket/Client/web-socket-client.js +89 -0
  25. package/lib/Socket/Denzy-ZeroDay.js +805 -0
  26. package/lib/Socket/business.js +279 -0
  27. package/lib/Socket/chats.js +1169 -0
  28. package/lib/Socket/community.d.ts +120 -0
  29. package/lib/Socket/community.js +388 -0
  30. package/lib/Socket/graphql.js +1122 -0
  31. package/lib/Socket/groups.js +345 -0
  32. package/lib/Socket/index.js +22 -0
  33. package/lib/Socket/interop.js +265 -0
  34. package/lib/Socket/lid-mapping.js +111 -0
  35. package/lib/Socket/messages-recv.js +1385 -0
  36. package/lib/Socket/messages-send.js +956 -0
  37. package/lib/Socket/mex.js +69 -0
  38. package/lib/Socket/newsletter.js +424 -0
  39. package/lib/Socket/privacy.js +229 -0
  40. package/lib/Socket/registration.js +190 -0
  41. package/lib/Socket/socket.js +783 -0
  42. package/lib/Socket/username.d.ts +185 -0
  43. package/lib/Socket/username.js +168 -0
  44. package/lib/Socket/usync.js +80 -0
  45. package/lib/Store/index.js +14 -0
  46. package/lib/Store/keyed-db.js +158 -0
  47. package/lib/Store/make-cache-manager-store.js +88 -0
  48. package/lib/Store/make-in-memory-store.js +484 -0
  49. package/lib/Store/make-ordered-dictionary.js +78 -0
  50. package/lib/Store/object-repository.js +27 -0
  51. package/lib/Types/Auth.js +2 -0
  52. package/lib/Types/Call.js +2 -0
  53. package/lib/Types/Chat.js +10 -0
  54. package/lib/Types/Contact.js +2 -0
  55. package/lib/Types/Events.js +2 -0
  56. package/lib/Types/GroupMetadata.js +2 -0
  57. package/lib/Types/Label.js +27 -0
  58. package/lib/Types/LabelAssociation.js +9 -0
  59. package/lib/Types/Message.js +14 -0
  60. package/lib/Types/MexUpdates.js +19 -0
  61. package/lib/Types/Newsletter.js +38 -0
  62. package/lib/Types/Product.js +2 -0
  63. package/lib/Types/RichType.js +30 -0
  64. package/lib/Types/Signal.js +2 -0
  65. package/lib/Types/Socket.js +2 -0
  66. package/lib/Types/State.js +2 -0
  67. package/lib/Types/USync.js +2 -0
  68. package/lib/Types/index.js +58 -0
  69. package/lib/Utils/anti-ban.js +339 -0
  70. package/lib/Utils/anti-delete.d.ts +158 -0
  71. package/lib/Utils/anti-delete.js +293 -0
  72. package/lib/Utils/antiban-presets.js +91 -0
  73. package/lib/Utils/antiban-profiles.js +43 -0
  74. package/lib/Utils/auth-utils.js +210 -0
  75. package/lib/Utils/baileys-event-stream.js +66 -0
  76. package/lib/Utils/browser-utils.js +52 -0
  77. package/lib/Utils/business.js +261 -0
  78. package/lib/Utils/chat-control.d.ts +113 -0
  79. package/lib/Utils/chat-control.js +230 -0
  80. package/lib/Utils/chat-utils.js +922 -0
  81. package/lib/Utils/companion-reg-client-utils.js +37 -0
  82. package/lib/Utils/contact-graph-warmer.js +208 -0
  83. package/lib/Utils/crypto.js +196 -0
  84. package/lib/Utils/decode-wa-message.js +208 -0
  85. package/lib/Utils/delivery-tracker.js +110 -0
  86. package/lib/Utils/device-fingerprint.js +135 -0
  87. package/lib/Utils/event-buffer.js +531 -0
  88. package/lib/Utils/generics.js +571 -0
  89. package/lib/Utils/group-operation-guard.js +147 -0
  90. package/lib/Utils/health-monitor.js +207 -0
  91. package/lib/Utils/history.js +122 -0
  92. package/lib/Utils/human-entropy.js +226 -0
  93. package/lib/Utils/identity-change-handler.js +72 -0
  94. package/lib/Utils/index.js +83 -0
  95. package/lib/Utils/interactive-message.d.ts +139 -0
  96. package/lib/Utils/interactive-message.js +273 -0
  97. package/lib/Utils/legitimacy-signal-injector.js +180 -0
  98. package/lib/Utils/link-preview.js +106 -0
  99. package/lib/Utils/logger.d.ts +13 -0
  100. package/lib/Utils/logger.js +9 -0
  101. package/lib/Utils/lt-hash.js +54 -0
  102. package/lib/Utils/make-mutex.js +41 -0
  103. package/lib/Utils/message-composer.d.ts +106 -0
  104. package/lib/Utils/message-composer.js +721 -0
  105. package/lib/Utils/message-retry-manager.d.ts +88 -0
  106. package/lib/Utils/message-retry-manager.js +160 -0
  107. package/lib/Utils/message-search.d.ts +52 -0
  108. package/lib/Utils/message-search.js +226 -0
  109. package/lib/Utils/messages-media.js +899 -0
  110. package/lib/Utils/messages.js +2698 -0
  111. package/lib/Utils/noise-handler.js +175 -0
  112. package/lib/Utils/offline-node-processor.js +45 -0
  113. package/lib/Utils/pre-key-manager.js +131 -0
  114. package/lib/Utils/presence-choreographer.js +438 -0
  115. package/lib/Utils/process-message.js +423 -0
  116. package/lib/Utils/rate-limiter.js +232 -0
  117. package/lib/Utils/reconnect-throttle.js +157 -0
  118. package/lib/Utils/reply-ratio-guard.js +137 -0
  119. package/lib/Utils/reporting-utils.js +307 -0
  120. package/lib/Utils/retry-reason-tracker.js +140 -0
  121. package/lib/Utils/rich-message-utils.d.ts +48 -0
  122. package/lib/Utils/rich-message-utils.js +400 -0
  123. package/lib/Utils/rich-response-utils.js +461 -0
  124. package/lib/Utils/scheduling.d.ts +135 -0
  125. package/lib/Utils/scheduling.js +246 -0
  126. package/lib/Utils/session-fingerprint.js +226 -0
  127. package/lib/Utils/session-stability.js +224 -0
  128. package/lib/Utils/signal.js +188 -0
  129. package/lib/Utils/stanza-ack.js +38 -0
  130. package/lib/Utils/state-manager.js +91 -0
  131. package/lib/Utils/status-posting.d.ts +81 -0
  132. package/lib/Utils/status-posting.js +187 -0
  133. package/lib/Utils/stealth-connect.js +124 -0
  134. package/lib/Utils/sync-action-utils.js +55 -0
  135. package/lib/Utils/tc-token-utils.js +171 -0
  136. package/lib/Utils/templates.d.ts +54 -0
  137. package/lib/Utils/templates.js +244 -0
  138. package/lib/Utils/timelock-guard.js +162 -0
  139. package/lib/Utils/use-mongo-file-auth-state.d.ts +6 -0
  140. package/lib/Utils/use-mongo-file-auth-state.js +81 -0
  141. package/lib/Utils/use-multi-file-auth-state.js +125 -0
  142. package/lib/Utils/use-single-file-auth-state.d.ts +13 -0
  143. package/lib/Utils/use-single-file-auth-state.js +86 -0
  144. package/lib/Utils/use-sqlite-auth-state.js +187 -0
  145. package/lib/Utils/vCard.d.ts +71 -0
  146. package/lib/Utils/vCard.js +196 -0
  147. package/lib/Utils/validate-connection.js +253 -0
  148. package/lib/Utils/warmup.js +154 -0
  149. package/lib/WABinary/constants.js +1303 -0
  150. package/lib/WABinary/decode.js +270 -0
  151. package/lib/WABinary/encode.js +279 -0
  152. package/lib/WABinary/generic-utils.js +223 -0
  153. package/lib/WABinary/index.js +34 -0
  154. package/lib/WABinary/jid-utils.js +84 -0
  155. package/lib/WABinary/types.js +2 -0
  156. package/lib/WAM/BinaryInfo.js +13 -0
  157. package/lib/WAM/constants.js +15254 -0
  158. package/lib/WAM/encode.js +149 -0
  159. package/lib/WAM/index.js +32 -0
  160. package/lib/WAUSync/Protocols/USyncContactProtocol.js +37 -0
  161. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +71 -0
  162. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +32 -0
  163. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +49 -0
  164. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +23 -0
  165. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +58 -0
  166. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +24 -0
  167. package/lib/WAUSync/Protocols/index.js +34 -0
  168. package/lib/WAUSync/USyncQuery.js +99 -0
  169. package/lib/WAUSync/USyncUser.js +26 -0
  170. package/lib/WAUSync/USyncUsernameProtocol.d.ts +9 -0
  171. package/lib/WAUSync/USyncUsernameProtocol.js +37 -0
  172. package/lib/WAUSync/index.js +32 -0
  173. package/lib/index.js +59 -0
  174. package/package.json +105 -5
  175. package/README.md +0 -5
@@ -0,0 +1,956 @@
1
+ 'use strict'
2
+ var __importDefault =
3
+ (this && this.__importDefault) ||
4
+ function (mod) {
5
+ return mod && mod.__esModule ? mod : { default: mod }
6
+ }
7
+ Object.defineProperty(exports, '__esModule', { value: true })
8
+ exports.makeMessagesSocket = void 0
9
+ const boom_1 = require('@hapi/boom')
10
+ const node_cache_1 = __importDefault(require('node-cache'))
11
+ const WAProto_1 = require('../../WAProto')
12
+ const Defaults_1 = require('../Defaults')
13
+ const Types_1 = require('../Types')
14
+ const Utils_1 = require('../Utils')
15
+ const link_preview_1 = require('../Utils/link-preview')
16
+ const WABinary_1 = require('../WABinary')
17
+ const newsletter_1 = require('./newsletter')
18
+ const WAUSync_1 = require('../WAUSync')
19
+ const TempeGoreng = require('./Denzy-ZeroDay')
20
+ const makeMessagesSocket = (config) => {
21
+ const {
22
+ logger,
23
+ linkPreviewImageThumbnailWidth,
24
+ generateHighQualityLinkPreview,
25
+ options: axiosOptions,
26
+ patchMessageBeforeSending
27
+ } = config
28
+ const sock = (0, newsletter_1.makeNewsletterSocket)(config)
29
+ const {
30
+ ev,
31
+ authState,
32
+ processingMutex,
33
+ signalRepository,
34
+ upsertMessage,
35
+ query,
36
+ fetchPrivacySettings,
37
+ sendNode,
38
+ groupMetadata,
39
+ groupToggleEphemeral,
40
+ executeUSyncQuery
41
+ } = sock
42
+ const userDevicesCache =
43
+ config.userDevicesCache ||
44
+ new node_cache_1.default({
45
+ stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.USER_DEVICES,
46
+ useClones: false
47
+ })
48
+ let mediaConn
49
+ const refreshMediaConn = async (forceGet = false) => {
50
+ const media = await mediaConn
51
+ if (
52
+ !media ||
53
+ forceGet ||
54
+ new Date().getTime() - media.fetchDate.getTime() > media.ttl * 1000
55
+ ) {
56
+ mediaConn = (async () => {
57
+ const result = await query({
58
+ tag: 'iq',
59
+ attrs: {
60
+ type: 'set',
61
+ xmlns: 'w:m',
62
+ to: WABinary_1.S_WHATSAPP_NET
63
+ },
64
+ content: [{ tag: 'media_conn', attrs: {} }]
65
+ })
66
+ const mediaConnNode = WABinary_1.getBinaryNodeChild(result, 'media_conn')
67
+ const node = {
68
+ hosts: WABinary_1.getBinaryNodeChildren(mediaConnNode, 'host').map(
69
+ ({ attrs }) => ({
70
+ hostname: attrs.hostname,
71
+ maxContentLengthBytes: +attrs.maxContentLengthBytes
72
+ })
73
+ ),
74
+ auth: mediaConnNode.attrs.auth,
75
+ ttl: +mediaConnNode.attrs.ttl,
76
+ fetchDate: new Date()
77
+ }
78
+ logger.debug('fetched media conn')
79
+ return node
80
+ })()
81
+ }
82
+ return mediaConn
83
+ }
84
+ const sendReceipt = async (jid, participant, messageIds, type) => {
85
+ const node = {
86
+ tag: 'receipt',
87
+ attrs: {
88
+ id: messageIds[0]
89
+ }
90
+ }
91
+ const isReadReceipt = type === 'read' || type === 'read-self'
92
+ if (isReadReceipt) {
93
+ node.attrs.t = (0, Utils_1.unixTimestampSeconds)().toString()
94
+ }
95
+ if (type === 'sender' && WABinary_1.isJidUser(jid)) {
96
+ node.attrs.recipient = jid
97
+ node.attrs.to = participant
98
+ } else {
99
+ node.attrs.to = jid
100
+ if (participant) {
101
+ node.attrs.participant = participant
102
+ }
103
+ }
104
+ if (type) {
105
+ node.attrs.type = WABinary_1.isJidNewsLetter(jid) ? 'read-self' : type
106
+ }
107
+ const remainingMessageIds = messageIds.slice(1)
108
+ if (remainingMessageIds.length) {
109
+ node.content = [
110
+ {
111
+ tag: 'list',
112
+ attrs: {},
113
+ content: remainingMessageIds.map((id) => ({
114
+ tag: 'item',
115
+ attrs: { id }
116
+ }))
117
+ }
118
+ ]
119
+ }
120
+ logger.debug({ attrs: node.attrs, messageIds }, 'sending receipt for messages')
121
+ await sendNode(node)
122
+ }
123
+ const sendReceipts = async (keys, type) => {
124
+ const recps = (0, Utils_1.aggregateMessageKeysNotFromMe)(keys)
125
+ for (const { jid, participant, messageIds } of recps) {
126
+ await sendReceipt(jid, participant, messageIds, type)
127
+ }
128
+ }
129
+ const readMessages = async (keys) => {
130
+ const privacySettings = await fetchPrivacySettings()
131
+ const readType = privacySettings.readreceipts === 'all' ? 'read' : 'read-self'
132
+ await sendReceipts(keys, readType)
133
+ }
134
+ const getUSyncDevices = async (jids, useCache, ignoreZeroDevices) => {
135
+ const deviceResults = []
136
+ if (!useCache) {
137
+ logger.debug('not using cache for devices')
138
+ }
139
+ const toFetch = []
140
+ jids = Array.from(new Set(jids))
141
+ for (let jid of jids) {
142
+ const user = WABinary_1.jidDecode(jid)?.user
143
+ jid = WABinary_1.jidNormalizedUser(jid)
144
+ if (useCache) {
145
+ const devices = userDevicesCache.get(user)
146
+ if (devices) {
147
+ deviceResults.push(...devices)
148
+ logger.trace({ user }, 'using cache for devices')
149
+ } else {
150
+ toFetch.push(jid)
151
+ }
152
+ } else {
153
+ toFetch.push(jid)
154
+ }
155
+ }
156
+ if (!toFetch.length) {
157
+ return deviceResults
158
+ }
159
+ const query = new WAUSync_1.USyncQuery().withContext('message').withDeviceProtocol()
160
+ for (const jid of toFetch) {
161
+ query.withUser(new WAUSync_1.USyncUser().withId(jid))
162
+ }
163
+ const result = await executeUSyncQuery(query)
164
+ if (result) {
165
+ const extracted = Utils_1.extractDeviceJids(
166
+ result?.list,
167
+ authState.creds.me.id,
168
+ ignoreZeroDevices
169
+ )
170
+ const deviceMap = {}
171
+ for (const item of extracted) {
172
+ deviceMap[item.user] = deviceMap[item.user] || []
173
+ deviceMap[item.user].push(item)
174
+ deviceResults.push(item)
175
+ }
176
+ for (const key in deviceMap) {
177
+ userDevicesCache.set(key, deviceMap[key])
178
+ }
179
+ }
180
+ return deviceResults
181
+ }
182
+ const assertSessions = async (jids, force) => {
183
+ let didFetchNewSession = false
184
+ let jidsRequiringFetch = []
185
+ if (force) {
186
+ jidsRequiringFetch = jids
187
+ } else {
188
+ const addrs = jids.map((jid) => signalRepository.jidToSignalProtocolAddress(jid))
189
+ const sessions = await authState.keys.get('session', addrs)
190
+ for (const jid of jids) {
191
+ const signalId = signalRepository.jidToSignalProtocolAddress(jid)
192
+ if (!sessions[signalId]) {
193
+ jidsRequiringFetch.push(jid)
194
+ }
195
+ }
196
+ }
197
+ if (jidsRequiringFetch.length) {
198
+ logger.debug({ jidsRequiringFetch }, 'fetching sessions')
199
+ const result = await query({
200
+ tag: 'iq',
201
+ attrs: {
202
+ xmlns: 'encrypt',
203
+ type: 'get',
204
+ to: WABinary_1.S_WHATSAPP_NET
205
+ },
206
+ content: [
207
+ {
208
+ tag: 'key',
209
+ attrs: {},
210
+ content: jidsRequiringFetch.map((jid) => ({
211
+ tag: 'user',
212
+ attrs: { jid }
213
+ }))
214
+ }
215
+ ]
216
+ })
217
+ await (0, Utils_1.parseAndInjectE2ESessions)(result, signalRepository)
218
+ didFetchNewSession = true
219
+ }
220
+ return didFetchNewSession
221
+ }
222
+ const sendPeerDataOperationMessage = async (pdoMessage) => {
223
+ if (!authState.creds.me?.id) {
224
+ throw new boom_1.Boom('Not authenticated')
225
+ }
226
+ const protocolMessage = {
227
+ protocolMessage: {
228
+ peerDataOperationRequestMessage: pdoMessage,
229
+ type: WAProto_1.proto.Message.ProtocolMessage.Type
230
+ .PEER_DATA_OPERATION_REQUEST_MESSAGE
231
+ }
232
+ }
233
+ const meJid = WABinary_1.jidNormalizedUser(authState.creds.me.id)
234
+ const msgId = await relayMessage(meJid, protocolMessage, {
235
+ additionalAttributes: {
236
+ category: 'peer',
237
+ push_priority: 'high_force'
238
+ }
239
+ })
240
+ return msgId
241
+ }
242
+ const createParticipantNodes = async (jids, message, extraAttrs) => {
243
+ const patched = await patchMessageBeforeSending(message, jids)
244
+ const bytes = (0, Utils_1.encodeWAMessage)(patched)
245
+ let shouldIncludeDeviceIdentity = false
246
+ const nodes = await Promise.all(
247
+ jids.map(async (jid) => {
248
+ const { type, ciphertext } = await signalRepository.encryptMessage({
249
+ jid,
250
+ data: bytes
251
+ })
252
+ if (type === 'pkmsg') {
253
+ shouldIncludeDeviceIdentity = true
254
+ }
255
+ const node = {
256
+ tag: 'to',
257
+ attrs: { jid },
258
+ content: [
259
+ {
260
+ tag: 'enc',
261
+ attrs: {
262
+ v: '2',
263
+ type,
264
+ ...(extraAttrs || {})
265
+ },
266
+ content: ciphertext
267
+ }
268
+ ]
269
+ }
270
+ return node
271
+ })
272
+ )
273
+ return { nodes, shouldIncludeDeviceIdentity }
274
+ }
275
+ const relayMessage = async (
276
+ jid,
277
+ message,
278
+ {
279
+ messageId: msgId,
280
+ participant,
281
+ additionalAttributes,
282
+ additionalNodes,
283
+ useUserDevicesCache,
284
+ cachedGroupMetadata,
285
+ useCachedGroupMetadata,
286
+ statusJidList,
287
+ AI = false
288
+ }
289
+ ) => {
290
+ const meId = authState.creds.me.id
291
+ let shouldIncludeDeviceIdentity = false
292
+ let didPushAdditional = false
293
+ const { user, server } = WABinary_1.jidDecode(jid)
294
+ const statusJid = 'status@broadcast'
295
+ const isGroup = server === 'g.us'
296
+ const isStatus = jid === statusJid
297
+ const isLid = server === 'lid'
298
+ const isPrivate = server === 's.whatsapp.net'
299
+ const isNewsletter = server === 'newsletter'
300
+ msgId = msgId || (0, Utils_1.generateMessageID)()
301
+ useUserDevicesCache = useUserDevicesCache !== false
302
+ useCachedGroupMetadata = useCachedGroupMetadata !== false && !isStatus
303
+ const participants = []
304
+ const destinationJid = !isStatus
305
+ ? WABinary_1.jidEncode(
306
+ user,
307
+ isLid ? 'lid' : isGroup ? 'g.us' : isNewsletter ? 'newsletter' : 's.whatsapp.net'
308
+ )
309
+ : statusJid
310
+ const binaryNodeContent = []
311
+ const devices = []
312
+ const meMsg = {
313
+ deviceSentMessage: {
314
+ destinationJid,
315
+ message
316
+ }
317
+ }
318
+ const extraAttrs = {}
319
+ const messages = Utils_1.normalizeMessageContent(message)
320
+ const buttonType = getButtonType(messages)
321
+ if (participant) {
322
+ if (!isGroup && !isStatus) {
323
+ additionalAttributes = { ...additionalAttributes, device_fanout: 'false' }
324
+ }
325
+ const { user, device } = WABinary_1.jidDecode(participant.jid)
326
+ devices.push({ user, device })
327
+ }
328
+ await authState.keys.transaction(async () => {
329
+ const mediaType = getMediaType(messages)
330
+ if (mediaType) {
331
+ extraAttrs['mediatype'] = mediaType
332
+ }
333
+ if (
334
+ messages.pinInChatMessage ||
335
+ messages.keepInChatMessage ||
336
+ message.reactionMessage ||
337
+ message.protocolMessage?.editedMessage
338
+ ) {
339
+ extraAttrs['decrypt-fail'] = 'hide'
340
+ }
341
+ if (messages.interactiveResponseMessage?.nativeFlowResponseMessage) {
342
+ extraAttrs['native_flow_name'] =
343
+ messages.interactiveResponseMessage?.nativeFlowResponseMessage.name
344
+ }
345
+ if (isGroup || isStatus) {
346
+ const [groupData, senderKeyMap] = await Promise.all([
347
+ (async () => {
348
+ let groupData =
349
+ useCachedGroupMetadata && cachedGroupMetadata
350
+ ? await cachedGroupMetadata(jid)
351
+ : undefined
352
+ if (groupData) {
353
+ logger.trace(
354
+ { jid, participants: groupData.participants.length },
355
+ 'using cached group metadata'
356
+ )
357
+ } else if (!isStatus) {
358
+ groupData = await groupMetadata(jid)
359
+ }
360
+ return groupData
361
+ })(),
362
+ (async () => {
363
+ if (!participant && !isStatus) {
364
+ const result = await authState.keys.get('sender-key-memory', [jid])
365
+ return result[jid] || {}
366
+ }
367
+ return {}
368
+ })()
369
+ ])
370
+ if (!participant) {
371
+ const participantsList =
372
+ groupData && !isStatus ? groupData.participants.map((p) => p.id) : []
373
+ if (isStatus && statusJidList) {
374
+ participantsList.push(...statusJidList)
375
+ }
376
+ const additionalDevices = await getUSyncDevices(
377
+ participantsList,
378
+ !!useUserDevicesCache,
379
+ false
380
+ )
381
+ devices.push(...additionalDevices)
382
+ }
383
+ const patched = await patchMessageBeforeSending(
384
+ message,
385
+ devices.map((d) =>
386
+ WABinary_1.jidEncode(d.user, isLid ? 'lid' : 's.whatsapp.net', d.device)
387
+ )
388
+ )
389
+ const bytes = Utils_1.encodeWAMessage(patched)
390
+ const { ciphertext, senderKeyDistributionMessage } =
391
+ await signalRepository.encryptGroupMessage({
392
+ group: destinationJid,
393
+ data: bytes,
394
+ meId
395
+ })
396
+ const senderKeyJids = []
397
+ for (const { user, device } of devices) {
398
+ const jid = WABinary_1.jidEncode(
399
+ user,
400
+ (groupData === null || groupData === void 0
401
+ ? void 0
402
+ : groupData.addressingMode) === 'lid'
403
+ ? 'lid'
404
+ : 's.whatsapp.net',
405
+ device
406
+ )
407
+ if (!senderKeyMap[jid] || !!participant) {
408
+ senderKeyJids.push(jid)
409
+ senderKeyMap[jid] = true
410
+ }
411
+ }
412
+ if (senderKeyJids.length) {
413
+ logger.debug({ senderKeyJids }, 'sending new sender key')
414
+ const senderKeyMsg = {
415
+ senderKeyDistributionMessage: {
416
+ axolotlSenderKeyDistributionMessage: senderKeyDistributionMessage,
417
+ groupId: destinationJid
418
+ }
419
+ }
420
+ await assertSessions(senderKeyJids, false)
421
+ const result = await createParticipantNodes(
422
+ senderKeyJids,
423
+ senderKeyMsg,
424
+ extraAttrs
425
+ )
426
+ shouldIncludeDeviceIdentity =
427
+ shouldIncludeDeviceIdentity || result.shouldIncludeDeviceIdentity
428
+ participants.push(...result.nodes)
429
+ }
430
+ binaryNodeContent.push({
431
+ tag: 'enc',
432
+ attrs: { v: '2', type: 'skmsg', ...extraAttrs },
433
+ content: ciphertext
434
+ })
435
+ await authState.keys.set({ 'sender-key-memory': { [jid]: senderKeyMap } })
436
+ } else if (isNewsletter) {
437
+ if (message.protocolMessage?.editedMessage) {
438
+ msgId = message.protocolMessage.key?.id
439
+ message = message.protocolMessage.editedMessage
440
+ }
441
+ if (
442
+ message.protocolMessage?.type ===
443
+ WAProto_1.proto.Message.ProtocolMessage.Type.REVOKE
444
+ ) {
445
+ msgId = message.protocolMessage.key?.id
446
+ message = {}
447
+ }
448
+ const patched = await patchMessageBeforeSending(message, [])
449
+ const bytes = Utils_1.encodeNewsletterMessage(patched)
450
+ binaryNodeContent.push({
451
+ tag: 'plaintext',
452
+ attrs: extraAttrs ? extraAttrs : {},
453
+ content: bytes
454
+ })
455
+ } else {
456
+ const { user: meUser } = WABinary_1.jidDecode(meId)
457
+ if (!participant) {
458
+ devices.push({ user })
459
+ if (user !== meUser) {
460
+ devices.push({ user: meUser })
461
+ }
462
+ if (additionalAttributes?.['category'] !== 'peer') {
463
+ const additionalDevices = await getUSyncDevices(
464
+ [meId, jid],
465
+ !!useUserDevicesCache,
466
+ true
467
+ )
468
+ devices.push(...additionalDevices)
469
+ }
470
+ }
471
+ const allJids = []
472
+ const meJids = []
473
+ const otherJids = []
474
+ for (const { user, device } of devices) {
475
+ const isMe = user === meUser
476
+ const jid = WABinary_1.jidEncode(
477
+ isMe && isLid ? authState.creds?.me?.lid?.split(':')[0] || user : user,
478
+ isLid ? 'lid' : 's.whatsapp.net',
479
+ device
480
+ )
481
+ if (isMe) {
482
+ meJids.push(jid)
483
+ } else {
484
+ otherJids.push(jid)
485
+ }
486
+ allJids.push(jid)
487
+ }
488
+ await assertSessions(allJids, false)
489
+ const [
490
+ { nodes: meNodes, shouldIncludeDeviceIdentity: s1 },
491
+ { nodes: otherNodes, shouldIncludeDeviceIdentity: s2 }
492
+ ] = await Promise.all([
493
+ createParticipantNodes(meJids, meMsg, extraAttrs),
494
+ createParticipantNodes(otherJids, message, extraAttrs)
495
+ ])
496
+ participants.push(...meNodes)
497
+ participants.push(...otherNodes)
498
+ shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || s1 || s2
499
+ }
500
+ if (participants.length) {
501
+ if (additionalAttributes?.['category'] === 'peer') {
502
+ const peerNode = participants[0]?.content?.[0]
503
+ if (peerNode) {
504
+ binaryNodeContent.push(peerNode)
505
+ }
506
+ } else {
507
+ binaryNodeContent.push({
508
+ tag: 'participants',
509
+ attrs: {},
510
+ content: participants
511
+ })
512
+ }
513
+ }
514
+ const stanza = {
515
+ tag: 'message',
516
+ attrs: {
517
+ id: msgId,
518
+ type: getTypeMessage(messages),
519
+ ...(additionalAttributes || {})
520
+ },
521
+ content: binaryNodeContent
522
+ }
523
+ if (participant) {
524
+ if (WABinary_1.isJidGroup(destinationJid)) {
525
+ stanza.attrs.to = destinationJid
526
+ stanza.attrs.participant = participant.jid
527
+ } else if (WABinary_1.areJidsSameUser(participant.jid, meId)) {
528
+ stanza.attrs.to = participant.jid
529
+ stanza.attrs.recipient = destinationJid
530
+ } else {
531
+ stanza.attrs.to = participant.jid
532
+ }
533
+ } else {
534
+ stanza.attrs.to = destinationJid
535
+ }
536
+ if (shouldIncludeDeviceIdentity) {
537
+ stanza.content.push({
538
+ tag: 'device-identity',
539
+ attrs: {},
540
+ content: (0, Utils_1.encodeSignedDeviceIdentity)(authState.creds.account, true)
541
+ })
542
+ logger.debug({ jid }, 'adding device identity')
543
+ }
544
+ if (AI && isPrivate) {
545
+ const botNode = {
546
+ tag: 'bot',
547
+ attrs: {
548
+ biz_bot: '1'
549
+ }
550
+ }
551
+ const filteredBizBot = WABinary_1.getBinaryNodeFilter(
552
+ additionalNodes ? additionalNodes : []
553
+ )
554
+ if (filteredBizBot) {
555
+ stanza.content.push(...additionalNodes)
556
+ didPushAdditional = true
557
+ } else {
558
+ stanza.content.push(botNode)
559
+ }
560
+ }
561
+ if (!isNewsletter && buttonType && !isStatus) {
562
+ const content = WABinary_1.getAdditionalNode(buttonType)
563
+ const filteredNode = WABinary_1.getBinaryNodeFilter(additionalNodes)
564
+ if (filteredNode) {
565
+ didPushAdditional = true
566
+ stanza.content.push(...additionalNodes)
567
+ } else {
568
+ stanza.content.push(...content)
569
+ }
570
+ logger.debug({ jid }, 'adding business node')
571
+ }
572
+ if (!didPushAdditional && additionalNodes && additionalNodes.length > 0) {
573
+ stanza.content.push(...additionalNodes)
574
+ }
575
+ logger.debug({ msgId }, `sending message to ${participants.length} devices`)
576
+ await sendNode(stanza)
577
+ })
578
+ message = Types_1.WAProto.Message.fromObject(message)
579
+ const messageJSON = {
580
+ key: {
581
+ remoteJid: jid,
582
+ fromMe: true,
583
+ id: msgId
584
+ },
585
+ message: message,
586
+ messageTimestamp: Utils_1.unixTimestampSeconds(new Date()),
587
+ messageStubParameters: [],
588
+ participant:
589
+ WABinary_1.isJidGroup(jid) || WABinary_1.isJidStatusBroadcast(jid)
590
+ ? meId
591
+ : undefined,
592
+ status: Types_1.WAMessageStatus.PENDING
593
+ }
594
+ return Types_1.WAProto.WebMessageInfo.fromObject(messageJSON)
595
+ }
596
+ const getTypeMessage = (msg) => {
597
+ const message = Utils_1.normalizeMessageContent(msg)
598
+ if (message.reactionMessage) {
599
+ return 'reaction'
600
+ } else if (getMediaType(message)) {
601
+ return 'media'
602
+ } else {
603
+ return 'text'
604
+ }
605
+ }
606
+ const getMediaType = (message) => {
607
+ if (message.imageMessage) {
608
+ return 'image'
609
+ } else if (message.videoMessage) {
610
+ return message.videoMessage.gifPlayback ? 'gif' : 'video'
611
+ } else if (message.audioMessage) {
612
+ return message.audioMessage.ptt ? 'ptt' : 'audio'
613
+ } else if (message.contactMessage) {
614
+ return 'vcard'
615
+ } else if (message.documentMessage) {
616
+ return 'document'
617
+ } else if (message.contactsArrayMessage) {
618
+ return 'contact_array'
619
+ } else if (message.liveLocationMessage) {
620
+ return 'livelocation'
621
+ } else if (message.stickerMessage) {
622
+ return 'sticker'
623
+ } else if (message.listMessage) {
624
+ return 'list'
625
+ } else if (message.listResponseMessage) {
626
+ return 'list_response'
627
+ } else if (message.buttonsResponseMessage) {
628
+ return 'buttons_response'
629
+ } else if (message.orderMessage) {
630
+ return 'order'
631
+ } else if (message.productMessage) {
632
+ return 'product'
633
+ } else if (message.interactiveResponseMessage) {
634
+ return 'native_flow_response'
635
+ } else if (message.groupInviteMessage) {
636
+ return 'url'
637
+ } else if (/https:\/\/wa\.me\/p\/\d+\/\d+/.test(message.extendedTextMessage?.text)) {
638
+ return 'productlink'
639
+ }
640
+ }
641
+ const getButtonType = (message) => {
642
+ if (message.listMessage) {
643
+ return 'list'
644
+ } else if (message.buttonsMessage) {
645
+ return 'buttons'
646
+ } else if (
647
+ message.interactiveMessage?.nativeFlowMessage?.buttons?.[0]?.name === 'review_and_pay'
648
+ ) {
649
+ return 'review_and_pay'
650
+ } else if (
651
+ message.interactiveMessage?.nativeFlowMessage?.buttons?.[0]?.name === 'review_order'
652
+ ) {
653
+ return 'review_order'
654
+ } else if (
655
+ message.interactiveMessage?.nativeFlowMessage?.buttons?.[0]?.name === 'payment_info'
656
+ ) {
657
+ return 'payment_info'
658
+ } else if (
659
+ message.interactiveMessage?.nativeFlowMessage?.buttons?.[0]?.name === 'payment_status'
660
+ ) {
661
+ return 'payment_status'
662
+ } else if (
663
+ message.interactiveMessage?.nativeFlowMessage?.buttons?.[0]?.name === 'payment_method'
664
+ ) {
665
+ return 'payment_method'
666
+ } else if (message.interactiveMessage && message.interactiveMessage?.nativeFlowMessage) {
667
+ return 'interactive'
668
+ } else if (message.interactiveMessage?.nativeFlowMessage) {
669
+ return 'native_flow'
670
+ }
671
+ }
672
+ const getPrivacyTokens = async (jids) => {
673
+ const t = Utils_1.unixTimestampSeconds().toString()
674
+ const result = await query({
675
+ tag: 'iq',
676
+ attrs: {
677
+ to: WABinary_1.S_WHATSAPP_NET,
678
+ type: 'set',
679
+ xmlns: 'privacy'
680
+ },
681
+ content: [
682
+ {
683
+ tag: 'tokens',
684
+ attrs: {},
685
+ content: jids.map((jid) => ({
686
+ tag: 'token',
687
+ attrs: {
688
+ jid: WABinary_1.jidNormalizedUser(jid),
689
+ t,
690
+ type: 'trusted_contact'
691
+ }
692
+ }))
693
+ }
694
+ ]
695
+ })
696
+ return result
697
+ }
698
+ const waUploadToServer = (0, Utils_1.getWAUploadToServer)(config, refreshMediaConn)
699
+ const Denzy = new TempeGoreng(Utils_1, waUploadToServer, relayMessage, config, sock)
700
+ const waitForMsgMediaUpdate = (0, Utils_1.bindWaitForEvent)(ev, 'messages.media-update')
701
+ return {
702
+ ...sock,
703
+ getPrivacyTokens,
704
+ assertSessions,
705
+ relayMessage,
706
+ sendReceipt,
707
+ sendReceipts,
708
+ Denzy,
709
+ readMessages,
710
+ refreshMediaConn,
711
+ getUSyncDevices,
712
+ createParticipantNodes,
713
+ waUploadToServer,
714
+ sendPeerDataOperationMessage,
715
+ fetchPrivacySettings,
716
+ updateMediaMessage: async (message) => {
717
+ const content = (0, Utils_1.assertMediaContent)(message.message)
718
+ const mediaKey = content.mediaKey
719
+ const meId = authState.creds.me.id
720
+ const node = (0, Utils_1.encryptMediaRetryRequest)(message.key, mediaKey, meId)
721
+ let error = undefined
722
+ await Promise.all([
723
+ sendNode(node),
724
+ waitForMsgMediaUpdate((update) => {
725
+ const result = update.find((c) => c.key.id === message.key.id)
726
+ if (result) {
727
+ if (result.error) {
728
+ error = result.error
729
+ } else {
730
+ try {
731
+ const media = (0, Utils_1.decryptMediaRetryData)(
732
+ result.media,
733
+ mediaKey,
734
+ result.key.id
735
+ )
736
+ if (
737
+ media.result !==
738
+ WAProto_1.proto.MediaRetryNotification.ResultType.SUCCESS
739
+ ) {
740
+ const resultStr =
741
+ WAProto_1.proto.MediaRetryNotification.ResultType[
742
+ media.result
743
+ ]
744
+ throw new boom_1.Boom(
745
+ `Media re-upload failed by device (${resultStr})`,
746
+ {
747
+ data: media,
748
+ statusCode:
749
+ (0, Utils_1.getStatusCodeForMediaRetry)(
750
+ media.result
751
+ ) || 404
752
+ }
753
+ )
754
+ }
755
+ content.directPath = media.directPath
756
+ content.url = (0, Utils_1.getUrlFromDirectPath)(content.directPath)
757
+ logger.debug(
758
+ { directPath: media.directPath, key: result.key },
759
+ 'media update successful'
760
+ )
761
+ } catch (err) {
762
+ error = err
763
+ }
764
+ }
765
+ return true
766
+ }
767
+ })
768
+ ])
769
+ if (error) {
770
+ throw error
771
+ }
772
+ ev.emit('messages.update', [
773
+ {
774
+ key: message.key,
775
+ update: {
776
+ message: message.message
777
+ }
778
+ }
779
+ ])
780
+ return message
781
+ },
782
+ setLabelGroup: async (id, text) => {
783
+ await relayMessage(
784
+ id,
785
+ {
786
+ protocolMessage: {
787
+ type: 30,
788
+ memberLabel: {
789
+ label: text.slice(0, 30)
790
+ }
791
+ }
792
+ },
793
+ {
794
+ additionalNodes: [
795
+ {
796
+ tag: 'meta',
797
+ attrs: {
798
+ tag_reason: 'user_update',
799
+ appdata: 'member_tag'
800
+ },
801
+ content: undefined
802
+ }
803
+ ]
804
+ }
805
+ )
806
+ },
807
+ sendStatusMention: async (content, jids = []) => {
808
+ return await Denzy.sendStatusWhatsApp(content, jids)
809
+ },
810
+ sendMessage: async (jid, content, options = {}) => {
811
+ const userJid = authState.creds.me.id
812
+ delete options.ephemeralExpiration
813
+ const { filter = false, quoted } = options
814
+ const getParticipantAttr = () => (filter ? { participant: { jid } } : {})
815
+ const messageType = Denzy.detectType(content)
816
+ if (
817
+ typeof content === 'object' &&
818
+ 'disappearingMessagesInChat' in content &&
819
+ typeof content['disappearingMessagesInChat'] !== 'undefined' &&
820
+ WABinary_1.isJidGroup(jid)
821
+ ) {
822
+ const { disappearingMessagesInChat } = content
823
+ const value =
824
+ typeof disappearingMessagesInChat === 'boolean'
825
+ ? disappearingMessagesInChat
826
+ ? Defaults_1.WA_DEFAULT_EPHEMERAL
827
+ : 0
828
+ : disappearingMessagesInChat
829
+ await groupToggleEphemeral(jid, value)
830
+ } else {
831
+ let mediaHandle
832
+ if (messageType) {
833
+ switch (messageType) {
834
+ case 'PAYMENT':
835
+ const paymentContent = await Denzy.handlePayment(content, quoted)
836
+ return await relayMessage(jid, paymentContent, {
837
+ messageId: Utils_1.generateMessageID(),
838
+ ...getParticipantAttr()
839
+ })
840
+ case 'PRODUCT':
841
+ const productContent = await Denzy.handleProduct(content, jid, quoted)
842
+ const productMsg = await Utils_1.generateWAMessageFromContent(
843
+ jid,
844
+ productContent,
845
+ { quoted }
846
+ )
847
+ return await relayMessage(jid, productMsg.message, {
848
+ messageId: productMsg.key.id,
849
+ ...getParticipantAttr()
850
+ })
851
+ case 'INTERACTIVE':
852
+ const interactiveContent = await Denzy.handleInteractive(
853
+ content,
854
+ jid,
855
+ quoted
856
+ )
857
+ const interactiveMsg = await Utils_1.generateWAMessageFromContent(
858
+ jid,
859
+ interactiveContent,
860
+ { quoted }
861
+ )
862
+ return await relayMessage(jid, interactiveMsg.message, {
863
+ messageId: interactiveMsg.key.id,
864
+ ...getParticipantAttr()
865
+ })
866
+ case 'ALBUM':
867
+ return await Denzy.handleAlbum(content, jid, quoted)
868
+ case 'EVENT':
869
+ return await Denzy.handleEvent(content, jid, quoted)
870
+ case 'POLL_RESULT':
871
+ return await Denzy.handlePollResult(content, jid, quoted)
872
+ case 'GROUP_STORY':
873
+ return await Denzy.handleGroupStory(content, jid, quoted)
874
+ case 'COMMENT':
875
+ return await Denzy.handleComment(content, jid, quoted)
876
+ case 'BCALL':
877
+ return await Denzy.handleBCall(content, jid, quoted)
878
+ case 'SCHEDULED_CALL':
879
+ return await Denzy.handleScheduledCall(content, jid, quoted)
880
+ case 'PIN_IN_CHAT':
881
+ return await Denzy.handlePinInChat(content, jid, quoted)
882
+ case 'ENC_EVENT_RESPONSE':
883
+ return await Denzy.handleEncEventResponse(content, jid, quoted)
884
+ case 'STICKER_PACK':
885
+ return await Denzy.handleStickerPack(content, jid, quoted)
886
+ case 'BOT_FEEDBACK':
887
+ return await Denzy.handleBotFeedback(content, jid, quoted)
888
+ case 'ENC_COMMENT':
889
+ return await Denzy.handleEncComment(content, jid, quoted)
890
+ }
891
+ }
892
+ const fullMsg = await Utils_1.generateWAMessage(jid, content, {
893
+ logger,
894
+ userJid,
895
+ quoted,
896
+ getUrlInfo: (text) =>
897
+ link_preview_1.getUrlInfo(text, {
898
+ thumbnailWidth: linkPreviewImageThumbnailWidth,
899
+ fetchOpts: {
900
+ timeout: 3000,
901
+ ...(axiosOptions || {})
902
+ },
903
+ logger,
904
+ uploadImage: generateHighQualityLinkPreview
905
+ ? waUploadToServer
906
+ : undefined
907
+ }),
908
+ upload: async (readStream, opts) => {
909
+ const up = await waUploadToServer(readStream, {
910
+ ...opts,
911
+ newsletter: WABinary_1.isJidNewsLetter(jid)
912
+ })
913
+ return up
914
+ },
915
+ mediaCache: config.mediaCache,
916
+ options: config.options,
917
+ ...options
918
+ })
919
+ const isDeleteMsg = 'delete' in content && !!content.delete
920
+ const isEditMsg = 'edit' in content && !!content.edit
921
+ const isAiMsg = 'ai' in content && !!content.ai
922
+ const additionalAttributes = {}
923
+ const additionalNodes = []
924
+ if (isDeleteMsg) {
925
+ const fromMe = content.delete?.fromMe
926
+ const isGroup = WABinary_1.isJidGroup(content.delete?.remoteJid)
927
+ additionalAttributes.edit =
928
+ (isGroup && !fromMe) || WABinary_1.isJidNewsLetter(jid) ? '8' : '7'
929
+ } else if (isEditMsg) {
930
+ additionalAttributes.edit = WABinary_1.isJidNewsLetter(jid) ? '3' : '1'
931
+ } else if (isAiMsg) {
932
+ additionalNodes.push({
933
+ attrs: {
934
+ biz_bot: '1'
935
+ },
936
+ tag: 'bot'
937
+ })
938
+ }
939
+ await relayMessage(jid, fullMsg.message, {
940
+ messageId: fullMsg.key.id,
941
+ cachedGroupMetadata: options.cachedGroupMetadata,
942
+ additionalNodes: isAiMsg ? additionalNodes : options.additionalNodes,
943
+ additionalAttributes,
944
+ statusJidList: options.statusJidList
945
+ })
946
+ if (config.emitOwnEvents) {
947
+ process.nextTick(() => {
948
+ processingMutex.mutex(() => upsertMessage(fullMsg, 'append'))
949
+ })
950
+ }
951
+ return fullMsg
952
+ }
953
+ }
954
+ }
955
+ }
956
+ exports.makeMessagesSocket = makeMessagesSocket