Webhook receivers and adapters that sit between the Wrily GitHub App and Wrily's GitHub Actions workflow. Each subfolder is one deployment option — pick whichever fits your infrastructure.
The Wrily App sends pull_request webhooks to some URL. Something at that URL needs to:
- Verify the HMAC signature on the incoming webhook.
- Filter to relevant events (
pull_requestwithopened/synchronize/reopened). - Mint App installation tokens — one scoped to
barryroodt/wrily, one scoped to the consumer repo, and optionally one scoped to a shared skills repo. - POST a
repository_dispatch(review-pr)event tobarryroodt/wrilywith the consumer-scoped token and optional shared-skills token in the payload.
That receiver is what lives here. Swapping implementations is a single URL change in the App's webhook config — the Wrily-side workflow (.github/workflows/dispatch-review.yml) never changes.
See docs/design/webhook-architecture.md for the full flow and security model.
| Folder | Runtime | Status | Best for |
|---|---|---|---|
cloudflare-worker/ |
Cloudflare Workers | ✅ Recommended | Default choice. Both secrets in CF-encrypted Worker secrets, ~120 LOC TypeScript with tests, wrangler deploy. |
n8n/ |
Self-hosted or Cloud n8n | ✅ Alternative | Teams already running n8n and OK with secrets stored as plaintext n8n Variables (Code nodes can't access n8n credentials — known platform limitation). |
aws-lambda/ |
AWS Lambda | 🟡 Not yet built | Teams standardised on AWS. Same shape as the Worker, packaged as a Lambda. |
The receivers are wire-compatible. The Wrily-side workflow doesn't care which one is in front of it.
Every receiver must:
- Accept POST to its webhook URL with GitHub's
X-Hub-Signature-256header. - Verify the signature against a shared webhook secret. Reject 401 on mismatch.
- Filter to
pull_requestevents with action in{opened, synchronize, reopened}. - For matching events:
- Mint a short-lived installation token scoped to
barryroodt/wrily. - Mint a short-lived installation token scoped to the consumer repo (
$.repository.full_name). - Optionally mint a short-lived installation token scoped to the configured shared skills repo.
- POST to
https://api.github.com/repos/barryroodt/wrily/dispatcheswith:{ "event_type": "review-pr", "client_payload": { "consumer_repo": "<org>/<repo>", "pr_number": 123, "head_sha": "...", "base_ref": "main", "consumer_token": "ghs_...", "shared_token": "ghs_... or null", "shared_repo": "your-org/shared-wrily-skills or null" } } - Return 200 to the webhook.
- Mint a short-lived installation token scoped to
- Never log the private key or any minted token.
- Create a new subfolder named after the runtime (
cloudflare-worker/,aws-lambda/, etc.). - Include: the receiver code/config, a
README.md, and a setup runbook. - Follow the contract above — Wrily-side changes should be zero.
- Add the row to the table above.