fix: detect view-once media (image/video/audio) (#309)
* fix: detect view-once media (image/video/audio) on stanza 1 for linked devices When a view-once arrives at a linked device (InfiniteAPI), the server sends: - Stanza 1: enc payload with full media metadata (mediaKey, directPath) wrapped in viewOnceMessage > imageMessage/videoMessage/audioMessage with viewOnce: true - Stanza 2: unavailable view_once fanout placeholder (already handled) Previously only stanza 2 set key.isViewOnce = true. Stanza 1 was emitted as plain media with no view-once indicator, making it indistinguishable from regular media on the consumer side (messages.upsert). This fix inspects the decrypted proto for viewOnceMessage (v1/v2/v2Ext) wrappers containing a media message with viewOnce=true and propagates key.isViewOnce=true. The viewOnceMessage wrapper is also used for interactive messages (carousel, buttons, lists) but those carry interactiveMessage/listMessage inside -- never imageMessage.viewOnce / videoMessage.viewOnce / audioMessage.viewOnce. The distinction is unambiguous and does not affect interactive message handling. Verified via WA Desktop
This commit is contained in:
@@ -392,6 +392,23 @@ export const decryptMessageNode = (
|
|||||||
} else {
|
} else {
|
||||||
fullMessage.message = msg
|
fullMessage.message = msg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Detect view-once media on stanza 1 received by linked device.
|
||||||
|
// viewOnceMessage wrapper is also used for interactive messages
|
||||||
|
// (interactiveMessage, listMessage, nativeFlowMessage) -- those do NOT have
|
||||||
|
// imageMessage.viewOnce / videoMessage.viewOnce / audioMessage.viewOnce = true.
|
||||||
|
// Only real view-once media carries viewOnce: true on the inner media message.
|
||||||
|
const viewOnceInner =
|
||||||
|
msg.viewOnceMessage?.message ||
|
||||||
|
msg.viewOnceMessageV2?.message ||
|
||||||
|
msg.viewOnceMessageV2Extension?.message
|
||||||
|
if (
|
||||||
|
viewOnceInner?.imageMessage?.viewOnce ||
|
||||||
|
viewOnceInner?.videoMessage?.viewOnce ||
|
||||||
|
viewOnceInner?.audioMessage?.viewOnce
|
||||||
|
) {
|
||||||
|
fullMessage.key.isViewOnce = true
|
||||||
|
}
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
// Check if this is a final failure after all retries exhausted
|
// Check if this is a final failure after all retries exhausted
|
||||||
const isRetryExhausted = err instanceof RetryExhaustedError
|
const isRetryExhausted = err instanceof RetryExhaustedError
|
||||||
|
|||||||
Reference in New Issue
Block a user