notifycat

module
v0.15.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 24, 2026 License: MIT

README

Notifycat

Notifycat logo

CI Release Go Version Go Report Card Conventional Commits

Notifycat listens for GitHub pull request webhooks and keeps Slack up to date.

One pull request gets one Slack message. As the PR opens, moves to draft, gets reviewed, merges, or closes, Notifycat updates that message and adds the configured reactions. The result is a quieter channel: reviewers can follow the state of a PR without digging through repeated notifications.

It is intentionally small: one HTTP endpoint, a SQLite database (for Slack message timestamps), and a declarative mappings.yaml that decides which PRs route to which Slack channels.

Quick start

You'll need a host with Docker + Compose V2, a domain name pointing at it, and inbound ports 80/443 open. In about 10 minutes you'll have Notifycat running behind automatic HTTPS and posting PR updates to Slack — no Go toolchain, no SQLite client, no manual file editing.

curl -fsSL https://github.com/mptooling/notifycat/releases/latest/download/install.sh | sh
cd notifycat
./notifycat setup          # interactive wizard — writes .env and mappings.yaml
docker compose up -d       # start Notifycat + Caddy (HTTPS via Let's Encrypt)
./notifycat doctor         # verify setup

The installer downloads a pinned, checksum-verified bundle into ./notifycat. The setup wizard prompts for your domain, Slack token, webhook secret, and first mapping. For the full walkthrough — webhook registration, a delivery smoke test, and troubleshooting — see Install with Docker Compose, then run through the Security & permissions checklist before go-live.

Alternative: run from source (contributors)

Most users want the one-command path above. Build from source if you're contributing or want to run without Docker.

Requires:

  • Go 1.25.10 or newer (go version to check).
  • git to clone the repository.
  • sh and curl for the helper scripts under scripts/.
  • A public URL (ngrok or Cloudflare Tunnel) only if you want GitHub to deliver real webhooks to your laptop. Local CLI commands (validate / doctor) don't need one.

Six commands from "nothing" to "running":

git clone https://github.com/mptooling/notifycat.git && cd notifycat
cp .env.example .env                       # then edit: set GITHUB_WEBHOOK_SECRET, SLACK_BOT_TOKEN
cp mappings.example.yaml mappings.yaml     # then edit: real Slack channel IDs

go run ./cmd/notifycat-mapping validate
go run ./cmd/notifycat-doctor
go run ./cmd/notifycat-server

The binaries pick up .env from the current working directory and default to ./mappings.yaml and ./data/notifycat.db. See Getting started for the end-to-end walkthrough including the tunnel + webhook setup.

What It Handles

  • pull_request webhooks for opened, closed, and converted-to-draft PRs.
  • pull_request_review webhooks for approved, commented, and changes-requested reviews.
  • pull_request_review_comment webhooks for line-specific PR comments.
  • GitHub HMAC-SHA256 verification through X-Hub-Signature-256.
  • Repository routing from a declarative mappings.yaml — explicit lists or repositories: "*" for a whole org. See mappings.example.yaml.
  • Slack message updates instead of repeated new messages for the same PR.

Binaries

Binary Purpose
notifycat-server HTTP server for GitHub webhooks
notifycat-mapping CLI for listing and validating the mappings file
notifycat-migrate Applies embedded SQLite migrations
notifycat-doctor Preflight diagnostics (config, database, mappings, optional per-repo Slack/GitHub)
notifycat-smoke Forges a signed PR event end-to-end to confirm Slack delivery

Documentation

Full documentation is published at https://mptooling.github.io/notifycat/.

Development

The project includes a justfile for common development commands. Install just (brew install just on macOS), then run:

just
just check
just serve

just is a developer tool only. It is not part of the Go module, the Docker runtime image, or production dependencies.

The underlying checks are:

go vet ./...
golangci-lint run ./...
govulncheck ./...
go test -race ./...
go build ./...

See CONTRIBUTING.md for contributor setup, pull request expectations, and issue reporting guidance.

Community

License

MIT. See LICENSE.

Directories

