feat(04-03): the /cari command + venue card + OPEN deep link (D-01/D-02/D-10/D-11)
- cari.ts: /cari + /search twin, 128-char pre-search cap (T-04-21), honest no-match refusal (D-13), single sendVenue card with inline OPEN + alternates - deep-link carrier corrected per RESEARCH Pitfall 1: web_app button URL carries ?dest=<plain slug id> — WebAppInfo has only a url field; no crypto - origin from configured MINI_APP_URL only (never user input); blank origin omits the OPEN button instead of guessing (T-04-30) - strings.ts: searchUsage/searchNoMatch/searchQueryTooLong/searchOpenButton/ osmAttribution in en+ms; helpMenu gains the /cari line in both locales - category-only logging law (D-15): four literal rejection categories, query never logged; success path logs nothing - config: MINI_APP_URL in Env + wrangler vars (public, not secret) + .dev.vars.example + docs/CONFIGURATION.md row and sections - bot deps gain @araharah/search (workspace link)
This commit is contained in:
+15
-2
@@ -24,13 +24,14 @@ Configuration surfaces, by kind:
|
||||
|
||||
## Environment variables
|
||||
|
||||
Three variables reach the Worker (`bot/src/config.ts` declares them as a typed `Env` interface);
|
||||
a fourth (`WEBHOOK_URL`) is consumed only by the one-time registration scripts, never by the Worker.
|
||||
Four variables reach the Worker (`bot/src/config.ts` declares them as a typed `Env` interface);
|
||||
a fifth (`WEBHOOK_URL`) is consumed only by the one-time registration scripts, never by the Worker.
|
||||
|
||||
| Variable | Required | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `BOT_TOKEN` | **Required** | none | Telegram Bot API token from @BotFather. Used by `createBot()` in `bot/src/bot/bot.ts` to construct the grammY `Bot`, and by `validateInitData()` in `bot/src/security/initdata.ts` as the HMAC key for Mini App `initData` verification. |
|
||||
| `WEBHOOK_SECRET` | **Required** | none | Value Telegram echoes in the `X-Telegram-Bot-Api-Secret-Token` header on every update. `/telegram/webhook` constant-time-compares it **before** any bot processing or KV access. If missing or empty at request time the route fails closed with `500 Server misconfigured` — grammY's secret check would otherwise accept every request. |
|
||||
| `MINI_APP_URL` | **Required for the deep link** | none | Public origin of the deployed Mini App (e.g. `https://araharah-bot.<account>.workers.dev`) — NOT a secret, so it lives in `bot/wrangler.jsonc`'s `vars`, not in a secret. The `/cari` venue card's OPEN button is built from it: `<MINI_APP_URL>/?dest=<gazetteer id>`. It must equal the Mini App URL registered in @BotFather (Bot API 10.2 enforces the origin). The Worker never derives it from user input — an unvalidated origin would be an open redirect. |
|
||||
| `WEBHOOK_URL` | **Required for the one-time scripts** | none | Full origin + path of the deployed Worker, used by `bot/scripts/set-webhook.mjs` and `bot/scripts/set-menu-button.mjs`. If the value points at the workers.dev root (no path), `set-webhook.mjs` appends `/telegram/webhook` automatically. The Worker never reads this variable. |
|
||||
| `chat_sessions` | **Required (binding)** | n/a | Not an env var but a Cloudflare KV namespace binding. Wired in `bot/wrangler.jsonc` under `kv_namespaces`; every `kv.put()` in `bot/src/kv/sessions.ts` and `bot/src/kv/location-pin.ts` writes through it with an explicit `expirationTtl`. |
|
||||
|
||||
@@ -42,6 +43,9 @@ BOT_TOKEN=
|
||||
WEBHOOK_SECRET=
|
||||
# Full origin + path; set-webhook.mjs auto-appends /telegram/webhook if only an origin is set.
|
||||
WEBHOOK_URL=
|
||||
# Public Mini App origin (not a secret) — lives in bot/wrangler.jsonc "vars" in production.
|
||||
# The /cari venue card's OPEN button deep link is built from it: <MINI_APP_URL>/?dest=<id>.
|
||||
MINI_APP_URL=
|
||||
```
|
||||
|
||||
Script-level precedence: every script in `bot/scripts/` resolves a variable as
|
||||
@@ -120,6 +124,9 @@ print a missing-variable list to stderr and `process.exit(1)` before any network
|
||||
- `KV namespace id` — `bot/wrangler.jsonc` already carries a concrete id for `chat_sessions`; the
|
||||
file's leading comment notes it was filled in after `npx wrangler kv namespace create chat_sessions`.
|
||||
- `WEBHOOK_URL` path segment — auto-derived by `set-webhook.mjs` when the configured origin has no path.
|
||||
- `MINI_APP_URL` — a non-secret configuration value declared in the Worker `Env` and shipped via
|
||||
`bot/wrangler.jsonc`'s `vars` block (public origin, not a secret). When it is blank the `/cari`
|
||||
OPEN button is omitted rather than guessed; the venue card and its alternates still send.
|
||||
- KV TTLs — constants in source, not configuration: `SESSION_TTL_SECONDS = 900`
|
||||
(`bot/src/kv/sessions.ts`) and `PIN_TTL_SECONDS = 300` (`bot/src/kv/location-pin.ts`). Both are
|
||||
pinned by a grep gate in the test suite so no write path can persist without a TTL.
|
||||
@@ -141,6 +148,9 @@ print a missing-variable list to stderr and `process.exit(1)` before any network
|
||||
"not_found_handling": "none"
|
||||
},
|
||||
"run_worker_first": ["/api/*", "/telegram/*"],
|
||||
// Public vars (NOT secrets): the deployed Mini App ORIGIN used to build
|
||||
// the /cari venue card's OPEN deep link (<MINI_APP_URL>/?dest=<id>).
|
||||
"vars": { "MINI_APP_URL": "https://araharah-bot.<account>.workers.dev" },
|
||||
"kv_namespaces": [{ "binding": "chat_sessions", "id": "59f58a54bc44483e89872b20a005a5eb" }]
|
||||
}
|
||||
```
|
||||
@@ -154,6 +164,9 @@ Key notes:
|
||||
- `not_found_handling: "none"` — unmatched paths are not served the SPA `index.html` fallback.
|
||||
- `workers_dev: true` serves on the `<name>.<account>.workers.dev` URL, which is the `WEBHOOK_URL`
|
||||
target.
|
||||
- `vars: { "MINI_APP_URL": ... }` — a **public** origin shipped as a plain var (never a secret):
|
||||
the deployed Mini App origin the `/cari` venue card's OPEN button deep link is built from. It
|
||||
must equal the Mini App URL registered in @BotFather; see the env-var table above.
|
||||
|
||||
<!-- VERIFY: the Cloudflare account subdomain backing `araharah-bot.<account>.workers.dev` is not recorded in the repository. -->
|
||||
|
||||
|
||||
Reference in New Issue
Block a user