@nexustechpro/baileys 2.0.5 → 2.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/WAProto/index.js +22 -18
- package/lib/Defaults/baileys-version.json +1 -1
- package/lib/Defaults/index.js +7 -6
- package/lib/Signal/libsignal.js +65 -50
- package/lib/Socket/chats.js +64 -57
- package/lib/Socket/index.js +2 -3
- package/lib/Socket/messages-recv.js +227 -41
- package/lib/Socket/messages-send.js +79 -117
- package/lib/Socket/nexus-handler.js +325 -90
- package/lib/Socket/registration.js +50 -33
- package/lib/Socket/socket.js +232 -69
- package/lib/Types/Newsletter.js +37 -29
- package/lib/Types/State.js +43 -0
- package/lib/Utils/auth-utils.js +2 -2
- package/lib/Utils/chat-utils.js +48 -16
- package/lib/Utils/companion-reg-client-utils.js +34 -0
- package/lib/Utils/decode-wa-message.js +40 -8
- package/lib/Utils/generics.js +5 -7
- package/lib/Utils/index.js +4 -0
- package/lib/Utils/link-preview.js +10 -0
- package/lib/Utils/messages-media.js +426 -382
- package/lib/Utils/messages.js +602 -487
- package/lib/Utils/process-message.js +53 -35
- package/lib/Utils/reporting-utils.js +155 -0
- package/lib/Utils/signal.js +134 -104
- package/lib/Utils/sync-action-utils.js +33 -0
- package/lib/Utils/tc-token-utils.js +162 -0
- package/lib/WABinary/constants.js +6 -0
- package/lib/WABinary/index.js +1 -0
- package/lib/index.js +2 -3
- package/package.json +6 -4
|
@@ -4,8 +4,7 @@ import * as Utils from '../Utils/index.js'
|
|
|
4
4
|
import { proto } from '../../WAProto/index.js'
|
|
5
5
|
import { DEFAULT_CACHE_TTLS, WA_DEFAULT_EPHEMERAL } from '../Defaults/index.js'
|
|
6
6
|
import * as WABinary from '../WABinary/index.js'
|
|
7
|
-
import { getUrlInfo, migrateIndexKey } from '../Utils/index.js'
|
|
8
|
-
import { makeKeyedMutex } from '../Utils/make-mutex.js'
|
|
7
|
+
import { getUrlInfo, migrateIndexKey, getMessageReportingToken, shouldIncludeReportingToken, buildMergedTcTokenIndexWrite, isTcTokenExpired, readTcTokenIndex, resolveTcTokenJid, resolveIssuanceJid, shouldSendNewTcToken, storeTcTokensFromIqResult, makeKeyedMutex, makeMutex } from '../Utils/index.js'
|
|
9
8
|
import { USyncQuery, USyncUser } from '../WAUSync/index.js'
|
|
10
9
|
import { makeNewsletterSocket } from './newsletter.js'
|
|
11
10
|
import NexusHandler from './nexus-handler.js'
|
|
@@ -23,52 +22,11 @@ const {
|
|
|
23
22
|
const {
|
|
24
23
|
areJidsSameUser, getBinaryNodeChild, getBinaryNodeChildren, isHostedLidUser, isHostedPnUser,
|
|
25
24
|
isJidBroadcast, isJidGroup, isJidStatusBroadcast, isLidUser, isPnUser, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET,
|
|
26
|
-
getBinaryFilteredButtons, STORIES_JID, isJidUser, getButtonArgs, getButtonType
|
|
25
|
+
getBinaryFilteredButtons, STORIES_JID, isJidUser, getButtonArgs, getButtonType, isJidBot, isJidMetaAI
|
|
27
26
|
} = WABinary
|
|
28
27
|
|
|
29
|
-
const TC_TOKEN_BUCKET_DURATION = 604800 // 7 days
|
|
30
|
-
const TC_TOKEN_NUM_BUCKETS = 4 // ~28-day rolling window
|
|
31
|
-
|
|
32
|
-
const isTcTokenExpired = (timestamp) => {
|
|
33
|
-
if (timestamp === null || timestamp === undefined) return true
|
|
34
|
-
const ts = typeof timestamp === 'string' ? parseInt(timestamp) : timestamp
|
|
35
|
-
if (isNaN(ts)) return true
|
|
36
|
-
const now = Math.floor(Date.now() / 1000)
|
|
37
|
-
const currentBucket = Math.floor(now / TC_TOKEN_BUCKET_DURATION)
|
|
38
|
-
const cutoffBucket = currentBucket - (TC_TOKEN_NUM_BUCKETS - 1)
|
|
39
|
-
return ts < (cutoffBucket * TC_TOKEN_BUCKET_DURATION)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const shouldSendNewTcToken = (senderTimestamp) => {
|
|
43
|
-
if (senderTimestamp === undefined) return true
|
|
44
|
-
const now = Math.floor(Date.now() / 1000)
|
|
45
|
-
const currentBucket = Math.floor(now / TC_TOKEN_BUCKET_DURATION)
|
|
46
|
-
const senderBucket = Math.floor(senderTimestamp / TC_TOKEN_BUCKET_DURATION)
|
|
47
|
-
return currentBucket > senderBucket
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const resolveTcTokenJid = async (jid, getLIDForPN) => {
|
|
51
|
-
if (isLidUser(jid)) return jid
|
|
52
|
-
const lid = await getLIDForPN(jid)
|
|
53
|
-
return lid ?? jid
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const resolveIssuanceJid = async (jid, issueToLid, getLIDForPN, getPNForLID) => {
|
|
57
|
-
if (issueToLid) {
|
|
58
|
-
if (isLidUser(jid)) return jid
|
|
59
|
-
return (await getLIDForPN(jid)) ?? jid
|
|
60
|
-
}
|
|
61
|
-
if (!isLidUser(jid)) return jid
|
|
62
|
-
if (getPNForLID) return (await getPNForLID(jid)) ?? jid
|
|
63
|
-
return jid
|
|
64
|
-
}
|
|
65
|
-
|
|
66
28
|
export const makeMessagesSocket = (config) => {
|
|
67
|
-
const {
|
|
68
|
-
logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview,
|
|
69
|
-
options: httpRequestOptions, patchMessageBeforeSending, cachedGroupMetadata,
|
|
70
|
-
enableRecentMessageCache, maxMsgRetryCount
|
|
71
|
-
} = config
|
|
29
|
+
const { logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: httpRequestOptions, patchMessageBeforeSending, cachedGroupMetadata, enableRecentMessageCache, maxMsgRetryCount, getMessage } = config
|
|
72
30
|
|
|
73
31
|
const sock = makeNewsletterSocket(config)
|
|
74
32
|
const {
|
|
@@ -77,7 +35,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
77
35
|
} = sock
|
|
78
36
|
|
|
79
37
|
const userDevicesCache = config.userDevicesCache || new NodeCache({ stdTTL: DEFAULT_CACHE_TTLS.USER_DEVICES, useClones: false })
|
|
80
|
-
const
|
|
38
|
+
const devicesMutex = makeMutex()
|
|
81
39
|
const messageRetryManager = enableRecentMessageCache ? new MessageRetryManager(logger, maxMsgRetryCount) : null
|
|
82
40
|
const encryptionMutex = makeKeyedMutex()
|
|
83
41
|
|
|
@@ -111,9 +69,19 @@ export const makeMessagesSocket = (config) => {
|
|
|
111
69
|
const node = { tag: 'receipt', attrs: { id: messageIds[0] } }
|
|
112
70
|
const isReadReceipt = type === 'read' || type === 'read-self'
|
|
113
71
|
if (isReadReceipt) node.attrs.t = unixTimestampSeconds().toString()
|
|
72
|
+
if (isJidStatusBroadcast(jid) && !participant && getMessage) {
|
|
73
|
+
try {
|
|
74
|
+
const msg = await getMessage({ remoteJid: jid, id: messageIds[0], fromMe: false })
|
|
75
|
+
participant = msg?.key?.participant || msg?.participant || msg?.key?.remoteJid
|
|
76
|
+
logger.debug({ jid, resolvedParticipant: participant }, 'resolved status receipt participant from message store')
|
|
77
|
+
} catch (err) { logger.debug({ err, jid }, 'failed to resolve status receipt participant') }
|
|
78
|
+
}
|
|
114
79
|
if (type === 'sender' && (isPnUser(jid) || isLidUser(jid))) {
|
|
115
80
|
node.attrs.recipient = jid
|
|
116
81
|
node.attrs.to = participant
|
|
82
|
+
} else if (isJidStatusBroadcast(jid) && participant) {
|
|
83
|
+
node.attrs.to = jid
|
|
84
|
+
node.attrs.participant = participant
|
|
117
85
|
} else {
|
|
118
86
|
node.attrs.to = jid
|
|
119
87
|
if (participant) node.attrs.participant = participant
|
|
@@ -135,7 +103,9 @@ export const makeMessagesSocket = (config) => {
|
|
|
135
103
|
|
|
136
104
|
const readMessages = async (keys) => {
|
|
137
105
|
const privacySettings = await fetchPrivacySettings()
|
|
138
|
-
|
|
106
|
+
const hasStatusKey = keys.some(k => isJidStatusBroadcast(k.remoteJid))
|
|
107
|
+
const type = hasStatusKey ? 'read' : (privacySettings.readreceipts === 'all' ? 'read' : 'read-self')
|
|
108
|
+
await sendReceipts(keys, type)
|
|
139
109
|
}
|
|
140
110
|
|
|
141
111
|
const getUSyncDevices = async (jids, useCache, ignoreZeroDevices) => {
|
|
@@ -212,11 +182,13 @@ export const makeMessagesSocket = (config) => {
|
|
|
212
182
|
}
|
|
213
183
|
}
|
|
214
184
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
185
|
+
await devicesMutex.mutex(async () => {
|
|
186
|
+
if (userDevicesCache.mset) {
|
|
187
|
+
await userDevicesCache.mset(Object.entries(deviceMap).map(([key, value]) => ({ key, value })))
|
|
188
|
+
} else {
|
|
189
|
+
for (const key in deviceMap) if (deviceMap[key]) await userDevicesCache.set(key, deviceMap[key])
|
|
190
|
+
}
|
|
191
|
+
})
|
|
220
192
|
|
|
221
193
|
// Persist device lists for session migration (capped at 500 users)
|
|
222
194
|
const userDeviceUpdates = {}
|
|
@@ -243,16 +215,20 @@ export const makeMessagesSocket = (config) => {
|
|
|
243
215
|
if (force) {
|
|
244
216
|
jidsRequiringFetch = jids
|
|
245
217
|
} else {
|
|
246
|
-
|
|
247
|
-
const sessionBatch = await migrateIndexKey(authState.keys, 'session') // sessions live in index blob, not individual files
|
|
218
|
+
const sessionBatch = await migrateIndexKey(authState.keys, 'session')
|
|
248
219
|
for (const jid of jids) {
|
|
249
220
|
const signalId = signalRepository.jidToSignalProtocolAddress(jid)
|
|
250
221
|
if (!sessionBatch[signalId]) jidsRequiringFetch.push(jid)
|
|
251
222
|
}
|
|
252
223
|
}
|
|
253
224
|
if (jidsRequiringFetch.length) {
|
|
254
|
-
|
|
255
|
-
|
|
225
|
+
const wireJids = [
|
|
226
|
+
...jidsRequiringFetch.filter(jid => isLidUser(jid) || isHostedLidUser(jid)),
|
|
227
|
+
...((await signalRepository.lidMapping.getLIDsForPNs(jidsRequiringFetch.filter(jid => isPnUser(jid) || isHostedPnUser(jid)))) || []).map(a => a.lid)
|
|
228
|
+
]
|
|
229
|
+
const fetchTargets = wireJids.length ? wireJids : jidsRequiringFetch
|
|
230
|
+
logger.debug({ jidsRequiringFetch, fetchTargets }, 'fetching sessions')
|
|
231
|
+
const result = await query({ tag: 'iq', attrs: { xmlns: 'encrypt', type: 'get', to: S_WHATSAPP_NET }, content: [{ tag: 'key', attrs: {}, content: fetchTargets.map(jid => ({ tag: 'user', attrs: { jid, ...(force ? { reason: 'identity' } : {}) } })) }] })
|
|
256
232
|
await parseAndInjectE2ESessions(result, signalRepository)
|
|
257
233
|
didFetchNewSession = true
|
|
258
234
|
}
|
|
@@ -433,6 +409,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
433
409
|
const meMsg = { deviceSentMessage: { destinationJid, message }, messageContextInfo: message.messageContextInfo }
|
|
434
410
|
const extraAttrs = {}
|
|
435
411
|
const messages = normalizeMessageContent(message)
|
|
412
|
+
const reportingMessage = messages
|
|
436
413
|
const buttonType = getButtonType(messages)
|
|
437
414
|
|
|
438
415
|
let hasDeviceFanoutFalse = false
|
|
@@ -454,7 +431,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
454
431
|
return
|
|
455
432
|
}
|
|
456
433
|
|
|
457
|
-
if (messages?.pinInChatMessage || messages?.keepInChatMessage || message.reactionMessage || message.protocolMessage?.editedMessage) {
|
|
434
|
+
if (messages?.pinInChatMessage || messages?.keepInChatMessage || (message.reactionMessage && !isStatus) || message.protocolMessage?.editedMessage) {
|
|
458
435
|
extraAttrs['decrypt-fail'] = 'hide'
|
|
459
436
|
}
|
|
460
437
|
|
|
@@ -497,9 +474,10 @@ export const makeMessagesSocket = (config) => {
|
|
|
497
474
|
if (Array.isArray(patched)) throw new Boom('Per-jid patching not supported in groups')
|
|
498
475
|
|
|
499
476
|
const bytes = encodeWAMessage(patched)
|
|
477
|
+
const bytesU8 = new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength)
|
|
500
478
|
const gAddressingMode = additionalAttributes?.addressing_mode || groupData?.addressingMode || 'lid'
|
|
501
479
|
const groupSenderIdentity = gAddressingMode === 'lid' && meLid ? meLid : meId
|
|
502
|
-
const { ciphertext, senderKeyDistributionMessage } = await signalRepository.encryptGroupMessage({ group: destinationJid, data:
|
|
480
|
+
const { ciphertext, senderKeyDistributionMessage } = await signalRepository.encryptGroupMessage({ group: destinationJid, data: bytesU8, meId: groupSenderIdentity })
|
|
503
481
|
|
|
504
482
|
const senderKeyRecipients = devices
|
|
505
483
|
.filter(d => !isHostedLidUser(d.jid) && !isHostedPnUser(d.jid) && d.device !== 99)
|
|
@@ -527,9 +505,10 @@ export const makeMessagesSocket = (config) => {
|
|
|
527
505
|
if (Array.isArray(patched)) throw new Boom('Per-jid patching not supported in groups')
|
|
528
506
|
|
|
529
507
|
const bytes = encodeWAMessage(patched)
|
|
508
|
+
const bytesU8 = new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength)
|
|
530
509
|
const gAddressingMode = additionalAttributes?.addressing_mode || groupData?.addressingMode || 'lid'
|
|
531
510
|
const groupSenderIdentity = gAddressingMode === 'lid' && meLid ? meLid : meId
|
|
532
|
-
const { ciphertext, senderKeyDistributionMessage } = await signalRepository.encryptGroupMessage({ group: destinationJid, data:
|
|
511
|
+
const { ciphertext, senderKeyDistributionMessage } = await signalRepository.encryptGroupMessage({ group: destinationJid, data: bytesU8, meId: groupSenderIdentity })
|
|
533
512
|
|
|
534
513
|
const senderKeyMsg = { senderKeyDistributionMessage: { axolotlSenderKeyDistributionMessage: senderKeyDistributionMessage, groupId: destinationJid } }
|
|
535
514
|
await assertSessions([participant.jid])
|
|
@@ -657,48 +636,64 @@ export const makeMessagesSocket = (config) => {
|
|
|
657
636
|
logger.debug({ jid }, 'adding device identity')
|
|
658
637
|
}
|
|
659
638
|
|
|
660
|
-
// TC token handling for 1:1 messages
|
|
661
639
|
const isPeerMessage = additionalAttributes?.category === 'peer'
|
|
662
640
|
const is1on1 = !isGroup && !isRetryResend && !isStatus && !isNewsletter && !isPeerMessage
|
|
663
641
|
if (is1on1) {
|
|
664
642
|
const getLIDForPN = signalRepository.lidMapping.getLIDForPN.bind(signalRepository.lidMapping)
|
|
665
643
|
const tcTokenJid = await resolveTcTokenJid(destinationJid, getLIDForPN)
|
|
666
|
-
|
|
667
644
|
const contactTcTokenData = await authState.keys.get('tctoken', [tcTokenJid])
|
|
668
645
|
const existingEntry = contactTcTokenData[tcTokenJid]
|
|
669
646
|
let tcTokenBuffer = existingEntry?.token
|
|
670
|
-
|
|
671
|
-
// Clear expired tokens
|
|
672
647
|
if (tcTokenBuffer?.length && isTcTokenExpired(existingEntry?.timestamp)) {
|
|
673
|
-
logger.debug({ jid: destinationJid }, 'tctoken expired, clearing')
|
|
648
|
+
logger.debug({ jid: destinationJid, timestamp: existingEntry?.timestamp }, 'tctoken expired, clearing')
|
|
674
649
|
tcTokenBuffer = undefined
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
} catch { }
|
|
650
|
+
const cleared = existingEntry?.senderTimestamp !== undefined ? { token: Buffer.alloc(0), senderTimestamp: existingEntry.senderTimestamp } : null
|
|
651
|
+
try { await authState.keys.set({ tctoken: { [tcTokenJid]: cleared } }) } catch (err) { logger.debug({ jid: destinationJid, err: err?.message }, 'failed to persist tctoken expiry cleanup') }
|
|
678
652
|
}
|
|
679
|
-
|
|
680
|
-
if (tcTokenBuffer?.length) {
|
|
681
|
-
stanza.content.push({ tag: 'tctoken', attrs: {}, content: tcTokenBuffer })
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
// Fire-and-forget: issue our token to the contact after send
|
|
653
|
+
if (tcTokenBuffer?.length && sock.serverProps?.privacyTokenOn1to1) stanza.content.push({ tag: 'tctoken', attrs: {}, content: tcTokenBuffer })
|
|
685
654
|
const isProtocolMsg = !!normalizeMessageContent(message)?.protocolMessage
|
|
686
|
-
|
|
655
|
+
const isBotOrPSA = isJidBot(destinationJid) || isJidMetaAI(destinationJid)
|
|
656
|
+
if (!isProtocolMsg && !isBotOrPSA && shouldSendNewTcToken(existingEntry?.senderTimestamp) && !inFlightTcTokenIssuance.has(tcTokenJid)) {
|
|
687
657
|
inFlightTcTokenIssuance.add(tcTokenJid)
|
|
688
658
|
const issueTimestamp = unixTimestampSeconds()
|
|
689
659
|
const getPNForLID = signalRepository.lidMapping.getPNForLID.bind(signalRepository.lidMapping)
|
|
690
660
|
const issueToLid = sock.serverProps?.lidTrustedTokenIssueToLid ?? false
|
|
691
661
|
resolveIssuanceJid(destinationJid, issueToLid, getLIDForPN, getPNForLID)
|
|
692
662
|
.then(issueJid => issuePrivacyTokens([issueJid], issueTimestamp))
|
|
693
|
-
.then(async () => {
|
|
663
|
+
.then(async (result) => {
|
|
664
|
+
await storeTcTokensFromIqResult({ result, fallbackJid: tcTokenJid, keys: authState.keys, getLIDForPN })
|
|
694
665
|
const currentData = await authState.keys.get('tctoken', [tcTokenJid])
|
|
695
|
-
const
|
|
696
|
-
await authState.keys
|
|
666
|
+
const currentEntry = currentData[tcTokenJid]
|
|
667
|
+
const indexWrite = await buildMergedTcTokenIndexWrite(authState.keys, [tcTokenJid])
|
|
668
|
+
await authState.keys.set({ tctoken: { [tcTokenJid]: { token: Buffer.alloc(0), ...currentEntry, senderTimestamp: issueTimestamp }, ...indexWrite } })
|
|
697
669
|
})
|
|
698
670
|
.catch(err => logger.debug({ jid: destinationJid, err: err?.message }, 'fire-and-forget tctoken issuance failed'))
|
|
699
671
|
.finally(() => inFlightTcTokenIssuance.delete(tcTokenJid))
|
|
700
672
|
}
|
|
701
673
|
}
|
|
674
|
+
if (
|
|
675
|
+
!isNewsletter &&
|
|
676
|
+
!isRetryResend &&
|
|
677
|
+
reportingMessage?.messageContextInfo?.messageSecret &&
|
|
678
|
+
shouldIncludeReportingToken(reportingMessage)
|
|
679
|
+
) {
|
|
680
|
+
try {
|
|
681
|
+
const encoded = encodeWAMessage(reportingMessage)
|
|
682
|
+
const reportingKey = {
|
|
683
|
+
id: finalMsgId,
|
|
684
|
+
fromMe: true,
|
|
685
|
+
remoteJid: destinationJid,
|
|
686
|
+
participant: participant?.jid
|
|
687
|
+
}
|
|
688
|
+
const reportingNode = await getMessageReportingToken(encoded, reportingMessage, reportingKey)
|
|
689
|
+
if (reportingNode) {
|
|
690
|
+
stanza.content.push(reportingNode)
|
|
691
|
+
logger.trace({ jid }, 'added reporting token to message')
|
|
692
|
+
}
|
|
693
|
+
} catch (error) {
|
|
694
|
+
logger.warn({ jid, trace: error?.stack }, 'failed to attach reporting token')
|
|
695
|
+
}
|
|
696
|
+
}
|
|
702
697
|
|
|
703
698
|
logger.debug({ msgId: finalMsgId }, `sending message to ${participants.length} devices`)
|
|
704
699
|
await sendNode(stanza)
|
|
@@ -749,7 +744,9 @@ export const makeMessagesSocket = (config) => {
|
|
|
749
744
|
content = { ...rest, interactiveMessage: interactive }
|
|
750
745
|
}
|
|
751
746
|
|
|
752
|
-
|
|
747
|
+
// never route status reactions through nexus
|
|
748
|
+
const isStatusJid = jid === 'status@broadcast'
|
|
749
|
+
const messageType = !isStatusJid && nexus.detectType(content)
|
|
753
750
|
if (messageType) return await nexus.processMessage(content, jid, quoted)
|
|
754
751
|
|
|
755
752
|
if (content.disappearingMessagesInChat && isJidGroup(jid)) {
|
|
@@ -760,35 +757,6 @@ export const makeMessagesSocket = (config) => {
|
|
|
760
757
|
return
|
|
761
758
|
}
|
|
762
759
|
|
|
763
|
-
if (content.delete) {
|
|
764
|
-
const deleteKey = content.delete
|
|
765
|
-
if (!deleteKey.remoteJid || !deleteKey.id) {
|
|
766
|
-
logger.error({ deleteKey }, 'Invalid delete key: missing remoteJid or id')
|
|
767
|
-
throw new Boom('Delete key must have remoteJid and id', { statusCode: 400 })
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
const { server: deleteServer } = jidDecode(deleteKey.remoteJid)
|
|
771
|
-
let deleteAddressingMode = deleteServer === 'lid' ? 'lid' : 'pn'
|
|
772
|
-
if (isJidGroup(deleteKey.remoteJid)) {
|
|
773
|
-
const groupData = useCache && cachedGroupMetadata ? await cachedGroupMetadata(deleteKey.remoteJid) : undefined
|
|
774
|
-
deleteAddressingMode = groupData?.addressingMode || 'lid'
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
let normalizedParticipant = deleteKey.participant
|
|
778
|
-
if (deleteKey.fromMe || isJidGroup(deleteKey.remoteJid)) {
|
|
779
|
-
const senderJid = (deleteAddressingMode === 'lid' && meLid) ? meLid : meId
|
|
780
|
-
normalizedParticipant = jidNormalizedUser(senderJid)
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
content.delete = {
|
|
784
|
-
remoteJid: deleteKey.remoteJid,
|
|
785
|
-
fromMe: deleteKey.fromMe === true || deleteKey.fromMe === 'true',
|
|
786
|
-
id: deleteKey.id,
|
|
787
|
-
...(normalizedParticipant ? { participant: jidNormalizedUser(normalizedParticipant) } : {}),
|
|
788
|
-
addressingMode: deleteAddressingMode
|
|
789
|
-
}
|
|
790
|
-
logger.debug({ jid, deleteKey: content.delete }, 'processing message deletion')
|
|
791
|
-
}
|
|
792
760
|
|
|
793
761
|
const fullMsg = await generateWAMessage(jid, content, {
|
|
794
762
|
logger,
|
|
@@ -805,7 +773,9 @@ export const makeMessagesSocket = (config) => {
|
|
|
805
773
|
|
|
806
774
|
const additionalAttributes = {}, additionalNodes = []
|
|
807
775
|
if (content.delete) {
|
|
808
|
-
|
|
776
|
+
const fromMe = content.delete?.fromMe
|
|
777
|
+
const isGroupDelete = isJidGroup(content.delete?.remoteJid)
|
|
778
|
+
additionalAttributes.edit = (isGroupDelete && !fromMe) ? '8' : '7'
|
|
809
779
|
} else if (content.edit) {
|
|
810
780
|
additionalAttributes.edit = '1'
|
|
811
781
|
} else if (content.pin) {
|
|
@@ -815,15 +785,6 @@ export const makeMessagesSocket = (config) => {
|
|
|
815
785
|
if (content.event) additionalNodes.push({ tag: 'meta', attrs: { event_type: 'creation' } })
|
|
816
786
|
if (content.ai) additionalNodes.push({ tag: 'bot', attrs: { biz_bot: '1' } })
|
|
817
787
|
|
|
818
|
-
// Pre-fetch TC token for new DM contacts
|
|
819
|
-
if (!isJidGroup(jid) && !isJidStatusBroadcast(jid) && !isJidBroadcast(jid) && !content.disappearingMessagesInChat) {
|
|
820
|
-
const existingToken = await authState.keys.get('tctoken', [jid])
|
|
821
|
-
if (!existingToken[jid]) {
|
|
822
|
-
try { await getPrivacyTokens([jid]); logger.debug({ jid }, 'fetched tctoken for new contact') }
|
|
823
|
-
catch (err) { logger.warn({ jid, err }, 'failed to fetch tctoken') }
|
|
824
|
-
}
|
|
825
|
-
}
|
|
826
|
-
|
|
827
788
|
await relayMessage(jid, fullMsg.message, {
|
|
828
789
|
messageId: fullMsg.key.id,
|
|
829
790
|
useCachedGroupMetadata: options.useCachedGroupMetadata,
|
|
@@ -844,6 +805,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
844
805
|
sendReceipt, sendReceipts, nexus, readMessages, refreshMediaConn,
|
|
845
806
|
waUploadToServer, fetchPrivacySettings, sendPeerDataOperationMessage,
|
|
846
807
|
createParticipantNodes, getUSyncDevices, messageRetryManager, updateMemberLabel,
|
|
808
|
+
userDevicesCache, devicesMutex,
|
|
847
809
|
|
|
848
810
|
updateMediaMessage: async (message) => {
|
|
849
811
|
const content = assertMediaContent(message.message)
|