Skip to content

Configuration

Notifycat reads configuration from environment variables. For local development, it also loads .env if the file exists.

Secrets should stay in environment variables or your deployment secret manager. Do not put real tokens in committed files.

Required Variables

Variable Description
GITHUB_WEBHOOK_SECRET The secret configured on the GitHub webhook.
SLACK_BOT_TOKEN Slack bot token, usually starting with xoxb-.

The server and CLIs fail fast when either value is missing. Use a long random GITHUB_WEBHOOK_SECRET; 32 characters or more is a good baseline.

Server and Logging

Variable Default Notes
ADDR :8080 HTTP listen address.
LOG_LEVEL info Supported values: debug, info, warn, error.
LOG_FORMAT text Use json for structured production logs.

Database

Variable Default Notes
DATABASE_URL file:./data/notifycat.db SQLite path or file: DSN. Stores the per-PR Slack message timestamps. Mappings live in YAML, not the database.

In Docker, the image sets:

DATABASE_URL=file:/data/notifycat.db

Mount /data if you want the database to survive container restarts.

Mappings File

Variable Default Notes
NOTIFYCAT_MAPPINGS_FILE ./mappings.yaml Path to the declarative mappings file. The sibling lock file (e.g. ./mappings.lock) is derived by swapping the .yaml/.yml extension for .lock.

Both notifycat-server and notifycat-mapping read this file. See Mappings file for the schema and mappings.example.yaml for a copy-paste starting point.

Slack

Variable Default Notes
SLACK_BASE_URL https://slack.com Mostly useful for tests.

GitHub (validation only)

Variable Default Notes
GITHUB_TOKEN (unset) Optional PAT used by notifycat-mapping validate and notifycat-doctor to read repo webhook config. Required scope: admin:repo_hook (or repo for private repos). The server does not need this; if unset, the webhook-coverage check is skipped.
GITHUB_BASE_URL https://api.github.com Override for GitHub Enterprise or tests.

GITHUB_TOKEN is also read by scripts/github-webhook-create.sh, but that script creates the webhook and only needs the Webhooks: Read and write permission on a fine-grained PAT. The validate/doctor reading path needs admin:repo_hook / repo. A single token that has both works everywhere; otherwise issue separate PATs.

Cleanup

Variable Default Notes
NOTIFYCAT_MESSAGE_TTL_DAYS 30 Days a slack_messages row may go without an update before the in-process cleanup removes it. Must be > 0. The cleanup runs once at startup and then once every 24 hours; it only deletes the DB row, never the actual Slack message.

Reviewer suppression

Variable Default Notes
NOTIFYCAT_IGNORE_AI_REVIEWS false When true, suppress reactions.add for any review event whose sender.type == "Bot" — Copilot, Claude, Codex, dependabot, github-actions, release-please, and any other GitHub App or legacy bot account. Detection is intentionally coarse: notifycat does not distinguish AI reviewers from scripted bots. See Operations → Bot-reviewer suppression for the trade-off and failure-mode guide.

Dependabot / Renovate format

Variable Default Notes
NOTIFYCAT_DEPENDABOT_FORMAT true When true, PRs opened by dependabot[bot] or renovate[bot] post a compact Slack message instead of the standard "please review" format: :package: <bot> bumped <link> for routine bumps, or :rotating_light: <bot> security update <link> when the PR body shows a security advisory. Set false to render those PRs with today's standard format. See Operations → Dependabot / Renovate format for detection details.

Reactions

Variable Default Notes
SLACK_REACTIONS_ENABLED true Turns reaction updates on or off.
SLACK_REACTION_NEW_PR eyes Added when a PR is opened. Doubles as the leading emoji of the new-PR message.
SLACK_REACTION_MERGED_PR twisted_rightwards_arrows Added when a PR is merged.
SLACK_REACTION_CLOSED_PR x Added when a PR is closed without merge.
SLACK_REACTION_PR_APPROVED white_check_mark Added when a review approves the PR.
SLACK_REACTION_PR_COMMENTED speech_balloon Added when a review comments on the PR.
SLACK_REACTION_PR_REQUEST_CHANGE exclamation Added when a review requests changes.
SLACK_REACTION_BOT_REVIEW robot_face Distinct marker added alongside the normal reaction when a bot reviewer's activity is not suppressed (i.e. NOTIFYCAT_IGNORE_AI_REVIEWS=false). Lets bot reviews stay visible but recognisable. Set empty (SLACK_REACTION_BOT_REVIEW=) to keep bot reviews indistinguishable from human ones. Mutually exclusive with suppression: when NOTIFYCAT_IGNORE_AI_REVIEWS=true the bot reaction is skipped entirely, so this marker never appears.

Use Slack emoji names without surrounding colons. For example, set SLACK_REACTION_PR_APPROVED=shipit, not :shipit:.

Mapping CLI

Mappings are defined in mappings.yaml, not in environment variables. The notifycat-mapping binary has two subcommands:

notifycat-mapping list                    # print the parsed file (no network)
notifycat-mapping validate                # validate every entry, cache-aware
notifycat-mapping validate owner/repo     # validate a single entry, ignore cache for it
notifycat-mapping validate --force        # ignore the lock entirely; revalidate everything

validate checks each entry end-to-end: the Slack channel ID is well-formed, the bot token has the required scopes, the bot is a member of the channel, and (when GITHUB_TOKEN is set) the GitHub webhook is subscribed to pull_request, pull_request_review, and pull_request_review_comment. See docs/operations.md for the failure-mode remediation table. The server runs the same validation at boot and refuses to start on failure.