A Telegram Mini App that opens AI courses with no sign-up
BiliMind runs on the web, as Android and iOS builds, and inside Telegram. This case study covers the Telegram entry point: a Mini App for the BiliMind AI course generator that opens from a chat, signs the learner in silently and lands them on their Today screen with the lessons and reviews due. There is no registration form. A learner's Telegram account becomes their BiliMind account.
It is deliberately not a chatbot. This is Telegram Mini App development in the strict sense: identity, session handling and a full Nuxt web app running inside Telegram's webview.
Key features
- Silent sign-in — Telegram's signed
initDatais exchanged for a BiliMind session at launch, so the learner never sees a login form. - Signature and replay checks — HMAC-SHA256 verification as specified by Telegram, a constant-time hash comparison and an
auth_datefreshness window of 24 hours by default. - Race-safe accounts — users are found or created by Telegram ID with
createOrFirst, so two simultaneous launches never produce duplicate accounts. - One account model — a new Telegram user gets a personal "organization of one" and a Sanctum token, and the response mirrors the email login payload, so the frontend handles both paths the same way.
- Deep links respected — launches that land on the home, login or registration page go straight to Today, while links to a shared course or a specific lesson open where they point.
- No cost for web visitors — the Telegram SDK loads on demand only after a Mini App launch is detected, instead of as a blocking script on every page.
How it works
Laravel backend
POST /api/auth/telegram has to be public, since it is the endpoint that mints the token, so it shares the rate limiter used by login and registration. TelegramService sorts the payload fields into a data-check string, derives the secret key from the bot token, compares hashes with hash_equals and treats a missing auth_date as stale. When the user already exists, their cached Telegram username is refreshed and a missing personal organization is repaired. A development-only bypass lets the flow run locally without a real bot and stays off in production. The find-or-create-by-Telegram-ID pattern is the same one we use in Bronjoy.
Nuxt frontend
Telegram's launch signals are fragile. The #tgWebAppData hash disappears on the first client-side navigation, and window.Telegram.WebApp.initData exists only after the SDK has run. We persist the Mini App context the moment either signal appears, in a durable cookie that outlives the 30-day auth cookie. That way a reopened webview holding a stale token is re-authenticated through initData instead of being bounced to the login form. Telegram's webview has its own cookie jar, so the flag never leaks into a normal browser.
A client plugin runs before the global auth guard, concurrent callers share a single in-flight sign-in request, and the app calls ready() and expand() to take the full viewport height. Everything degrades to no-ops in a regular browser or the native mobile shell.
Our role
We designed and built the Mini App sign-in end to end, including the Laravel endpoint and validation service and the Nuxt detection and session logic, as part of our in-house BiliMind product.
Related work
The course generator itself is covered in the main BiliMind case study. This work sits within our Telegram bot development and web app development services, and the Bronjoy Telegram booking bot shows a bot and Mini App built for bookings.



