Slack
The Slack adapter slakd connects one bot to one workspace through the HTTP Events API of Slack. Slack posts events to https://<your-host>/slack/events. proxyd forwards each event to slakd unchanged, so the X-Slack-Signature HMAC stays valid.
An event passes proxyd, slakd and routd before the agent runs
- Slack posts an event to
https://<your-host>/slack/events. proxydforwards the raw body and the Slack signature headers unchanged toslakd:8080.slakdchecks the HMAC, converts the event to an inbound message and posts it toroutd.routdroutes the message to a group and starts the turn.runedstarts the guest of the agent.- The agent calls
replyorsend, andslakdposts the text through the Web API of Slack.
Each Slack chat has a JID with the workspace, the kind and the ID
Route rules match against these JIDs:
| chat type | JID format | example |
|---|---|---|
| channel | slack:<workspace>/channel/<channel_id> | slack:T012ABCD/channel/C0HJKL456 |
| DM | slack:<workspace>/dm/<dm_id> | slack:T012ABCD/dm/D0XY9876 |
| multi-person DM | slack:<workspace>/group/<mpim_id> | slack:T012ABCD/group/G0AB1234 |
The workspace and channel IDs are the IDs from Slack, so you can copy them from a Slack URL. A thread uses the Slack thread_ts as the message topic, and all replies in the thread have that topic.
Step 1: make a Slack app
- Open api.slack.com/apps, then Create New App, then From scratch.
- Give the app a name and select the workspace.
Step 2: add the bot token scopes
Under OAuth & Permissions, add these Bot Token Scopes:
channels:history channels:read
groups:history groups:read
im:history im:read
mpim:history mpim:read
chat:write chat:write.public
reactions:read reactions:write
files:read files:write
users:read
Step 3: subscribe to the events
- Enable events.
- Set the Request URL to
https://<your-host>/slack/events. Slack sends aurl_verificationchallenge once, andslakdsends it back. The Request URL becomes green whenproxydandslakdboth run. - Subscribe to these bot events:
message.channels,message.groups,message.im,message.mpim,reaction_addedandmember_joined_channel.
app_mention is not necessary. slakd sets verb=mention when the message text contains <@bot_user_id>. With both subscriptions, Slack sends each mention twice: once as message.* and once as app_mention.Step 4: copy the two secrets
- In Basic Information, copy the Signing Secret into
SLACK_SIGNING_SECRET. - Click Install to Workspace and copy the Bot User OAuth Token, which starts with
xoxb-, intoSLACK_BOT_TOKEN.
Step 5: configure the instance
Add the secrets to /srv/data/arizuko_<instance>/.env:
SLACK_BOT_TOKEN=xoxb-...
SLACK_SIGNING_SECRET=...
# optional
SLAKD_USERS_CACHE_TTL=900
Select the package and restart. The existing package selections stay:
./arizuko package add -i <instance> catalog:slakd
sudo systemctl restart arizuko_<instance>
Check that slakd runs:
./arizuko status -i <instance>
sudo journalctl -u arizuko_<instance> --since "30s ago" --no-pager \
| grep -E "slack|slakd"
Step 6: invite the bot to a channel
In each Slack channel where the agent must read or post:
/invite @<your-bot-name>
A DM needs no invite. Any user in the workspace can send a DM to the bot.
Step 7: add a route
Without a route, routd stores the Slack messages and starts no turn. Add a route for the whole platform:
./arizuko route -i <instance> add 'platform=slack' main
Or add a route for one channel:
./arizuko route -i <instance> add 'chat_jid=slack:T012ABCD/channel/C0HJKL456' engineering
Step 8: enable the AI pane
This step is optional. The Slack "Agents & AI Apps" pane gives the bot its own panel with a title, suggested prompts and a typing indicator. The bot also sees which channel the user has open. Slack pane explains the concept.
- In Agents & AI Apps, turn the feature on for the app.
- In OAuth & Permissions, add
assistant:writeto the bot token scopes. Keepchat:write. Install the app again, so that the new scope applies. - In Event Subscriptions, subscribe to
assistant_thread_startedandassistant_thread_context_changed. Keepmessage.im, because the bot reads pane messages from the same DM channel.
When the user clicks the AI icon, slakd writes a row in pane_sessions, sets the pane title and sets the first prompts. The title is <ASSISTANT_NAME> — chat, or chat without the variable. After that, the agent changes the title and the prompts with the pane_set_title and pane_set_prompts MCP tools.
The health endpoint follows auth.test
The /health endpoint of slakd returns 503 while the Slack auth.test call fails, for example after a token revoke or a network outage. When no event arrives for a long time, slakd calls auth.test again. When auth.test keeps failing past a deadline, slakd exits, and the container restarts.
Four problems have a known cause
- The Request URL stays red
proxydserves/slack/only whenSLACK_BOT_TOKENis set, so check.envand runarizuko generateagain. Or the signing secret is wrong, andslakdrefuses the challenge. Look forslack events: signature rejectedin the log.- The bot is in the channel and does not answer
- Add a route. Without a route, no turn starts.
/healthreturns 503- The bot token is revoked or wrong. Install the app again, copy the new
xoxb-token into.envand restart. - Reactions do not arrive
- Subscribe to
reaction_addedunder Event Subscriptions. Slack does not send it by default.
slakd reads six variables
| variable | required | default | notes |
|---|---|---|---|
SLACK_BOT_TOKEN | yes | — | Bot User OAuth Token, starts with xoxb- |
SLACK_SIGNING_SECRET | yes | — | App → Basic Information → Signing Secret |
SLAKD_USERS_CACHE_TTL | no | 900 | seconds that slakd keeps users.info and conversations.info answers |
ASSISTANT_NAME | no | — | shown in the pane title, <name> — chat, and in the typing indicator; without it the title is only "chat" |
AUTHD_SERVICE_KEY | yes | — | slakd exchanges it at AUTHD_URL for the service:slakd ES256 token that it sends to routd; the channel record is bound to that verified subject |
MEDIA_MAX_FILE_BYTES | no | 20971520, 20 MiB | the largest inbound file; slakd skips a larger upload and logs one line |
/commands before the bot sees them. To send a command to the agent, start it with a backslash: \new, \ping. routd reads \ as /.slakd does not support OAuth install, Socket Mode, Enterprise Grid, Slack slash commands, modals, Block Kit or user tokens. Install the app by hand, and Slack sends events through proxyd.