> ## Documentation Index
> Fetch the complete documentation index at: https://docs.moldable.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Slack

> Configure the Slack channel adapter.

This enables you to use Slack to securely connect with your local computer via the gateway.

The Slack adapter supports both Socket Mode and Events API HTTP mode for inbound events, and Slack Web API for outbound messages. It supports DMs, channels, mention gating, and thread-aware replies.

## Requirements

* A Slack bot token (`xoxb-...`).
* For Socket Mode: a Slack app-level token (`xapp-...`).
* For HTTP mode: a Slack signing secret.
* Slack app event subscriptions for `message` and `app_mention`.
* Bot invited to channels where you want group replies.

## Socket mode configuration (default)

```json theme={null}
{
  "channels": {
    "slack": {
      "enabled": true,
      "mode": "socket",
      "bot_token_ref": "vault:secret:<slack-bot-token-ref>",
      "app_token_ref": "vault:secret:<slack-app-token-ref>",
      "allow_from": [],
      "groups": [],
      "require_mention": true,
      "reply_to_mode": "off",
      "allow_bots": false,
      "media_max_mb": 20
    }
  }
}
```

## HTTP events mode configuration

```json theme={null}
{
  "channels": {
    "slack": {
      "enabled": true,
      "mode": "http",
      "bot_token_ref": "vault:secret:<slack-bot-token-ref>",
      "signing_secret_ref": "vault:secret:<slack-signing-secret-ref>",
      "webhook_path": "/slack/events"
    }
  }
}
```

When `mode` is `http`, Slack should send Events API callbacks to the gateway HTTP server at `channels.slack.webhook_path` (default `/slack/events`).

## Multi-account configuration

Slack supports additional account-specific adapters via `channels.slack.accounts`:

```json theme={null}
{
  "channels": {
    "slack": {
      "enabled": true,
      "mode": "socket",
      "bot_token_ref": "vault:secret:<default-slack-bot-token>",
      "app_token_ref": "vault:secret:<default-slack-app-token>",
      "accounts": {
        "ops": {
          "enabled": true,
          "mode": "socket",
          "bot_token_ref": "vault:secret:<ops-slack-bot-token>",
          "app_token_ref": "vault:secret:<ops-slack-app-token>"
        }
      }
    }
  }
}
```

Account adapters are exposed internally as channel IDs like `slack/<account-id>`.
For account HTTP mode, give each account a unique webhook path so ingress can route signatures/events to the correct account config.

## Optional user token (read-biased)

Slack can also use an optional user token for read-path operations:

```json theme={null}
{
  "channels": {
    "slack": {
      "user_token_ref": "vault:secret:<slack-user-token-ref>",
      "user_token_read_only": true
    }
  }
}
```

* Read-path calls (history + attachment fetches) prefer `user_token_ref` when present.
* Writes continue to use bot token by default.
* If `user_token_read_only` is `false`, writes may fall back to user token when bot token is unavailable.

`reply_to_mode` supports:

* `off`: only keep replying in-thread when the inbound message is already in a thread.
* `first`: first chunk replies in-thread, later chunks in channel root.
* `all`: all chunks reply in-thread.

You can override threading per chat type:

```json theme={null}
{
  "channels": {
    "slack": {
      "reply_to_mode": "off",
      "reply_to_mode_by_chat_type": {
        "direct": "all",
        "group": "first",
        "channel": "off"
      }
    }
  }
}
```

Thread session behavior for inbound Slack threads is configurable:

* `thread_history_scope`: `thread` (default) or `channel`
* `thread_inherit_parent`: `true|false` (default `false`)

When `thread_history_scope` is `thread`, Slack thread replies use a thread-scoped session key.
When `thread_inherit_parent` is `true`, thread-scoped sessions keep a parent session link to the channel session.

## Reaction notifications

Slack reaction events can be forwarded into the gateway via:

* `reaction_notifications`: `off | own | all | allowlist` (default: `own`)
* `reaction_allowlist`: user IDs used when mode is `allowlist`

Slack also forwards selected non-message events as notification text in-channel:

* `pin_added` / `pin_removed`
* `member_joined_channel` / `member_left_channel`
* `channel_rename`

## Chunking and limits

Slack chunking uses the shared markdown renderer:

* Use `gateway.markdown.channels.slack.chunk_limit` for Slack text chunk size.
* Slack chunk split behavior is newline-first with whitespace fallback via the shared renderer.
* There is no separate Slack-only `chunk_mode` knob today.

`allow_bots` is `false` by default. Enable only if you intentionally want bot-authored Slack messages to trigger gateway handling.
You can also override this per group/channel via `channels.slack.group_rules.<channel_id>.allow_bots`.

## Group mention gating

If `require_mention` is enabled, group/channel messages are processed only when the bot is explicitly mentioned (`<@BOT_ID>`).

## Group DM controls

Slack MPIM/group-DM ingestion can be controlled with:

* `dm_group_enabled` (default `true`)
* `dm_group_channels` (optional allowlist of MPIM channel IDs when enabled)

## Slash commands (HTTP mode)

When Slack sends signed slash-command form payloads to the configured webhook path, the gateway enqueues them as inbound Slack messages:

* Message text format: `<command> <text>` (for example `/ask status`)
* Message context: `peer_id=user_id`, `chat_id=channel_id`, `display_name=user_name`

## Pairing and allowlists

Slack uses the shared pairing and allowlist rules. See [Security and pairing](/core/security-and-pairing).
For Slack, allowlists can match user ID (`U...`) and sender display-name forms like `alice` or `@alice`.
Per-channel sender allowlists use `channels.slack.group_rules.<channel_id>.allow_from`.
On startup, Slack normalizes allowlist-style identifiers to canonical IDs where possible:

* user entries: `@name` / `email` / `slack:<id>` -> `U...` / `W...`
* channel entries: `#channel` / `channel:<id>` / `slack:<id>` -> `C...` / `G...`

## Channel metadata context

For inbound group/channel messages, Slack channel topic/purpose metadata is fetched and appended as untrusted context text when available.

## Slack action controls

Slack supports action execution through `send_chat_action` when enabled:

* `actions_enabled` (default `false`)
* `action_allow` (allowlist of action keys, for example `reaction_add`, `reaction_remove`, `pin_add`, `pin_remove`, `message_delete`, `member_info`, `emoji_list`, `search_messages`, `channel_info`; `*` allows all)

Supported action payload formats:

* `reaction:add:<emoji>:<message_ts>`
* `reaction:remove:<emoji>:<message_ts>`
* `pin:add:<message_ts>`
* `pin:remove:<message_ts>`
* `message:delete:<message_ts>` (or `delete:<message_ts>`)
* `member:info:<user_id|@mention>`
* `emoji:list`
* `channel:info` (current channel) or `channel:info:<channel_id>`
* `search:messages:<query>`

## Security tips

* Keep `pairing.dm_policy=pairing` unless you have a tightly controlled setup.
* Prefer `allow_from` and `group_allow_from` for high-trust deployments.
* Keep Slack tokens in Vault-backed `*_ref` fields, not plaintext config.
