Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Adolf is a fork/vendored clone of github.com/openclaw/openclaw (v2026.6.11), free to diverge. Tree copied sans upstream .git; upstream remote added for future syncs. Node pinned to 24 (.nvmrc); engines already require >=22.19. Preserves docs/ARCHITECTURE.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
5.6 KiB
5.6 KiB
summary, read_when, title
| summary | read_when | title | |
|---|---|---|---|
| Image and media handling rules for send, gateway, and agent replies |
|
Image and media support |
The WhatsApp channel runs on Baileys Web. This page covers media handling rules for send, gateway, and agent replies.
Goals
- Send media with an optional caption via
openclaw message send --media. - Allow auto-replies from the web inbox to include media alongside text.
- Keep per-type limits sane and predictable.
CLI Surface
openclaw message send --target <dest> --media <path-or-url> [--message <caption>]
--media <path-or-url>— attach media (image/audio/video/document); accepts local paths or URLs. Optional; caption can be empty for media-only sends.--gif-playback— treat video media as GIF playback (WhatsApp only).--force-document— send media as a document to avoid channel compression (Telegram, WhatsApp); applies to images, GIFs, and videos.--reply-to <id>,--thread-id <id>,--pin,--silent— delivery/threading options shared with text-only sends.--dry-run— print the resolved payload and skip sending.--json— print the result as JSON:{ action, channel, dryRun, handledBy, messageId?, payload }(payloadcarries the channel-specific send result, including any media reference).
WhatsApp Web channel behavior
- Input: local file path or HTTP(S) URL.
- Flow: load into a buffer, detect media kind, then build the outbound payload per kind:
- Images: optimized to fit under
channels.whatsapp.mediaMaxMb(default 50MB). Opaque images are recompressed to JPEG (default side ladder starts at 2048px, descending on repeated size misses); images with transparency are kept as PNG. If the source is already an acceptable JPEG/PNG/WebP within the size and side-length budget, the original bytes are preserved unchanged instead of being recompressed. Animated GIFs are never re-encoded, only size-checked. - Audio/voice: unless already native voice audio (
.ogg/.opus, oraudio/ogg/audio/opus), outbound audio is transcoded viaffmpegto Opus/OGG (48kHz mono, 64kbps, capped at 20 minutes) before sending as a voice note (ptt: true). - Video: pass-through up to 16MB.
- Documents: anything else, up to 100MB, with filename preserved when available.
- Images: optimized to fit under
- WhatsApp GIF-style playback: send an MP4 with
gifPlayback: true(CLI:--gif-playback) so mobile clients loop it inline. - MIME detection prefers sniffed magic bytes, then the file extension, then response headers; a generic sniffed container (
application/octet-stream,zip) never overrides a more specific extension mapping (for example XLSX vs ZIP). - Caption comes from
--messageorreply.text; empty caption is allowed. - Logging: non-verbose shows
↩️/✅; verbose includes size and source path/URL.
Auto-Reply Pipeline
getReplyFromConfigreturns a reply payload (or array of payloads) withtext?,mediaUrl?, andmediaUrls?among other fields.- When media is present, the web sender resolves local paths or URLs using the same pipeline as
openclaw message send. - Multiple media entries are sent sequentially if provided.
Inbound Media To Commands
- When inbound web messages include media, OpenClaw downloads it to a temp file and exposes templating variables:
{{MediaUrl}}— pseudo-URL for the inbound media.{{MediaPath}}— local temp path written before running the command.
- When a per-session Docker sandbox is enabled, inbound media is copied into the sandbox workspace and
MediaPath/MediaUrlare rewritten to a sandbox-relative path likemedia/inbound/<filename>. - Media understanding (configured via
tools.media.*or sharedtools.media.models) runs before templating and can insert[Image],[Audio], and[Video]blocks intoBody.- Audio sets
{{Transcript}}and uses the transcript for command parsing so slash commands still work. - Video and image descriptions preserve any caption text for command parsing.
- If the active primary model already supports vision natively, OpenClaw skips the
[Image]summary block and passes the original image to the model instead.
- Audio sets
- By default only the first matching image/audio/video attachment is processed; set
tools.media.<capability>.attachmentsto process multiple attachments.
Limits and errors
Outbound send caps (WhatsApp web send)
- Images: up to
channels.whatsapp.mediaMaxMb(default 50MB) after optimization. - Audio/video: 16MB cap (shared default; overridden by
mediaMaxMbwhen sending through WhatsApp). - Documents: 100MB cap (shared default; overridden by
mediaMaxMbwhen sending through WhatsApp). - Oversize or unreadable media produces a clear error in logs, and the reply is skipped.
Media understanding caps (transcription/description)
- Image default: 10MB (
tools.media.image.maxBytes). - Audio default: 20MB (
tools.media.audio.maxBytes). - Video default: 50MB (
tools.media.video.maxBytes). - Oversize media skips understanding, but the reply still goes through with the original body.
Notes for Tests
- Cover send and reply flows for image/audio/document cases.
- Validate size bounds after image optimization and the voice-note flag for audio.
- Ensure multi-media replies fan out as sequential sends.