Skip to content

Feat/view once receive#316

Merged
rsalcara merged 5 commits into
masterfrom
feat/view-once-receive
Mar 23, 2026
Merged

Feat/view once receive#316
rsalcara merged 5 commits into
masterfrom
feat/view-once-receive

Conversation

@rsalcara

Copy link
Copy Markdown
Owner

Feat/view once receive

rsalcara and others added 4 commits March 20, 2026 09:35
…d 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 CDP capture (2026-03-19) and Android Frida DB capture
of view-once types 42/43/82 in msgstore.db (2026-03-20).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fullMessage.key is always present on WAMessage. Use consistent style
with stanza-2 handling at line 297.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…e attribute

Without this fix, view-once media (image/video/audio) was sent without
mediatype="image/video/audio" on the enc node because getMediaType only
checked the top-level message fields. The viewOnceMessage wrapper hides
the inner imageMessage, causing mediatype to be empty and WA servers to
silently drop the message on the recipient side.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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
Copilot AI review requested due to automatic review settings March 23, 2026 03:04
@github-actions

github-actions Bot commented Mar 23, 2026

Copy link
Copy Markdown

Thanks for opening this pull request and contributing to the project!

The next step is for the maintainers to review your changes. If everything looks good, it will be approved and merged into the main branch.

In the meantime, anyone in the community is encouraged to test this pull request and provide feedback.

✅ How to confirm it works

If you’ve tested this PR, please comment below with:

Tested and working ✅

This helps us speed up the review and merge process.

📦 To test this PR locally:

# NPM
npm install @whiskeysockets/baileys@rsalcara/InfiniteAPI#feat/view-once-receive

# Yarn (v2+)
yarn add @whiskeysockets/baileys@rsalcara/InfiniteAPI#feat/view-once-receive

# PNPM
pnpm add @whiskeysockets/baileys@rsalcara/InfiniteAPI#feat/view-once-receive

If you encounter any issues or have feedback, feel free to comment as well.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d870ffb2a3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Socket/messages-recv.ts Outdated
Comment thread src/Socket/messages-send.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds view-once handling for linked devices by marking view-once messages during decrypt, adjusting send-side fanout behavior for view-once, and short-circuiting receipt of <unavailable type="view_once"/> sync stanzas.

Changes:

  • Detects actual view-once media after decrypt and sets fullMessage.key.isViewOnce.
  • Alters send fanout for view-once wrappers (DSM recipients + participant hash selection) and unwraps view-once wrappers when deriving mediatype.
  • In receive path, ACKs and skips decryption for <unavailable type="view_once"/> stanzas.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/Utils/decode-wa-message.ts Marks decrypted messages as view-once when inner media has viewOnce: true.
src/Socket/messages-send.ts Changes DSM recipient selection / phash recipients for view-once; unwraps view-once wrapper in getMediaType.
src/Socket/messages-recv.ts ACKs and returns early on <unavailable type="view_once"/> messages.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/Socket/messages-send.ts Outdated
Comment thread src/Socket/messages-send.ts Outdated
P1 (messages-recv.ts): remove early return for <unavailable type="view_once"/>.
decryptMessageNode already handles this gracefully — decode-wa-message.ts sets
fullMessage.key.isViewOnce=true and skips the CIPHERTEXT stub (line 464).
The early return was preventing upsertMessage from emitting an event to consumers,
making view-once sends from the primary phone invisible on linked devices.

P2 (messages-send.ts): restrict isViewOnceMsg detection to actual view-once media.
Previously checked only for the presence of viewOnceMessage* wrappers, which are
also used by buttons/lists/carousels (non-view-once). Now unwraps the inner message
and checks imageMessage.viewOnce / videoMessage.viewOnce / audioMessage.viewOnce,
consistent with the detection in decode-wa-message.ts. Prevents companion DSM
filtering from incorrectly applying to interactive messages.

P3 (messages-send.ts): move assertSessions to use only the recipients actually
encrypted for. For view-once, omitted companions no longer cause assertSessions
to fail or do unnecessary session validation work.

Co-Authored-By: Renato Alcara
@rsalcara rsalcara merged commit 452df5d into master Mar 23, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants