feat(telegram): add bot + mini app MVP for voice calls#158
Draft
yagudaev wants to merge 6 commits into
Draft
Conversation
216655a to
7b11b3b
Compare
yagudaev
commented
Apr 19, 2026
|
|
||
| const app = express() | ||
|
|
||
| app.use(express.json({ limit: "32kb" })) |
Owner
Author
There was a problem hiding this comment.
big enough for ai conversations?
Two new workspaces share a single deployment; the relay stays per-user. The bot stores each user's relay URL and opens a mini app webview that talks to their relay directly, reusing the existing Gemini session pipeline with a new initData-based auth path. - relay-server: POST /auth/telegram validates Telegram initData HMAC (timing-safe) and mints short-lived signed tickets; session.config accepts tickets alongside the legacy RELAY_API_KEY. No existing clients change. - telegram-bot: grammY bot with /call, /setrelay, /getrelay, /forget; per-user relay URLs in better-sqlite3; menu button registered. - telegram-miniapp: static Vite + TS webview reusing desktop's audio-engine (AudioWorklet emitted as a separate asset for iOS WKWebView compatibility); vanilla port of useRealtime without React. Tests: 9 auth unit + 9 relay integration (spawns relay, exercises full auth + WS handshake + CORS + tamper/replay rejection) + 10 bot store; mini app builds clean. Browser-level E2E verified via Playwright against a live Gemini session. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Show agent name in transcripts via ?startapp=<Name> (from agent's /call reply); falls back to bot first_name from /auth/telegram response. - Cache auth ticket in-memory for 4 min to skip re-auth on quick restarts. - Bump initData freshness window 5min -> 1h (fixes 401 on restart after idle; matches standard Telegram practice). - Remove telegram-bot workspace: OpenClaw owns the bot's long-poll, so a sidecar grammY bot isn't viable. /call now flows through OpenClaw agent instructions + customCommands; mini app is launched via plain t.me/<bot>/<shortname> URL that Telegram auto-renders as a pill. - Vite preview allowedHosts for .ts.net (Tailscale Funnel). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- rate-limit /auth/telegram at 30 req/min/IP to block token-guess floods - swap Math.random() for randomBytes() in integration test key - simplify toBase64Url trailing-= strip to avoid polynomial regex warning - document HMAC-as-MAC (not password hash) with suppression comment - ship telegram-miniapp/CLAUDE.md docs Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- new Starlight page covering architecture, OpenClaw setup, BotFather flow, ticket auth, Funnel dev, gotchas - sidebar + landing grid updated - test-telegram-auth: update assertion to match 1h freshness window (caught by codex review) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2dab677 to
af9a764
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
telegram-miniappworkspace): Vite + TS static webview, AudioWorklet on its own thread (emitted as a separate asset for iOS WKWebView), reuses desktop's audio pipeline. Launched viat.me/<bot>/<shortname>URL that Telegram auto-renders as a "Launch" pill.POST /auth/telegramvalidates TelegraminitDataHMAC and mints short-lived signed tickets.session.configaccepts tickets alongside the existingRELAY_API_KEY. Desktop/mobile paths unchanged.?startapp=<Name>from the agent's/callreply, falling back to the bot's first_name fromgetMe.OpenClaw integration
OpenClaw (
openclaw/openclaw) owns the bot's long-poll connection, so a sidecar bot process on the same token isn't viable. This PR removes the originally-plannedtelegram-botworkspace entirely. The/callUX instead flows through two small OpenClaw-side changes (made outside this repo, on the Hetzner gateway):/call, reply withhttps://t.me/<bot>/<shortname>?startapp=<AgentName>and nothing else. Telegram renders the URL as a Launch pill.calltochannels.telegram.customCommandsin the OpenClaw config, then restart the gateway to pushsetMyCommands.Note: OpenClaw's inline-keyboard builder currently filters out
web_appbuttons (onlycallback_datais supported). Using a plain-URL pill sidesteps that limitation.Architecture
Static mini app served publicly over HTTPS; per-user relay (bot + mini app are shared). The mini app reads
?relay=<url>baked into the Web App URL registered with@BotFather, POSTsinitDatato that relay to get a ticket, and opens a WSS session — same protocol as desktop/mobile.Security notes
{tgUid, exp}withRELAY_API_KEYas secret; 5 min TTL; raw relay key never leaves the server./auth/telegramonly.Test plan
relay-server/test/test-telegram-auth.ts(HMAC freshness, tamper rejection, ticket roundtrip)relay-server/test/test-telegram-integration.ts(spawns relay, exercises /auth/telegram + WS handshake + CORS preflight + legacy-key regression)/callvia OpenClaw, Launch pill → mini app opens → voice conversation works with agent-name transcriptsFollow-ups (out of MVP)
TELEGRAM_BOT_TOKENS=t1,t2,t3) so one relay can serve Pam + Holly + Buffet. Currently one bot per relay instance.web_appbutton support toextensions/telegram/src/inline-keyboard.tsfor nicer UX than the plain-URL pill.🤖 Generated with Claude Code