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/
This commit is contained in:
2026-04-11 09:49:06 +07:00
parent e76ad8c0ee
commit c4314f21df
51 changed files with 6928 additions and 1 deletions

View File

@@ -0,0 +1,68 @@
# 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**:
```toml
[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)
```toml
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)
```bash
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.