openclaw message CLI: Send Messages & Channel Actions

Reference for the openclaw message command, covering message sending and channel actions across multiple platforms. Essential for users managing multi-channel communication from the CLI.

Read this when

  • Adding or modifying message CLI actions
  • Changing outbound channel behavior

openclaw message

A unified command to send messages and perform channel actions across Discord, Google Chat, iMessage, Matrix, Mattermost (plugin), Microsoft Teams, Signal, Slack, Telegram, and WhatsApp.

openclaw message <subcommand> [flags]

Channel selection

  • When multiple channels are set up, --channel <name> becomes mandatory; if only one channel exists, that channel is used by default.
  • Acceptable values: discord|googlechat|imessage|matrix|mattermost|msteams|signal|slack|telegram|whatsapp (the plugin is required for Mattermost).
  • Targets prefixed with a channel, like discord:channel:123, identify the owning plugin without needing an explicit --channel.

Target formats (-t, --target)

ChannelFormat
Discordchannel:<id>, user:<id>, <@id> mention, or a plain numeric id (interpreted as a channel id)
Google Chatspaces/<spaceId> or users/<userId>
iMessagehandle, chat_id:<id>, chat_guid:<guid>, or chat_identifier:<id>
Mattermost (plugin)channel:<id>, user:<id>, @username, or a bare id (interpreted as a channel)
Matrix@user:server, !room:server, or #alias:server
Microsoft Teamsconversation:<id> (19:...@thread.tacv2), a plain conversation id, or user:<aad-object-id>
Signal+E.164, group:<id>, uuid:<id>, username:<name>/u:<name>, or any of these with a signal: prefix
Slackchannel:<id> or user:<id> (a bare id is interpreted as a channel)
Telegramchat id, @username, or a forum topic target: <chatId>:topic:<topicId> (or --thread-id <topicId>)
WhatsAppE.164, group JID (...@g.us), or Channel/Newsletter JID (...@newsletter)

Channel name resolution: for providers that maintain a directory (Discord, Slack, and others), names such as Help or #help are looked up from the directory cache, with a fallback to a live directory query when the cache does not contain the entry and the provider supports it.

Common flags

All actions accept these parameters: --channel <name>, --account <id>, --json, --dry-run, --verbose. Actions that require a destination also accept -t, --target <dest>.

SecretRef resolution

openclaw message resolves channel SecretRefs before executing the action, applying the narrowest possible scope:

  • channel scope when --channel is provided (or inferred from a prefixed target)
  • account scope when --account is also provided
  • all configured channels when neither is provided

Unresolved SecretRefs on unrelated channels never block a targeted action; an unresolved SecretRef on the chosen channel or account causes the action to fail immediately.

Actions

Core

ActionChannelsRequiredNotes
sendDiscord, Google Chat, iMessage, Matrix, Mattermost (plugin), Microsoft Teams, Signal, Slack, Telegram, WhatsApp--target, plus one of --message/--media/--presentationRefer to the Send section below.
pollDiscord, Matrix, Microsoft Teams, Telegram, WhatsApp--target, --poll-question, --poll-option (repeat)Check the Poll section below.
reactDiscord, Matrix, Nextcloud Talk, Signal, Slack, Telegram, WhatsApp--message-id, --target--emoji, --remove (requires --emoji; leave it out to clear your own reactions where the platform allows, see Reactions). On WhatsApp: --participant, --from-me. For Signal group reactions you need --target-author or --target-author-uuid. Nextcloud Talk can only add reactions; --remove results in an error.
reactionsDiscord, Matrix, Microsoft Teams, Slack--message-id, --target--limit.
readDiscord, Matrix, Microsoft Teams, Slack--target--limit, --message-id, --before, --after. For Discord: --around, --include-thread. In Slack: --message-id reads a particular timestamp; pair it with --thread-id to reply directly in a thread.
editDiscord, Matrix, Microsoft Teams, Slack, Telegram--message-id, --message, --targetTelegram forum threads make use of --thread-id.
deleteDiscord, Matrix, Microsoft Teams, Slack, Telegram--message-id, --target
pin / unpinDiscord, Matrix, Microsoft Teams, Slack--message-id, --targetunpin also supports --pinned-message-id (in Microsoft Teams this is the resource ID for pin/list-pins, not the chat message ID).
pins (list)Discord, Matrix, Microsoft Teams, Slack--target--limit.
permissionsDiscord, Matrix--targetOn Matrix this works only when encryption is active and verification actions are permitted.
searchDiscord--guild-id, --query--channel-id, --channel-ids (repeat), --author-id, --author-ids (repeat), --limit.
member infoDiscord, Matrix, Microsoft Teams, Slack--user-id--guild-id (Discord).

Send

