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

# Slack Channel

> Socket mode and HTTP events integration for Slack

The Slack channel connects NullClaw to Slack using Socket Mode for real-time events and the Web API for sending messages.

## Features

* Socket Mode for real-time message delivery
* HTTP Events API fallback
* Direct messages and channel support
* Thread support
* Permission policies (DM and group)
* Allowlist-based access control
* Automatic reconnection
* Bot user context awareness

## Configuration

Add Slack to your `config.json`:

```json theme={null}
{
  "channels": {
    "slack": {
      "accounts": {
        "main": {
          "bot_token": "xoxb-YOUR-BOT-TOKEN",
          "app_token": "xapp-YOUR-APP-TOKEN",
          "allow_from": ["U123456789", "U987654321"],
          "channel_id": null,
          "mode": "socket",
          "dm_policy": "allowlist",
          "group_policy": "mention_only"
        }
      }
    }
  }
}
```

### Configuration Options

<ParamField path="bot_token" type="string" required>
  Slack bot token starting with `xoxb-`. Get this from your Slack App's "OAuth & Permissions" page.
</ParamField>

<ParamField path="app_token" type="string" default="null">
  Slack app-level token starting with `xapp-`. Required for Socket Mode. Get this from "Basic Information > App-Level Tokens".
</ParamField>

<ParamField path="allow_from" type="string[]" default="[]">
  List of allowed Slack user IDs (e.g., `U123456789`). Use `"*"` to allow everyone.

  **Finding user IDs**: Click a user's profile → More → Copy member ID
</ParamField>

<ParamField path="channel_id" type="string" default="null">
  Restrict bot to a specific channel ID (e.g., `C123456789`). If `null`, works in all channels.
</ParamField>

<ParamField path="mode" type="enum" default="socket">
  Message delivery mode:

  * `socket` — Real-time Socket Mode (recommended)
  * `http` — HTTP Events API with webhook
</ParamField>

<ParamField path="dm_policy" type="enum" default="allowlist">
  Direct message permission policy:

  * `allow` — Allow all DMs
  * `deny` — Deny all DMs
  * `allowlist` — Only allow DMs from users in `allow_from`
</ParamField>

<ParamField path="group_policy" type="enum" default="mention_only">
  Channel/group message policy:

  * `open` — Respond to all messages
  * `mention_only` — Only respond when mentioned with `@botname`
  * `allowlist` — Only respond to users in `allow_from`
</ParamField>

<ParamField path="signing_secret" type="string" default="null">
  Slack signing secret for verifying HTTP requests (required for HTTP mode). Found under "Basic Information > App Credentials".
</ParamField>

<ParamField path="webhook_path" type="string" default="/slack/events">
  Webhook endpoint path for HTTP mode
</ParamField>

<ParamField path="account_id" type="string" default="default">
  Account identifier for multi-account setups
</ParamField>

## Setup Guide

