← Back to PRs

#8705: feat(whatsapp): add viewOnce support for ephemeral media

by ndohuu open 2026-02-04 09:14 View on GitHub →
channel: whatsapp-web stale
## Summary WhatsApp supports `viewOnce` media messages — images, videos, and audio/PTT that disappear after the recipient opens them once. The `SendParamsSchema` already includes `viewOnce: Type.Optional(Type.Boolean())` and the message tool exposes it, but the parameter is never threaded through to the Baileys socket. ## Root Cause The WhatsApp extension plugin (`extensions/whatsapp/src/channel.ts`) defines `outbound.sendMedia` but doesn't destructure or forward the `viewOnce` parameter from the `ChannelOutboundContext`. Several intermediate layers also needed updating. ## Changes (7 files, +19 -4 lines) 1. **`extensions/whatsapp/src/channel.ts`** — destructure `viewOnce` in `sendMedia` and pass to `sendMessageWhatsApp` 2. **`src/channels/plugins/outbound/whatsapp.ts`** — same fix for the fallback adapter 3. **`src/channels/plugins/types.adapters.ts`** — add `viewOnce?: boolean` to `ChannelOutboundContext` 4. **`src/infra/outbound/deliver.ts`** — thread `viewOnce` through `createChannelHandler` → `createPluginHandler` → `sendMedia` closure + add to `deliverOutboundPayloads` params 5. **`src/web/active-listener.ts`** — add `viewOnce?: boolean` to `ActiveWebSendOptions` 6. **`src/web/outbound.ts`** — add `viewOnce` to options type + include in `sendOptions` construction 7. **`src/web/inbound/send-api.ts`** — read `sendOptions?.viewOnce` and apply to Baileys payload for image, video, and audio messages ## Testing Tested locally with OpenClaw gateway + WhatsApp Web (Baileys): - ✅ Image with `viewOnce: true` → displays as view-once - ✅ Audio/PTT with `viewOnce: true` → displays as view-once voice message - ✅ Video with `viewOnce: true` → expected to work (same code path as image) - ✅ Without `viewOnce` → normal media delivery (no regression) ## Usage ```ts // Via message tool message({ action: 'send', target: '+1234567890', message: 'secret photo', filePath: '/path/to/image.jpg', viewOnce: true }) ``` <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR wires the existing `viewOnce` send parameter through the outbound delivery stack for WhatsApp media: it adds `viewOnce?: boolean` to the outbound context/options types, threads it through `deliverOutboundPayloads` → plugin adapters (`extensions/whatsapp` and the fallback adapter), and applies it in the Baileys payload for image/video/audio messages. Overall this fits cleanly into the existing “channel docking” model where core outbound delivery builds a channel handler and delegates to channel-specific outbound adapters, with the Web/Baileys layer translating `ActiveWebSendOptions` into Baileys message content. <h3>Confidence Score: 4/5</h3> - This PR is largely safe to merge, but there is one functional gap where `viewOnce` is not forwarded on the `sendPayload` path. - The change is small and mostly type/threading updates, and the Baileys payload changes are straightforward. The main concern is that outbound deliveries using `sendPayload` (when `payload.channelData` is present) won’t receive the new `viewOnce` flag, which can cause inconsistent behavior depending on which outbound path is used. - src/infra/outbound/deliver.ts <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> <!-- /greptile_comment -->

Most Similar PRs