Skip to main content

Telegram Mini Apps

Bookygram ships two Telegram Mini Apps. Both are React 19, TypeScript and Vite single-page apps that open inside Telegram from their own bot and talk only to the Bookygram API.

Client appProfessional (master) app
Workspaceapps/client_tg_app (bookygram-client-tg)apps/master_tg_app (master-tg-app)
Who uses itPeople booking appointmentsProfessionals running schedules, services and appointments
BotClient botProfessional bot
Channel-auth app IDclientprofessional
Dev serverhttp://127.0.0.1:4178 (fixed port)http://localhost:5173, listening on all interfaces
Preview servervite preview on 4178vite preview on 4173
API access in developmentCalls VITE_API_URL directly (default http://127.0.0.1:3000)Same origin; the dev and preview servers proxy /auth and /professional to the API
BehaviorTelegram client Mini AppTelegram professional Mini App

Connected mode and browser preview​

Each app decides its mode once, when it starts:

  • Connected — Telegram supplied raw signed launch data (Telegram.WebApp.initData). The app signs in through the API and shows only server data. See Mini App sign-in and Mini App OIDC flow.
  • Preview — there is no launch data, for example when the page is opened in a normal browser. The app shows a labeled sample experience kept in localStorage. It never signs in and never calls the API.

The client app loads the two modes as separate bundles (src/ConnectedClientMiniApp.tsx and src/ClientMiniApp.tsx), so the sample data and mock link resolver are never part of the connected bundle. initDataUnsafe is used only for display hints such as the start parameter; it never authenticates anyone.

Commands​

Run these from the app's directory, after npm install at the repository root and a build of packages/contracts:

CommandClient appProfessional app
npm run devVite dev server on 127.0.0.1:4178Vite dev server on :5173
npm run buildtsc --noEmit && vite buildtsc --noEmit && vite build
npm run previewServes dist/ on 127.0.0.1:4178Serves dist/ on :4173
npm testNode tests in tests/ and Vitest in src/Vitest in src/ and Node tests in tests/

Telegram opens Mini Apps only from HTTPS URLs. For a phone, expose the dev or preview server through an HTTPS tunnel. The client dev server allows ngrok hostnames (.ngrok-free.app, .ngrok-free.dev, .ngrok.app, .ngrok.io); the professional server allows any host.

Local bot launchers​

Both apps include small Python launchers for testing a Mini App from a real Telegram chat. They poll the bot with getUpdates, so they cannot run while that bot's webhook points at the API — use a separate test bot or stop the launcher first. See Move Telegram webhooks to the API.

LauncherWhat it does
client_tg_app/bot.py --url <https-url>Sets the chat menu to the given Mini App URL and acknowledges messages. Reads TELEGRAM_BOT_TOKEN from client_tg_app/.env.local. Contact updates are acknowledged but never linked to an API account
client_tg_app/preview_server.pyServes the built dist/ on 127.0.0.1:4179 for a tunnel
master_tg_app/bot/bot.pySets the Графік menu button and answers /start with an Open schedule button. Reads BOT_TOKEN and WEBAPP_URL from master_tg_app/.env
master_tg_app/bot/run_preview.py --port 4175Builds the app, serves it, starts an ngrok tunnel on a fixed development domain, runs bot.py, and rebuilds and reloads open Mini Apps when source files change

These launchers are for development only. They do not authenticate anyone and do not replace the API webhooks.

Source map​

ConcernClient appProfessional app
Entry and mode choicesrc/main.tsxsrc/main.tsx, src/App.tsx
Telegram SDK adaptersrc/telegram.tssrc/telegram.ts
Session (sign-in, refresh, sign-out)src/channelSession.tssrc/channelSession.ts
Business API clientsrc/clientApi.tssrc/professionalApi.ts
Server-backed statesrc/connectedStore.tssrc/connectedStore.tsx
Sample preview datasrc/mockApi.ts, src/account.tssrc/store.tsx

The two channelSession.ts files implement the same session logic; the professional copy only adds signOut to its token-source interface.