Gabriel Radureau d8b102fbf9
All checks were successful
Docker Build / build-and-push-image (push) Successful in 42s
server: don't reject Telegram updates with unknown fields
DisallowUnknownFields rejected real Telegram payloads (entities, from,
date, etc. that our minimal structs don't cover). Lenient decode is the
right default for an upstream webhook we don't control.
2026-05-09 13:06:40 +02:00
2026-05-09 12:51:16 +02:00
2026-05-09 12:23:59 +02:00
2026-05-09 12:23:59 +02:00
2026-05-09 12:23:59 +02:00
2026-05-09 12:23:59 +02:00
2026-05-09 12:23:59 +02:00
2026-05-09 12:23:59 +02:00
2026-05-09 12:23:59 +02:00
2026-05-09 12:23:59 +02:00

telegram-gateway

Telegram webhook gateway for the Arcodange home lab. Replaces polling-based bots (e.g. those scheduled in Cowork) with direct webhook delivery from Telegram, routed to per-bot handlers running on the k3s cluster.

Phase 1 (MVP): single sync echo handler, end-to-end flow validated. Phase 2 (planned): http forward handler + Postgres-backed durable queue. Phase 3 (planned): async shell / script / ollama handlers.

See the design doc at ~/.claude/plans/pour-les-notifications-on-inherited-seal.md.

Architecture (current)

Telegram → Cloudflare Tunnel (tg.arcodange.fr) → Service telegram-gateway:8080
        → /bot/<slug> → secret_token check → handler dispatch → Bot API sendMessage

Routes

Method Path Description
GET /healthz Liveness probe
GET /readyz Readiness probe
POST /bot/{slug} Telegram webhook entry (validates secret)

Local dev

# 1. Provide a config + env
export BOT_FACTORY_TOKEN='8737289837:…'                # from @BotFather
export BOT_FACTORY_SECRET=$(openssl rand -hex 32)

# 2. Run
make run                                                # uses bots.example.yaml

# 3. Smoke a webhook
curl -X POST -H "X-Telegram-Bot-Api-Secret-Token: $BOT_FACTORY_SECRET" \
     -H 'Content-Type: application/json' \
     -d '{"update_id":1,"message":{"chat":{"id":<your-chat-id>},"text":"hi"}}' \
     http://localhost:8080/bot/factory

Set / delete webhook

# Once the gateway is reachable at https://tg.arcodange.fr:
export BOT_FACTORY_TOKEN=export BOT_FACTORY_SECRET=…
make setwebhook SLUG=factory BASE_URL=https://tg.arcodange.fr
make deletewebhook SLUG=factory

Configuration

  • Routing (non-secret): YAML at $CONFIG_PATH (default /etc/telegram-gateway/bots.yaml, mounted from a ConfigMap in cluster).
  • Secrets: per-bot env vars BOT_<UPPER_SLUG>_TOKEN, BOT_<UPPER_SLUG>_SECRET. Sourced from Vault path kvv2/telegram-gateway/config via Vault Secrets Operator.

Cluster deploy

  • Image: gitea.arcodange.lab/arcodange/telegram-gateway:<tag>
  • Helm chart: chart/
  • ArgoCD app: telegram-gateway (in factory/argocd/values.yaml)
  • Public URL: https://tg.arcodange.fr (Cloudflare déjà configuré pour router *.arcodange.fr vers le home lab → Traefik route par Host)
  • Secrets Phase 1 : kubectl create secret generic telegram-gateway-bots … (sans Vault). Migration vers Vault Secrets Operator en Phase 2+ via vault.enabled: true dans chart/values.yaml.

Voir DEPLOY.md pour la procédure end-to-end.

Layout

.
├── main.go                  # bootstrap, subcommand dispatch
├── server.go                # HTTP routes
├── middleware.go            # secret validation, recover, access log
├── handlers.go              # Handler interface + Registry
├── handler_echo.go          # echo handler
├── telegram.go              # Telegram Bot API client
├── telegram_types.go        # Update / Message structs
├── config.go                # YAML routing config + per-bot env merge
├── setwebhook.go            # CLI subcommands (setwebhook / deletewebhook)
├── chart/                   # Helm chart
└── .gitea/workflows/        # CI: docker build → gitea registry
Description
No description provided
Readme 167 KiB
Languages
Go 96.2%
Smarty 1.9%
Makefile 1.4%
Dockerfile 0.5%