feat(noitu): add the noitu HTML5 Telegram game

Serve the BotFather game noitu from the bot's HTTP server under
/games/noitu when GAME_BASE_URL is set. /noitu sends the game, Play
answers with a signed, expiring link, and the server validates every
word against the embedded noitu dictionary (CC BY-SA 4.0), runs the
bot opponent and turn timer, and reports the score with setGameScore.

Modules can now register game-short-name callbacks and HTTP routes.
This commit is contained in:
tiennm99 committed 2026-10-09 14:32:57 +07:00
1 parent fe552f43e4
commit 6f30d13b2d
52 files changed
+42452 -35

No files matched your search

+16 -2
View File
@@ -15,7 +15,7 @@ MONGO_DATABASE=tiennm99bot
# Comma-separated module list. Empty = load every module, including any module
# added later — so list them explicitly when a deployment should only gain a new
# module deliberately.
MODULES=util,misc,random,amlich,wordle,loldle,lol,stock,gold,coin,stats,monkeyd,sticker,alias,blacklist,weather
MODULES=util,misc,random,amlich,wordle,loldle,noitu,lol,stock,gold,coin,stats,monkeyd,sticker,alias,blacklist,weather
# Telegram user id for owner-only commands.
OWNER_ID=
# Comma-separated admin Telegram user ids.
@@ -49,10 +49,24 @@ LOL_PANDASCORE_TOKEN=
# only when running the bot outside compose. Leave blank to fall back to text.
RENDERER_URL=
# Optional public HTTPS base URL for the noitu HTML5 game, e.g.
# https://noitu.example.com. It must route to the bot container's port 8080
# (attach a Coolify domain to the bot service); the game page is served under
# <GAME_BASE_URL>/games/noitu/. Unset or invalid = the game is disabled: /noitu
# still sends the game, Play explains it is not configured, and no /games/
# route exists. See docs/noitu-game.md.
GAME_BASE_URL=
# Optional secret (at least 32 bytes) that signs noitu game links. Unset = a key
# derived from TELEGRAM_BOT_TOKEN, so rotating the bot token invalidates open
# game links. A value shorter than 32 bytes disables the game. Secret.
NOITU_GAME_SECRET=
# ====================== Leave UNSET on self-host ==================
# Defaults are correct for self-host:
# KV_PROVIDER — auto-selects mongodb because MONGO_URL is set
# PORT — defaults to 8080 (internal health server)
# PORT — defaults to 8080 (health server, plus the noitu game
# when GAME_BASE_URL is set)
# TELEGRAM_WEBHOOK_SECRET — long polling has no webhook
# GOLD_VNAPP_API_KEY — gold module auto-fetches + caches the key to Mongo
# Stock/coin/gold URL env overrides are not supported; modules use coded