Step-by-step guide to create and configure a Slack bot for openab.
- Go to https://api.slack.com/apps
- Click Create New App → From scratch
- Enter an app name (e.g. "OpenAB") and select your workspace
- Click Create App
Socket Mode uses a persistent WebSocket connection — no public URL or ingress needed.
- In the left sidebar, click Socket Mode
- Toggle Enable Socket Mode to ON
- You'll be prompted to generate an App-Level Token:
- Token name:
openab-socket(or any name) - Scope:
connections:write - Click Generate
- Token name:
- Copy the token (
xapp-...) — this is yourSLACK_APP_TOKEN
- In the left sidebar, click Event Subscriptions
- Toggle Enable Events to ON
- Under Subscribe to bot events, add:
app_mention— triggers when someone @mentions the botmessage.channels— receives messages in public channels (for thread follow-ups)message.groups— receives messages in private channels (for thread follow-ups)
- Click Save Changes
- In the left sidebar, click OAuth & Permissions
- Under Bot Token Scopes, add:
| Scope | Purpose |
|---|---|
app_mentions:read |
Receive @mention events |
chat:write |
Send and edit messages |
channels:history |
Read public channel messages (for thread context) |
groups:history |
Read private channel messages (for thread context) |
channels:read |
List public channels |
groups:read |
List private channels |
reactions:write |
Add/remove emoji reactions |
files:read |
Download file attachments (images, audio) |
users:read |
Resolve user display names |
- In the left sidebar, click Install App
- Click Install to Workspace (or Reinstall if you've changed scopes)
- Authorize the requested permissions
- Copy the Bot User OAuth Token (
xoxb-...) — this is yourSLACK_BOT_TOKEN
📖 Full config options with defaults: docs/config-reference.md
Add the [slack] section to your config.toml:
[slack]
bot_token = "${SLACK_BOT_TOKEN}"
app_token = "${SLACK_APP_TOKEN}"
allowed_channels = [] # empty = allow all channels
# allowed_users = ["U0123456789"] # empty = allow all usersSet the environment variables:
export SLACK_BOT_TOKEN="xoxb-..."
export SLACK_APP_TOKEN="xapp-..."In each Slack channel where you want to use the bot:
/invite @OpenAB
In a channel where the bot is invited:
@OpenAB explain this code
The bot will reply in a thread. After that, just type in the thread — no @mention needed for follow-ups.
openab supports /models, /agents, and /cancel on Discord, but not on Slack. If you previously configured these commands in your Slack app's Slash Commands page, you can safely delete them — the Slack adapter ignores both slash_commands and interactive envelope types.
The root cause is a combination of three Slack-specific platform constraints, none of which is fixable from openab's side:
-
Slack blocks third-party slash commands inside threads. Invoking
/modelsfrom a thread's reply composer returns the Slack error"/models is not supported in threads. Sorry!". This is enforced by the Slack client itself, not by any app setting — enabling Interactivity, Socket Mode, or reinstalling the app does not bypass it. Slack's built-in commands (/remind,/shrug, etc.) get special treatment that custom apps cannot. -
Channel-level slash command payloads have no thread context. If the user types
/modelsin the channel's main composer instead of a thread, Slack delivers the command but the payload carries nothread_ts. Since openab keys each ACP session by thread (slack:<thread_ts>orslack:<trigger_ts>), the command cannot be routed to the right session. Sessions are never keyed bychannel_idalone, so there's no workaround on the adapter side. -
Most ACP agents don't expose a model-switch surface. Even when routing succeeded,
/modelsreads the session'sconfigOptionsfrom the ACPinitializeresponse. Onlykiro-cliemits these in the expected format (via itsmodels/modesfallback).claude-code,codex,gemini,cursor-agent, andopencodedo not, so the menu would be empty for those backends — the user would see"⚠️ No model options available"with no recourse.
On Discord, none of these apply: slash commands work in thread-channels, the channel ID is the thread key, and users typically stay within a single agent per deployment anyway.
- Change the agent: edit
[agent]inconfig.toml(or the Helm chart values) and restart the pod / process - Change the Claude model (for
claude-code): setANTHROPIC_DEFAULT_MODEL(or equivalent env var depending on your claude-code-acp version) and restart — model selection happens at process start, not at runtime - Cancel an in-flight turn: there is no built-in way on Slack currently.
- Channel ID: Right-click the channel name → View channel details → ID at the bottom (starts with
Cfor public,Gfor private) - User ID: Click a user's profile → ... menu → Copy member ID (starts with
U)
- Verify Socket Mode is enabled in your app settings
- Check that
app_mentionis subscribed under bot events (not user events) - Ensure the app is reinstalled after adding new event subscriptions
- Check the bot is invited to the channel (
/invite @YourSlackAppName) - Run with
RUST_LOG=openab=debug cargo runto see incoming events
- Verify
message.channels(andmessage.groupsfor private channels) are subscribed under bot events - Reinstall the app after adding these events
- Verify your
SLACK_BOT_TOKENstarts withxoxb- - Verify your
SLACK_APP_TOKENstarts withxapp- - Check the tokens haven't been revoked in your app settings
- Verify
reactions:writescope is added - Reinstall the app after adding the scope