branch:
README.md
4566 bytesRaw
# GitHub Webhook Dashboard

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

## Features

- **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

## Quick Start

### 1. Install dependencies

```bash
npm install
```

### 2. Configure webhook secret

Copy `.dev.vars.example` to `.dev.vars` and set your webhook secret:

```bash
cp .dev.vars.example .dev.vars
```

Edit `.dev.vars`:

```
GITHUB_WEBHOOK_SECRET=your-secret-here
```

### 3. Start the development server

```bash
npm start
```

### 4. Expose your local server (for testing)

Since GitHub needs to reach your webhook endpoint, use a tool like ngrok:

```bash
ngrok http 5173
```

Copy the ngrok URL (e.g., `https://abc123.ngrok.io`).

### 5. Configure GitHub Webhook

1. Go to your GitHub repository → **Settings** → **Webhooks**
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 (or "Send me everything")
4. Click **Add webhook**

### 6. Connect to your repo

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

## How It Works

### Architecture

```
GitHub → POST /webhooks/github/owner/repo → Worker → RepoAgent (Durable Object)
                                                            ↓
Browser ← WebSocket ← Agent broadcasts state updates ←─────┘
```

### Key Patterns Demonstrated

1. **Webhook Routing**

   ```typescript
   // Route webhooks to the right agent based on repository
   const agentName = sanitizeRepoName(payload.repository.full_name);
   const agent = await getAgentByName(env.RepoAgent, agentName);
   return agent.fetch(request);
   ```

2. **Signature Verification**

   ```typescript
   // Verify GitHub's HMAC-SHA256 signature
   const key = await crypto.subtle.importKey(
     "raw",
     secret,
     { name: "HMAC", hash: "SHA-256" },
     false,
     ["sign"]
   );
   const signature = await crypto.subtle.sign("HMAC", key, payload);
   ```

3. **Event Storage in SQLite**

   ```typescript
   this.sql`INSERT INTO events (id, type, title, ...) VALUES (...)`;
   ```

4. **Real-time State Broadcasting**
   - When a webhook arrives, the agent updates its state
   - Connected clients receive the update via WebSocket

## Supported Events

| Event Type      | Description                         |
| --------------- | ----------------------------------- |
| `push`          | Commits pushed to a branch          |
| `pull_request`  | PR opened, closed, merged, etc.     |
| `issues`        | Issue opened, closed, labeled, etc. |
| `issue_comment` | Comment on an issue or PR           |
| `star`          | Repository starred/unstarred        |
| `fork`          | Repository forked                   |
| `release`       | Release published                   |
| `ping`          | Webhook configured                  |

## Deployment

```bash
npm run deploy
```

After deploying:

1. Set the webhook secret in Cloudflare:

   ```bash
   wrangler secret put GITHUB_WEBHOOK_SECRET
   ```

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

## Project Structure

```
examples/github-webhook/
├── src/
│   ├── server.ts        # RepoAgent + webhook routing
│   ├── client.tsx       # React dashboard
│   ├── github-types.ts  # TypeScript types for GitHub payloads
│   └── styles.css       # Dashboard styles
├── public/
│   └── normalize.css
├── index.html
├── wrangler.jsonc
└── package.json
```