799e10dcc2fcc9c1660a7a481df58dd04962857b
Some checks failed
Docker Build / build-and-push-image (push) Has been cancelled
Adds the async dispatch infrastructure : - Postgres pool + embedded migration (CREATE TABLE/INDEX IF NOT EXISTS gateway_jobs). Auto-applied at boot. lib/pq driver (matches webapp convention). - queue.go : Enqueue (idempotent on UNIQUE(bot_slug, update_id) — handles Telegram redelivery), Pop with FOR UPDATE SKIP LOCKED, MarkDone, MarkFailed with exponential backoff (30s → 2m → 10m → 1h → dead at 5). - worker.go : goroutine that drains the queue, dispatches via the same Handler interface as sync, schedules retries on failure, notifies the user once when a job goes to dead. - BotConfig gains `async: bool`. Registry refuses bots with async=true if DATABASE_URL is unset (queue=nil). - Server : when bot.Async, the webhook ack is immediate ; the update payload is enqueued for the worker. When DATABASE_URL is unset (current default), queue/worker stay disabled and only sync handlers (echo, http, auth) work — no breaking change to the running cluster. Refs ~/.claude/plans/pour-les-notifications-on-inherited-seal.md § Phase 2.
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
echohandler, end-to-end flow validated. Phase 2 (planned):httpforward handler + Postgres-backed durable queue. Phase 3 (planned): asyncshell/script/ollamahandlers.
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 pathkvv2/telegram-gateway/configvia Vault Secrets Operator.
Cluster deploy
- Image:
gitea.arcodange.lab/arcodange/telegram-gateway:<tag> - Helm chart:
chart/ - ArgoCD app:
telegram-gateway(infactory/argocd/values.yaml) - Public URL:
https://tg.arcodange.fr(Cloudflare déjà configuré pour router*.arcodange.frvers 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+ viavault.enabled: truedanschart/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
Languages
Go
96.2%
Smarty
1.9%
Makefile
1.4%
Dockerfile
0.5%