@pontasockets/baileys 0.2.0 → 0.2.3

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.
@@ -1,1471 +0,0 @@
1
- "use strict"
2
-
3
- var __importDefault = (this && this.__importDefault) || function(mod) {
4
- return (mod && mod.__esModule) ? mod : {
5
- "default": mod
6
- }
7
- }
8
-
9
- Object.defineProperty(exports, "__esModule", {
10
- value: true
11
- })
12
-
13
- const node_cache_1 = __importDefault(require("@cacheable/node-cache"))
14
- const boom_1 = require("@hapi/boom")
15
- const crypto_1 = require("crypto")
16
- const WAProto_1 = require("../../WAProto")
17
- const Defaults_1 = require("../Defaults")
18
- const Utils_1 = require("../Utils")
19
- const Types_1 = require("../Types")
20
- const WABinary_1 = require("../WABinary")
21
- const WAUSync_1 = require("../WAUSync")
22
- const newsletter_1 = require("./newsletter")
23
- const link_preview_1 = require("../Utils/link-preview")
24
- const make_keyed_mutex_1 = require("../Utils/make-mutex")
25
-
26
- const makeMessagesSocket = (config) => {
27
- const {
28
- logger,
29
- maxMsgRetryCount,
30
- linkPreviewImageThumbnailWidth,
31
- generateHighQualityLinkPreview,
32
- options: axiosOptions,
33
- patchMessageBeforeSending,
34
- cachedGroupMetadata,
35
- enableRecentMessageCache
36
- } = config
37
- const sock = newsletter_1.makeNewsletterSocket(config)
38
- const {
39
- ev,
40
- authState,
41
- processingMutex,
42
- signalRepository,
43
- upsertMessage,
44
- createCallLink,
45
- query,
46
- fetchPrivacySettings,
47
- sendNode,
48
- groupQuery,
49
- groupMetadata,
50
- groupToggleEphemeral,
51
- newsletterWMexQuery,
52
- executeUSyncQuery
53
- } = sock
54
-
55
- const userDevicesCache = config.userDevicesCache || new node_cache_1.default({
56
- stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.USER_DEVICES,
57
- useClones: false
58
- })
59
-
60
- const messageRetryManager = enableRecentMessageCache ? new Utils_1.MessageRetryManager(logger, maxMsgRetryCount) : null
61
- const encryptionMutex = make_keyed_mutex_1.makeKeyedMutex()
62
- let mediaConn
63
-
64
- const refreshMediaConn = async (forceGet = false) => {
65
- const media = await mediaConn
66
- if (!media || forceGet || (new Date().getTime() - media.fetchDate.getTime()) > media.ttl * 1000) {
67
- mediaConn = (async () => {
68
- const result = await query({
69
- tag: 'iq',
70
- attrs: {
71
- type: 'set',
72
- xmlns: 'w:m',
73
- to: WABinary_1.S_WHATSAPP_NET,
74
- },
75
- content: [{
76
- tag: 'media_conn',
77
- attrs: {}
78
- }]
79
- })
80
- const mediaConnNode = WABinary_1.getBinaryNodeChild(result, 'media_conn')
81
- const node = {
82
- hosts: WABinary_1.getBinaryNodeChildren(mediaConnNode, 'host').map(({
83
- attrs
84
- }) => ({
85
- hostname: attrs.hostname,
86
- maxContentLengthBytes: +attrs.maxContentLengthBytes,
87
- })),
88
- auth: mediaConnNode.attrs.auth,
89
- ttl: +mediaConnNode.attrs.ttl,
90
- fetchDate: new Date()
91
- }
92
- logger.debug('fetched media conn')
93
- return node
94
- })()
95
- }
96
- return mediaConn
97
- }
98
-
99
- const sendReceipt = async (jid, participant, messageIds, type) => {
100
- const node = {
101
- tag: 'receipt',
102
- attrs: {
103
- id: messageIds[0],
104
- },
105
- }
106
- const isReadReceipt = type === 'read' || type === 'read-self'
107
- if (isReadReceipt) {
108
- node.attrs.t = Utils_1.unixTimestampSeconds().toString()
109
- }
110
- if (type === 'sender' && WABinary_1.isJidUser(jid)) {
111
- node.attrs.recipient = jid
112
- node.attrs.to = participant
113
- } else {
114
- node.attrs.to = jid
115
- if (participant) {
116
- node.attrs.participant = participant
117
- }
118
- }
119
- if (type) {
120
- node.attrs.type = WABinary_1.isJidNewsletter(jid) ? 'read-self' : type
121
- }
122
- const remainingMessageIds = messageIds.slice(1)
123
- if (remainingMessageIds.length) {
124
- node.content = [{
125
- tag: 'list',
126
- attrs: {},
127
- content: remainingMessageIds.map(id => ({
128
- tag: 'item',
129
- attrs: {
130
- id
131
- }
132
- }))
133
- }]
134
- }
135
- logger.debug({
136
- attrs: node.attrs,
137
- messageIds
138
- }, 'sending receipt for messages')
139
- await sendNode(node)
140
- }
141
-
142
- const sendReceipts = async (keys, type) => {
143
- const recps = Utils_1.aggregateMessageKeysNotFromMe(keys)
144
- for (const { jid, participant, messageIds } of recps) {
145
- await sendReceipt(jid, participant, messageIds, type)
146
- }
147
- }
148
-
149
- const readMessages = async (keys) => {
150
- const privacySettings = await fetchPrivacySettings()
151
- const readType = privacySettings.readreceipts === 'all' ? 'read' : 'read-self'
152
- await sendReceipts(keys, readType)
153
- }
154
-
155
- const deduplicateLidPnJids = (jids) => {
156
- const lidUsers = new Set()
157
- const filteredJids = []
158
-
159
- for (const jid of jids) {
160
- if (WABinary_1.isLidUser(jid)) {
161
- const user = WABinary_1.jidDecode(jid)?.user
162
- if (user) lidUsers.add(user)
163
- }
164
- }
165
-
166
- for (const jid of jids) {
167
- if (WABinary_1.isJidUser(jid)) {
168
- const user = WABinary_1.jidDecode(jid)?.user
169
- if (user && lidUsers.has(user)) {
170
- logger.debug({
171
- jid
172
- }, 'Skipping PN - LID version exists')
173
- continue
174
- }
175
- }
176
- filteredJids.push(jid)
177
- }
178
- return filteredJids
179
- }
180
-
181
- const profilePictureUrl = async (jid) => {
182
- if (WABinary_1.isJidNewsletter(jid)) {
183
- let node = await newsletterWMexQuery(undefined, Types_1.QueryIds.METADATA, {
184
- input: {
185
- key: jid,
186
- type: 'JID',
187
- view_role: 'GUEST'
188
- },
189
- fetch_viewer_metadata: true,
190
- fetch_full_image: true,
191
- fetch_creation_time: true
192
- })
193
- let result = WABinary_1.getBinaryNodeChild(node, 'result')?.content?.toString()
194
- let metadata = JSON.parse(result).data[Types_1.XWAPaths.NEWSLETTER]
195
- return Utils_1.getUrlFromDirectPath(metadata.thread_metadata.picture?.direct_path || '')
196
- } else {
197
- const result = await query({
198
- tag: 'iq',
199
- attrs: {
200
- target: WABinary_1.jidNormalizedUser(jid),
201
- to: WABinary_1.S_WHATSAPP_NET,
202
- type: 'get',
203
- xmlns: 'w:profile:picture'
204
- },
205
- content: [{
206
- tag: 'picture',
207
- attrs: {
208
- type: 'image',
209
- query: 'url'
210
- }
211
- }]
212
- })
213
- const child = WABinary_1.getBinaryNodeChild(result, 'picture')
214
- return child?.attrs?.url || null
215
- }
216
- }
217
-
218
- const getUSyncDevices = async (jids, useCache, ignoreZeroDevices) => {
219
- const deviceResults = []
220
-
221
- if (!useCache) {
222
- logger.debug('not using cache for devices')
223
- }
224
-
225
- const toFetch = []
226
-
227
- jids = deduplicateLidPnJids(Array.from(new Set(jids)))
228
- const jidsWithUser = jids
229
- .map(jid => {
230
- const decoded = WABinary_1.jidDecode(jid)
231
- const user = decoded?.user
232
- const device = decoded?.device
233
- const isExplicitDevice = typeof device === 'number' && device >= 0
234
-
235
- if (isExplicitDevice && user) {
236
- deviceResults.push({
237
- user,
238
- device,
239
- wireJid: jid
240
- });
241
- return null
242
- }
243
-
244
- jid = WABinary_1.jidNormalizedUser(jid)
245
- return {
246
- jid,
247
- user
248
- }
249
- })
250
- .filter(jid => jid !== null)
251
-
252
- let mgetDevices
253
- if (useCache && userDevicesCache.mget) {
254
- const usersToFetch = jidsWithUser.map(j => j?.user).filter(Boolean)
255
- mgetDevices = await userDevicesCache.mget(usersToFetch)
256
- }
257
-
258
- for (const { jid, user } of jidsWithUser) {
259
- if (useCache) {
260
- const devices = mgetDevices?.[user] || (userDevicesCache.mget ? undefined : (await userDevicesCache.get(user)))
261
- if (devices) {
262
- const isLidJid = WABinary_1.isLidUser(jid)
263
- const devicesWithWire = devices.map(d => ({
264
- ...d,
265
- wireJid: isLidJid ? WABinary_1.jidEncode(d.user, 'lid', d.device) : WABinary_1.jidEncode(d.user, 's.whatsapp.net', d.device)
266
- }))
267
- deviceResults.push(...devicesWithWire)
268
- logger.trace({
269
- user
270
- }, 'using cache for devices')
271
- } else {
272
- toFetch.push(jid)
273
- }
274
- } else {
275
- toFetch.push(jid)
276
- }
277
- }
278
-
279
- if (!toFetch.length) {
280
- return deviceResults
281
- }
282
-
283
- const requestedLidUsers = new Set()
284
- for (const jid of toFetch) {
285
- if (WABinary_1.isLidUser(jid)) {
286
- const user = WABinary_1.jidDecode(jid)?.user
287
- if (user) requestedLidUsers.add(user)
288
- }
289
- }
290
-
291
- const query = new WAUSync_1.USyncQuery().withContext('message').withDeviceProtocol()
292
- for (const jid of toFetch) {
293
- query.withUser(new WAUSync_1.USyncUser().withId(jid))
294
- }
295
-
296
- const result = await executeUSyncQuery(query)
297
- if (result) {
298
- const extracted = Utils_1.extractDeviceJids(result?.list, authState.creds.me.id, ignoreZeroDevices)
299
- const deviceMap = {}
300
- for (const item of extracted) {
301
- deviceMap[item.user] = deviceMap[item.user] || []
302
- deviceMap[item.user]?.push(item)
303
- }
304
- for (const [user, userDevices] of Object.entries(deviceMap)) {
305
- const isLidUser = requestedLidUsers.has(user)
306
- for (const item of userDevices) {
307
- const finalWireJid = isLidUser ? WABinary_1.jidEncode(user, 'lid', item.device) : WABinary_1.jidEncode(item.user, 's.whatsapp.net', item.device)
308
- deviceResults.push({
309
- ...item,
310
- wireJid: finalWireJid
311
- });
312
- logger.debug({
313
- user: item.user,
314
- device: item.device,
315
- finalWireJid,
316
- usedLid: isLidUser
317
- }, 'Processed device with LID priority')
318
- }
319
- }
320
-
321
- if (userDevicesCache.mset) {
322
- await userDevicesCache.mset(Object.entries(deviceMap).map(([key, value]) => ({
323
- key,
324
- value
325
- })))
326
- } else {
327
- for (const key in deviceMap) {
328
- if (deviceMap[key]) await userDevicesCache.set(key, deviceMap[key])
329
- }
330
- }
331
- }
332
- return deviceResults
333
- }
334
-
335
- const assertSessions = async (jids, force) => {
336
- let didFetchNewSession = false;
337
- let jidsRequiringFetch = [];
338
-
339
- if (force) {
340
- jidsRequiringFetch = jids;
341
- } else {
342
- const addrs = jids.map(jid => (signalRepository.jidToSignalProtocolAddress(jid)));
343
- const sessions = await authState.keys.get('session', addrs);
344
- for (const jid of jids) {
345
- const signalId = signalRepository.jidToSignalProtocolAddress(jid);
346
- if (!sessions[signalId]) {
347
- jidsRequiringFetch.push(jid);
348
- }
349
- }
350
- }
351
-
352
- if (jidsRequiringFetch.length) {
353
- logger.debug({ jidsRequiringFetch }, 'fetching sessions');
354
-
355
- const result = await query({
356
- tag: 'iq',
357
- attrs: {
358
- xmlns: 'encrypt',
359
- type: 'get',
360
- to: WABinary_1.S_WHATSAPP_NET,
361
- },
362
- content: [
363
- {
364
- tag: 'key',
365
- attrs: {},
366
- content: jidsRequiringFetch.map(jid => ({
367
- tag: 'user',
368
- attrs: { jid },
369
- }))
370
- }
371
- ]
372
- });
373
- await (0, Utils_1.parseAndInjectE2ESessions)(result, signalRepository);
374
- didFetchNewSession = true;
375
- }
376
- return didFetchNewSession;
377
- };
378
-
379
- const sendPeerDataOperationMessage = async (pdoMessage) => {
380
- if (!authState.creds.me?.id) {
381
- throw new boom_1.Boom('Not authenticated')
382
- }
383
-
384
- const protocolMessage = {
385
- protocolMessage: {
386
- peerDataOperationRequestMessage: pdoMessage,
387
- type: WAProto_1.proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_MESSAGE
388
- }
389
- }
390
-
391
- const meJid = WABinary_1.jidNormalizedUser(authState.creds.me.id)
392
- const msgId = await relayMessage(meJid, protocolMessage, {
393
- additionalAttributes: {
394
- category: 'peer',
395
- push_priority: 'high_force',
396
- },
397
- })
398
- return msgId
399
- }
400
-
401
- const createParticipantNodes = async (jids, message, extraAttrs) => {
402
- let patched = await patchMessageBeforeSending(message, jids);
403
-
404
- if (!Array.isArray(patched)) {
405
- patched = jids ? jids.map(jid => ({ recipientJid: jid, ...patched })) : [patched];
406
- }
407
-
408
- let shouldIncludeDeviceIdentity = false;
409
- const nodes = await Promise.all(patched.map(async (patchedMessageWithJid) => {
410
- const { recipientJid: jid, ...patchedMessage } = patchedMessageWithJid;
411
- if (!jid) {
412
- return {};
413
- }
414
-
415
- const bytes = (0, Utils_1.encodeWAMessage)(patchedMessage);
416
- const { type, ciphertext } = await signalRepository.encryptMessage({ jid, data: bytes });
417
- if (type === 'pkmsg') {
418
- shouldIncludeDeviceIdentity = true;
419
- }
420
- const node = {
421
- tag: 'to',
422
- attrs: { jid },
423
- content: [{
424
- tag: 'enc',
425
- attrs: {
426
- v: '2',
427
- type,
428
- ...extraAttrs || {}
429
- },
430
- content: ciphertext
431
- }]
432
- };
433
- return node;
434
- }));
435
- return { nodes, shouldIncludeDeviceIdentity };
436
- };
437
-
438
- const relayMessage = async (jid, message, {
439
- messageId: msgId,
440
- participant,
441
- additionalAttributes,
442
- useUserDevicesCache,
443
- useCachedGroupMetadata,
444
- statusJidList,
445
- additionalNodes,
446
- ai = false
447
- }) => {
448
- const meId = authState.creds.me.id
449
- const meLid = authState.creds.me?.lid
450
-
451
- let additionalAlready = false
452
- let shouldIncludeDeviceIdentity = false
453
-
454
- const {
455
- user,
456
- server
457
- } = WABinary_1.jidDecode(jid)
458
-
459
- const statusJid = 'status@broadcast'
460
- const isGroup = server === 'g.us'
461
- const isPrivate = server === 's.whatsapp.net'
462
- const isNewsletter = server == 'newsletter'
463
- const isStatus = jid === statusJid
464
- const isLid = server === 'lid'
465
-
466
- const finalJid = jid
467
-
468
- let ownId = meId
469
-
470
- if (isLid && meLid) {
471
- ownId = meLid
472
- logger.debug({
473
- to: jid,
474
- ownId
475
- }, 'Using LID identity for @lid conversation')
476
- } else {
477
- logger.debug({
478
- to: jid,
479
- ownId
480
- }, 'Using PN identity for @s.whatsapp.net conversation')
481
- }
482
-
483
- msgId = msgId || Utils_1.generateMessageID(authState.creds.me.id)
484
- useUserDevicesCache = useUserDevicesCache !== false
485
- useCachedGroupMetadata = useCachedGroupMetadata !== false && !isStatus
486
-
487
- const participants = []
488
- const destinationJid = !isStatus ? finalJid : statusJid
489
- const binaryNodeContent = []
490
- const devices = []
491
-
492
- const meMsg = {
493
- deviceSentMessage: {
494
- destinationJid,
495
- message
496
- },
497
- messageContextInfo: message.messageContextInfo || {}
498
- }
499
-
500
- const extraAttrs = {}
501
- const regexGroupOld = /^(\d{1,15})-(\d+)@g\.us$/
502
- const messages = Utils_1.normalizeMessageContent(message)
503
- const buttonType = getButtonType(messages)
504
- const pollMessage = messages.pollCreationMessage || messages.pollCreationMessageV2 || messages.pollCreationMessageV3
505
-
506
- if (participant) {
507
- if (!isGroup && !isStatus) {
508
- additionalAttributes = {
509
- ...additionalAttributes,
510
- 'device_fanout': 'false'
511
- }
512
- }
513
-
514
- const {
515
- user,
516
- device
517
- } = WABinary_1.jidDecode(participant.jid)
518
-
519
- devices.push({
520
- user,
521
- device,
522
- wireJid: participant.jid
523
- })
524
- }
525
-
526
- await authState.keys.transaction(async () => {
527
- const mediaType = getMediaType(message)
528
- if (mediaType) {
529
- extraAttrs['mediatype'] = mediaType
530
- }
531
-
532
- if (messages.pinInChatMessage || messages.keepInChatMessage || message.reactionMessage || message.protocolMessage?.editedMessage) {
533
- extraAttrs['decrypt-fail'] = 'hide'
534
- }
535
-
536
- if (messages.interactiveResponseMessage?.nativeFlowResponseMessage) {
537
- extraAttrs['native_flow_name'] = messages.interactiveResponseMessage.nativeFlowResponseMessage?.name || 'menu_options'
538
- }
539
-
540
- if (isGroup || isStatus) {
541
- const [groupData, senderKeyMap] = await Promise.all([
542
- (async () => {
543
- let groupData = useCachedGroupMetadata && cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined
544
- if (groupData && Array.isArray(groupData?.participants)) {
545
- logger.trace({
546
- jid,
547
- participants: groupData.participants.length
548
- }, 'using cached group metadata')
549
- } else if (!isStatus) {
550
- groupData = await global.groupMetadataCache(jid)
551
- }
552
- return groupData
553
- })(),
554
- (async () => {
555
- if (!participant && !isStatus) {
556
- const result = await authState.keys.get('sender-key-memory', [jid])
557
- return result[jid] || {}
558
- }
559
- return {}
560
- })()
561
- ])
562
-
563
- if (!participant) {
564
- const participantsList = (groupData && !isStatus) ? groupData.participants.map(p => p.id) : []
565
- if (isStatus && statusJidList) {
566
- participantsList.push(...statusJidList)
567
- }
568
- if (!isStatus) {
569
- const groupAddressingMode = groupData?.addressingMode || (isLid ? Types_1.WAMessageAddressingMode.LID : Types_1.WAMessageAddressingMode.PN)
570
- additionalAttributes = {
571
- ...additionalAttributes,
572
- addressing_mode: groupAddressingMode
573
- }
574
- }
575
- const additionalDevices = await getUSyncDevices(participantsList, !!useUserDevicesCache, false)
576
- devices.push(...additionalDevices)
577
- }
578
-
579
- const patched = await patchMessageBeforeSending(message, devices.map(d => WABinary_1.jidEncode(d.user, isLid ? 'lid' : 's.whatsapp.net', d.device)))
580
- const bytes = Utils_1.encodeWAMessage(patched)
581
-
582
- const groupAddressingMode = groupData?.addressingMode || (isLid ? 'lid' : 'pn')
583
- const groupSenderIdentity = groupAddressingMode === 'lid' && meLid ? meLid : meId
584
-
585
- const {
586
- ciphertext,
587
- senderKeyDistributionMessage
588
- } = await signalRepository.encryptGroupMessage({
589
- group: destinationJid,
590
- data: bytes,
591
- meId: groupSenderIdentity
592
- })
593
-
594
- const senderKeyJids = []
595
-
596
- for (const device of devices) {
597
- const deviceJid = device.wireJid
598
- const hasKey = !!senderKeyMap[deviceJid]
599
- if (!hasKey || !!participant) {
600
- senderKeyJids.push(deviceJid)
601
- senderKeyMap[deviceJid] = true
602
- }
603
- }
604
-
605
- if (senderKeyJids.length) {
606
- logger.debug({
607
- senderKeyJids
608
- }, 'sending new sender key')
609
- const senderKeyMsg = {
610
- senderKeyDistributionMessage: {
611
- axolotlSenderKeyDistributionMessage: senderKeyDistributionMessage,
612
- groupId: destinationJid
613
- }
614
- }
615
-
616
- await assertSessions(senderKeyJids, false)
617
- const result = await createParticipantNodes(senderKeyJids, senderKeyMsg, extraAttrs)
618
- shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || result.shouldIncludeDeviceIdentity
619
- participants.push(...result.nodes)
620
- }
621
-
622
- binaryNodeContent.push({
623
- tag: 'enc',
624
- attrs: {
625
- v: '2',
626
- type: 'skmsg',
627
- ...extraAttrs
628
- },
629
- content: ciphertext
630
- })
631
-
632
- await authState.keys.set({
633
- 'sender-key-memory': {
634
- [jid]: senderKeyMap
635
- }
636
- })
637
- } else if (isNewsletter) {
638
- if (message.protocolMessage?.editedMessage) {
639
- msgId = message.protocolMessage.key?.id
640
- message = message.protocolMessage.editedMessage
641
- }
642
-
643
- if (message.protocolMessage?.type === WAProto_1.proto.Message.ProtocolMessage.Type.REVOKE) {
644
- msgId = message.protocolMessage.key?.id
645
- message = {}
646
- }
647
-
648
- const patched = await patchMessageBeforeSending(message, [])
649
- const bytes = Utils_1.encodeNewsletterMessage(patched)
650
-
651
- binaryNodeContent.push({
652
- tag: 'plaintext',
653
- attrs: extraAttrs,
654
- content: bytes
655
- })
656
- } else {
657
- const {
658
- user: ownUser
659
- } = WABinary_1.jidDecode(ownId)
660
-
661
- if (!participant) {
662
- const targetUserServer = isLid ? 'lid' : 's.whatsapp.net'
663
- devices.push({
664
- user,
665
- device: 0,
666
- wireJid: WABinary_1.jidEncode(user, targetUserServer, 0)
667
- })
668
-
669
- if (user !== ownUser) {
670
- const ownUserServer = isLid ? 'lid' : 's.whatsapp.net';
671
- const ownUserForAddressing = isLid && meLid ? WABinary_1.jidDecode(meLid).user : WABinary_1.jidDecode(meId).user
672
- devices.push({
673
- user: ownUserForAddressing,
674
- device: 0,
675
- wireJid: WABinary_1.jidEncode(ownUserForAddressing, ownUserServer, 0)
676
- })
677
- }
678
-
679
- if (additionalAttributes?.['category'] !== 'peer') {
680
- devices.length = 0
681
- const senderIdentity = isLid && meLid ? WABinary_1.jidEncode(WABinary_1.jidDecode(meLid)?.user, 'lid', undefined) : WABinary_1.jidEncode(WABinary_1.jidDecode(meId)?.user, 's.whatsapp.net', undefined)
682
- const sessionDevices = await getUSyncDevices([senderIdentity, jid], false, false)
683
- devices.push(...sessionDevices)
684
- logger.debug({
685
- deviceCount: devices.length,
686
- devices: devices.map(d => `${d.user}:${d.device}@${WABinary_1.jidDecode(d.wireJid)?.server}`)
687
- }, 'Device enumeration complete with unified addressing')
688
- }
689
- }
690
-
691
- const allJids = []
692
- const meJids = []
693
- const otherJids = []
694
-
695
- const {
696
- user: mePnUser
697
- } = WABinary_1.jidDecode(meId)
698
- const {
699
- user: meLidUser
700
- } = meLid ? WABinary_1.jidDecode(meLid) : {
701
- user: null
702
- }
703
-
704
- for (const { user, wireJid } of devices) {
705
- const isExactSenderDevice = wireJid === meId || (meLid && wireJid === meLid)
706
- if (isExactSenderDevice) {
707
- logger.debug({
708
- wireJid,
709
- meId,
710
- meLid
711
- }, 'Skipping exact sender device (whatsmeow pattern)')
712
- continue
713
- }
714
- const isMe = user === mePnUser || (meLidUser && user === meLidUser)
715
- const jid = wireJid
716
- if (isMe) {
717
- meJids.push(jid)
718
- } else {
719
- otherJids.push(jid)
720
- }
721
- allJids.push(jid)
722
- }
723
-
724
- await assertSessions([...otherJids, ...meJids], false)
725
- const [{
726
- nodes: meNodes,
727
- shouldIncludeDeviceIdentity: s1
728
- }, {
729
- nodes: otherNodes,
730
- shouldIncludeDeviceIdentity: s2
731
- }] = await Promise.all([
732
- createParticipantNodes(meJids, meMsg || message, extraAttrs),
733
- createParticipantNodes(otherJids, message, extraAttrs, meMsg)
734
- ])
735
-
736
- participants.push(...meNodes)
737
- participants.push(...otherNodes)
738
- if (meJids.length > 0 || otherJids.length > 0) {
739
- extraAttrs['phash'] = Utils_1.generateParticipantHashV2([...meJids, ...otherJids])
740
- }
741
- shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || s1 || s2
742
- }
743
-
744
- if (participants.length) {
745
- if (additionalAttributes?.['category'] === 'peer') {
746
- const peerNode = participants[0]?.content?.[0]
747
- if (peerNode) {
748
- binaryNodeContent.push(peerNode)
749
- }
750
- } else {
751
- binaryNodeContent.push({
752
- tag: 'participants',
753
- attrs: {},
754
- content: participants
755
- })
756
- }
757
- }
758
-
759
- const stanza = {
760
- tag: 'message',
761
- attrs: {
762
- to: destinationJid,
763
- id: msgId,
764
- type: getTypeMessage(message),
765
- ...(additionalAttributes || {})
766
- },
767
- content: binaryNodeContent
768
- }
769
-
770
- if (participant) {
771
- if (WABinary_1.isJidGroup(destinationJid)) {
772
- stanza.attrs.to = destinationJid
773
- stanza.attrs.participant = participant.jid
774
- } else if (WABinary_1.areJidsSameUser(participant.jid, meId)) {
775
- stanza.attrs.to = participant.jid
776
- stanza.attrs.recipient = destinationJid
777
- } else {
778
- stanza.attrs.to = participant.jid
779
- }
780
- } else {
781
- stanza.attrs.to = destinationJid
782
- }
783
-
784
- if (shouldIncludeDeviceIdentity) {
785
- stanza.content.push({
786
- tag: 'device-identity',
787
- attrs: {},
788
- content: Utils_1.encodeSignedDeviceIdentity(authState.creds.account, true)
789
- })
790
- logger.debug({
791
- jid
792
- }, 'adding device identity')
793
- }
794
-
795
- if (isGroup && regexGroupOld.test(jid) && !message.reactionMessage) {
796
- stanza.content.push({
797
- tag: 'multicast',
798
- attrs: {}
799
- })
800
- }
801
-
802
- if (pollMessage || messages.eventMessage) {
803
- let attrs = {};
804
- if (messages.eventMessage) {
805
- attrs.event_type = 'creation';
806
- } else {
807
- attrs.polltype = 'creation';
808
- if (isNewsletter) {
809
- attrs.contenttype = (pollMessage && pollMessage.pollContentType === 2) ? 'image' : 'text';
810
- }
811
- }
812
- stanza.content.push({
813
- tag: 'meta',
814
- attrs: attrs
815
- });
816
- }
817
-
818
- if (!isNewsletter && buttonType) {
819
- const buttonsNode = getButtonArgs(messages)
820
- const filteredButtons = WABinary_1.getBinaryFilteredButtons(additionalNodes ? additionalNodes : [])
821
- if (filteredButtons) {
822
- stanza.content.push(...additionalNodes)
823
- additionalAlready = true
824
- } else {
825
- stanza.content.push(buttonsNode)
826
- }
827
- }
828
-
829
- if (!ai && isPrivate) {
830
- const botNode = {
831
- tag: 'bot',
832
- attrs: {
833
- biz_bot: '1'
834
- }
835
- }
836
- const filteredBizBot = WABinary_1.getBinaryFilteredBizBot(additionalNodes ? additionalNodes : [])
837
- if (filteredBizBot) {
838
- stanza.content.push(...additionalNodes)
839
- additionalAlready = true
840
- } else {
841
- stanza.content.push(botNode)
842
- }
843
- }
844
-
845
- if (!additionalAlready && additionalNodes && additionalNodes.length > 0) {
846
- stanza.content.push(...additionalNodes)
847
- }
848
-
849
- logger.debug({
850
- msgId
851
- }, `sending message to ${participants.length} devices`)
852
-
853
- await sendNode(stanza)
854
- if (messageRetryManager && !participant) {
855
- messageRetryManager.addRecentMessage(destinationJid, msgId, message)
856
- }
857
- }, meId)
858
- return msgId
859
- }
860
-
861
- const getTypeMessage = (msg) => {
862
- const message = Utils_1.normalizeMessageContent(msg)
863
- if (message.pollCreationMessage || message.pollCreationMessageV2 || message.pollCreationMessageV3) {
864
- return 'poll'
865
- } else if (message.reactionMessage) {
866
- return 'reaction'
867
- } else if (message.eventMessage) {
868
- return 'event'
869
- } else if (getMediaType(message)) {
870
- return 'media'
871
- } else {
872
- return 'text'
873
- }
874
- }
875
-
876
- const getMediaType = (message) => {
877
- if (message.imageMessage) {
878
- return 'image'
879
- } else if (message.stickerMessage) {
880
- return message.stickerMessage.isLottie ? '1p_sticker' : message.stickerMessage.isAvatar ? 'avatar_sticker' : 'sticker'
881
- } else if (message.videoMessage) {
882
- return message.videoMessage.gifPlayback ? 'gif' : 'video'
883
- } else if (message.audioMessage) {
884
- return message.audioMessage.ptt ? 'ptt' : 'audio'
885
- } else if (message.ptvMessage) {
886
- return 'ptv'
887
- } else if (message.albumMessage) {
888
- return 'collection'
889
- } else if (message.contactMessage) {
890
- return 'vcard'
891
- } else if (message.documentMessage) {
892
- return 'document'
893
- } else if (message.stickerPackMessage) {
894
- return 'sticker_pack'
895
- } else if (message.contactsArrayMessage) {
896
- return 'contact_array'
897
- } else if (message.locationMessage) {
898
- return 'location'
899
- } else if (message.liveLocationMessage) {
900
- return 'livelocation'
901
- } else if (message.listMessage) {
902
- return 'list'
903
- } else if (message.listResponseMessage) {
904
- return 'list_response'
905
- } else if (message.buttonsResponseMessage) {
906
- return 'buttons_response'
907
- } else if (message.orderMessage) {
908
- return 'order'
909
- } else if (message.productMessage) {
910
- return 'product'
911
- } else if (message.interactiveResponseMessage) {
912
- return 'native_flow_response'
913
- } else if (/https:\/\/wa\.me\/c\/\d+/.test(message.extendedTextMessage?.text)) {
914
- return 'cataloglink'
915
- } else if (/https:\/\/wa\.me\/p\/\d+\/\d+/.test(message.extendedTextMessage?.text)) {
916
- return 'productlink'
917
- } else if (message.extendedTextMessage?.matchedText || message.groupInviteMessage) {
918
- return 'url'
919
- }
920
- }
921
-
922
- const getButtonType = (message) => {
923
- const message_content = message.viewOnceMessage?.message || message;
924
- if (message_content.listMessage) {
925
- return 'list';
926
- } else if (message_content.buttonsMessage) {
927
- return 'buttons';
928
- } else if (message_content.interactiveMessage?.nativeFlowMessage) {
929
- return 'native_flow';
930
- }
931
- };
932
-
933
- const getButtonArgs = (message) => {
934
- const message_content = message.viewOnceMessage?.message || message;
935
- const message_flow = message_content.interactiveMessage?.nativeFlowMessage;
936
- const flow_buttons_first = message_flow?.buttons?.[0]?.name;
937
- const flow_buttons_special = [ 'mpm', 'cta_catalog', 'send_location', 'call_permission_request', 'wa_payment_transaction_details', 'automated_greeting_message_view_catalog' ];
938
- const baseArgs = {
939
- tag: 'biz',
940
- attrs: {
941
- actual_actors: '2',
942
- host_storage: '2',
943
- privacy_mode_ts: Utils_1.unixTimestampSeconds().toString()
944
- }
945
- };
946
- if (message_flow && (flow_buttons_first === 'review_and_pay' || flow_buttons_first === 'payment_info')) {
947
- return {
948
- tag: 'biz',
949
- attrs: {
950
- native_flow_name: flow_buttons_first === 'review_and_pay' ? 'order_details' : flow_buttons_first
951
- }
952
- };
953
- }
954
- if (message_flow && flow_buttons_special.includes(flow_buttons_first)) {
955
- return {
956
- ...baseArgs,
957
- content: [
958
- {
959
- tag: 'interactive',
960
- attrs: { type: 'native_flow', v: '1' },
961
- content: [{
962
- tag: 'native_flow',
963
- attrs: { v: '2', name: flow_buttons_first }
964
- }]
965
- },
966
- {
967
- tag: 'quality_control',
968
- attrs: { source_type: 'third_party' }
969
- }
970
- ]
971
- };
972
- }
973
- if (message_flow || message_content.buttonsMessage) {
974
- return {
975
- ...baseArgs,
976
- content: [
977
- {
978
- tag: 'interactive',
979
- attrs: { type: 'native_flow', v: '1' },
980
- content: [{
981
- tag: 'native_flow',
982
- attrs: { v: '9', name: 'mixed' }
983
- }]
984
- },
985
- {
986
- tag: 'quality_control',
987
- attrs: { source_type: 'third_party' }
988
- }
989
- ]
990
- };
991
- }
992
- if (message_content.listMessage) {
993
- return {
994
- ...baseArgs,
995
- content: [
996
- {
997
- tag: 'list',
998
- attrs: { v: '2', type: 'product_list' }
999
- },
1000
- {
1001
- tag: 'quality_control',
1002
- attrs: { source_type: 'third_party' }
1003
- }
1004
- ]
1005
- };
1006
- }
1007
- return baseArgs;
1008
- };
1009
-
1010
- const getPrivacyTokens = async (jids) => {
1011
- const t = Utils_1.unixTimestampSeconds().toString()
1012
-
1013
- const result = await query({
1014
- tag: 'iq',
1015
- attrs: {
1016
- to: WABinary_1.S_WHATSAPP_NET,
1017
- type: 'set',
1018
- xmlns: 'privacy'
1019
- },
1020
- content: [{
1021
- tag: 'tokens',
1022
- attrs: {},
1023
- content: jids.map(jid => ({
1024
- tag: 'token',
1025
- attrs: {
1026
- jid: WABinary_1.jidNormalizedUser(jid),
1027
- t,
1028
- type: 'trusted_contact'
1029
- }
1030
- }))
1031
- }]
1032
- })
1033
-
1034
- return result
1035
- }
1036
-
1037
- const getEphemeralGroup = (jid) => {
1038
- if (!WABinary_1.isJidGroup(jid)) throw new TypeError("Jid should originate from a group!")
1039
-
1040
- return groupQuery(jid, 'get', [{
1041
- tag: 'query',
1042
- attrs: {
1043
- request: 'interactive'
1044
- }
1045
- }])
1046
- .then((groups) => WABinary_1.getBinaryNodeChild(groups, 'group'))
1047
- .then((metadata) => WABinary_1.getBinaryNodeChild(metadata, 'ephemeral')?.attrs?.expiration || 0)
1048
- }
1049
-
1050
- const waUploadToServer = Utils_1.getWAUploadToServer(config, refreshMediaConn)
1051
-
1052
- const waitForMsgMediaUpdate = Utils_1.bindWaitForEvent(ev, 'messages.media-update')
1053
-
1054
- return {
1055
- ...sock,
1056
- getPrivacyTokens,
1057
- assertSessions,
1058
- relayMessage,
1059
- sendReceipt,
1060
- sendReceipts,
1061
- readMessages,
1062
- profilePictureUrl,
1063
- getUSyncDevices,
1064
- refreshMediaConn,
1065
- waUploadToServer,
1066
- getEphemeralGroup,
1067
- fetchPrivacySettings,
1068
- messageRetryManager,
1069
- createParticipantNodes,
1070
- sendPeerDataOperationMessage,
1071
- updateMediaMessage: async (message) => {
1072
- const content = Utils_1.assertMediaContent(message.message)
1073
- const mediaKey = content.mediaKey
1074
- const meId = authState.creds.me.id
1075
- const node = await Utils_1.encryptMediaRetryRequest(message.key, mediaKey, meId)
1076
- let error = undefined
1077
-
1078
- await Promise.all([
1079
- sendNode(node),
1080
- waitForMsgMediaUpdate(async (update) => {
1081
- const result = update.find(c => c.key.id === message.key.id)
1082
- if (result) {
1083
- if (result.error) {
1084
- error = result.error
1085
- } else {
1086
- try {
1087
- const media = await Utils_1.decryptMediaRetryData(result.media, mediaKey, result.key.id)
1088
-
1089
- if (media.result !== WAProto_1.proto.MediaRetryNotification.ResultType.SUCCESS) {
1090
- const resultStr = WAProto_1.proto.MediaRetryNotification.ResultType[media.result]
1091
-
1092
- throw new boom_1.Boom(`Media re-upload failed by device (${resultStr})`, {
1093
- data: media,
1094
- statusCode: Utils_1.getStatusCodeForMediaRetry(media.result) || 404
1095
- })
1096
- }
1097
-
1098
- content.directPath = media.directPath
1099
-
1100
- content.url = Utils_1.getUrlFromDirectPath(content.directPath)
1101
-
1102
- logger.debug({
1103
- directPath: media.directPath,
1104
- key: result.key
1105
- }, 'media update successful')
1106
- } catch (err) {
1107
- error = err
1108
- }
1109
- }
1110
-
1111
- return true
1112
- }
1113
- })
1114
- ])
1115
-
1116
- if (error) {
1117
- throw error
1118
- }
1119
-
1120
- ev.emit('messages.update', [{
1121
- key: message.key,
1122
- update: {
1123
- message: message.message
1124
- }
1125
- }])
1126
-
1127
- return message
1128
- },
1129
- sendStatusMentions: async (content, jids = []) => {
1130
- const userJid = WABinary_1.jidNormalizedUser(authState.creds.me.id)
1131
- let allUsers = new Set()
1132
- allUsers.add(userJid)
1133
-
1134
- for (const id of jids) {
1135
- const isGroup = WABinary_1.isJidGroup(id)
1136
- const isPrivate = WABinary_1.isJidUser(id)
1137
-
1138
- if (isGroup) {
1139
- try {
1140
- const metadata = await cachedGroupMetadata(id) || await global.groupMetadataCache(id)
1141
- const participants = metadata.participants.map(p => WABinary_1.jidNormalizedUser(p.id))
1142
- participants.forEach(jid => allUsers.add(jid))
1143
- } catch (error) {
1144
- logger.error(`Error getting metadata for group ${id}: ${error}`)
1145
- }
1146
- } else if (isPrivate) {
1147
- allUsers.add(WABinary_1.jidNormalizedUser(id))
1148
- }
1149
- }
1150
-
1151
- const uniqueUsers = Array.from(allUsers)
1152
- const getRandomHexColor = () => "#" + Math.floor(Math.random() * 16777215).toString(16).padStart(6, "0")
1153
-
1154
- const isMedia = content.image || content.video || content.audio
1155
- const isAudio = !!content.audio
1156
-
1157
- const messageContent = {
1158
- ...content
1159
- }
1160
-
1161
- if (isMedia && !isAudio) {
1162
- if (messageContent.text) {
1163
- messageContent.caption = messageContent.text
1164
-
1165
- delete messageContent.text
1166
- }
1167
-
1168
- delete messageContent.ptt
1169
- delete messageContent.font
1170
- delete messageContent.backgroundColor
1171
- delete messageContent.textColor
1172
- }
1173
-
1174
- if (isAudio) {
1175
- delete messageContent.text
1176
- delete messageContent.caption
1177
- delete messageContent.font
1178
- delete messageContent.textColor
1179
- }
1180
-
1181
- const font = !isMedia ? (content.font || Math.floor(Math.random() * 9)) : undefined
1182
- const textColor = !isMedia ? (content.textColor || getRandomHexColor()) : undefined
1183
- const backgroundColor = (!isMedia || isAudio) ? (content.backgroundColor || getRandomHexColor()) : undefined
1184
- const ptt = isAudio ? (typeof content.ptt === 'boolean' ? content.ptt : true) : undefined
1185
-
1186
- let msg
1187
- let mediaHandle
1188
- try {
1189
- msg = await Utils_1.generateWAMessage(WABinary_1.STORIES_JID, messageContent, {
1190
- logger,
1191
- userJid,
1192
- getUrlInfo: text => link_preview_1.getUrlInfo(text, {
1193
- thumbnailWidth: linkPreviewImageThumbnailWidth,
1194
- fetchOpts: {
1195
- timeout: 3000,
1196
- ...axiosOptions || {}
1197
- },
1198
- logger,
1199
- uploadImage: generateHighQualityLinkPreview ? waUploadToServer : undefined
1200
- }),
1201
- upload: async (encFilePath, opts) => {
1202
- const up = await waUploadToServer(encFilePath, {
1203
- ...opts
1204
- })
1205
- mediaHandle = up.handle
1206
- return up
1207
- },
1208
- mediaCache: config.mediaCache,
1209
- options: config.options,
1210
- font,
1211
- textColor,
1212
- backgroundColor,
1213
- ptt
1214
- })
1215
- } catch (error) {
1216
- logger.error(`Error generating message: ${error}`)
1217
- throw error
1218
- }
1219
-
1220
- await relayMessage(WABinary_1.STORIES_JID, msg.message, {
1221
- messageId: msg.key.id,
1222
- statusJidList: uniqueUsers,
1223
- additionalNodes: [{
1224
- tag: 'meta',
1225
- attrs: {},
1226
- content: [{
1227
- tag: 'mentioned_users',
1228
- attrs: {},
1229
- content: jids.map(jid => ({
1230
- tag: 'to',
1231
- attrs: {
1232
- jid: WABinary_1.jidNormalizedUser(jid)
1233
- }
1234
- }))
1235
- }]
1236
- }]
1237
- })
1238
-
1239
- for (const id of jids) {
1240
- try {
1241
- const normalizedId = WABinary_1.jidNormalizedUser(id)
1242
- const isPrivate = WABinary_1.isJidUser(normalizedId)
1243
- const type = isPrivate ? 'statusMentionMessage' : 'groupStatusMentionMessage'
1244
-
1245
- const protocolMessage = {
1246
- [type]: {
1247
- message: {
1248
- protocolMessage: {
1249
- key: msg.key,
1250
- type: 25
1251
- }
1252
- }
1253
- },
1254
- messageContextInfo: {
1255
- messageSecret: crypto_1.randomBytes(32)
1256
- }
1257
- }
1258
-
1259
- const statusMsg = await Utils_1.generateWAMessageFromContent(normalizedId,
1260
- protocolMessage, {}
1261
- )
1262
-
1263
- await relayMessage(
1264
- normalizedId,
1265
- statusMsg.message, {
1266
- additionalNodes: [{
1267
- tag: 'meta',
1268
- attrs: isPrivate ? {
1269
- is_status_mention: 'true'
1270
- } : {
1271
- is_group_status_mention: 'true'
1272
- }
1273
- }]
1274
- }
1275
- )
1276
-
1277
- await Utils_1.delay(2000)
1278
- } catch (error) {
1279
- logger.error(`Error sending to ${id}: ${error}`)
1280
- }
1281
- }
1282
-
1283
- return msg
1284
- },
1285
- sendAlbumMessage: async (jid, medias, options = {}) => {
1286
- const userJid = authState.creds.me.id
1287
- for (const media of medias) {
1288
- if (!media.image && !media.video) throw new TypeError(`medias[i] must have image or video property`)
1289
- }
1290
- if (medias.length < 2) throw new RangeError("Minimum 2 media")
1291
- const time = options.delay || 500
1292
- delete options.delay
1293
- const album = await Utils_1.generateWAMessageFromContent(jid, {
1294
- albumMessage: {
1295
- expectedImageCount: medias.filter(media => media.image).length,
1296
- expectedVideoCount: medias.filter(media => media.video).length,
1297
- ...options
1298
- }
1299
- }, {
1300
- userJid,
1301
- ...options
1302
- })
1303
- await relayMessage(jid, album.message, {
1304
- messageId: album.key.id
1305
- })
1306
- let mediaHandle
1307
- let msg
1308
- for (const i in medias) {
1309
- const media = medias[i]
1310
- if (media.image) {
1311
- msg = await Utils_1.generateWAMessage(jid, {
1312
- image: media.image,
1313
- ...media,
1314
- ...options
1315
- }, {
1316
- userJid,
1317
- upload: async (readStream, opts) => {
1318
- const up = await waUploadToServer(readStream, {
1319
- ...opts,
1320
- newsletter: WABinary_1.isJidNewsletter(jid)
1321
- })
1322
- mediaHandle = up.handle
1323
- return up
1324
- },
1325
- ...options
1326
- })
1327
- } else if (media.video) {
1328
- msg = await Utils_1.generateWAMessage(jid, {
1329
- video: media.video,
1330
- ...media,
1331
- ...options
1332
- }, {
1333
- userJid,
1334
- upload: async (readStream, opts) => {
1335
- const up = await waUploadToServer(readStream, {
1336
- ...opts,
1337
- newsletter: WABinary_1.isJidNewsletter(jid)
1338
- })
1339
- mediaHandle = up.handle
1340
- return up
1341
- },
1342
- ...options,
1343
- })
1344
- }
1345
- if (msg) {
1346
- msg.message.messageContextInfo = {
1347
- messageSecret: crypto_1.randomBytes(32),
1348
- messageAssociation: {
1349
- associationType: 1,
1350
- parentMessageKey: album.key
1351
- }
1352
- }
1353
- }
1354
- await relayMessage(jid, msg.message, {
1355
- messageId: msg.key.id
1356
- })
1357
- await Utils_1.delay(time)
1358
- }
1359
- return album
1360
- },
1361
- sendMessage: async (jid, content, options = {}) => {
1362
- const userJid = authState.creds.me.id
1363
- const additionalAttributes = {}
1364
-
1365
- if (typeof content === 'object' && 'disappearingMessagesInChat' in content && typeof content['disappearingMessagesInChat'] !== 'undefined' && WABinary_1.isJidGroup(jid)) {
1366
- const { disappearingMessagesInChat } = content
1367
- const value = typeof disappearingMessagesInChat === 'boolean' ? (disappearingMessagesInChat ? Defaults_1.WA_DEFAULT_EPHEMERAL : 0) : disappearingMessagesInChat
1368
- await groupToggleEphemeral(jid, value)
1369
- } else if (typeof content === 'object' && 'album' in content && content.album) {
1370
- const albumMsg = await Utils_1.prepareAlbumMessageContent(jid, content.album, {
1371
- sock: {
1372
- relayMessage,
1373
- waUploadToServer
1374
- },
1375
- userJid: userJid,
1376
- ...options
1377
- })
1378
-
1379
- for (const media of albumMsg) {
1380
- await Utils_1.delay(options.delay || 500)
1381
- await relayMessage(jid, media.message, {
1382
- messageId: media.key.id,
1383
- useCachedGroupMetadata: options.useCachedGroupMetadata,
1384
- additionalAttributes,
1385
- statusJidList: options.statusJidList,
1386
- additionalNodes: options.additionalNodes,
1387
- ai: options.ai
1388
- })
1389
- }
1390
-
1391
- return albumMsg
1392
- } else {
1393
- let mediaHandle
1394
-
1395
- const fullMsg = await Utils_1.generateWAMessage(jid, content, {
1396
- logger,
1397
- userJid,
1398
- getUrlInfo: text => link_preview_1.getUrlInfo(text, {
1399
- thumbnailWidth: linkPreviewImageThumbnailWidth,
1400
- fetchOpts: {
1401
- timeout: 3000,
1402
- ...axiosOptions || {}
1403
- },
1404
- logger,
1405
- uploadImage: generateHighQualityLinkPreview ? waUploadToServer : undefined
1406
- }),
1407
- getProfilePicUrl: profilePictureUrl,
1408
- getCallLink: createCallLink,
1409
- upload: async (encFilePath, opts) => {
1410
- const up = await waUploadToServer(encFilePath, {
1411
- ...opts,
1412
- newsletter: WABinary_1.isJidNewsletter(jid)
1413
- })
1414
- mediaHandle = up.handle
1415
- return up
1416
- },
1417
- mediaCache: config.mediaCache,
1418
- options: config.options,
1419
- messageId: Utils_1.generateMessageID(userJid),
1420
- ...options,
1421
- })
1422
-
1423
- const isPin = 'pin' in content && !!content.pin
1424
- const isEdit = 'edit' in content && !!content.edit
1425
- const isDelete = 'delete' in content && !!content.delete
1426
- const isKeep = 'keep' in content && !!content.keep && content.keep?.type === 2
1427
-
1428
- if (isDelete || isKeep) {
1429
- if (WABinary_1.isJidGroup(content.delete?.remoteJid) && !content.delete?.fromMe || WABinary_1.isJidNewsletter(jid)) {
1430
- additionalAttributes.edit = '8'
1431
- } else {
1432
- additionalAttributes.edit = '7'
1433
- }
1434
- } else if (isEdit) {
1435
- additionalAttributes.edit = WABinary_1.isJidNewsletter(jid) ? '3' : '1'
1436
- } else if (isPin) {
1437
- additionalAttributes.edit = '2'
1438
- }
1439
-
1440
- if (mediaHandle) {
1441
- additionalAttributes['media_id'] = mediaHandle
1442
- }
1443
-
1444
- if ('cachedGroupMetadata' in options) {
1445
- console.warn('cachedGroupMetadata in sendMessage are deprecated, now cachedGroupMetadata is part of the socket config.')
1446
- }
1447
-
1448
- await relayMessage(jid, fullMsg.message, {
1449
- messageId: fullMsg.key.id,
1450
- useCachedGroupMetadata: options.useCachedGroupMetadata,
1451
- additionalAttributes,
1452
- statusJidList: options.statusJidList,
1453
- additionalNodes: options.additionalNodes,
1454
- ai: options.ai
1455
- })
1456
-
1457
- if (config.emitOwnEvents) {
1458
- process.nextTick(() => {
1459
- processingMutex.mutex(() => (upsertMessage(fullMsg, 'append')))
1460
- })
1461
- }
1462
-
1463
- return fullMsg
1464
- }
1465
- }
1466
- }
1467
- }
1468
-
1469
- module.exports = {
1470
- makeMessagesSocket
1471
- }