Skip to content

Slack App Setup

Junior receives Slack traffic at one webhook route:

https://<your-domain>/api/webhooks/slack

Use your tunnel URL for local development and your Vercel URL for production.

Create a Slack app in the workspace where users will talk to Junior, then add the signing secret and bot token to your Junior environment:

Terminal window
SLACK_SIGNING_SECRET=...
SLACK_BOT_TOKEN=xoxb-...

Use SLACK_BOT_TOKEN for normal bot replies. Use SLACK_BOT_USER_TOKEN only when your installation intentionally uses that token shape.

Grant the smallest scopes that cover the Slack features you enable. A typical Junior installation needs scopes for mentions, posting replies, reading thread context, reactions, user lookup, and file workflows.

Capability Slack scopes to verify
Mentions app_mentions:read
Thread replies and private auth prompts chat:write
Processing reactions reactions:write
User lookup and App Home ownership users:read
Thread and channel history in channels and DMs channels:history, channels:read, groups:history, groups:read, im:history, mpim:history as needed
On-demand join of public channels channels:join required to join a public channel when reading linked threads or history
Public workspace search (messages) search:read.public required for interactive public Slack search
Public workspace search (files) search:read.files required when searching public files
Public workspace search (users) search:read.users required when searching people via public search
File/image context and generated files files:read, files:write when file workflows are enabled
Direct links back to Slack conversations team:read
Dashboard link previews and “Continue here” links:read, links:write
Push notifications on a Slack notification schedule dnd:read
Slack assistant status/title surfaces assistant:write and other assistant scopes required by your Slack app configuration

Slack requires reinstalling the app after scope changes. Reinstall before debugging runtime behavior.

Public search uses Slack Real-time Search on interactive turns. The bot app must include search:read.public. Add search:read.files and search:read.users when those content types are enabled. On-demand public channel joins require channels:join. The reference manifest in packages/junior/slack-manifest.yml lists the full required bot scope set.

Also enable App Home in Slack app settings. Junior publishes the connected-account view when Slack sends app_home_opened.

Set Event Subscriptions to the Junior webhook URL:

https://<your-domain>/api/webhooks/slack

Subscribe to the events that match your usage:

Event Why Junior uses it
app_mention Channel and thread mentions.
message.im Direct messages.
app_home_opened Connected-account App Home view.
entity_details_requested Open and refresh Work Object details.
Slack assistant thread events Assistant-thread title, status, and prompt surfaces.
agent_session_stopped Slack’s stop button for a running Junior Turn.
channel_created Optional auto-join of new public channels.
link_shared Previews of dashboard conversation links.

If your app relies on subscribed-thread follow-ups in shared channels, enable the channel message events required by that Slack app model and confirm the bot is present in those channels.

For dashboard link previews, add the dashboard host under App Unfurl Domains too. A preview of a public dashboard conversation in a public channel has a Continue here button. Anyone signed in can click it to move the conversation into that message’s thread.

Slack shows a stop button on a working thread only when the app subscribes to agent_session_stopped. Existing apps must add this bot event in the Slack app settings. The button stops the current Turn, the same as the stop keyword. The thread stays subscribed.

To make Junior join each new public channel, subscribe to channel_created and turn on the option. Junior does not join channels that existed before. The app needs channels:join.

server.ts
export default await createApp({
plugins,
slack: { autoJoinNewChannels: true },
});

For object previews, enable Work Object Previews → Item and Task in the Slack app settings. Existing apps must also add entity_details_requested to their bot event subscriptions; deploying Junior does not update Slack app settings.

Set the Interactivity request URL to the same webhook route:

https://<your-domain>/api/webhooks/slack

Junior uses interactivity for App Home actions such as disconnecting provider accounts. It also uses it when Junior asks for input. A simple question shows one button for each choice, and the first click is the answer. Other questions show a button that opens a form. The answer is sent as a reply from the person who answered, in the same thread. Junior then replaces the controls with that person’s answer.

For local development, expose your dev server with a tunnel:

Terminal window
cloudflared tunnel --url http://localhost:3000

Then set Slack Event Subscriptions and Interactivity to the tunnel URL plus /api/webhooks/slack.

Verify the setup:

  1. GET http://localhost:3000/health returns status: "ok".
  2. Mention Junior in a channel where the bot is installed.
  3. Confirm Junior adds a processing reaction and posts a reply in the same thread.
  4. Open App Home and confirm the connected-account view loads.

After Slack works locally, follow Deploy to Vercel and update Slack URLs to your production domain.