openclaw message send --channel discord \
  --target channel:123 --message "hi" --reply-to 456
  • --media <path-or-url>: attach an image, audio, video, or document by providing either a local path or a URL.
  • --presentation <json>: a combined payload with text, context, divider, chart, table, buttons, and select blocks, adapted for each channel's capabilities. Refer to Message Presentation.
  • --delivery <json>: general delivery preferences, such as {"pin": true}. When the channel supports it, --pin acts as a shortcut for pinned delivery.
  • --reply-to <id>, --thread-id <id> (Telegram forum topic; Slack thread timestamp, using the same field as --reply-to).
  • --force-document (Telegram, WhatsApp): send images, GIFs, or videos as documents to bypass channel compression.
  • --silent (Telegram, Discord): suppress the notification for this message.
  • --gif-playback (WhatsApp only): treat video media as a GIF animation.
openclaw message send --channel discord \
  --target channel:123 --message "Choose:" \
  --presentation '{"blocks":[{"type":"buttons","buttons":[{"label":"Approve","value":"approve","style":"success"},{"label":"Decline","value":"decline","style":"danger"}]}]}'
openclaw message send --channel telegram --target @mychat --message "Choose:" \
  --presentation '{"blocks":[{"type":"buttons","buttons":[{"label":"Yes","value":"cmd:yes"},{"label":"No","value":"cmd:no"}]}]}'

Slack renders supported chart blocks natively; on all other channels the same data is presented as readable text:

openclaw message send --channel slack --target channel:C123 \
  --presentation '{"blocks":[{"type":"chart","chartType":"bar","title":"Quarterly revenue","categories":["Q1","Q2"],"series":[{"name":"Revenue","values":[120,145]}],"xLabel":"Quarter"}]}'

Slack also renders explicit table blocks natively. On other channels the caption and each row are displayed as deterministic text:

openclaw message send --channel slack --target channel:C123 \
  --presentation '{"title":"Pipeline report","blocks":[{"type":"table","caption":"Open pipeline","headers":["Account","Stage","ARR"],"rows":[["Acme","Won",125000],["Globex","Review",82000]],"rowHeaderColumnIndex":0}]}'

Telegram Mini App buttons use webApp (web_app still parses legacy JSON) and only appear in private chats between a user and the bot:

openclaw message send --channel telegram --target 123456789 --message "Open app:" \
  --presentation '{"blocks":[{"type":"buttons","buttons":[{"label":"Launch","webApp":{"url":"https://example.com/app"}}]}]}'
openclaw message send --channel telegram --target @mychat \
  --media ./diagram.png --force-document
openclaw message send --channel msteams \
  --target conversation:19:abc@thread.tacv2 \
  --presentation '{"title":"Status update","blocks":[{"type":"text","text":"Build completed"}]}'

Poll

openclaw message poll --channel discord \
  --target channel:123 \
  --poll-question "Snack?" \
  --poll-option Pizza --poll-option Sushi \
  --poll-multi --poll-duration-hours 48
  • --poll-option <choice>: repeat the action 2 to 12 times.
  • --poll-multi: permit multiple selections.
  • Discord: --poll-duration-hours, --silent, --message.
  • Telegram: --poll-duration-seconds <n> (range 5 to 600), --silent, --poll-anonymous / --poll-public, --thread-id.
openclaw message poll --channel telegram \
  --target @mychat \
  --poll-question "Lunch?" \
  --poll-option Pizza --poll-option Sushi \
  --poll-duration-seconds 120 --silent
openclaw message poll --channel msteams \
  --target conversation:19:abc@thread.tacv2 \
  --poll-question "Lunch?" \
  --poll-option Pizza --poll-option Sushi

Threads

  • thread create: Discord channels. Mandatory fields: --thread-name, --target (channel id). Optional fields: --message-id, --message, --auto-archive-min.
  • thread list: Discord channels. Mandatory field: --guild-id. Optional fields: --channel-id, --include-archived, --before, --limit.
  • thread reply: Discord channels. Mandatory fields: --target (thread id), --message. Optional fields: --media, --reply-to.

Emojis

  • emoji list: Discord (--guild-id), Slack (no additional flags).
  • emoji upload: Discord. Mandatory fields: --guild-id, --emoji-name, --media. Optional field: --role-ids (repeat).

Stickers

  • sticker send: Discord. Mandatory fields: --target, --sticker-id (repeat). Optional field: --message.
  • sticker upload: Discord. Mandatory fields: --guild-id, --sticker-name, --sticker-desc, --sticker-tags, --media.

Roles, channels, voice, events (Discord)

  • role info: --guild-id.
  • role add / role remove: --guild-id, --user-id, --role-id.
  • channel info: --target.
  • channel list: --guild-id.
  • voice status: --guild-id, --user-id.
  • event list: --guild-id.
  • event create: --guild-id, --event-name, and --start-time are mandatory; --end-time, --desc, --channel-id, --location, --event-type, and --image <url-or-path> are not.

Moderation (Discord)

  • timeout: --guild-id and --user-id; optionally --duration-min or --until (leaving both out removes the timeout), --reason.
  • kick: --guild-id, --user-id, and --reason.
  • ban: --guild-id, --user-id, --delete-days, and --reason.

Broadcast

openclaw message broadcast --targets <target...> [--channel all] [--message <text>] [--media <url>] [--dry-run]

A single message is delivered to several destinations. --targets expects a list separated by spaces. To send to all configured providers, use --channel all.