OpenClaw plugin that intercepts media-only inbound messages before they reach the LLM. If the channel provides readable local attachment paths, the plugin stages them through obsidian-cli-plugins so a later text message can create one Obsidian file-mode record with all staged media. This is an OpenClaw runtime plugin, not a general-purpose npm library. It depends on OpenClaw typed hooks (inboundcl
npx mdskills install DXShelley/openclaw-obsidian-media-claimEfficient plugin that intercepts media-only messages before LLM processing to save tokens and enable batched Obsidian records.
1# OpenClaw Obsidian Media Claim23OpenClaw plugin that intercepts media-only inbound messages before they reach the LLM. If the channel provides readable local attachment paths, the plugin stages them through `obsidian-cli-plugins` so a later text message can create one Obsidian file-mode record with all staged media.45This is an OpenClaw runtime plugin, not a general-purpose npm library. It depends on OpenClaw typed hooks (`inbound_claim` and `before_dispatch`) and is useful only inside an OpenClaw plugin runtime that supports those hooks.67## Why89Some channels deliver several images or videos as separate media-only events before the user sends the actual instruction, for example:1011```text12[image]13[image]14把上面两张图记录到 ob15```1617Without an early `inbound_claim` guard, each media-only event can be sent to the model and waste tokens. This plugin claims those events, replies with a short acknowledgement, and keeps the media available for the later Obsidian record workflow.1819## Behavior2021- Claims only media-only inbound messages.22- Does not claim messages that contain user text, `bodyForAgent`, or transcript text.23- Registers both `inbound_claim` and a `before_dispatch` fallback, because current OpenClaw dispatch only targets `inbound_claim` for plugin-owned conversation bindings.24- Treats empty-body dispatch events from configured media-capable channels as media-only events. This covers QQBot media messages where the session transcript later gets an `[Attachment: ...]` marker, but the `before_dispatch` hook event itself has no media metadata.25- Detects generic `[Attachment: /path/to/file]` markers.26- Detects common metadata paths: `mediaPaths`, `MediaPaths`, `localMediaPaths`, `mediaPath`, `MediaPath`, and `mediaList`.27- Stages readable local files with `obsidian_workflows.py attachment-stage`.28- Supports optional channel allow/deny lists.29- Does not write Obsidian notes or media files directly; Obsidian-side effects are delegated to `obsidian-cli-plugins/scripts/obsidian_workflows.py`.30- May still claim media-only messages when only remote media URLs are present, but it cannot stage attachments unless the channel/runtime exposes readable local file paths.3132## Requirements3334- OpenClaw 2026.6.11 or a compatible version with `inbound_claim` and `before_dispatch` typed hooks.35- Node.js 22.19 or newer.36- `obsidian-cli-plugins` installed as an OpenClaw, Codex, or cc-switch skill when `stageAttachments` is enabled.3738## Install3940From a local checkout:4142```bash43openclaw plugins install /path/to/openclaw-obsidian-media-claim --force44```4546From npm after publishing:4748```bash49openclaw plugins install obsidian-media-claim50```5152From ClawHub after publishing:5354```bash55openclaw plugins install clawhub:obsidian-media-claim56```5758Then enable the plugin with conversation access for `inbound_claim`:5960```json61{62 "plugins": {63 "entries": {64 "obsidian-media-claim": {65 "enabled": true,66 "hooks": {67 "allowConversationAccess": true,68 "timeoutMs": 1500069 },70 "config": {71 "stageAttachments": true,72 "replyContent": "收到媒体,已保存。"73 }74 }75 }76 }77}78```7980`allowConversationAccess=true` is required for non-bundled OpenClaw plugins that register conversation-aware typed hooks.8182## Configuration8384```json85{86 "stageAttachments": true,87 "replyContent": "收到媒体,已保存。",88 "python": "python3",89 "obsidianWorkflowsPath": "/Users/you/.openclaw/skills/obsidian-cli-plugins/scripts/obsidian_workflows.py",90 "onlyChannels": ["qqbot", "wecom", "webchat"],91 "ignoredChannels": ["telegram"],92 "claimEmptyBodyMediaEvents": true,93 "emptyBodyMediaChannels": ["qqbot", "wecom", "webchat", "telegram", "feishu"]94}95```9697Fields:9899- `stageAttachments`: set `false` to claim media-only messages without staging files.100- `replyContent`: synthetic reply for claimed messages.101- `python`: Python executable used for `obsidian_workflows.py`.102- `obsidianWorkflowsPath`: explicit path to the Obsidian workflow launcher. This script is executed locally with `execFile`; configure only trusted paths because its behavior controls the real attachment-staging side effects.103- `onlyChannels`: optional channel allowlist.104- `ignoredChannels`: optional channel denylist.105- `claimEmptyBodyMediaEvents`: claim empty `before_dispatch` events from media-capable channels. Disable this if one of your channels legitimately sends empty text-only messages that should reach the agent.106- `emptyBodyMediaChannels`: channel ids where empty `before_dispatch` bodies are treated as media-only events.107108If `obsidianWorkflowsPath` is omitted, the plugin tries these paths:109110```text111~/.openclaw/skills/obsidian-cli-plugins/scripts/obsidian_workflows.py112~/.codex/skills/obsidian-cli-plugins/scripts/obsidian_workflows.py113~/.cc-switch/skills/obsidian-cli-plugins/scripts/obsidian_workflows.py114```115116## Verify117118```bash119npm run verify120```121122For a local linked install:123124```bash125npm run verify:install126openclaw plugins inspect obsidian-media-claim127```128129Restart or refresh the OpenClaw gateway after installing or updating runtime plugins.130131## Publish132133Prepare a package:134135```bash136npm run pack:dry-run137```138139Publish to npm:140141```bash142npm publish143```144145Publish to ClawHub after logging in with the platform CLI:146147```bash148clawhub login149clawhub package publish . --family code-plugin --dry-run150clawhub package publish . --family code-plugin151```152153If your ClawHub namespace requires a scoped package name, update `package.json#name` and the install examples before publishing. OpenClaw package publishing requires `package.json#openclaw.compat.pluginApi` and `package.json#openclaw.build.openclawVersion`; both are included in this package.154155## License156157MIT158
Full transparency — inspect the skill content before installing.