Path Synopsis
cmd
notifycat-doctor command
Command notifycat-doctor runs end-to-end preflight diagnostics for a notifycat installation.
Command notifycat-doctor runs end-to-end preflight diagnostics for a notifycat installation.
notifycat-mapping command
Command notifycat-mapping is the CLI for the declarative mappings.yaml workflow: `list` prints the file, `validate` runs the cache-aware validation pipeline.
Command notifycat-mapping is the CLI for the declarative mappings.yaml workflow: `list` prints the file, `validate` runs the cache-aware validation pipeline.
notifycat-migrate command
Command notifycat-migrate applies the embedded database migrations.
Command notifycat-migrate applies the embedded database migrations.
notifycat-server command
Command notifycat-server starts the HTTP server that receives GitHub webhooks and posts to Slack.
Command notifycat-server starts the HTTP server that receives GitHub webhooks and posts to Slack.
notifycat-smoke command
Command notifycat-smoke runs an end-to-end delivery test against the running notifycat stack.
Command notifycat-smoke runs an end-to-end delivery test against the running notifycat stack.
internal
aireview
Package aireview identifies webhook events from a "bot reviewer" (any account whose sender.type is "Bot") and exposes two orthogonal policies over that identity.
Package aireview identifies webhook events from a "bot reviewer" (any account whose sender.type is "Bot") and exposes two orthogonal policies over that identity.
app
Package app is the composition root for notifycat.
Package app is the composition root for notifycat.
botpr
Package botpr classifies pull requests opened by dependency-update bots (Dependabot, Renovate) so the notifier can render a compact Slack message instead of the standard "please review" format, and tell routine version bumps apart from security-advisory updates.
Package botpr classifies pull requests opened by dependency-update bots (Dependabot, Renovate) so the notifier can render a compact Slack message instead of the standard "please review" format, and tell routine version bumps apart from security-advisory updates.
cleanup
Package cleanup runs the scheduled, in-process pruning of stale rows from the slack_messages table.
Package cleanup runs the scheduled, in-process pruning of stale rows from the slack_messages table.
config
Package config loads runtime configuration from environment variables (and optionally from a .env file in development).
Package config loads runtime configuration from environment variables (and optionally from a .env file in development).
doctor
Package doctor runs end-to-end preflight diagnostics for a notifycat installation.
Package doctor runs end-to-end preflight diagnostics for a notifycat installation.
github
Package github is a minimal GitHub API client covering only the endpoints notifycat needs for validation.
Package github is a minimal GitHub API client covering only the endpoints notifycat needs for validation.
githubhook
Package githubhook authenticates and parses inbound GitHub webhook requests.
Package githubhook authenticates and parses inbound GitHub webhook requests.
mappings
Package mappings owns the declarative repository → Slack-channel configuration: parsing mappings.yaml, the in-memory Provider used at runtime, and the mappings.lock cache that records which entries have been validated.
Package mappings owns the declarative repository → Slack-channel configuration: parsing mappings.yaml, the in-memory Provider used at runtime, and the mappings.lock cache that records which entries have been validated.
pullrequest
Package pullrequest holds the domain model for GitHub pull-request events and the handlers that update Slack in response.
Package pullrequest holds the domain model for GitHub pull-request events and the handlers that update Slack in response.
slack
Package slack talks to the Slack Web API for the PR notifier: posting, updating, and deleting messages, adding emoji reactions, and composing the blocks of the notification.
Package slack talks to the Slack Web API for the PR notifier: posting, updating, and deleting messages, adding emoji reactions, and composing the blocks of the notification.
smoke
Package smoke drives an end-to-end delivery test against a running notifycat stack.
Package smoke drives an end-to-end delivery test against a running notifycat stack.
store
Package store owns the database schema, GORM models, repositories, and the goose-driven migration runner.
Package store owns the database schema, GORM models, repositories, and the goose-driven migration runner.
validate
Package validate verifies that a repository → Slack-channel mapping is usable end-to-end before GitHub fires a real PR event: the mapping row exists, the channel ID is well-formed, the Slack bot has the right scopes and is a member of the channel, and (when GitHub credentials are available) the webhook is subscribed to the events notifycat needs.
Package validate verifies that a repository → Slack-channel mapping is usable end-to-end before GitHub fires a real PR event: the mapping row exists, the channel ID is well-formed, the Slack bot has the right scopes and is a member of the channel, and (when GitHub credentials are available) the webhook is subscribed to the events notifycat needs.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL