https://github.com/hugobatista/tailhoogram
Send Tailscale webhook events to Telegram using Cloudflare Workers
https://github.com/hugobatista/tailhoogram
audit cloudflare cloudflare-workers events security tailnet tailscale telegram webhook
Last synced: about 1 month ago
JSON representation
Send Tailscale webhook events to Telegram using Cloudflare Workers
- Host: GitHub
- URL: https://github.com/hugobatista/tailhoogram
- Owner: hugobatista
- License: gpl-3.0
- Created: 2026-02-16T10:56:38.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2026-05-25T18:40:56.000Z (about 1 month ago)
- Last Synced: 2026-05-25T20:29:55.941Z (about 1 month ago)
- Topics: audit, cloudflare, cloudflare-workers, events, security, tailnet, tailscale, telegram, webhook
- Language: Python
- Homepage:
- Size: 59.6 KB
- Stars: 5
- Watchers: 0
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
[](https://go.hugobatista.com/gh/tailhoogram/releases)
[](https://go.hugobatista.com/gh/tailhoogram/actions/workflows/test.yml)
[](https://go.hugobatista.com/gh/tailhoogram/actions/workflows/lint.yml)
[](https://deploy.workers.cloudflare.com/?url=https://github.com/hugobatista/tailhoogram)
# TailHoogram
**Sends Tailscale events to Telegram using Cloudflare Workers**
Tailscale natively supports Slack, Discord, Google Chat, and Mattermost—but not Telegram.
**TailHoogram bridges that gap with secure webhook processing**, sending the event to Telegram.
Can be deployed on Cloudflare Workers, even with the free tier.
## Quick Start
**Prerequisites:** Python 3.12+, `uv`, Tailscale account, Telegram bot token
```bash
# Install
uv sync --extra dev
# Configure (.env file)
TAILSCALE_WEBHOOK_SECRET=your-secret
TELEGRAM_BOT_TOKEN=your-bot-token
TELEGRAM_CHAT_ID=your-chat-id
# Run locally with pywrangler
uv run pywrangler dev
# Deploy to Cloudflare Workers
uv run pywrangler secret put TAILSCALE_WEBHOOK_SECRET
uv run pywrangler secret put TELEGRAM_BOT_TOKEN
uv run pywrangler secret put TELEGRAM_CHAT_ID
uv run pywrangler deploy
```
Note: If you use a system keyring, you can skip the `.env` file step and use [kleys](https://go.hugobatista.com/gh/kleys) to automatically load secrets from your vault.
```bash
# Run with secrets from vault
kleys uv run pywrangler dev
```
**Tailscale Setup:**
1. Go to Tailscale admin → Webhooks
2. Create webhook pointing to `https://your-domain/events`
3. Copy the secret and set as `TAILSCALE_WEBHOOK_SECRET`
4. Hit "Test" to verify
## Testing locally
Test your webhook endpoint locally using the included test script:
```bash
# Test default endpoint (localhost:8000)
python test-endpoint.py
# Test custom endpoint
python test-endpoint.py --endpoint example.com:8080
```
The script automatically loads `TAILSCALE_WEBHOOK_SECRET` from your `.env` file and sends a properly signed test webhook.
## Environment Variables
| Variable | Description | Required |
|----------|-------------|----------|
| `TAILSCALE_WEBHOOK_SECRET` | Secret from Tailscale webhook setup | Yes |
| `TELEGRAM_BOT_TOKEN` | Bot token from @BotFather | Yes |
| `TELEGRAM_CHAT_ID` | Target chat ID | Yes |
## Security
- **HMAC-SHA256 signature verification** on every webhook
- **Replay protection** (5-minute timestamp window)
- **Firewall recommendation:** Restrict to Tailscale IP ranges ([docs](https://tailscale.com/docs/reference/faq/firewall-ports))
## Example Notification
```
🔔 Tailscale Event
Type: policyUpdate
Tailnet: hugo-tailscale
Message: Tailnet policy file updated
Time: 2026-02-15T09:33:14.089607+00:00
Details:
url: https://login.tailscale.com/admin/acls
actor: hugobatista
```
## Using VSCode Dev Containers
This project includes a VSCode Dev Container configuration for easy local development. It sets up a consistent environment with all dependencies installed.
### SELinux Users (ex: Fedora, RHEL, CentOS)
If you encounter permission issues with the dev container, you may need to adjust your SELinux policies, by relabeling the project directory with s0 and container_file_t contexts:
```bash
sudo chcon -Rt container_file_t -l s0 ./tailhoogram
# this command recursively changes the context of all files in the project directory to be accessible by the container
```
To restore the original context after development, you can use:
```bash
sudo restorecon -RvF ./tailhoogram
# this command recursively restores the default SELinux context for all files in the project directory
```