Full driving school in a Telegram chat

Full driving school in a Telegram chat

The platform needed to live where the users already were — Telegram. Not a standalone app that requires a download and an account creation flow, but a native experience inside the messenger they open fifty times a day. We built a complete Telegram Mini App: a bot that handles onboarding, payments, and notifications, paired with a full Next.js web application embedded as a Telegram WebApp. The user taps a button in the chat, and they're inside a polished learning interface — home screen, topic browser, exam simulator, road signs catalog, personal profile — all without ever leaving Telegram.

bot, payments, and race conditions

Telegram Mini App home screen with learning modules, progress ring, and daily streak

The bot layer, built with aiogram, manages everything that happens in the chat itself. New users go through a conversational onboarding: choose their language, get a quick tour of features, and land on the Mini App. Subscription payments run through Telegram's native Payments API, which keeps the checkout flow inside the messenger — no redirects to external payment pages, no card form trust issues. But Telegram Payments has its quirks. The payment confirmation comes as a webhook event, and there's a race condition window: the user can close the app after initiating payment but before the webhook arrives. If the backend marks the subscription as active only on webhook receipt, the user might reopen the app and still see "unpaid" for a few seconds. We handle this with an optimistic status update on the client side, backed by a server-side verification that runs on the next app open. If the webhook never arrives (payment actually failed), the optimistic state rolls back.

viewports and native feel

The frontend is a Next.js 14 application styled with Tailwind and animated with Framer Motion and GSAP. State management runs through Zustand for global app state (user profile, subscription, language preference) and TanStack Query for all server data (questions, progress, signs). The UI had to feel native to Telegram — matching the dark/light theme, respecting the platform's safe areas and viewport constraints — while still being a fully functional learning application. Telegram Mini App viewports are notoriously inconsistent: different heights on different devices, different behavior when the keyboard opens, occasional resizing when the Telegram header collapses. We burned more time on viewport edge cases than on any single feature. The solution was a combination of CSS viewport units, a resize observer, and a debounced layout adjustment that prevents the content from jumping while the viewport settles.

reminders across time zones

fortune wheel animation with prize reveal and confetti

Push notification scheduling was another layer of complexity. The bot sends daily study reminders and streak notifications through Telegram messages, but users are spread across multiple time zones within the country. A reminder at 9 AM in Tashkent hits at 10 AM in the eastern regions — acceptable, but a midnight reminder is not. We store each user's timezone (detected during onboarding from the Telegram client data when available, with a manual fallback), and the scheduler groups notification batches by timezone offset. Background tasks handle subscription expiration too: a periodic job checks for subscriptions past their end date and downgrades access automatically, sending a "your subscription has expired" notification with a one-tap renewal button.

fortune wheel and prize economics

The fortune wheel was a gamification feature the client specifically requested to boost daily engagement. Users get one free spin per day, with prizes ranging from bonus AI consultant messages to discount codes for subscription renewal. The engineering challenge wasn't the spinning animation (GSAP handles that beautifully) — it was the prize distribution algorithm. The wheel needs to feel exciting and fair, but the economics need to be sustainable. We implemented a weighted random distribution with daily and weekly caps per prize tier: high-value prizes (extended subscriptions) have both low probability and hard limits, so no matter how many users spin on a given day, the total giveaway stays within budget. The backend determines the prize before the spin animation starts — the frontend animation is purely cosmetic, landing on whichever segment the server already chose.

retention and defensive engineering

The whole system comes together as a surprisingly smooth experience: a user gets a morning reminder, taps it, opens the Mini App, studies a topic, takes a practice exam, spins the wheel, and closes Telegram — all in the same conversational thread where they might also be chatting with friends. The client saw daily active user retention climb significantly after launching the reminder system and fortune wheel together. The takeaway from this build: Telegram Mini Apps are powerful but underspecified. The documentation covers the happy path, but real-world device fragmentation, payment edge cases, and viewport behavior require the same defensive engineering you'd apply to any cross-platform mobile app. Treating it as "just a web page in Telegram" is a fast track to a broken experience.

Stack

Frontend: Next.js 14, React 18, Tailwind CSS, Zustand, TanStack Query, Framer Motion, GSAP

Bot: aiogram, Telegram Payments API, Telegram WebApp SDK

Backend: FastAPI, PostgreSQL, APScheduler-style background tasks

Infra: timezone-aware notification scheduler, subscription lifecycle manager

2026, «VOSGLOS». All rights reserved.