TaskFlow
DashboardFreewriteWhiteboardsProjectsCRMTasksNotificationsSettingsAgent TowerAPI Docs
OpenClaw Docs
?

User

Member

Caricamento in corso...

Home
Progetti
Task
Notifiche
CRM

    OpenClaw

    Documentation Mirror

    Documentation Overview

    Docs

    Auth credential semantics
    Scheduled tasks
    Hooks
    Automation & tasks
    Standing orders
    Task flow
    Background tasks
    BlueBubbles
    Broadcast groups
    Channel routing
    Discord
    Feishu
    Google Chat
    Group messages
    Groups
    iMessage
    Chat channels
    IRC
    LINE
    Channel location parsing
    Matrix
    Matrix migration
    Matrix push rules for quiet previews
    Mattermost
    Microsoft Teams
    Nextcloud Talk
    Nostr
    Pairing
    QA channel
    QQ bot
    Signal
    Slack
    Synology Chat
    Telegram
    Tlon
    Channel troubleshooting
    Twitch
    WeChat
    WhatsApp
    Yuanbao
    Zalo
    Zalo personal
    CI pipeline
    ACP
    Agent
    Agents
    Approvals
    Backup
    Browser
    Channels
    Clawbot
    `openclaw commitments`
    Completion
    Config
    Configure
    Cron
    Daemon
    Dashboard
    Devices
    Directory
    DNS
    Docs
    Doctor
    Flows (redirect)
    Gateway
    Health
    Hooks
    CLI reference
    Inference CLI
    Logs
    MCP
    Memory
    Message
    Migrate
    Models
    Node
    Nodes
    Onboard
    Pairing
    Plugins
    Proxy
    QR
    Reset
    Sandbox CLI
    Secrets
    Security
    Sessions
    Setup
    Skills
    Status
    System
    `openclaw tasks`
    TUI
    Uninstall
    Update
    Voicecall
    Webhooks
    Wiki
    Active memory
    Agent runtime
    Agent loop
    Agent runtimes
    Agent workspace
    Gateway architecture
    Channel docking
    Inferred commitments
    Compaction
    Context
    Context engine
    Delegate architecture
    Dreaming
    Experimental features
    Features
    Markdown formatting
    Memory overview
    Builtin memory engine
    Honcho memory
    QMD memory engine
    Memory search
    Messages
    Model failover
    Model providers
    Models CLI
    Multi-agent routing
    OAuth
    OpenClaw App SDK
    Presence
    QA overview
    Matrix QA
    Command queue
    Steering queue
    Retry policy
    Session management
    Session pruning
    Session tools
    SOUL.md personality guide
    Streaming and chunking
    System prompt
    Timezones
    TypeBox
    Typing indicators
    Usage tracking
    Date and time
    Node + tsx crash
    Diagnostics flags
    Authentication
    Background exec and process tool
    Bonjour discovery
    Bridge protocol
    CLI backends
    Configuration — agents
    Configuration — channels
    Configuration — tools and custom providers
    Configuration
    Configuration examples
    Configuration reference
    Diagnostics export
    Discovery and transports
    Doctor
    Gateway lock
    Health checks
    Heartbeat
    Gateway runbook
    Local models
    Gateway logging
    Multiple gateways
    Network model
    OpenAI chat completions
    OpenResponses API
    OpenShell
    OpenTelemetry export
    Gateway-owned pairing
    Prometheus metrics
    Gateway protocol
    Remote access
    Remote gateway setup
    Sandbox vs tool policy vs elevated
    Sandboxing
    Secrets management
    Secrets apply plan contract
    Security audit checks
    Security
    Tailscale
    Tools invoke API
    Troubleshooting
    Trusted proxy auth
    Debugging
    Environment variables
    FAQ
    FAQ: first-run setup
    FAQ: models and auth
    GPT-5.5 / Codex agentic parity
    GPT-5.5 / Codex parity maintainer notes
    Help
    Scripts
    Testing
    Testing: live suites
    General troubleshooting
    OpenClaw
    Ansible
    Azure
    Bun (experimental)
    ClawDock
    Release channels
    DigitalOcean
    Docker
    Docker VM runtime
    exe.dev
    Fly.io
    GCP
    Hetzner
    Hostinger
    Install
    Installer internals
    Kubernetes
    macOS VMs
    Migration guide
    Migrating from Claude
    Migrating from Hermes
    Nix
    Node.js
    Northflank
    Oracle Cloud
    Podman
    Railway
    Raspberry Pi
    Render
    Uninstall
    Updating
    Logging
    Network
    Audio and voice notes
    Camera capture
    Image and media support
    Nodes
    Location command
    Media understanding
    Talk mode
    Node troubleshooting
    Voice wake
    Pi integration architecture
    Pi development workflow
    Android app
    Platforms
    iOS app
    Linux app
    Gateway on macOS
    Canvas
    Gateway lifecycle
    macOS dev setup
    Health checks (macOS)
    Menu bar icon
    macOS logging
    Menu bar
    Peekaboo bridge
    macOS permissions
    Remote control
    macOS signing
    Skills (macOS)
    Voice overlay
    Voice wake (macOS)
    WebChat (macOS)
    macOS IPC
    macOS app
    Windows
    Plugin internals
    Plugin architecture internals
    Building plugins
    Plugin bundles
    Codex Computer Use
    Codex harness
    Community plugins
    Plugin compatibility
    Google Meet plugin
    Plugin hooks
    Plugin manifest
    Memory LanceDB
    Memory wiki
    Message presentation
    Agent harness plugins
    Building channel plugins
    Channel turn kernel
    Plugin entry points
    Plugin SDK migration
    Plugin SDK overview
    Building provider plugins
    Plugin runtime helpers
    Plugin setup and config
    Plugin SDK subpaths
    Plugin testing
    Skill workshop plugin
    Voice call plugin
    Webhooks plugin
    Zalo personal plugin
    OpenProse
    Alibaba Model Studio
    Anthropic
    Arcee AI
    Azure Speech
    Amazon Bedrock
    Amazon Bedrock Mantle
    Chutes
    Claude Max API proxy
    Cloudflare AI gateway
    ComfyUI
    Deepgram
    Deepinfra
    DeepSeek
    ElevenLabs
    Fal
    Fireworks
    GitHub Copilot
    GLM (Zhipu)
    Google (Gemini)
    Gradium
    Groq
    Hugging Face (inference)
    Provider directory
    Inferrs
    Inworld
    Kilocode
    LiteLLM
    LM Studio
    MiniMax
    Mistral
    Model provider quickstart
    Moonshot AI
    NVIDIA
    Ollama
    OpenAI
    OpenCode
    OpenCode Go
    OpenRouter
    Perplexity
    Qianfan
    Qwen
    Runway
    SGLang
    StepFun
    Synthetic
    Tencent Cloud (TokenHub)
    Together AI
    Venice AI
    Vercel AI gateway
    vLLM
    Volcengine (Doubao)
    Vydra
    xAI
    Xiaomi MiMo
    Z.AI
    Default AGENTS.md
    Release policy
    API usage and costs
    Credits
    Device model database
    Full release validation
    Memory configuration reference
    OpenClaw App SDK API design
    Prompt caching
    Rich output protocol
    RPC adapters
    SecretRef credential surface
    Session management deep dive
    AGENTS.md template
    BOOT.md template
    BOOTSTRAP.md template
    HEARTBEAT.md template
    IDENTITY template
    SOUL.md template
    TOOLS.md template
    USER template
    Tests
    Token use and costs
    Transcript hygiene
    Onboarding reference
    Contributing to the threat model
    Threat model (MITRE ATLAS)
    Formal verification (security models)
    Network proxy
    Agent bootstrapping
    Docs directory
    Getting started
    Docs hubs
    OpenClaw lore
    Onboarding (macOS app)
    Onboarding overview
    Personal assistant setup
    Setup
    Showcase
    Onboarding (CLI)
    CLI automation
    CLI setup reference
    ACP agents
    ACP agents — setup
    Agent send
    apply_patch tool
    Brave search
    Browser (OpenClaw-managed)
    Browser control API
    Browser troubleshooting
    Browser login
    WSL2 + Windows + remote Chrome CDP troubleshooting
    BTW side questions
    ClawHub
    Code execution
    Creating skills
    Diffs
    DuckDuckGo search
    Elevated mode
    Exa search
    Exec tool
    Exec approvals
    Exec approvals — advanced
    Firecrawl
    Gemini search
    Grok search
    Image generation
    Tools and plugins
    Kimi search
    LLM task
    Lobster
    Tool-loop detection
    Media overview
    MiniMax search
    Multi-agent sandbox and tools
    Music generation
    Ollama web search
    PDF tool
    Perplexity search
    Plugins
    Reactions
    SearXNG search
    Skills
    Skills config
    Slash commands
    Sub-agents
    Tavily
    Thinking levels
    Tokenjuice
    Trajectory bundles
    Text-to-speech
    Video generation
    Web search
    Web fetch
    Linux server
    Control UI
    Dashboard
    Web
    TUI
    WebChat

    OpenAPI Specs

    openapi
    TaskFlow
    docs/openclaw
    Original Docs

    Real-time Synchronized Documentation

    Last sync: 01/05/2026 07:04:04

    Note: This content is mirrored from docs.openclaw.ai and is subject to their terms and conditions.

    OpenClaw Docs

    v2.4.0 Production

    Last synced: Today, 22:00

    Technical reference for the OpenClaw framework. Real-time synchronization with the official documentation engine.

    Use this file to discover all available pages before exploring further.

    Discord

    Ready for DMs and guild channels via the official Discord gateway.

    Pairing

    Discord DMs default to pairing mode.

    Slash commands

    Native command behavior and command catalog.

    Channel troubleshooting

    Cross-channel diagnostics and repair flow.

    Quick setup

    You will need to create a new application with a bot, add the bot to your server, and pair it to OpenClaw. We recommend adding your bot to your own private server. If you don't have one yet, create one first (choose Create My Own > For me and my friends).

    Create a Discord application and bot

    Go to the [Discord Developer Portal](https://discord.com/developers/applications) and click **New Application**. Name it something like "OpenClaw".
    text
    Click **Bot** on the sidebar. Set the **Username** to whatever you call your OpenClaw agent.

    Enable privileged intents

    Still on the **Bot** page, scroll down to **Privileged Gateway Intents** and enable:
    text
    * **Message Content Intent** (required) * **Server Members Intent** (recommended; required for role allowlists and name-to-ID matching) * **Presence Intent** (optional; only needed for presence updates)

    Copy your bot token

    Scroll back up on the **Bot** page and click **Reset Token**.
    text
    <Note> Despite the name, this generates your first token — nothing is being "reset." </Note> Copy the token and save it somewhere. This is your **Bot Token** and you will need it shortly.

    Generate an invite URL and add the bot to your server

    Click **OAuth2** on the sidebar. You'll generate an invite URL with the right permissions to add the bot to your server.
    text
    Scroll down to **OAuth2 URL Generator** and enable: * `bot` * `applications.commands` A **Bot Permissions** section will appear below. Enable at least: **General Permissions** * View Channels **Text Permissions** * Send Messages * Read Message History * Embed Links * Attach Files * Add Reactions (optional) This is the baseline set for normal text channels. If you plan to post in Discord threads, including forum or media channel workflows that create or continue a thread, also enable **Send Messages in Threads**. Copy the generated URL at the bottom, paste it into your browser, select your server, and click **Continue** to connect. You should now see your bot in the Discord server.

    Enable Developer Mode and collect your IDs

    Back in the Discord app, you need to enable Developer Mode so you can copy internal IDs.
    text
    1. Click **User Settings** (gear icon next to your avatar) → **Advanced** → toggle on **Developer Mode** 2. Right-click your **server icon** in the sidebar → **Copy Server ID** 3. Right-click your **own avatar** → **Copy User ID** Save your **Server ID** and **User ID** alongside your Bot Token — you'll send all three to OpenClaw in the next step.

    Allow DMs from server members

    For pairing to work, Discord needs to allow your bot to DM you. Right-click your **server icon** → **Privacy Settings** → toggle on **Direct Messages**.
    text
    This lets server members (including bots) send you DMs. Keep this enabled if you want to use Discord DMs with OpenClaw. If you only plan to use guild channels, you can disable DMs after pairing.

    Set your bot token securely (do not send it in chat)

    Your Discord bot token is a secret (like a password). Set it on the machine running OpenClaw before messaging your agent.
    text
    ```bash} export DISCORD_BOT_TOKEN="YOUR_BOT_TOKEN" cat > discord.patch.json5 <<'JSON5' { channels: { discord: { enabled: true, token: { source: "env", provider: "default", id: "DISCORD_BOT_TOKEN" }, }, }, } JSON5 openclaw config patch --file ./discord.patch.json5 --dry-run openclaw config patch --file ./discord.patch.json5 openclaw gateway ``` If OpenClaw is already running as a background service, restart it via the OpenClaw Mac app or by stopping and restarting the `openclaw gateway run` process. For managed service installs, run `openclaw gateway install` from a shell where `DISCORD_BOT_TOKEN` is present, or store the variable in `~/.openclaw/.env`, so the service can resolve the env SecretRef after restart. If your host is blocked or rate-limited by Discord's startup application lookup, set the Discord application/client ID from the Developer Portal so startup can skip that REST call. Use `channels.discord.applicationId` for the default account, or `channels.discord.accounts.<accountId>.applicationId` when you run multiple Discord bots.

    Configure OpenClaw and pair

    Chat with your OpenClaw agent on any existing channel (e.g. Telegram) and tell it. If Discord is your first channel, use the CLI / config tab instead.
    text
    > "I already set my Discord bot token in config. Please finish Discord setup with User ID `<user_id>` and Server ID `<server_id>`." </Tab> <Tab title="CLI / config"> If you prefer file-based config, set: ```json5} { channels: { discord: { enabled: true, token: { source: "env", provider: "default", id: "DISCORD_BOT_TOKEN", }, }, }, } ``` Env fallback for the default account: ```bash} DISCORD_BOT_TOKEN=... ``` For scripted or remote setup, write the same JSON5 block with `openclaw config patch --file ./discord.patch.json5 --dry-run` and then rerun without `--dry-run`. Plaintext `token` values are supported. SecretRef values are also supported for `channels.discord.token` across env/file/exec providers. See [Secrets Management](/gateway/secrets). For multiple Discord bots, keep each bot token and application ID under its account. A top-level `channels.discord.applicationId` is inherited by accounts, so only set it there when every account should use the same application ID. ```json5} { channels: { discord: { enabled: true, accounts: { personal: { token: { source: "env", provider: "default", id: "DISCORD_PERSONAL_TOKEN" }, applicationId: "111111111111111111", }, work: { token: { source: "env", provider: "default", id: "DISCORD_WORK_TOKEN" }, applicationId: "222222222222222222", }, }, }, }, } ``` </Tab> </Tabs>

    Approve first DM pairing

    Wait until the gateway is running, then DM your bot in Discord. It will respond with a pairing code.
    text
    <Tabs> <Tab title="Ask your agent"> Send the pairing code to your agent on your existing channel: > "Approve this Discord pairing code: `<CODE>`" </Tab> <Tab title="CLI"> ```bash} openclaw pairing list discord openclaw pairing approve discord <CODE> ``` </Tab> </Tabs> Pairing codes expire after 1 hour. You should now be able to chat with your agent in Discord via DM.

    note

    Token resolution is account-aware. Config token values win over env fallback. `DISCORD_BOT_TOKEN` is only used for the default account. If two enabled Discord accounts resolve to the same bot token, OpenClaw starts only one gateway monitor for that token. A config-sourced token wins over the default env fallback; otherwise the first enabled account wins and the duplicate account is reported disabled. For advanced outbound calls (message tool/channel actions), an explicit per-call `token` is used for that call. This applies to send and read/probe-style actions (for example read/search/fetch/thread/pins/permissions). Account policy/retry settings still come from the selected account in the active runtime snapshot.

    Recommended: Set up a guild workspace

    Once DMs are working, you can set up your Discord server as a full workspace where each channel gets its own agent session with its own context. This is recommended for private servers where it's just you and your bot.

    Add your server to the guild allowlist

    This enables your agent to respond in any channel on your server, not just DMs.
    text
    <Tabs> <Tab title="Ask your agent"> > "Add my Discord Server ID `<server_id>` to the guild allowlist" </Tab> <Tab title="Config"> ```json5} { channels: { discord: { groupPolicy: "allowlist", guilds: { YOUR_SERVER_ID: { requireMention: true, users: ["YOUR_USER_ID"], }, }, }, }, } ``` </Tab> </Tabs>

    Allow responses without @mention

    By default, your agent only responds in guild channels when @mentioned. For a private server, you probably want it to respond to every message.
    text
    In guild channels, normal assistant final replies stay private by default. Visible Discord output must be sent explicitly with the `message` tool, so the agent can lurk by default and only post when it decides a channel reply is useful. <Tabs> <Tab title="Ask your agent"> > "Allow my agent to respond on this server without having to be @mentioned" </Tab> <Tab title="Config"> Set `requireMention: false` in your guild config: ```json5} { channels: { discord: { guilds: { YOUR_SERVER_ID: { requireMention: false, }, }, }, }, } ``` To restore legacy automatic final replies for group/channel rooms, set `messages.groupChat.visibleReplies: "automatic"`. </Tab> </Tabs>

    Plan for memory in guild channels

    By default, long-term memory (MEMORY.md) only loads in DM sessions. Guild channels do not auto-load MEMORY.md.
    text
    <Tabs> <Tab title="Ask your agent"> > "When I ask questions in Discord channels, use memory\_search or memory\_get if you need long-term context from MEMORY.md." </Tab> <Tab title="Manual"> If you need shared context in every channel, put the stable instructions in `AGENTS.md` or `USER.md` (they are injected for every session). Keep long-term notes in `MEMORY.md` and access them on demand with memory tools. </Tab> </Tabs>

    Now create some channels on your Discord server and start chatting. Your agent can see the channel name, and each channel gets its own isolated session — so you can set up

    text
    #coding
    ,
    text
    #home
    ,
    text
    #research
    , or whatever fits your workflow.

    Runtime model

    • Gateway owns the Discord connection.
    • Reply routing is deterministic: Discord inbound replies back to Discord.
    • Discord guild/channel metadata is added to the model prompt as untrusted context, not as a user-visible reply prefix. If a model copies that envelope back, OpenClaw strips the copied metadata from outbound replies and from future replay context.
    • By default (
      text
      session.dmScope=main
      ), direct chats share the agent main session (
      text
      agent:main:main
      ).
    • Guild channels are isolated session keys (
      text
      agent:<agentId>:discord:channel:<channelId>
      ).
    • Group DMs are ignored by default (
      text
      channels.discord.dm.groupEnabled=false
      ).
    • Native slash commands run in isolated command sessions (
      text
      agent:<agentId>:discord:slash:<userId>
      ), while still carrying
      text
      CommandTargetSessionKey
      to the routed conversation session.
    • Text-only cron/heartbeat announce delivery to Discord uses the final assistant-visible answer once. Media and structured component payloads remain multi-message when the agent emits multiple deliverable payloads.

    Forum channels

    Discord forum and media channels only accept thread posts. OpenClaw supports two ways to create them:

    • Send a message to the forum parent (
      text
      channel:<forumId>
      ) to auto-create a thread. The thread title uses the first non-empty line of your message.
    • Use
      text
      openclaw message thread create
      to create a thread directly. Do not pass
      text
      --message-id
      for forum channels.

    Example: send to forum parent to create a thread

    bash
    openclaw message send --channel discord --target channel:<forumId> \ --message "Topic title\nBody of the post"

    Example: create a forum thread explicitly

    bash
    openclaw message thread create --channel discord --target channel:<forumId> \ --thread-name "Topic title" --message "Body of the post"

    Forum parents do not accept Discord components. If you need components, send to the thread itself (

    text
    channel:<threadId>
    ).

    Interactive components

    OpenClaw supports Discord components v2 containers for agent messages. Use the message tool with a

    text
    components
    payload. Interaction results are routed back to the agent as normal inbound messages and follow the existing Discord
    text
    replyToMode
    settings.

    Supported blocks:

    • text
      text
      ,
      text
      section
      ,
      text
      separator
      ,
      text
      actions
      ,
      text
      media-gallery
      ,
      text
      file
    • Action rows allow up to 5 buttons or a single select menu
    • Select types:
      text
      string
      ,
      text
      user
      ,
      text
      role
      ,
      text
      mentionable
      ,
      text
      channel

    By default, components are single use. Set

    text
    components.reusable=true
    to allow buttons, selects, and forms to be used multiple times until they expire.

    To restrict who can click a button, set

    text
    allowedUsers
    on that button (Discord user IDs, tags, or
    text
    *
    ). When configured, unmatched users receive an ephemeral denial.

    The

    text
    /model
    and
    text
    /models
    slash commands open an interactive model picker with provider, model, and compatible runtime dropdowns plus a Submit step.
    text
    /models add
    is deprecated and now returns a deprecation message instead of registering models from chat. The picker reply is ephemeral and only the invoking user can use it.

    File attachments:

    • text
      file
      blocks must point to an attachment reference (
      text
      attachment://<filename>
      )
    • Provide the attachment via
      text
      media
      /
      text
      path
      /
      text
      filePath
      (single file); use
      text
      media-gallery
      for multiple files
    • Use
      text
      filename
      to override the upload name when it should match the attachment reference

    Modal forms:

    • Add
      text
      components.modal
      with up to 5 fields
    • Field types:
      text
      text
      ,
      text
      checkbox
      ,
      text
      radio
      ,
      text
      select
      ,
      text
      role-select
      ,
      text
      user-select
    • OpenClaw adds a trigger button automatically

    Example:

    json5
    { channel: "discord", action: "send", to: "channel:123456789012345678", message: "Optional fallback text", components: { reusable: true, text: "Choose a path", blocks: [ { type: "actions", buttons: [ { label: "Approve", style: "success", allowedUsers: ["123456789012345678"], }, { label: "Decline", style: "danger" }, ], }, { type: "actions", select: { type: "string", placeholder: "Pick an option", options: [ { label: "Option A", value: "a" }, { label: "Option B", value: "b" }, ], }, }, ], modal: { title: "Details", triggerLabel: "Open form", fields: [ { type: "text", label: "Requester" }, { type: "select", label: "Priority", options: [ { label: "Low", value: "low" }, { label: "High", value: "high" }, ], }, ], }, }, }

    Access control and routing

    `channels.discord.dmPolicy` controls DM access. `channels.discord.allowFrom` is the canonical DM allowlist.
    text
    * `pairing` (default) * `allowlist` * `open` (requires `channels.discord.allowFrom` to include `"*"`) * `disabled` If DM policy is not open, unknown users are blocked (or prompted for pairing in `pairing` mode). Multi-account precedence: * `channels.discord.accounts.default.allowFrom` applies only to the `default` account. * For one account, `allowFrom` takes precedence over legacy `dm.allowFrom`. * Named accounts inherit `channels.discord.allowFrom` when their own `allowFrom` and legacy `dm.allowFrom` are unset. * Named accounts do not inherit `channels.discord.accounts.default.allowFrom`. Legacy `channels.discord.dm.policy` and `channels.discord.dm.allowFrom` still read for compatibility. `openclaw doctor --fix` migrates them to `dmPolicy` and `allowFrom` when it can do so without changing access. DM target format for delivery: * `user:<id>` * `<@id>` mention Bare numeric IDs normally resolve as channel IDs when a channel default is active, but IDs listed in the account's effective DM `allowFrom` are treated as user DM targets for compatibility.
    Guild handling is controlled by `channels.discord.groupPolicy`:
    text
    * `open` * `allowlist` * `disabled` Secure baseline when `channels.discord` exists is `allowlist`. `allowlist` behavior: * guild must match `channels.discord.guilds` (`id` preferred, slug accepted) * optional sender allowlists: `users` (stable IDs recommended) and `roles` (role IDs only); if either is configured, senders are allowed when they match `users` OR `roles` * direct name/tag matching is disabled by default; enable `channels.discord.dangerouslyAllowNameMatching: true` only as break-glass compatibility mode * names/tags are supported for `users`, but IDs are safer; `openclaw security audit` warns when name/tag entries are used * if a guild has `channels` configured, non-listed channels are denied * if a guild has no `channels` block, all channels in that allowlisted guild are allowed Example: ```json5} { channels: { discord: { groupPolicy: "allowlist", guilds: { "123456789012345678": { requireMention: true, ignoreOtherMentions: true, users: ["987654321098765432"], roles: ["123456789012345678"], channels: { general: { allow: true }, help: { allow: true, requireMention: true }, }, }, }, }, }, } ``` If you only set `DISCORD_BOT_TOKEN` and do not create a `channels.discord` block, runtime fallback is `groupPolicy="allowlist"` (with a warning in logs), even if `channels.defaults.groupPolicy` is `open`.
    Guild messages are mention-gated by default.
    text
    Mention detection includes: * explicit bot mention * configured mention patterns (`agents.list[].groupChat.mentionPatterns`, fallback `messages.groupChat.mentionPatterns`) * implicit reply-to-bot behavior in supported cases `requireMention` is configured per guild/channel (`channels.discord.guilds...`). `ignoreOtherMentions` optionally drops messages that mention another user/role but not the bot (excluding @everyone/@here). Group DMs: * default: ignored (`dm.groupEnabled=false`) * optional allowlist via `dm.groupChannels` (channel IDs or slugs)

    Role-based agent routing

    Use

    text
    bindings[].match.roles
    to route Discord guild members to different agents by role ID. Role-based bindings accept role IDs only and are evaluated after peer or parent-peer bindings and before guild-only bindings. If a binding also sets other match fields (for example
    text
    peer
    +
    text
    guildId
    +
    text
    roles
    ), all configured fields must match.

    json5
    { bindings: [ { agentId: "opus", match: { channel: "discord", guildId: "123456789012345678", roles: ["111111111111111111"], }, }, { agentId: "sonnet", match: { channel: "discord", guildId: "123456789012345678", }, }, ], }

    Native commands and command auth

    • text
      commands.native
      defaults to
      text
      "auto"
      and is enabled for Discord.
    • Per-channel override:
      text
      channels.discord.commands.native
      .
    • text
      commands.native=false
      explicitly clears previously registered Discord native commands.
    • Native command auth uses the same Discord allowlists/policies as normal message handling.
    • Commands may still be visible in Discord UI for users who are not authorized; execution still enforces OpenClaw auth and returns "not authorized".

    See Slash commands for command catalog and behavior.

    Default slash command settings:

    • text
      ephemeral: true

    Feature details

    Tools and action gates

    Discord message actions include messaging, channel admin, moderation, presence, and metadata actions.

    Core examples:

    • messaging:
      text
      sendMessage
      ,
      text
      readMessages
      ,
      text
      editMessage
      ,
      text
      deleteMessage
      ,
      text
      threadReply
    • reactions:
      text
      react
      ,
      text
      reactions
      ,
      text
      emojiList
    • moderation:
      text
      timeout
      ,
      text
      kick
      ,
      text
      ban
    • presence:
      text
      setPresence

    The

    text
    event-create
    action accepts an optional
    text
    image
    parameter (URL or local file path) to set the scheduled event cover image.

    Action gates live under

    text
    channels.discord.actions.*
    .

    Default gate behavior:

    Action groupDefault
    reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissionsenabled
    rolesdisabled
    moderationdisabled
    presencedisabled

    Components v2 UI

    OpenClaw uses Discord components v2 for exec approvals and cross-context markers. Discord message actions can also accept

    text
    components
    for custom UI (advanced; requires constructing a component payload via the discord tool), while legacy
    text
    embeds
    remain available but are not recommended.

    • text
      channels.discord.ui.components.accentColor
      sets the accent color used by Discord component containers (hex).
    • Set per account with
      text
      channels.discord.accounts.<id>.ui.components.accentColor
      .
    • text
      embeds
      are ignored when components v2 are present.

    Example:

    json5
    { channels: { discord: { ui: { components: { accentColor: "#5865F2", }, }, }, }, }

    Voice

    Discord has two distinct voice surfaces: realtime voice channels (continuous conversations) and voice message attachments (the waveform preview format). The gateway supports both.

    Voice channels

    Setup checklist:

    1. Enable Message Content Intent in the Discord Developer Portal.
    2. Enable Server Members Intent when role/user allowlists are used.
    3. Invite the bot with
      text
      bot
      and
      text
      applications.commands
      scopes.
    4. Grant Connect, Speak, Send Messages, and Read Message History in the target voice channel.
    5. Enable native commands (
      text
      commands.native
      or
      text
      channels.discord.commands.native
      ).
    6. Configure
      text
      channels.discord.voice
      .

    Use

    text
    /vc join|leave|status
    to control sessions. The command uses the account default agent and follows the same allowlist and group policy rules as other Discord commands.

    bash
    /vc join channel:<voice-channel-id> /vc status /vc leave

    Auto-join example:

    json5
    { channels: { discord: { voice: { enabled: true, model: "openai/gpt-5.4-mini", autoJoin: [ { guildId: "123456789012345678", channelId: "234567890123456789", }, ], daveEncryption: true, decryptionFailureTolerance: 24, tts: { provider: "openai", openai: { voice: "onyx" }, }, }, }, }, }

    Notes:

    • text
      voice.tts
      overrides
      text
      messages.tts
      for voice playback only.
    • text
      voice.model
      overrides the LLM used for Discord voice channel responses only. Leave it unset to inherit the routed agent model.
    • STT uses
      text
      tools.media.audio
      ;
      text
      voice.model
      does not affect transcription.
    • Voice transcript turns derive owner status from Discord
      text
      allowFrom
      (or
      text
      dm.allowFrom
      ); non-owner speakers cannot access owner-only tools (for example
      text
      gateway
      and
      text
      cron
      ).
    • Voice is enabled by default; set
      text
      channels.discord.voice.enabled=false
      to disable voice runtime and the
      text
      GuildVoiceStates
      gateway intent.
    • text
      channels.discord.intents.voiceStates
      can explicitly override voice-state intent subscription. Leave it unset for the intent to follow
      text
      voice.enabled
      .
    • text
      voice.daveEncryption
      and
      text
      voice.decryptionFailureTolerance
      pass through to
      text
      @discordjs/voice
      join options.
    • text
      @discordjs/voice
      defaults are
      text
      daveEncryption=true
      and
      text
      decryptionFailureTolerance=24
      if unset.
    • OpenClaw also watches receive decrypt failures and auto-recovers by leaving/rejoining the voice channel after repeated failures in a short window.
    • If receive logs repeatedly show
      text
      DecryptionFailed(UnencryptedWhenPassthroughDisabled)
      after updating, collect a dependency report and logs. The bundled
      text
      @discordjs/voice
      line includes the upstream padding fix from discord.js PR #11449, which closed discord.js issue #11419.

    Voice channel pipeline:

    • Discord PCM capture is converted to a WAV temp file.
    • text
      tools.media.audio
      handles STT, for example
      text
      openai/gpt-4o-mini-transcribe
      .
    • The transcript is sent through normal Discord ingress and routing.
    • text
      voice.model
      , when set, overrides only the response LLM for this voice-channel turn.
    • text
      voice.tts
      is merged over
      text
      messages.tts
      ; the resulting audio is played in the joined channel.

    Credentials are resolved per component: LLM route auth for

    text
    voice.model
    , STT auth for
    text
    tools.media.audio
    , and TTS auth for
    text
    messages.tts
    /
    text
    voice.tts
    .

    Voice messages

    Discord voice messages show a waveform preview and require OGG/Opus audio. OpenClaw generates the waveform automatically, but needs

    text
    ffmpeg
    and
    text
    ffprobe
    on the gateway host to inspect and convert.

    • Provide a local file path (URLs are rejected).
    • Omit text content (Discord rejects text + voice message in the same payload).
    • Any audio format is accepted; OpenClaw converts to OGG/Opus as needed.
    bash
    message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true)

    Troubleshooting

    Configuration reference

    Primary reference: Configuration reference - Discord.

    Safety and operations

    • Treat bot tokens as secrets (
      text
      DISCORD_BOT_TOKEN
      preferred in supervised environments).
    • Grant least-privilege Discord permissions.
    • If command deploy/state is stale, restart gateway and re-check with
      text
      openclaw channels status --probe
      .

    Related

    Pairing

    Pair a Discord user to the gateway.

    Groups

    Group chat and allowlist behavior.

    Channel routing

    Route inbound messages to agents.

    Security

    Threat model and hardening.

    Multi-agent routing

    Map guilds and channels to agents.

    Slash commands

    Native command behavior.

    © 2024 TaskFlow Mirror

    Powered by TaskFlow Sync Engine