Skip to content

Configuration

Secrets

WebHooker requires several secrets to function. For local development, store them in .dev.vars. For production, use Cloudflare Worker Secrets.

Required Secrets

VariableDescription
GITHUB_WEBHOOK_SECRETWebhook secret from your GitHub App settings
GITHUB_APP_IDNumeric ID of your GitHub App
GITHUB_PRIVATE_KEYApp private key (PEM format, with \n escapes)
GITHUB_CLIENT_IDOAuth client ID from App settings
GITHUB_CLIENT_SECRETOAuth client secret from App settings
DISCORD_TOKENDiscord bot token
DISCORD_CHANNEL_IDDefault Discord channel ID for messages

Optional Secrets

VariableDescriptionDefault
BASE_URLPublic URL for OAuth callbackshttp://localhost:8787

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.

On first boot, 7 default routes are used if no KV config exists.

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": "DISCORD_CHANNEL_ID",
    "threadId": "OPTIONAL_THREAD_ID"
  }
}

Default Routes

IDEvent(s)Description
all-pushpushAll push events
pull-requestspull_requestAll PR activity
issuesissuesIssue open/close/edit
issue-commentsissue_commentIssue and PR comments
workflow-runsworkflow_runCI/CD workflow completions
releasesreleaseRelease publish/edit
branch-activitycreate, deleteBranch/tag creation and deletion

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

TypeMatchesExample
eventGitHub event namepush, pull_request, issues
repoRepository full nameorg/repo
actorSender loginusername, [bot]
actionEvent actionopened, closed, published
branchBranch namemain, feature/*
keywordText in payload bodydeploy, /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 PatternValueTTL
config:routesJSON array of routesPermanent
token:{userId}{ accessToken, expiresAt }Until expiry
state:{hex}{ userId, createdAt }600 seconds

Released under the MIT License.