mirror of
https://github.com/ReCloudStudio/WebHooker.git
synced 2026-09-23 00:21:28 +00:00
129 lines
5.3 KiB
Markdown
129 lines
5.3 KiB
Markdown
# Configuration
|
|
|
|
## Secrets
|
|
|
|
WebHooker requires several secrets to function. For local development, store them in `.dev.vars`. For production, use Cloudflare Worker Secrets.
|
|
|
|
### Required Secrets
|
|
|
|
| Variable | Description |
|
|
| ----------------------- | ----------------------------------------------- |
|
|
| `GITHUB_WEBHOOK_SECRET` | Webhook secret from your GitHub App settings |
|
|
| `GITHUB_APP_ID` | Numeric ID of your GitHub App |
|
|
| `GITHUB_PRIVATE_KEY` | App private key (PEM format, with `\n` escapes) |
|
|
| `GITHUB_CLIENT_ID` | OAuth client ID from App settings |
|
|
| `GITHUB_CLIENT_SECRET` | OAuth client secret from App settings |
|
|
| `DISCORD_TOKEN` | Discord bot token |
|
|
|
|
### Optional Secrets
|
|
|
|
| Variable | Description | Default |
|
|
| ------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------- |
|
|
| `BASE_URL` | Public URL for OAuth callbacks | `http://localhost:8787` |
|
|
| `ADMIN_USER_IDS` | Comma-separated GitHub user IDs (or logins) allowed to access the Web UI | Disabled |
|
|
| `DISCORD_GATEWAY_ENABLED` | Set to `true` to connect the Discord Gateway (bot online status); messaging works without it via REST | `false` |
|
|
|
|
## Web UI
|
|
|
|
WebHooker ships with a built-in config console at `/admin` for managing routes in the browser. It is protected by GitHub OAuth plus an admin whitelist.
|
|
|
|
### Setup
|
|
|
|
1. Configure `ADMIN_USER_IDS` with the GitHub user IDs allowed to manage routes. Logins are also accepted, e.g. `ADMIN_USER_IDS=12345,RhenCloud`. If unset, the console is disabled.
|
|
2. Open `/admin` and sign in with GitHub.
|
|
3. Only users in the whitelist receive a session cookie; everyone else gets `403`.
|
|
|
|
### Endpoints
|
|
|
|
| Endpoint | Description |
|
|
| ----------------------- | --------------------------- |
|
|
| `GET /admin` | Config console UI |
|
|
| `GET /admin/login` | Start GitHub OAuth sign-in |
|
|
| `GET /admin/logout` | Destroy session |
|
|
| `GET /admin/api/routes` | List routes (admin only) |
|
|
| `PUT /admin/api/routes` | Replace routes (admin only) |
|
|
|
|
The console lets you add, edit, delete, and toggle routes. Saved routes are written to KV `config:routes` immediately and the config cache is invalidated so the webhook pipeline picks them up on the next run.
|
|
|
|
## Routes
|
|
|
|
Routes define which events get forwarded to which Discord channels. They are stored in Cloudflare KV under the key `config:routes` as a JSON array.
|
|
|
|
There are **no default routes** — each route must define its own target. If no routes are configured, no events are forwarded.
|
|
|
|
### Route Schema
|
|
|
|
```json
|
|
{
|
|
"id": "unique-route-id",
|
|
"name": "Human-readable name",
|
|
"enabled": true,
|
|
"filters": [
|
|
{ "type": "event", "match": "push" },
|
|
{ "type": "repo", "match": "org/repo", "exclude": false }
|
|
],
|
|
"target": {
|
|
"channelId": "REQUIRED_CHANNEL_ID",
|
|
"threadId": "OPTIONAL_THREAD_ID"
|
|
}
|
|
}
|
|
```
|
|
|
|
`target.channelId` is required and used as-is; there is no fallback to a default channel.
|
|
|
|
### Custom Route Example
|
|
|
|
```json
|
|
[
|
|
{
|
|
"id": "backend-prs",
|
|
"name": "Backend PRs",
|
|
"enabled": true,
|
|
"filters": [
|
|
{ "type": "repo", "match": "myorg/backend" },
|
|
{ "type": "event", "match": "pull_request" },
|
|
{ "type": "actor", "match": "[bot]", "exclude": true }
|
|
],
|
|
"target": {
|
|
"channelId": "1234567890",
|
|
"threadId": "9876543210"
|
|
}
|
|
}
|
|
]
|
|
```
|
|
|
|
## Filter Types
|
|
|
|
| Type | Matches | Example |
|
|
| --------- | -------------------- | -------------------------------- |
|
|
| `event` | GitHub event name | `push`, `pull_request`, `issues` |
|
|
| `repo` | Repository full name | `org/repo` |
|
|
| `actor` | Sender login | `username`, `[bot]` |
|
|
| `action` | Event action | `opened`, `closed`, `published` |
|
|
| `branch` | Branch name | `main`, `feature/*` |
|
|
| `keyword` | Text in payload body | `deploy`, `/fix\s+\d+/` (regex) |
|
|
|
|
### Filter Behavior
|
|
|
|
- All filters in a route must match for the route to trigger (AND logic)
|
|
- Set `"exclude": true` on any filter to invert it (NOT logic)
|
|
- `keyword` filter supports regex patterns — falls back to substring match if regex is invalid
|
|
- `branch` filter works for push, pull_request, create/delete, workflow_run, and code_scanning_alert events
|
|
|
|
### Match Values
|
|
|
|
Filters accept either a single string or an array of strings:
|
|
|
|
```json
|
|
{ "type": "event", "match": "push" }
|
|
{ "type": "event", "match": ["push", "pull_request"] }
|
|
```
|
|
|
|
## KV Storage Layout
|
|
|
|
| Key Pattern | Value | TTL |
|
|
| ---------------- | --------------------------------- | ------------ |
|
|
| `config:routes` | JSON array of routes | Permanent |
|
|
| `session:{id}` | Admin session `{ userId, login }` | 7 days |
|
|
| `token:{userId}` | `{ accessToken, expiresAt }` | Until expiry |
|
|
| `state:{hex}` | `{ userId, createdAt }` | 600 seconds |
|