arizuko

arizuko › howto › Slack

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

  1. Slack posts an event to https://<your-host>/slack/events.
  2. proxyd forwards the raw body and the Slack signature headers unchanged to slakd:8080.
  3. slakd checks the HMAC, converts the event to an inbound message and posts it to routd.
  4. routd routes the message to a group and starts the turn. runed starts the guest of the agent.
  5. The agent calls reply or send, and slakd posts 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 typeJID formatexample
channelslack:<workspace>/channel/<channel_id>slack:T012ABCD/channel/C0HJKL456
DMslack:<workspace>/dm/<dm_id>slack:T012ABCD/dm/D0XY9876
multi-person DMslack:<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

  1. Open api.slack.com/apps, then Create New App, then From scratch.
  2. 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

  1. Enable events.
  2. Set the Request URL to https://<your-host>/slack/events. Slack sends a url_verification challenge once, and slakd sends it back. The Request URL becomes green when proxyd and slakd both run.
  3. Subscribe to these bot events: message.channels, message.groups, message.im, message.mpim, reaction_added and member_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

  1. In Basic Information, copy the Signing Secret into SLACK_SIGNING_SECRET.
  2. Click Install to Workspace and copy the Bot User OAuth Token, which starts with xoxb-, into SLACK_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.

  1. In Agents & AI Apps, turn the feature on for the app.
  2. In OAuth & Permissions, add assistant:write to the bot token scopes. Keep chat:write. Install the app again, so that the new scope applies.
  3. In Event Subscriptions, subscribe to assistant_thread_started and assistant_thread_context_changed. Keep message.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
proxyd serves /slack/ only when SLACK_BOT_TOKEN is set, so check .env and run arizuko generate again. Or the signing secret is wrong, and slakd refuses the challenge. Look for slack events: signature rejected in the log.
The bot is in the channel and does not answer
Add a route. Without a route, no turn starts.
/health returns 503
The bot token is revoked or wrong. Install the app again, copy the new xoxb- token into .env and restart.
Reactions do not arrive
Subscribe to reaction_added under Event Subscriptions. Slack does not send it by default.

slakd reads six variables

variablerequireddefaultnotes
SLACK_BOT_TOKENyes—Bot User OAuth Token, starts with xoxb-
SLACK_SIGNING_SECRETyes—App → Basic Information → Signing Secret
SLAKD_USERS_CACHE_TTLno900seconds that slakd keeps users.info and conversations.info answers
ASSISTANT_NAMEno—shown in the pane title, <name> — chat, and in the typing indicator; without it the title is only "chat"
AUTHD_SERVICE_KEYyes—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_BYTESno20971520, 20 MiBthe largest inbound file; slakd skips a larger upload and logs one line
Slack takes slash commands for itself. Slack catches /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.