Getting Started¶
Prerequisites¶
Installation¶
# Clone the repo
git clone git@github.com:feds01/prbot.git
cd prbot
# Install dependencies and pre-commit hooks
just install
# or without just:
uv sync --dev && uv run pre-commit install
Quick start¶
1. Configure credentials¶
Copy the example env file and fill in your credentials:
You'll need GitHub credentials and at least one messaging integration — see the guides for how to obtain them:
- GitHub integration — create a GitHub App and get your app ID + private key + webhook secret
- Slack integration — create a Slack app and get your bot token + signing secret
- Discord integration — create a Discord bot and get your bot token
2. Upload custom emoji¶
prbot uses custom emoji for PR status reactions. Upload them to your Slack workspace or Discord server:
# Slack
uv run python scripts/upload_emojis.py slack --token xoxp-your-admin-token
# Discord
uv run python scripts/upload_emojis.py discord --token YOUR_BOT_TOKEN --guild-id 123456789
See Custom emoji for details and customization options.
3. Run the server¶
The server starts at http://localhost:8080 with the following endpoints:
| Endpoint | Method | Description |
|---|---|---|
/slack/events |
POST | Slack event subscription |
/github/webhooks |
POST | GitHub webhook receiver |
/health |
GET | Health check |
Discord
The Discord integration connects via WebSocket (Discord Gateway), so no HTTP endpoint is needed. It starts automatically when PR_BOT_DISCORD__BOT_TOKEN is set.
Local development with webhooks
To receive Slack events and GitHub webhooks locally, you'll need a tunnel. ngrok or cloudflared work well:
Use the generated URL as your base URL when configuring Slack and GitHub.
3. Run checks¶
just check # lint + format-check + typecheck + migration check
just test # run tests
just lint-fix # auto-fix lint issues
just format # auto-format code
Architecture¶
graph TB
subgraph Integrations
Slack[Slack]
Discord[Discord]
end
subgraph Application
HIM[Handle Incoming Message]
HGW[Handle GitHub Webhook]
RTP[Reconcile Tracked PRs]
end
subgraph Domain
TE[TrackedPR Entity]
VO[Value Objects]
SR[Status Resolver]
end
subgraph Infrastructure
GH[GitHub Gateway]
DB[(SQLite)]
end
Slack -->|message events| HIM
Discord -->|message events| HIM
GH_WH[GitHub Webhooks] -->|PR events| HGW
HIM --> GH
HGW --> GH
HIM --> DB
HGW --> DB
RTP --> HGW
HIM --> SR
HGW --> SR
SR --> VO
prbot follows a clean architecture with ports and adapters:
- Domain — core business logic, no framework dependencies
- Application — use cases that orchestrate domain logic
- Infrastructure — external API clients (GitHub REST API)
- Integration — messaging platform adapters (Slack, Discord, etc.)
- Data — persistence with SQLAlchemy + async SQLite
Startup behavior¶
On startup, prbot automatically:
- Runs database migrations — schema is always up to date, no manual steps needed
- Backfills missed messages — for each channel, fetches messages posted since the last tracked timestamp and processes any PR URLs found
- Reconciles tracked PRs — re-checks all tracked PRs against GitHub to catch any webhook events missed during downtime
Database migrations¶
Migrations run automatically on startup (step 1 above), so no manual steps are needed for deployment.
The project uses Alembic for migrations. After modifying the SQLAlchemy models: