Skip to main content
A real-time GitHub repository activity monitor built with Cloudflare Agents. Demonstrates how to handle webhooks with Agents, verify signatures, store events in SQLite, and stream updates to connected clients.

What it demonstrates

  • Webhook Handling - Receive and process GitHub webhooks
  • Signature Verification - HMAC-SHA256 verification of webhook payloads
  • Agent-per-Repository - Each repo gets its own isolated agent instance
  • Real-time Updates - WebSocket connection streams events as they arrive
  • Event History - Events stored in SQLite for persistence
  • Beautiful Dashboard - Dark-themed UI with live event feed

Architecture

Server Implementation

src/server.ts

How It Works

1

GitHub sends webhook

When an event occurs (push, PR, issue, etc.), GitHub POSTs to /webhooks/github/owner/repo with a signed payload.
2

Worker routes to agent

The Worker extracts the repository name and routes to the appropriate RepoAgent Durable Object (one per repo).
3

Agent verifies signature

The agent verifies the HMAC-SHA256 signature using the webhook secret to prevent spoofing.
4

Event stored in SQLite

The agent parses the event, updates repository stats, and stores the event in SQLite for persistence.
5

State broadcast to clients

The agent’s state is automatically broadcast to all connected WebSocket clients, updating the UI in real-time.

Supported Events

Setup Instructions

1

Install dependencies

2

Configure webhook secret

Copy .dev.vars.example to .dev.vars:
Edit .dev.vars:
3

Start development server

4

Expose local server

Since GitHub needs to reach your webhook endpoint, use ngrok:
Copy the ngrok URL (e.g., https://abc123.ngrok.io).
5

Configure GitHub webhook

  1. Go to your GitHub repository → SettingsWebhooks
  2. Click Add webhook
  3. Configure:
    • Payload URL: https://your-ngrok-url.ngrok.io/webhooks/github/owner/repo
    • Content type: application/json
    • Secret: Same value as GITHUB_WEBHOOK_SECRET
    • Events: Select which events to receive
  4. Click Add webhook
6

Connect to your repo

Open http://localhost:5173, enter your repository name (e.g., cloudflare/agents), and click Connect.

Key Patterns

Webhook Routing

Each repository gets its own agent instance, identified by the sanitized repo name.

Signature Verification

GitHub signs every webhook with HMAC-SHA256. Always verify signatures to prevent spoofing.

Event Storage in SQLite

Events are stored in SQLite and automatically persist across hibernation.

Real-time State Broadcasting

When setState() is called, the new state is automatically broadcast to all connected clients via WebSocket.

Deployment

After deploying:
  1. Set the webhook secret in Cloudflare:
  2. Update your GitHub webhook URL to your deployed worker URL:

Extending This Example

Ideas for enhancements:
  • AI PR Summaries - Use OpenAI to summarize PR diffs
  • Slack Notifications - Forward important events to Slack
  • Multi-Repo Dashboard - Monitor all your repos in one view
  • Custom Alerts - Schedule reminders for stale PRs
  • Webhook Replay - Re-send events for testing

Email Agent

Process emails with secure routing

x402 Payments

HTTP payment gating with verification

Workflows

Multi-step workflows with approval gates

Webhooks Guide

In-depth guide to webhook handling