<Steps>
  <Step title="Create a Slack App">
    1. Go to [Slack API Apps](https://api.slack.com/apps)
    2. Click "Create New App"
    3. Choose "From scratch"
    4. Enter app name and select workspace
    5. Click "Create App"
  </Step>

  <Step title="Configure Bot Scopes">
    1. Navigate to "OAuth & Permissions"
    2. Scroll to "Scopes" > "Bot Token Scopes"
    3. Add the following scopes:
       * `chat:write` — Send messages
       * `channels:history` — Read channel messages
       * `groups:history` — Read private channel messages
       * `im:history` — Read DM messages
       * `app_mentions:read` — Detect mentions
    4. Click "Install to Workspace"
    5. Authorize the app
    6. Copy the "Bot User OAuth Token" (starts with `xoxb-`)
  </Step>

  <Step title="Enable Socket Mode">
    1. Navigate to "Socket Mode" in the left sidebar
    2. Toggle "Enable Socket Mode" to On
    3. Under "Basic Information" > "App-Level Tokens":
       * Click "Generate Token and Scopes"
       * Name: "NullClaw Socket Token"
       * Scope: `connections:write`
    4. Copy the app token (starts with `xapp-`)
  </Step>

  <Step title="Subscribe to Events">
    1. Navigate to "Event Subscriptions"
    2. Toggle "Enable Events" to On
    3. Under "Subscribe to bot events", add:
       * `message.channels` — Channel messages
       * `message.groups` — Private channel messages
       * `message.im` — Direct messages
       * `app_mention` — Bot mentions
    4. Click "Save Changes"
  </Step>

  <Step title="Get Your User ID">
    1. In Slack, click your profile picture
    2. Select "Profile"
    3. Click "More" (three dots)
    4. Select "Copy member ID"
  </Step>

  <Step title="Configure NullClaw">
    Add tokens and user ID to `~/.nullclaw/config.json`:

    ```json theme={null}
    {
      "channels": {
        "slack": {
          "accounts": {
            "main": {
              "bot_token": "xoxb-YOUR-BOT-TOKEN",
              "app_token": "xapp-YOUR-APP-TOKEN",
              "allow_from": ["YOUR_USER_ID"]
            }
          }
        }
      }
    }
    ```
  </Step>

  <Step title="Start NullClaw">
    Run `nullclaw` and send a DM to your bot or mention it in a channel. You should receive a response.
  </Step>
</Steps>

## Socket Mode vs HTTP Events

### Socket Mode (Recommended)

**Advantages:**

* No public endpoint required
* Works behind firewalls/NAT
* Easier setup (no webhook configuration)
* Real-time delivery

**Configuration:**

```json theme={null}
{
  "mode": "socket",
  "app_token": "xapp-..."
}
```

### HTTP Events Mode

**Advantages:**

* No persistent WebSocket connection
* Better for serverless deployments
* Request verification via signing secret

**Configuration:**

```json theme={null}
{
  "mode": "http",
  "signing_secret": "your_signing_secret",
  "webhook_path": "/slack/events"
}
```

**Additional setup for HTTP mode:**

1. Configure gateway in NullClaw config
2. Expose webhook endpoint (via ngrok, Cloudflare Tunnel, etc.)
3. Set Request URL in Slack "Event Subscriptions" to `https://your-domain.com/slack/events`

## Permission Policies

### Allowlist-Only (Secure Default)

```json theme={null}
{
  "dm_policy": "allowlist",
  "group_policy": "allowlist",
  "allow_from": ["U123456789", "U987654321"]
}
```

Only specified users can interact in both DMs and channels.

### Mention-Only in Channels

```json theme={null}
{
  "dm_policy": "allowlist",
  "group_policy": "mention_only",
  "allow_from": ["U123456789"]
}
```

Allowlist applies to DMs, but anyone can interact in channels by mentioning the bot.

### Open Access

```json theme={null}
{
  "dm_policy": "allow",
  "group_policy": "open",
  "allow_from": ["*"]
}
```

Anyone can interact anywhere (not recommended for production).

## Thread Support

NullClaw automatically detects and maintains thread context:

* Messages in threads are replied to in the same thread
* Thread metadata is preserved across message exchanges
* Use `channel_id:thread_ts` format for explicit thread targeting

## Multiple Workspaces

Run bots in multiple Slack workspaces:

```json theme={null}
{
  "channels": {
    "slack": {
      "accounts": {
        "workspace1": {
          "bot_token": "xoxb-TOKEN-1",
          "app_token": "xapp-TOKEN-1",
          "allow_from": ["U111111"]
        },
        "workspace2": {
          "bot_token": "xoxb-TOKEN-2",
          "app_token": "xapp-TOKEN-2",
          "group_policy": "mention_only"
        }
      }
    }
  }
}
```

## Troubleshooting

### Socket Connection Failed

1. Verify app token starts with `xapp-` and is valid
2. Check that `connections:write` scope is granted to the app token
3. Ensure Socket Mode is enabled in Slack App settings
4. Review logs: `nullclaw --log-level debug`

### Bot Not Responding

1. Verify user ID is in `allow_from`
2. Check dm\_policy and group\_policy settings
3. Ensure bot has correct event subscriptions
4. Verify bot token has required OAuth scopes
5. If in a channel, check group\_policy (may need to mention bot)

### HTTP Events Not Working

1. Verify signing secret is correct
2. Check that webhook URL is publicly accessible
3. Ensure Request URL in Slack matches your webhook endpoint
4. Verify SSL certificate is valid
5. Check gateway configuration in NullClaw

### Missing Message History

1. Add missing history scopes:
   * `channels:history`
   * `groups:history`
   * `im:history`
2. Reinstall app to workspace after adding scopes
3. Restart NullClaw

## Source Code

Implementation: `src/channels/slack.zig`
