fix: handle view-once send/recv on linked devices
- messages-send.ts: for view-once messages, send DSM only to device=0 (primary phone). Companion devices (device>0) are omitted from participants — the WA server generates <unavailable type="view_once"/> for them automatically. Sending explicit <unavailable> from a companion is rejected by the server and breaks delivery. phash is recalculated to match the actual participants sent. - messages-recv.ts: add early return for <unavailable type="view_once"/> stanzas received by the companion (API). When the primary phone sends a view-once, linked companions receive this node with no enc content. Previously the code tried to decrypt it and crashed with a 500 error. Co-Authored-By: Renato Alcara
This commit is contained in:
@@ -2258,6 +2258,17 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle view-once unavailable sync from primary device.
|
||||||
|
// When the primary device sends a view-once, linked companions receive
|
||||||
|
// <unavailable type="view_once"/> — no enc content, just a sync signal.
|
||||||
|
// Acknowledge and skip decryption (nothing to decrypt).
|
||||||
|
const unavailableNode = getBinaryNodeChild(node, 'unavailable')
|
||||||
|
if (unavailableNode?.attrs?.type === 'view_once') {
|
||||||
|
logger.debug({ id: node.attrs.id, from: node.attrs.from }, 'received view_once unavailable sync from primary device')
|
||||||
|
await sendMessageAck(node)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
fullMessage: msg,
|
fullMessage: msg,
|
||||||
category,
|
category,
|
||||||
|
|||||||
@@ -1279,19 +1279,35 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
|||||||
|
|
||||||
await assertSessions(effectiveAllRecipients)
|
await assertSessions(effectiveAllRecipients)
|
||||||
|
|
||||||
|
// For view-once: only send DSM to primary phone (device=0).
|
||||||
|
// Companion devices (device>0) are omitted — WA server generates
|
||||||
|
// <unavailable type="view_once"/> for them automatically.
|
||||||
|
// Sending explicit <unavailable> from a companion is rejected by the server.
|
||||||
|
const isViewOnceMsg = !!(
|
||||||
|
message.viewOnceMessageV2 ||
|
||||||
|
message.viewOnceMessage ||
|
||||||
|
message.viewOnceMessageV2Extension
|
||||||
|
)
|
||||||
|
const viewOnceMeRecipients = isViewOnceMsg
|
||||||
|
? effectiveMeRecipients.filter(jid => !jidDecode(jid)?.device)
|
||||||
|
: effectiveMeRecipients
|
||||||
|
|
||||||
const [
|
const [
|
||||||
{ nodes: meNodes, shouldIncludeDeviceIdentity: s1 },
|
{ nodes: meNodes, shouldIncludeDeviceIdentity: s1 },
|
||||||
{ nodes: otherNodes, shouldIncludeDeviceIdentity: s2 }
|
{ nodes: otherNodes, shouldIncludeDeviceIdentity: s2 }
|
||||||
] = await Promise.all([
|
] = await Promise.all([
|
||||||
// For own devices: use DSM (deviceSentMessage) wrapper
|
// For own devices: use DSM (deviceSentMessage) wrapper
|
||||||
createParticipantNodes(effectiveMeRecipients, meMsg || message, extraAttrs),
|
createParticipantNodes(viewOnceMeRecipients, meMsg || message, extraAttrs),
|
||||||
createParticipantNodes(effectiveOtherRecipients, message, extraAttrs)
|
createParticipantNodes(effectiveOtherRecipients, message, extraAttrs)
|
||||||
])
|
])
|
||||||
participants.push(...meNodes)
|
participants.push(...meNodes)
|
||||||
participants.push(...otherNodes)
|
participants.push(...otherNodes)
|
||||||
|
|
||||||
if (effectiveMeRecipients.length > 0 || effectiveOtherRecipients.length > 0) {
|
const phashRecipients = isViewOnceMsg
|
||||||
extraAttrs['phash'] = generateParticipantHashV2(effectiveAllRecipients)
|
? [...viewOnceMeRecipients, ...effectiveOtherRecipients]
|
||||||
|
: effectiveAllRecipients
|
||||||
|
if (phashRecipients.length > 0) {
|
||||||
|
extraAttrs['phash'] = generateParticipantHashV2(phashRecipients)
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || s1 || s2
|
shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || s1 || s2
|
||||||
|
|||||||
Reference in New Issue
Block a user