Skip to content

Slack app setup

Notifycat posts to Slack with a bot token. You need one Slack app in the workspace where PR notifications should appear.

For production setup, use the shell script directly. It only needs sh and curl; jq is optional and only makes the output easier to read.

Create the app from the manifest

The repository includes the Slack app manifest at docs/slack-app-manifest.json. The manifest defines the bot user and the Slack scopes Notifycat needs.

Create a Slack app configuration token from Slack API: Your Apps. The token lives under the workspace-level Your App Configuration Tokens panel on that page — scroll past the apps list, generate a new token, and copy the xoxe-… value. Then run:

SLACK_APP_CONFIG_TOKEN=xoxe-your-token ./scripts/slack-app-create.sh

For Enterprise Grid or org-level configuration tokens, pass the workspace ID:

SLACK_APP_CONFIG_TOKEN=xoxe-your-token \
SLACK_TEAM_ID=T123 \
./scripts/slack-app-create.sh

The script validates the required inputs before calling Slack. It does not store the configuration token, and it does not belong in Notifycat production configuration.

After the app is created:

  1. Open the app settings page printed by the script, or open Slack API: Your Apps and select the new app.
  2. Go to Install App.
  3. Install the app to the workspace.
  4. Copy the Bot User OAuth Token.
  5. Set that token as SLACK_BOT_TOKEN in Notifycat.
SLACK_BOT_TOKEN=xoxb-your-token

The Slack API response can include an oauth_authorize_url. Do not use that URL for Notifycat setup. That URL starts a full OAuth callback flow, and Notifycat does not implement the redirect handler or code exchange. Use Install App in the Slack app settings instead.

Local development shortcut

If you use just while working on the repository, this recipe calls the same script:

SLACK_APP_CONFIG_TOKEN=xoxe-your-token just slack-app-create

Production instructions should use ./scripts/slack-app-create.sh directly so operators do not need to install just.

Manual fallback

If the API-based setup is not available in your workspace, create the app in the Slack UI:

  1. Open Slack API: Your Apps.
  2. Select Create New App.
  3. Choose From scratch.
  4. Pick the workspace and name the app notifycat.
  5. Open OAuth & Permissions.
  6. Add the bot scopes listed below.
  7. Click Install to Workspace.
  8. Copy the Bot User OAuth Token and set it as SLACK_BOT_TOKEN.

Bot scopes

Scope Why Notifycat needs it
chat:write Post, update, and delete PR messages.
chat:write.public Post into public channels without inviting the bot first.
reactions:write Add configured PR-state reactions.
channels:read Used by notifycat-config validate to confirm the bot can see the target channel. Add groups:read as well if you map private channels.

The manifest includes these scopes. If you create the app manually, add the same scopes in OAuth & Permissions.

notifycat-config validate reads X-OAuth-Scopes from Slack's auth.test response and fails fast when chat:write or reactions:write is missing.

Optional: reactions:read

The running server never reads reactions back, so this scope is not required for normal operation. It is used by two optional commands: notifycat-smoke --reactions, which calls reactions.get to verify that the lifecycle emoji it triggered actually landed on the message, and notifycat-relocate, which carries a message's reactions over when it moves it to another channel. Without reactions:read, the reactions are still posted (that only needs reactions:write) but the smoke test reports ? could not verify … missing_scope instead of ✓ and exits successfully. Grant reactions:read only if you want that readback verification — leaving it off keeps the bot at least privilege.

Optional: channels:history / groups:history

Not required for normal operation. Two features read a posted message back with conversations.history, and only they need these scopes. channels:history covers public channels, groups:history private ones.

  • cleanup.delete_on_close reads the message before it deletes it, to keep a message that has a thread discussion. Startup validation (and notifycat-config validate) fails an entry that has the flag on while either scope is missing. Both are required because a channel ID does not tell a public channel from a private one.
  • notifycat-relocate reads a message's blocks in order to repost them in another channel. The command refuses to start without the scopes rather than failing partway.

Grant them when you use one of these features, and leave them off otherwise.

Channel access

Invite the bot to every channel listed in the mappings: section of config.yaml:

/invite @notifycat

This is required for reaction updates. chat:write.public lets Notifycat post the first message in public channels without joining them, but Slack may reject reactions.add unless the bot is a channel member. Inviting the bot keeps both message posting and reactions working for public and private channels.

Use the channel ID in mappings, not the display name. In Slack, open channel details and copy the channel ID. It usually starts with C.

Mentions

Each mapping in config.yaml can list Slack mentions that prefix the PR notification — users, user groups, @channel, or nobody at all. The formats, the three mention states, and how to find the IDs are covered in Route repositories to channels → Mentions.