An open API service indexing awesome lists of open source software.

https://github.com/brawl345/git-telegram-webhook

Receives GitHub webhook events and sends a formatted message to a Telegram chat
https://github.com/brawl345/git-telegram-webhook

git github golang telegram webhook

Last synced: about 2 months ago
JSON representation

Receives GitHub webhook events and sends a formatted message to a Telegram chat

Awesome Lists containing this project

README

          

# Git Telegram Webhook

Cloudflare Worker that receives GitHub webhook events and sends formatted messages to a Telegram chat.

## Supported Webhook Events

- [`ping`](https://docs.github.com/en/webhooks/webhook-events-and-payloads#ping)
- [`push`](https://docs.github.com/en/webhooks/webhook-events-and-payloads#push)

## Setup

### 1. Install dependencies

```bash
bun ci
```

### 2. Set secrets

```bash
bunx wrangler secret put TELEGRAM_BOT_TOKEN
bunx wrangler secret put GITHUB_WEBHOOK_SECRET
```

| Secret | Description |
|-------------------------|------------------------------------------------------------------------|
| `TELEGRAM_BOT_TOKEN` | API token of your Telegram bot |
| `GITHUB_WEBHOOK_SECRET` | Secret key used to verify GitHub webhook payloads |

### 3. Deploy

```bash
bun run deploy
```

You will receive a URL of the form `https://gitwebhook..workers.dev`.

### 4. Configure GitHub webhook

In your GitHub repo under **Settings → Webhooks → Add webhook**:

- **Payload URL:** `https://gitwebhook..workers.dev?chat_id=`
- **Content type:** `application/json`
- **Secret:** Your `GITHUB_WEBHOOK_SECRET`
- **Events:** Just the `push` event.

---

## Local Development

### Secrets for local development

Wrangler reads local secrets from a `.dev.vars` file (not committed). Copy the template and fill it in:

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

```ini
# .dev.vars
TELEGRAM_BOT_TOKEN=your-bot-token
GITHUB_WEBHOOK_SECRET=your-secret
# Optional: skip signature verification (local only!)
DANGEROUS_SKIP_GITHUB_WEBHOOK_SECRET_CHECK=true
```

### Start the worker locally

```bash
bun run dev
```

The worker will be available at `http://localhost:8787`.

### Testing webhooks locally

Since GitHub cannot reach a local URL, the easiest approach is `curl`.

**Option A – Skip signature verification** (`DANGEROUS_SKIP_GITHUB_WEBHOOK_SECRET_CHECK=true` in `.dev.vars`):

```bash
curl -X POST "http://localhost:8787?chat_id=YOUR_CHAT_ID" \
-H "Content-Type: application/json" \
-H "X-GitHub-Event: ping" \
-H "X-Hub-Signature-256: sha256=dummy" \
--data-binary @test-payloads/ping.json
```

**Option B – Compute the correct signature locally** (no skip needed):

GitHub computes the signature as an HMAC-SHA256 over the raw request body using the webhook secret as the key.

```bash
SECRET="your-webhook-secret"
PAYLOAD_FILE="test-payloads/ping.json"

HASH=$(SECRET="$SECRET" PAYLOAD_FILE="$PAYLOAD_FILE" bun -e "
const { createHmac } = require('crypto');
const { readFileSync } = require('fs');
process.stdout.write(
createHmac('sha256', process.env.SECRET)
.update(readFileSync(process.env.PAYLOAD_FILE))
.digest('hex')
);
")
SIG="sha256=$HASH"

curl -X POST "http://localhost:8787?chat_id=YOUR_CHAT_ID" \
-H "Content-Type: application/json" \
-H "X-GitHub-Event: ping" \
-H "X-Hub-Signature-256: $SIG" \
--data-binary @"$PAYLOAD_FILE"
```

Alternatively, use [Hookdeck CLI](https://hookdeck.com/docs/cli) or [ngrok](https://ngrok.com/) to tunnel to `localhost:8787` and set the tunnel URL as the webhook URL in GitHub.

```bash
# ngrok
ngrok http 8787

# Hookdeck
hookdeck listen 8787 github
```

## Debugging

### `DANGEROUS_SKIP_GITHUB_WEBHOOK_SECRET_CHECK`

When this variable is set to exactly **`true`** or **`1`**, HMAC signature verification is skipped. **Only use this for local development**, never in production.

### View logs

```bash
# Live logs of the deployed worker
bunx wrangler tail
```

---

## Tests

```bash
bun test
```