---
sidebar_position: 6
---
# Slack

Slack integration lets users create and follow up on CoderFlow tasks directly from Slack — by mentioning the bot, sending it a direct message, running a slash command, or invoking a message shortcut. Task results are posted back to the Slack thread where the request originated.

## Overview

When Slack is configured:

- **@CoderFlow mentions** — Users mention the bot in any channel or thread to start a task. The bot replies in the same thread; follow-up mentions in the thread continue the same task.
- **Direct messages** — Users DM the bot to start a task in a 1-on-1 conversation. Each thread maps 1-to-1 to a CoderFlow task.
- **Slash command** — `/coderflow <instructions>` works anywhere in Slack, including private DMs the bot isn't part of. In conversations where the bot has access, it posts a visible "Working on it…" message; otherwise it falls back to a side conversation in the user's CoderFlow app DM.
- **"Ask CoderFlow" message shortcut** — Right-click any message and choose **Ask CoderFlow** to open a modal where the user picks an environment (and optionally includes thread context), then runs the task in a private side conversation.
- **Thread follow-ups** — A Slack thread maps to a single ongoing task. Subsequent mentions in the same thread issue follow-ups on that task rather than spawning new ones.
- **Screenshot attachments** — Image files attached to the triggering Slack message, image URLs in Slack message attachments, or included thread context are downloaded and attached to the CoderFlow task, so agents can inspect screenshots from `/task-output/attachments/`. Up to 25 files per request and 50 MB per file are accepted; non-image files and oversized files are skipped.
- **Account linking** — Users link their Slack identity to their CoderFlow account once, after which all Slack-created tasks are attributed to them and run under their permissions.

Slack configuration is global — it applies to all environments and all users on the server.

## Prerequisites

- A Slack workspace where you can install a custom app
- The CoderFlow Slack webhook endpoints reachable from Slack over HTTPS — Slack's Events API, Interactivity, and Slash Commands all post to public webhook URLs. If the main CoderFlow server is behind a firewall, expose only `/api/slack/events`, `/api/slack/commands`, and `/api/slack/interactions` through a reverse proxy/tunnel, or use the Slack-only ingress listener described below.
- Permission to create Slack apps in your workspace (workspace owner or admin, depending on workspace policy)
- For Slack file attachments, the CoderFlow app must be added to the source channel or conversation. Slack's `files:read` scope only grants file access in channels and conversations the app has been added to.

## Setup

Setup has two stages: create the Slack app from a generated manifest, then enter the Slack credentials in CoderFlow Settings.

### 1. Configure Settings in CoderFlow

