A minimal backend API built with Bun and Hono to listen for GitHub pull request events.
✅ Listens only to pull request events
✅ Logs all PR-related details (commits, changes, authors, etc.)
✅ HMAC-SHA256 signature verification
✅ Built with Hono and Bun
✅ TypeScript support
✅ Single POST webhook endpoint
- Bun installed
bun installSet environment variables:
export GITHUB_WEBHOOK_SECRET="your-webhook-secret"
export PORT=3000Or create a .env file:
GITHUB_WEBHOOK_SECRET=your-webhook-secret
PORT=3000Note: The webhook secret must match the secret configured in your GitHub repository settings.
bun run devbun startThe server starts on http://localhost:3000 by default.
docker build -t github-webhook:latest .# Basic run
docker run -p 3000:3000 \
-e GITHUB_WEBHOOK_SECRET="your-secret" \
github-webhook:latest
# With environment file
docker run -p 3000:3000 \
--env-file .env \
github-webhook:latest# Start service
docker-compose up -d
# View logs
docker-compose logs -f
# Stop service
docker-compose downCreate .env file for docker-compose:
GITHUB_WEBHOOK_SECRET=your-webhook-secretDocker automatically checks health every 30 seconds:
# Check manually
curl http://localhost:3000/healthPOST /webhook/githubAccepts only pull_request events
Required Headers (sent automatically by GitHub):
X-Hub-Signature-256: GitHub's HMAC signatureX-GitHub-Event: Must bepull_request
GET /healthResponse: { "status": "ok" }
- Go to your GitHub repository → Settings → Webhooks
- Click Add webhook
- Payload URL:
https://your-domain.com/webhook/github - Content type:
application/json - Secret: Use a strong secret (store as
GITHUB_WEBHOOK_SECRET) - Which events would you like to trigger this webhook? → Select only Pull requests
- Click Add webhook
The webhook logs comprehensive pull request information:
======================================================================
✅ PULL REQUEST EVENT RECEIVED
======================================================================
📅 Timestamp: 2026-05-18T10:30:00.000Z
🔑 Delivery ID: 12345-67890
📍 Repository: octocat/Hello-World
🔗 Repository URL: https://github.com/octocat/Hello-World
📋 PULL REQUEST DETAILS:
🔢 PR Number: #42
📝 Title: Add new feature
⚡ Action: opened
📊 State: open
👤 Author: octocat
🔀 Head Branch: feature/new-feature
🔀 Base Branch: main
📈 Commits: 5
➕ Additions: 123
➖ Deletions: 45
📁 Changed Files: 8
💬 Comments: 2
👍 Approvals: 0
🎉 NEW PR OPENED
======================================================================
The webhook captures different pull request actions:
opened— New PR createdclosed— PR closed (includes merge status)reopened— PR reopenedsynchronize— New commits pushed to PRready_for_review— Draft PR marked readyconverted_to_draft— PR converted to draftedited— PR title/description updatedapproved— PR approvedreview_requested— Reviewer requestedauto_merge_enabled/auto_merge_disabled— Auto-merge status- And more...
Successful response:
{
"success": true,
"event": "pull_request",
"action": "opened",
"pr_number": 42,
"pr_title": "Add new feature",
"delivery": "12345-67890",
"processed_at": "2026-05-18T10:30:00.000Z"
}To test locally:
# Terminal 1: Start the server
bun run dev
# Terminal 2: Expose with ngrok
ngrok http 3000
# Use the ngrok URL as your GitHub webhook payload URLOther event types (push, issues, release, etc.) will receive a 202 response:
{
"success": false,
"message": "Event type \"push\" ignored. Only \"pull_request\" events are processed."
}MIT