Files
miti99bot/plans/reports/researcher-260411-0853-wrangler-config-secrets.md
tiennm99 c4314f21df feat: scaffold plug-n-play telegram bot on cloudflare workers
grammY-based bot with a module plugin system loaded from the MODULES env
var. Three command visibility levels (public/protected/private) share a
unified command namespace with conflict detection at registry build.

- 4 initial modules (util, wordle, loldle, misc); util fully implemented,
  others are stubs proving the plugin system end-to-end
- util: /info (chat/thread/sender ids) + /help (pure renderer over the
  registry, HTML parse mode, escapes user-influenced strings)
- KVStore interface with CFKVStore and a per-module prefixing factory;
  getJSON/putJSON convenience helpers; other backends drop in via one file
- Webhook at POST /webhook with secret-token validation via grammY's
  webhookCallback; no admin HTTP surface
- Post-deploy register script (npm run deploy = wrangler deploy && node
  --env-file=.env.deploy scripts/register.js) for setWebhook and
  setMyCommands; --dry-run flag for preview
- 56 vitest unit tests across 7 suites covering registry, db wrapper,
  dispatcher, help renderer, validators, and HTML escaper
- biome for lint + format; phased implementation plan under plans/
2026-04-11 09:49:06 +07:00

2.5 KiB

Researcher Report: wrangler.toml, secrets, and MODULES env var

Date: 2026-04-11 Scope: how to declare secrets vs vars, local dev via .dev.vars, and the list-env-var question.

Secrets vs vars

Kind Where declared Deployed via Local dev Use for
Secret NOT in wrangler.toml wrangler secret put NAME .dev.vars file (gitignored) TELEGRAM_BOT_TOKEN, TELEGRAM_WEBHOOK_SECRET, ADMIN_SECRET
Var [vars] in wrangler.toml wrangler deploy .dev.vars overrides MODULES, non-sensitive config
  • Both appear on env.NAME at runtime — indistinguishable in code.
  • .dev.vars is a dotenv file (KEY=value lines, no quotes required). Gitignore it.
  • wrangler secret put encrypts into CF's secret store — never visible again after set.

[vars] value types

  • Per wrangler docs, [vars] accepts strings and JSON objects, not top-level arrays.
  • Therefore MODULES must be a comma-separated string:
    [vars]
    MODULES = "util,wordle,loldle,misc"
    
  • Code parses with env.MODULES.split(",").map(s => s.trim()).filter(Boolean).
  • Rejected alternative: JSON-string MODULES = '["util","wordle"]' + JSON.parse. More ceremony, no benefit, looks ugly in TOML. Stick with CSV.

Full wrangler.toml template (proposed)

name = "miti99bot"
main = "src/index.js"
compatibility_date = "2026-04-01"
# No nodejs_compat — grammY + our code is pure Web APIs. Smaller bundle.

[vars]
MODULES = "util,wordle,loldle,misc"

[[kv_namespaces]]
binding = "KV"
id = "REPLACE_ME"
preview_id = "REPLACE_ME"

# Secrets (set via `wrangler secret put`):
#   TELEGRAM_BOT_TOKEN
#   TELEGRAM_WEBHOOK_SECRET
#   ADMIN_SECRET

Local dev flow

  1. .dev.vars contains:
    TELEGRAM_BOT_TOKEN=xxx
    TELEGRAM_WEBHOOK_SECRET=yyy
    ADMIN_SECRET=zzz
    
  2. wrangler dev picks up .dev.vars + [vars] + preview_id KV.
  3. For local Telegram testing, expose via cloudflared tunnel or ngrok, then setWebhook to the public URL.

Secrets setup commands (for README/phase-09)

wrangler secret put TELEGRAM_BOT_TOKEN
wrangler secret put TELEGRAM_WEBHOOK_SECRET
wrangler secret put ADMIN_SECRET
wrangler kv namespace create miti99bot-kv
wrangler kv namespace create miti99bot-kv --preview

Unresolved questions

  • Should MODULES default to a hard-coded list in code if the env var is empty? Recommendation: no — fail loudly on empty/missing MODULES so misconfiguration is obvious. /info still works since util is always in the list.