1. Go to **Settings &rarr; Slack Integration**
2. Toggle **Enabled** on
3. (Optional) Set the **App Suffix** if you want a non-default slash command name. With suffix `team`, the slash command becomes `/coderflow-team` and the bot is named accordingly. Leave blank for `/coderflow`.
4. (Optional) Set the **Task Link Base URL** if it should differ from the server's current URL. This is the URL Slack messages use when linking back to a task and for account-link pages.
5. (Optional) Set the **Slack Webhook Base URL** if Slack should call a different public URL, such as a Slack-only ingress listener or reverse proxy.
6. (Optional) Add **Channel Mappings** — see [Channel Mappings](#channel-mappings) below.

### 2. Create the Slack App from the Manifest

1. In the **Slack Integration** settings panel, expand **Quick Setup: Create Slack App from Manifest**
2. Click **Copy** to copy the generated manifest JSON
3. Open [api.slack.com/apps](https://api.slack.com/apps) and click **Create New App**
4. Choose **From a manifest**, select your workspace, click **Next**
5. Choose the **JSON** tab, paste the manifest, click **Next**, review, and click **Create**
6. From the new app's **Basic Information** page, copy the **Signing Secret**
7. Go to **OAuth & Permissions**, click **Install to Workspace**, approve the requested scopes, and copy the **Bot User OAuth Token** (starts with `xoxb-`)

If you are updating an existing CoderFlow Slack app from an older manifest, reinstall the app or approve the added `files:read` scope so CoderFlow can download image attachments from Slack messages.

### 3. Enter Credentials in CoderFlow

Back in **Settings &rarr; Slack Integration**:

1. Paste the **Bot Token**
2. Paste the **Signing Secret**
3. Pick a **Default Environment** (used when no other environment can be resolved — see [Environment Selection](#environment-selection))
4. Click **Test Connection** to verify the bot token reaches Slack
5. Click **Save**

Changes take effect immediately — no server restart needed.

### Optional Slack-Only Ingress Listener

By default, Slack routes are served by the main CoderFlow server at `/api/slack/*`. Production deployments can instead start a second Slack-only HTTP listener and expose only that port publicly.

This is route and port isolation, not process isolation. The listener runs inside the same Node process as the main CoderFlow server, so it reduces the public HTTP route surface but is not a separate process, user, container, or privilege boundary.

Set one of the following before starting the server:

```bash
SLACK_INGRESS_MODE=listener
SLACK_INGRESS_PORT=3002
SLACK_INGRESS_HOST=0.0.0.0
```

`SLACK_INGRESS_PORT` by itself also enables listener mode. `SLACK_WEBHOOK_PORT` and `SLACK_WEBHOOK_HOST` are accepted aliases.

`SLACK_WEBHOOK_BASE_URL` does not start or configure this listener. It is only a deployment-supplied default shown in the Slack settings UI for manifest generation; save **Slack Webhook Base URL** in the UI if you want it persisted in Slack configuration.

The Slack-only listener serves:

- `GET /health`
- `POST /api/slack/events`
- `POST /api/slack/commands`
- `POST /api/slack/interactions`

It does not serve the CoderFlow web UI, authenticated APIs, or the Slack account-link browser page.

When using this listener:

1. Set **Slack Webhook Base URL** to the public HTTPS URL for the listener, for example `https://slack-hooks.example.com`.
2. Set **Task Link Base URL** to the normal CoderFlow application URL users open in a browser. This is required for Slack account-link URLs when Slack uses the separate ingress URL.
3. Check the read-only **Ingress Listener** field to confirm the server sees the expected environment-driven listener mode.
4. Copy the generated Slack manifest after setting both fields.

### Channel Mappings

Channel mappings let admins pre-assign an environment to a specific Slack channel, so tasks started in that channel always run in the chosen environment without prompting users.

In the **Channel Mappings** subsection of the Slack settings panel:

1. Click **+ Add Channel Mapping**
2. Enter the Slack **Channel ID** (e.g., `C0123456789`). To find a channel ID in Slack, open the channel, click its name in the header, and scroll to the bottom of the **About** tab.
3. Enter a **Channel Name** for your own reference (display only — not used for matching)
4. Select an **Environment** from the dropdown
5. Click **Save** at the bottom of the panel

Channel mappings are not required. They are useful when teams have a dedicated channel for a specific project or codebase.

## Account Linking

Before a user can create CoderFlow tasks from Slack, their Slack identity must be linked to their CoderFlow user. This ensures tasks run under the user's CoderFlow permissions and are attributed to them.

**To link an account:**

1. In Slack, run `/coderflow link` (or `/coderflow-<suffix> link` if an app suffix is configured)
2. The bot replies with a one-time link
3. Click the link — the browser opens a CoderFlow page that completes the linking. The user must be signed into CoderFlow in the same browser.
4. The page confirms: *"Slack account linked. Your Slack user is now linked to this CoderFlow account. Future Slack-created tasks will appear under your CoderFlow user."*

If an unlinked user tries to create a task from Slack, the bot replies with a prompt to run `/coderflow link` first. No task is created.

The link token expires after a short window. If the link is reported as invalid or expired, run `/coderflow link` again to get a fresh one.

## Usage

### Mention the Bot in a Channel

In a channel where the bot is a member, mention the bot with your request:

```
@CoderFlow add a unit test for the login flow
```

The bot replies in a thread. Subsequent mentions in that same thread continue the conversation as follow-ups on the same task.

To add the bot to a channel: `/invite @CoderFlow` from inside the channel, or use the channel's **Integrations** settings.

### DM the Bot

Open a direct message with the @CoderFlow app and send your request as a normal message. Each Slack thread in the DM maps to one CoderFlow task. To start a new task, start a new thread in the DM.

### Slash Command

`/coderflow <instructions>` works anywhere in Slack:

- In a channel where the bot has access, the slash command posts a visible **Working on it…** acknowledgement, and the task and its results stay in that conversation.
- In a private DM the bot isn't part of, the slash command starts a side conversation in the user's CoderFlow app DM. An ephemeral message in the source DM explains where the work moved.

### "Ask CoderFlow" Message Shortcut

Right-click any message in Slack and choose **More message shortcuts &rarr; Ask CoderFlow**. A modal opens where the user:

1. Picks an environment
2. Optionally includes the original message thread as context

Clicking **Submit** creates a task in a private conversation with the user.

Image files attached to the selected message are included even when thread context is disabled. This includes Slack file uploads and safe HTTPS image URLs from Slack message attachments. When thread context is enabled, image files from the fetched thread context are included too.

## Environment Selection

When a task is created from Slack, the environment is resolved in this priority order:

1. **Inline `env:<name>` syntax** in the message — e.g., `@CoderFlow env:frontend fix the layout bug`
2. **Channel mapping** — if the source channel has an admin-configured mapping
3. **Single-environment auto-select** — if the user only has access to one environment, it is selected automatically
4. **Default environment** — the default configured in **Settings &rarr; Slack Integration**
5. **Interactive picker** — if none of the above resolve, the bot posts a dropdown for the user to choose from

Users can only select environments they have permission to create tasks in. Unauthorized environments are filtered from the picker.

## Security

- **Signature verification** — Every inbound request from Slack is verified with HMAC SHA-256 against the signing secret. Requests with invalid signatures are rejected.
- **Replay protection** — Requests with timestamps older than 5 minutes are rejected.
- **Event deduplication** — Slack's retry events are deduplicated to prevent duplicate task creation.
- **Optional ingress isolation** — A Slack-only listener can expose only the Slack webhook endpoints on a separate port, keeping the main CoderFlow application port private.
- **File access scope** — The generated manifest requests `files:read` so CoderFlow can download image file uploads from Slack messages that users explicitly send to or select for CoderFlow. Non-image files are ignored by the Slack integration. Image URLs from Slack message attachments are fetched without the bot token and are blocked if they are not HTTPS or resolve to private network addresses.
- **Token storage** — `slack.json` is written with `0o600` permissions (owner read/write only).
- **Secret masking** — The settings API never returns the bot token or signing secret in plain text. The UI shows whether each is set, not the value.
- **Account-linked permissions** — Tasks run under the linked CoderFlow user's permissions. Unlinked users cannot create tasks.

## Configuration File

The Slack configuration is stored in `slack.json` inside the server's data directory (`SERVER_DATA_PATH`, defaulting to `~/.coder/data`). The settings UI is the primary way to manage this — direct edits are possible but unusual.

Most Slack settings live in the JSON file or the UI. Deployment-level ingress settings are environment variables because they affect which network listeners start:

- `SLACK_INGRESS_MODE=listener` — start the optional Slack-only listener
- `SLACK_INGRESS_PORT` or `SLACK_WEBHOOK_PORT` — listener port
- `SLACK_INGRESS_HOST` or `SLACK_WEBHOOK_HOST` — listener bind host
- `SLACK_WEBHOOK_BASE_URL` — optional default shown in the settings UI for manifest generation. It is not a runtime listener setting and does not replace the saved Slack configuration used by SlackService.

## Troubleshooting

### Test Connection fails

- Verify the **Bot Token** starts with `xoxb-` and was copied from the **OAuth & Permissions** page after installing the app to the workspace
- Verify the **Signing Secret** was copied from **Basic Information**, not the App-Level Token or Verification Token
- Check that the workspace where the app was installed is the workspace where users will be using it

### Slack mentions don't trigger anything

- Confirm the bot has been invited to the channel (`/invite @CoderFlow`)
- Confirm the Slack app's **Event Subscriptions** are enabled and pointed at `https://<your-server>/api/slack/events` (the manifest sets this; if you edited it, re-verify)
- Check that the server URL is reachable from Slack over HTTPS — Slack will not deliver events to an unreachable or unverified URL
- Check the server logs for signature verification errors (often indicates the signing secret in CoderFlow doesn't match the Slack app)

### "Sending messages to this app has been turned off" in DMs

The Slack app's **App Home &rarr; Messages Tab** must be enabled and writable. The generated manifest sets this correctly; if you edited the manifest manually, re-enable it on the **App Home** settings page in Slack.

### Screenshot attachments are not available to tasks

- Confirm the Slack app has been reinstalled or reauthorized after adding the `files:read` scope.
- Confirm the CoderFlow app is a member of the channel or conversation where the file was shared. Message shortcuts can expose message text and preview metadata even when the app is not in the channel, but Slack will not let the bot token download files from conversations it cannot access.
- Confirm the attachment is either an image upload in Slack or an HTTPS image URL in a Slack message attachment. Non-image files are ignored, and image URLs are skipped if they resolve to private network addresses.
- Confirm the file is under 50 MB and that the request has at most 25 attached files. Files exceeding either limit are skipped.
- Check server logs for Slack file download warnings, such as missing scope, failed download, or files over the upload size limit.

### Slash command says "dispatch_failed" or times out

- The CoderFlow server must respond to `/api/slack/commands` within 3 seconds. If the server is overloaded or the URL is wrong, Slack reports a dispatch failure.
- Confirm `https://<your-server>/api/slack/commands` is reachable from the public internet

### "Link your Slack user to your CoderFlow account…"

The user has not linked their Slack identity yet. Run `/coderflow link` in Slack and follow the link, signed into CoderFlow in the same browser.

### A user can't see an environment they expect in the picker

The picker only shows environments the user has `tasks:create` permission on. Check **Administration &rarr; People & Access** to confirm their role grants access to that environment.

### Tasks aren't attributed to the right user

- Confirm the user has run `/coderflow link` and completed the link flow successfully
- If they linked under a different CoderFlow account by mistake, they can run `/coderflow link` again to overwrite the link with the currently signed-in CoderFlow user
