GitHub only allows one webhook endpoint per GitHub App. This service multiplexes that single webhook into authenticated WebSocket connections, so multiple clients can subscribe to just the events they care about.
export GITHUB_WEBHOOK_SECRET="your-webhook-secret"
go run ./cmd/server
go run ./cmd/client
const ws = new WebSocket('wss://your-server/ws', {
headers: { 'Authorization': 'Bearer ghp_your_github_token' }
});
ws.on('open', () => {
ws.send(JSON.stringify({
organization: "your-org",
event_types: ["pull_request"],
user_events_only: false
}));
});
ws.on('message', (data) => {
const event = JSON.parse(data);
console.log(`${event.type}: ${event.url}`);
});
ws.on('open', () => {
ws.send(JSON.stringify({
user_events_only: true // No organization required
}));
});
ws.on('open', () => {
ws.send(JSON.stringify({
pull_requests: [
"https://github.com/your-org/repo/pull/123",
"https://github.com/your-org/repo/pull/456"
]
// organization is optional - will receive PR events if you're a member
}));
});
Note: You can subscribe to up to 200 PRs per connection, and you must be a member of the organization that owns the PRs.
# Subscribe to organization events
go run ./cmd/client -org your-org
# Subscribe to specific PRs (no org required)
go run ./cmd/client -prs "https://github.com/your-org/repo/pull/123,https://github.com/your-org/repo/pull/456"
# Subscribe to your events across all organizations
go run ./cmd/client --user
# Combine filters
go run ./cmd/client -org your-org -user # Your events in a specific org
-webhook-secret="..." # GitHub webhook secret (required)
-allowed-events="..." # Event types to allow or "*" for all
-rate-limit=100 # Requests per minute per IP
-max-conns-per-ip=10 # WebSocket connections per IP
-max-conns-total=1000 # Total WebSocket connections
-letsencrypt # Auto HTTPS via Let's Encrypt
-le-domains="..." # Your domain(s)
- GitHub sends webhook to this service
- Service verifies HMAC signature
- Broadcasts event to WebSocket clients that:
- Have valid GitHub tokens
- Are members of the event's organization
- Have subscribed to that event type
make test # Run tests
make fmt # Format code
make lint # Run linter