From c0072be6a6667e90c0c9c8c517a20c99408d1d96 Mon Sep 17 00:00:00 2001 From: Sebastian <19554889+sebslight@users.noreply.github.com> Date: Tue, 17 Feb 2026 09:58:37 -0500 Subject: [PATCH] docs(cli): add components send example --- CHANGELOG.md | 1 + docs/cli/message.md | 10 ++++++++++ .../outbound/message-action-runner.test.ts | 18 ++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75a2a97f3f3..5e25b4f77f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -75,6 +75,7 @@ Docs: https://docs.openclaw.ai - CLI/Daemon: warn when a gateway restart sees a stale service token so users can reinstall with `openclaw gateway install --force`, and skip drift warnings for non-gateway service restarts. (#18018) - CLI/Status: fix `openclaw status --all` token summaries for bot-token-only channels so Mattermost/Zalo no longer show a bot+app warning. (#18527) Thanks @echo931. - CLI/Configure: make the `/model picker` allowlist prompt searchable with tokenized matching in `openclaw configure` so users can filter huge model lists by typing terms like `gpt-5.2 openai/`. (#19010) Thanks @bjesuiter. +- CLI/Message: preserve `--components` JSON payloads in `openclaw message send` so Discord component payloads are no longer dropped. (#18222) Thanks @saurabhchopade. - Voice Call: add an optional stale call reaper (`staleCallReaperSeconds`) to end stuck calls when enabled. (#18437) - Auto-reply/Subagents: propagate group context (`groupId`, `groupChannel`, `space`) when spawning via `/subagents spawn`, matching tool-triggered subagent spawn behavior. - Subagents: route nested announce results back to the parent session after the parent run ends, falling back only when the parent session is deleted. (#18043) diff --git a/docs/cli/message.md b/docs/cli/message.md index a9ac8c7948b..195e884a01d 100644 --- a/docs/cli/message.md +++ b/docs/cli/message.md @@ -191,6 +191,16 @@ openclaw message send --channel discord \ --target channel:123 --message "hi" --reply-to 456 ``` +Send a Discord message with components: + +``` +openclaw message send --channel discord \ + --target channel:123 --message "Choose:" \ + --components '{"text":"Choose a path","blocks":[{"type":"actions","buttons":[{"label":"Approve","style":"success"},{"label":"Decline","style":"danger"}]}]}' +``` + +See [Discord components](/channels/discord#interactive-components) for the full schema. + Create a Discord poll: ``` diff --git a/src/infra/outbound/message-action-runner.test.ts b/src/infra/outbound/message-action-runner.test.ts index c273d52ddb2..af62420d44a 100644 --- a/src/infra/outbound/message-action-runner.test.ts +++ b/src/infra/outbound/message-action-runner.test.ts @@ -815,6 +815,24 @@ describe("runMessageAction components parsing", () => { expect(handleAction).toHaveBeenCalled(); expect(result.payload).toMatchObject({ ok: true, components }); }); + + it("throws on invalid components JSON strings", async () => { + await expect( + runMessageAction({ + cfg: {} as OpenClawConfig, + action: "send", + params: { + channel: "discord", + target: "channel:123", + message: "hi", + components: "{not-json}", + }, + dryRun: false, + }), + ).rejects.toThrow(/--components must be valid JSON/); + + expect(handleAction).not.toHaveBeenCalled(); + }); }); describe("runMessageAction accountId defaults", () => {