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

# Slack Channel

> Setup and usage guide for the Slack Events API channel

The Slack channel enables IronClaw to respond to app mentions and direct messages in your Slack workspace.

## Features

* **App mentions** - `@YourBot` in any channel
* **Direct messages** - DM the bot directly
* **Thread support** - Conversations tracked via Slack's native threading
* **Signature validation** - HMAC-based request verification
* **DM pairing** - Approve unknown users with pairing codes

## Prerequisites

* Slack workspace admin access
* Public HTTPS URL for webhooks (ngrok, Cloudflare Tunnel, etc.)
* IronClaw installed and configured

## Setup

### 1. Create a Slack App

1. Go to [api.slack.com/apps](https://api.slack.com/apps)
2. Click **Create New App** → **From scratch**
3. Name your app (e.g., "IronClaw Agent") and select your workspace

### 2. Configure Bot Token Scopes

Under **OAuth & Permissions**, add these Bot Token Scopes:

* `app_mentions:read` - Detect @mentions
* `chat:write` - Send messages
* `im:history` - Read DM history
* `im:read` - Access DM channels
* `im:write` - Send DMs

### 3. Install App to Workspace

1. Click **Install to Workspace**
2. Copy the **Bot User OAuth Token** (starts with `xoxb-`)

### 4. Enable Event Subscriptions

1. Go to **Event Subscriptions** → Enable Events
2. Set **Request URL** to `https://your-tunnel-url/webhook/slack`
3. Under **Subscribe to bot events**, add:
   * `app_mention` - Bot is mentioned
   * `message.im` - DM received
4. Save Changes

### 5. Get Signing Secret

1. Go to **Basic Information** → **App Credentials**
2. Copy the **Signing Secret**

### 6. Configure IronClaw

Set environment variables:

```bash theme={null}
export SLACK_BOT_TOKEN=xoxb-your-token
export SLACK_SIGNING_SECRET=your-signing-secret
```

Or use the setup wizard:

```bash theme={null}
ironclaw onboard
```

### 7. Start IronClaw with Tunnel

```bash theme={null}
# Start tunnel
ngrok http 8080

# Set tunnel URL
export TUNNEL_URL=https://abc123.ngrok-free.app

# Run IronClaw
ironclaw run
```

## Configuration

Edit `~/.ironclaw/channels/slack.capabilities.json`:

```json theme={null}
{
  "config": {
    "signing_secret_name": "slack_signing_secret",
    "owner_id": null,
    "dm_policy": "pairing",
    "allow_from": []
  }
}
```

### Configuration Options

| Option | Type | Default | Description |
| - | - | - | - |
| `signing_secret_name` | `string` | `"slack_signing_secret"` | Name of secret containing signing secret |
| `owner_id` | `string` | `null` | Slack user ID; when set, only this user can message |
| `dm_policy` | `string` | `"pairing"` | `open`, `allowlist`, or `pairing` |
| `allow_from` | `array` | `[]` | Pre-approved user IDs. `["*"]` allows everyone |

## DM Pairing

When an unknown user DMs your bot with `dm_policy: "pairing"`:

### Flow

1. Unknown user sends a DM
2. Bot replies: `To pair with this bot, run: ironclaw pairing approve slack ABC12345`
3. You run: `ironclaw pairing approve slack ABC12345`
4. User is added to the allow list; future messages are delivered

### Commands

```bash theme={null}
# List pending pairing requests
ironclaw pairing list slack

# Approve a user by code
ironclaw pairing approve slack ABC12345
```

## Usage

### App Mentions (Channel)

Mention the bot in any channel where it's a member:

```
You: @IronClaw what's the current sprint status?
Bot: Let me check the project board...
     [reads workspace data]
     Current sprint: 5 tasks in progress, 3 blocked.
```

### Direct Messages

DM the bot directly:

```
You: Help me debug this error
Bot: Sure! Can you share the error message?

You: TypeError: Cannot read property 'map' of undefined
Bot: This error means you're calling .map() on a variable that is undefined.
     Let me check your code...
```

### Threaded Conversations

Replies automatically thread under the original message:

```
You: @IronClaw summarize this channel's history
Bot: [in thread] Here's a summary of the last 50 messages...

You: [in thread] What were the main action items?
Bot: [in thread] Main action items:
     1. Fix deployment pipeline
     2. Update documentation
     3. Schedule team sync
```

## Secrets

The channel requires two secrets:

### Bot Token

Slack Bot OAuth Token (starts with `xoxb-`):

```bash theme={null}
export SLACK_BOT_TOKEN=xoxb-123-456-abc
```

Or configure via secrets store:

```bash theme={null}
ironclaw secrets set slack_bot_token
```

### Signing Secret

Slack Signing Secret for HMAC validation:

```bash theme={null}
export SLACK_SIGNING_SECRET=your-signing-secret
```

The host validates the `X-Slack-Signature` header before forwarding events to the WASM channel.

## Events

### URL Verification

When you first set the Request URL in Slack's Event Subscriptions, Slack sends a challenge:

```json theme={null}
{
  "type": "url_verification",
  "challenge": "3eZbrw1aBm2rZgRNFdxV2595E9CY3gmdALWMmHkvFXO7tYXAYM8P"
}
```

The channel automatically responds with the challenge to complete verification.

### Event Callback

After verification, Slack sends event payloads:

```json theme={null}
{
  "type": "event_callback",
  "event": {
    "type": "app_mention",
    "user": "U123ABC",
    "text": "<@U987XYZ> hello",
    "channel": "C456DEF",
    "ts": "1234567890.123456"
  }
}
```

The channel extracts the text, strips the `<@U987XYZ>` mention, and forwards `"hello"` to the agent.

## Message Metadata

Each message includes metadata for response routing:

```json theme={null}
{
  "channel": "C456DEF",
  "thread_ts": "1234567890.123456",
  "message_ts": "1234567890.123456",
  "team_id": "T789GHI"
}
```

Responses use this metadata to post in the correct channel/thread.

## Permissions

### Owner Restriction

Limit the bot to a single user:

```json theme={null}
{
  "config": {
    "owner_id": "U123ABC"
  }
}
```

All messages from other users are silently dropped.

### DM Policy

**`open`** - Allow all DMs:

```json theme={null}
{"dm_policy": "open"}
```

**`allowlist`** - Only pre-approved users:

```json theme={null}
{
  "dm_policy": "allowlist",
  "allow_from": ["U123ABC", "U456DEF"]
}
```

**`pairing`** - Allowlist + interactive pairing:

```json theme={null}
{
  "dm_policy": "pairing",
  "allow_from": ["U123ABC"]
}
```

## Rate Limiting

Slack's API has a rate limit of \~1 request/second per method. The channel enforces 50 requests/minute for safety.

If you exceed this, responses will be queued and sent when the rate limit resets.

## Manual Installation

If the channel isn't installed via the wizard:

```bash theme={null}
# Build the Slack channel (requires wasm32-wasip2 target)
rustup target add wasm32-wasip2
cd ~/workspace/source/channels-src/slack
./build.sh

# Install
mkdir -p ~/.ironclaw/channels
cp slack.wasm slack.capabilities.json ~/.ironclaw/channels/
```

## Troubleshooting

### Events not received

1. **Check Request URL** - Verify the URL in Slack's Event Subscriptions matches your tunnel
2. **Tunnel running** - Ensure ngrok/Cloudflare tunnel is active
3. **Logs** - Check `ironclaw run` logs for "Slack event" messages
4. **Signature validation** - Ensure `SLACK_SIGNING_SECRET` is correct

### Bot not responding

1. **Bot is a member** - Add the bot to the channel (`/invite @YourBot`)
2. **Permissions** - Verify bot has `chat:write` scope
3. **Token valid** - Check `SLACK_BOT_TOKEN` starts with `xoxb-`
4. **Logs** - Look for "Slack API error" in logs

### Pairing not working

1. **DM policy** - Ensure `dm_policy` is `"pairing"`
2. **Signing secret** - Verify signature validation passes
3. **Logs** - Check for "Pairing request" or "Pairing upsert failed"

### Signature validation fails

* Ensure `SLACK_SIGNING_SECRET` matches the value in Slack App Credentials
* Check system clock is accurate (HMAC uses timestamp)
* Verify webhook requests are coming from Slack (not a proxy/firewall rewriting headers)

## Source Code

* **Implementation:** `~/workspace/source/channels-src/slack/src/lib.rs`
* **Capabilities:** `~/workspace/source/channels-src/slack/slack.capabilities.json`

## Example App Manifest

For faster setup, use this app manifest:

```yaml theme={null}
display_information:
  name: IronClaw Agent
features:
  bot_user:
    display_name: IronClaw
    always_online: true
oauth_config:
  scopes:
    bot:
      - app_mentions:read
      - chat:write
      - im:history
      - im:read
      - im:write
settings:
  event_subscriptions:
    request_url: https://your-tunnel-url/webhook/slack
    bot_events:
      - app_mention
      - message.im
  org_deploy_enabled: false
  socket_mode_enabled: false
```

1. Go to [api.slack.com/apps](https://api.slack.com/apps)
2. Click **Create New App** → **From an app manifest**
3. Paste the manifest above
4. Update `request_url` with your tunnel URL
5. Install to workspace
