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:26

    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.

    Slack

    Production-ready for DMs and channels via Slack app integrations. Default mode is Socket Mode; HTTP Request URLs are also supported.

    Pairing

    Slack DMs default to pairing mode.

    Slash commands

    Native command behavior and command catalog.

    Channel troubleshooting

    Cross-channel diagnostics and repair playbooks.

    Quick setup

    Create a new Slack app

    In Slack app settings press the **[Create New App](https://api.slack.com/apps/new)** button:
    text
    * choose **from a manifest** and select a workspace for your app * paste the [example manifest](#manifest-and-scope-checklist) from below and continue to create * generate an **App-Level Token** (`xapp-...`) with `connections:write` * install app and copy the **Bot Token** (`xoxb-...`) shown </Step> <Step title="Configure OpenClaw"> Recommended SecretRef setup: ```bash} export SLACK_APP_TOKEN=xapp-... export SLACK_BOT_TOKEN=xoxb-... cat > slack.socket.patch.json5 <<'JSON5' { channels: { slack: { enabled: true, mode: "socket", appToken: { source: "env", provider: "default", id: "SLACK_APP_TOKEN" }, botToken: { source: "env", provider: "default", id: "SLACK_BOT_TOKEN" }, }, }, } JSON5 openclaw config patch --file ./slack.socket.patch.json5 --dry-run openclaw config patch --file ./slack.socket.patch.json5 ``` Env fallback (default account only): ```bash} SLACK_APP_TOKEN=xapp-... SLACK_BOT_TOKEN=xoxb-... ``` </Step> <Step title="Start gateway"> ```bash} openclaw gateway ``` </Step> </Steps>

    Create a new Slack app

    In Slack app settings press the **[Create New App](https://api.slack.com/apps/new)** button:
    text
    * choose **from a manifest** and select a workspace for your app * paste the [example manifest](#manifest-and-scope-checklist) and update the URLs before create * save the **Signing Secret** for request verification * install app and copy the **Bot Token** (`xoxb-...`) shown </Step> <Step title="Configure OpenClaw"> Recommended SecretRef setup: ```bash} export SLACK_BOT_TOKEN=xoxb-... export SLACK_SIGNING_SECRET=... cat > slack.http.patch.json5 <<'JSON5' { channels: { slack: { enabled: true, mode: "http", botToken: { source: "env", provider: "default", id: "SLACK_BOT_TOKEN" }, signingSecret: { source: "env", provider: "default", id: "SLACK_SIGNING_SECRET" }, webhookPath: "/slack/events", }, }, } JSON5 openclaw config patch --file ./slack.http.patch.json5 --dry-run openclaw config patch --file ./slack.http.patch.json5 ``` <Note> Use unique webhook paths for multi-account HTTP Give each account a distinct `webhookPath` (default `/slack/events`) so registrations do not collide. </Note> </Step> <Step title="Start gateway"> ```bash} openclaw gateway ``` </Step> </Steps>

    Socket Mode transport tuning

    OpenClaw sets the Slack SDK client pong timeout to 15 seconds by default for Socket Mode. Override the transport settings only when you need workspace- or host-specific tuning:

    json5
    { channels: { slack: { mode: "socket", socketMode: { clientPingTimeout: 20000, serverPingTimeout: 30000, pingPongLoggingEnabled: false, }, }, }, }

    Use this only for Socket Mode workspaces that log Slack websocket pong/server-ping timeouts or run on hosts with known event-loop starvation.

    text
    clientPingTimeout
    is the pong wait after the SDK sends a client ping;
    text
    serverPingTimeout
    is the wait for Slack server pings. App messages and events remain application state, not transport liveness signals.

    Manifest and scope checklist

    The base Slack app manifest is the same for Socket Mode and HTTP Request URLs. Only the

    text
    settings
    block (and the slash command
    text
    url
    ) differs.

    Base manifest (Socket Mode default):

    json
    { "display_information": { "name": "OpenClaw", "description": "Slack connector for OpenClaw" }, "features": { "bot_user": { "display_name": "OpenClaw", "always_online": true }, "app_home": { "messages_tab_enabled": true, "messages_tab_read_only_enabled": false }, "slash_commands": [ { "command": "/openclaw", "description": "Send a message to OpenClaw", "should_escape": false } ] }, "oauth_config": { "scopes": { "bot": [ "app_mentions:read", "assistant:write", "channels:history", "channels:read", "chat:write", "commands", "emoji:read", "files:read", "files:write", "groups:history", "groups:read", "im:history", "im:read", "im:write", "mpim:history", "mpim:read", "mpim:write", "pins:read", "pins:write", "reactions:read", "reactions:write", "users:read" ] } }, "settings": { "socket_mode_enabled": true, "event_subscriptions": { "bot_events": [ "app_mention", "channel_rename", "member_joined_channel", "member_left_channel", "message.channels", "message.groups", "message.im", "message.mpim", "pin_added", "pin_removed", "reaction_added", "reaction_removed" ] } } }

    For HTTP Request URLs mode, replace

    text
    settings
    with the HTTP variant and add
    text
    url
    to each slash command. Public URL required:

    json
    { "features": { "slash_commands": [ { "command": "/openclaw", "description": "Send a message to OpenClaw", "should_escape": false, "url": "https://gateway-host.example.com/slack/events" } ] }, "settings": { "event_subscriptions": { "request_url": "https://gateway-host.example.com/slack/events", "bot_events": [ /* same as Socket Mode */ ] }, "interactivity": { "is_enabled": true, "request_url": "https://gateway-host.example.com/slack/events", "message_menu_options_url": "https://gateway-host.example.com/slack/events" } } }

    Additional manifest settings

    Surface different features that extend the above defaults.

    Token model

    • text
      botToken
      +
      text
      appToken
      are required for Socket Mode.
    • HTTP mode requires
      text
      botToken
      +
      text
      signingSecret
      .
    • text
      botToken
      ,
      text
      appToken
      ,
      text
      signingSecret
      , and
      text
      userToken
      accept plaintext strings or SecretRef objects.
    • Config tokens override env fallback.
    • text
      SLACK_BOT_TOKEN
      /
      text
      SLACK_APP_TOKEN
      env fallback applies only to the default account.
    • text
      userToken
      (
      text
      xoxp-...
      ) is config-only (no env fallback) and defaults to read-only behavior (
      text
      userTokenReadOnly: true
      ).

    Status snapshot behavior:

    • Slack account inspection tracks per-credential
      text
      *Source
      and
      text
      *Status
      fields (
      text
      botToken
      ,
      text
      appToken
      ,
      text
      signingSecret
      ,
      text
      userToken
      ).
    • Status is
      text
      available
      ,
      text
      configured_unavailable
      , or
      text
      missing
      .
    • text
      configured_unavailable
      means the account is configured through SecretRef or another non-inline secret source, but the current command/runtime path could not resolve the actual value.
    • In HTTP mode,
      text
      signingSecretStatus
      is included; in Socket Mode, the required pair is
      text
      botTokenStatus
      +
      text
      appTokenStatus
      .

    tip

    For actions/directory reads, user token can be preferred when configured. For writes, bot token remains preferred; user-token writes are only allowed when `userTokenReadOnly: false` and bot token is unavailable.

    Actions and gates

    Slack actions are controlled by

    text
    channels.slack.actions.*
    .

    Available action groups in current Slack tooling:

    GroupDefault
    messagesenabled
    reactionsenabled
    pinsenabled
    memberInfoenabled
    emojiListenabled

    Current Slack message actions include

    text
    send
    ,
    text
    upload-file
    ,
    text
    download-file
    ,
    text
    read
    ,
    text
    edit
    ,
    text
    delete
    ,
    text
    pin
    ,
    text
    unpin
    ,
    text
    list-pins
    ,
    text
    member-info
    , and
    text
    emoji-list
    .
    text
    download-file
    accepts Slack file IDs shown in inbound file placeholders and returns image previews for images or local file metadata for other file types.

    Access control and routing

    `channels.slack.dmPolicy` controls DM access. `channels.slack.allowFrom` is the canonical DM allowlist.
    text
    * `pairing` (default) * `allowlist` * `open` (requires `channels.slack.allowFrom` to include `"*"`) * `disabled` DM flags: * `dm.enabled` (default true) * `channels.slack.allowFrom` * `dm.allowFrom` (legacy) * `dm.groupEnabled` (group DMs default false) * `dm.groupChannels` (optional MPIM allowlist) Multi-account precedence: * `channels.slack.accounts.default.allowFrom` applies only to the `default` account. * Named accounts inherit `channels.slack.allowFrom` when their own `allowFrom` is unset. * Named accounts do not inherit `channels.slack.accounts.default.allowFrom`. Legacy `channels.slack.dm.policy` and `channels.slack.dm.allowFrom` still read for compatibility. `openclaw doctor --fix` migrates them to `dmPolicy` and `allowFrom` when it can do so without changing access. Pairing in DMs uses `openclaw pairing approve slack <code>`.
    `channels.slack.groupPolicy` controls channel handling:
    text
    * `open` * `allowlist` * `disabled` Channel allowlist lives under `channels.slack.channels` and **must use stable Slack channel IDs** (for example `C12345678`) as config keys. Runtime note: if `channels.slack` is completely missing (env-only setup), runtime falls back to `groupPolicy="allowlist"` and logs a warning (even if `channels.defaults.groupPolicy` is set). Name/ID resolution: * channel allowlist entries and DM allowlist entries are resolved at startup when token access allows * unresolved channel-name entries are kept as configured but ignored for routing by default * inbound authorization and channel routing are ID-first by default; direct username/slug matching requires `channels.slack.dangerouslyAllowNameMatching: true` <Warning> Name-based keys (`#channel-name` or `channel-name`) do **not** match under `groupPolicy: "allowlist"`. The channel lookup is ID-first by default, so a name-based key will never route successfully and all messages in that channel will be silently blocked. This differs from `groupPolicy: "open"`, where the channel key is not required for routing and a name-based key appears to work. Always use the Slack channel ID as the key. To find it: right-click the channel in Slack → **Copy link** — the ID (`C...`) appears at the end of the URL. Correct: ```json5} { channels: { slack: { groupPolicy: "allowlist", channels: { C12345678: { allow: true, requireMention: true }, }, }, }, } ``` Incorrect (silently blocked under `groupPolicy: "allowlist"`): ```json5} { channels: { slack: { groupPolicy: "allowlist", channels: { "#eng-my-channel": { allow: true, requireMention: true }, }, }, }, } ``` </Warning>
    Channel messages are mention-gated by default.
    text
    Mention sources: * explicit app mention (`<@botId>`) * mention regex patterns (`agents.list[].groupChat.mentionPatterns`, fallback `messages.groupChat.mentionPatterns`) * implicit reply-to-bot thread behavior (disabled when `thread.requireExplicitMention` is `true`) Per-channel controls (`channels.slack.channels.<id>`; names only via startup resolution or `dangerouslyAllowNameMatching`): * `requireMention` * `users` (allowlist) * `allowBots` * `skills` * `systemPrompt` * `tools`, `toolsBySender` * `toolsBySender` key format: `id:`, `e164:`, `username:`, `name:`, or `"*"` wildcard (legacy unprefixed keys still map to `id:` only) `allowBots` is conservative for channels and private channels: bot-authored room messages are accepted only when the sending bot is explicitly listed in that room's `users` allowlist, or when at least one explicit Slack owner ID from `channels.slack.allowFrom` is currently a room member. Wildcards and display-name owner entries do not satisfy owner presence. Owner presence uses Slack `conversations.members`; make sure the app has the matching read scope for the room type (`channels:read` for public channels, `groups:read` for private channels). If the member lookup fails, OpenClaw drops the bot-authored room message.

    Threading, sessions, and reply tags

    • DMs route as
      text
      direct
      ; channels as
      text
      channel
      ; MPIMs as
      text
      group
      .
    • With default
      text
      session.dmScope=main
      , Slack DMs collapse to agent main session.
    • Channel sessions:
      text
      agent:<agentId>:slack:channel:<channelId>
      .
    • Thread replies can create thread session suffixes (
      text
      :thread:<threadTs>
      ) when applicable.
    • text
      channels.slack.thread.historyScope
      default is
      text
      thread
      ;
      text
      thread.inheritParent
      default is
      text
      false
      .
    • text
      channels.slack.thread.initialHistoryLimit
      controls how many existing thread messages are fetched when a new thread session starts (default
      text
      20
      ; set
      text
      0
      to disable).
    • text
      channels.slack.thread.requireExplicitMention
      (default
      text
      false
      ): when
      text
      true
      , suppress implicit thread mentions so the bot only responds to explicit
      text
      @bot
      mentions inside threads, even when the bot already participated in the thread. Without this, replies in a bot-participated thread bypass
      text
      requireMention
      gating.

    Reply threading controls:

    • text
      channels.slack.replyToMode
      :
      text
      off|first|all|batched
      (default
      text
      off
      )
    • text
      channels.slack.replyToModeByChatType
      : per
      text
      direct|group|channel
    • legacy fallback for direct chats:
      text
      channels.slack.dm.replyToMode

    Manual reply tags are supported:

    • text
      [[reply_to_current]]
    • text
      [[reply_to:<id>]]

    note

    `replyToMode="off"` disables **all** reply threading in Slack, including explicit `[[reply_to_*]]` tags. This differs from Telegram, where explicit tags are still honored in `"off"` mode. Slack threads hide messages from the channel while Telegram replies stay visible inline.

    Ack reactions

    text
    ackReaction
    sends an acknowledgement emoji while OpenClaw is processing an inbound message.

    Resolution order:

    • text
      channels.slack.accounts.<accountId>.ackReaction
    • text
      channels.slack.ackReaction
    • text
      messages.ackReaction
    • agent identity emoji fallback (
      text
      agents.list[].identity.emoji
      , else "👀")

    Notes:

    • Slack expects shortcodes (for example
      text
      "eyes"
      ).
    • Use
      text
      ""
      to disable the reaction for the Slack account or globally.

    Text streaming

    text
    channels.slack.streaming
    controls live preview behavior:

    • text
      off
      : disable live preview streaming.
    • text
      partial
      (default): replace preview text with the latest partial output.
    • text
      block
      : append chunked preview updates.
    • text
      progress
      : show progress status text while generating, then send final text.
    • text
      streaming.preview.toolProgress
      : when draft preview is active, route tool/progress updates into the same edited preview message (default:
      text
      true
      ). Set
      text
      false
      to keep separate tool/progress messages.

    text
    channels.slack.streaming.nativeTransport
    controls Slack native text streaming when
    text
    channels.slack.streaming.mode
    is
    text
    partial
    (default:
    text
    true
    ).

    • A reply thread must be available for native text streaming and Slack assistant thread status to appear. Thread selection still follows
      text
      replyToMode
      .
    • Channel and group-chat roots can still use the normal draft preview when native streaming is unavailable.
    • Top-level Slack DMs stay off-thread by default, so they do not show the thread-style preview; use thread replies or
      text
      typingReaction
      if you want visible progress there.
    • Media and non-text payloads fall back to normal delivery.
    • Media/error finals cancel pending preview edits; eligible text/block finals flush only when they can edit the preview in place.
    • If streaming fails mid-reply, OpenClaw falls back to normal delivery for remaining payloads.

    Use draft preview instead of Slack native text streaming:

    json5
    { channels: { slack: { streaming: { mode: "partial", nativeTransport: false, }, }, }, }

    Legacy keys:

    • text
      channels.slack.streamMode
      (
      text
      replace | status_final | append
      ) is auto-migrated to
      text
      channels.slack.streaming.mode
      .
    • boolean
      text
      channels.slack.streaming
      is auto-migrated to
      text
      channels.slack.streaming.mode
      and
      text
      channels.slack.streaming.nativeTransport
      .
    • legacy
      text
      channels.slack.nativeStreaming
      is auto-migrated to
      text
      channels.slack.streaming.nativeTransport
      .

    Typing reaction fallback

    text
    typingReaction
    adds a temporary reaction to the inbound Slack message while OpenClaw is processing a reply, then removes it when the run finishes. This is most useful outside of thread replies, which use a default "is typing..." status indicator.

    Resolution order:

    • text
      channels.slack.accounts.<accountId>.typingReaction
    • text
      channels.slack.typingReaction

    Notes:

    • Slack expects shortcodes (for example
      text
      "hourglass_flowing_sand"
      ).
    • The reaction is best-effort and cleanup is attempted automatically after the reply or failure path completes.

    Media, chunking, and delivery

    Commands and slash behavior

    Slash commands appear in Slack as either a single configured command or multiple native commands. Configure

    text
    channels.slack.slashCommand
    to change command defaults:

    • text
      enabled: false
    • text
      name: "openclaw"
    • text
      sessionPrefix: "slack:slash"
    • text
      ephemeral: true
    txt
    /openclaw /help

    Native commands require additional manifest settings in your Slack app and are enabled with

    text
    channels.slack.commands.native: true
    or
    text
    commands.native: true
    in global configurations instead.

    • Native command auto-mode is off for Slack so
      text
      commands.native: "auto"
      does not enable Slack native commands.
    txt
    /help

    Native argument menus use an adaptive rendering strategy that shows a confirmation modal before dispatching a selected option value:

    • up to 5 options: button blocks
    • 6-100 options: static select menu
    • more than 100 options: external select with async option filtering when interactivity options handlers are available
    • exceeded Slack limits: encoded option values fall back to buttons
    txt
    /think

    Slash sessions use isolated keys like

    text
    agent:<agentId>:slack:slash:<userId>
    and still route command executions to the target conversation session using
    text
    CommandTargetSessionKey
    .

    Interactive replies

    Slack can render agent-authored interactive reply controls, but this feature is disabled by default.

    Enable it globally:

    json5
    { channels: { slack: { capabilities: { interactiveReplies: true, }, }, }, }

    Or enable it for one Slack account only:

    json5
    { channels: { slack: { accounts: { ops: { capabilities: { interactiveReplies: true, }, }, }, }, }, }

    When enabled, agents can emit Slack-only reply directives:

    • text
      [[slack_buttons: Approve:approve, Reject:reject]]
    • text
      [[slack_select: Choose a target | Canary:canary, Production:production]]

    These directives compile into Slack Block Kit and route clicks or selections back through the existing Slack interaction event path.

    Notes:

    • This is Slack-specific UI. Other channels do not translate Slack Block Kit directives into their own button systems.
    • The interactive callback values are OpenClaw-generated opaque tokens, not raw agent-authored values.
    • If generated interactive blocks would exceed Slack Block Kit limits, OpenClaw falls back to the original text reply instead of sending an invalid blocks payload.

    Exec approvals in Slack

    Slack can act as a native approval client with interactive buttons and interactions, instead of falling back to the Web UI or terminal.

    • Exec approvals use
      text
      channels.slack.execApprovals.*
      for native DM/channel routing.
    • Plugin approvals can still resolve through the same Slack-native button surface when the request already lands in Slack and the approval id kind is
      text
      plugin:
      .
    • Approver authorization is still enforced: only users identified as approvers can approve or deny requests through Slack.

    This uses the same shared approval button surface as other channels. When

    text
    interactivity
    is enabled in your Slack app settings, approval prompts render as Block Kit buttons directly in the conversation. When those buttons are present, they are the primary approval UX; OpenClaw should only include a manual
    text
    /approve
    command when the tool result says chat approvals are unavailable or manual approval is the only path.

    Config path:

    • text
      channels.slack.execApprovals.enabled
    • text
      channels.slack.execApprovals.approvers
      (optional; falls back to
      text
      commands.ownerAllowFrom
      when possible)
    • text
      channels.slack.execApprovals.target
      (
      text
      dm
      |
      text
      channel
      |
      text
      both
      , default:
      text
      dm
      )
    • text
      agentFilter
      ,
      text
      sessionFilter

    Slack auto-enables native exec approvals when

    text
    enabled
    is unset or
    text
    "auto"
    and at least one approver resolves. Set
    text
    enabled: false
    to disable Slack as a native approval client explicitly. Set
    text
    enabled: true
    to force native approvals on when approvers resolve.

    Default behavior with no explicit Slack exec approval config:

    json5
    { commands: { ownerAllowFrom: ["slack:U12345678"], }, }

    Explicit Slack-native config is only needed when you want to override approvers, add filters, or opt into origin-chat delivery:

    json5
    { channels: { slack: { execApprovals: { enabled: true, approvers: ["U12345678"], target: "both", }, }, }, }

    Shared

    text
    approvals.exec
    forwarding is separate. Use it only when exec approval prompts must also route to other chats or explicit out-of-band targets. Shared
    text
    approvals.plugin
    forwarding is also separate; Slack-native buttons can still resolve plugin approvals when those requests already land in Slack.

    Same-chat

    text
    /approve
    also works in Slack channels and DMs that already support commands. See Exec approvals for the full approval forwarding model.

    Events and operational behavior

    • Message edits/deletes are mapped into system events.
    • Thread broadcasts ("Also send to channel" thread replies) are processed as normal user messages.
    • Reaction add/remove events are mapped into system events.
    • Member join/leave, channel created/renamed, and pin add/remove events are mapped into system events.
    • text
      channel_id_changed
      can migrate channel config keys when
      text
      configWrites
      is enabled.
    • Channel topic/purpose metadata is treated as untrusted context and can be injected into routing context.
    • Thread starter and initial thread-history context seeding are filtered by configured sender allowlists when applicable.
    • Block actions and modal interactions emit structured
      text
      Slack interaction: ...
      system events with rich payload fields:
      • block actions: selected values, labels, picker values, and
        text
        workflow_*
        metadata
      • modal
        text
        view_submission
        and
        text
        view_closed
        events with routed channel metadata and form inputs

    Configuration reference

    Primary reference: Configuration reference - Slack.

    Troubleshooting

    Attachment vision reference

    Slack can attach downloaded media to the agent turn when Slack file downloads succeed and size limits permit. Image files can be passed through the media understanding path or directly to a vision-capable reply model; other files are retained as downloadable file context rather than treated as image input.

    Supported media types

    Media typeSourceCurrent behaviorNotes
    JPEG / PNG / GIF / WebP imagesSlack file URLDownloaded and attached to the turn for vision-capable handlingPer-file cap:
    text
    channels.slack.mediaMaxMb
    (default 20 MB)
    PDF filesSlack file URLDownloaded and exposed as file context for tools such as
    text
    download-file
    or
    text
    pdf
    Slack inbound does not convert PDFs into image-vision input automatically
    Other filesSlack file URLDownloaded when possible and exposed as file contextBinary files are not treated as image input
    Thread repliesThread starter filesRoot-message files can be hydrated as context when the reply has no direct mediaFile-only starters use an attachment placeholder
    Multi-image messagesMultiple Slack filesEach file is evaluated independentlySlack processing is capped at eight files per message

    Inbound pipeline

    When a Slack message with file attachments arrives:

    1. OpenClaw downloads the file from Slack's private URL using the bot token (
      text
      xoxb-...
      ).
    2. The file is written to the media store on success.
    3. Downloaded media paths and content types are added to the inbound context.
    4. Image-capable model/tool paths can use image attachments from that context.
    5. Non-image files remain available as file metadata or media references for tools that can handle them.

    Thread-root attachment inheritance

    When a message arrives in a thread (has a

    text
    thread_ts
    parent):

    • If the reply itself has no direct media and the included root message has files, Slack can hydrate the root files as thread-starter context.
    • Direct reply attachments take precedence over root-message attachments.
    • A root message that has only files and no text is represented with an attachment placeholder so the fallback can still include its files.

    Multi-attachment handling

    When a single Slack message contains multiple file attachments:

    • Each attachment is processed independently through the media pipeline.
    • Downloaded media references are aggregated into the message context.
    • Processing order follows Slack's file order in the event payload.
    • A failure in one attachment's download does not block others.

    Size, download, and model limits

    • Size cap: Default 20 MB per file. Configurable via
      text
      channels.slack.mediaMaxMb
      .
    • Download failures: Files that Slack cannot serve, expired URLs, inaccessible files, oversize files, and Slack auth/login HTML responses are skipped instead of being reported as unsupported formats.
    • Vision model: Image analysis uses the active reply model when it supports vision, or the image model configured at
      text
      agents.defaults.imageModel
      .

    Known limits

    ScenarioCurrent behaviorWorkaround
    Expired Slack file URLFile skipped; no error shownRe-upload the file in Slack
    Vision model not configuredImage attachments are stored as media references, but not analyzed as imagesConfigure
    text
    agents.defaults.imageModel
    or use a vision-capable reply model
    Very large images (> 20 MB by default)Skipped per size capIncrease
    text
    channels.slack.mediaMaxMb
    if Slack allows
    Forwarded/shared attachmentsText and Slack-hosted image/file media are best-effortRe-share directly in the OpenClaw thread
    PDF attachmentsStored as file/media context, not automatically routed through image visionUse
    text
    download-file
    for file metadata or the
    text
    pdf
    tool for PDF analysis

    Related documentation

    • Media understanding pipeline
    • PDF tool
    • Epic: #51349 — Slack attachment vision enablement
    • Regression tests: #51353
    • Live verification: #51354

    Related

    Pairing

    Pair a Slack user to the gateway.

    Groups

    Channel and group DM behavior.

    Channel routing

    Route inbound messages to agents.

    Security

    Threat model and hardening.

    Configuration

    Config layout and precedence.

    Slash commands

    Command catalog and behavior.

    © 2024 TaskFlow Mirror

    Powered by TaskFlow Sync Engine