Who the user is
What it is
When a Mini App opens, Telegram hands it `initData`: who opened it (a unique id, first name, maybe last name and username, language, Premium, whether they let your bot message them, a photo link), where it was opened, the start parameter and the time. It is signed, so your server can prove it came from Telegram. There is no phone number in it.
How to do it
- In the app, send the raw `Telegram.WebApp.initData` string to your server with every request.
- On the server, check it: line up all fields except `hash` alphabetically as… On the server, check it: line up all fields except `hash` alphabetically as `key=value` lines, sign them with HMAC-SHA-256 using a key made from your bot token and the word `WebAppData`, and compare the result with `hash`.
- Check `auth_date`, the moment the app was opened, and refuse old data.
- Only then trust `user.id` as the person's key.
- Need a phone number or permission to message? `requestContact` and `requestWriteAccess` ask the person.
- A partner without your token checks the `signature` field (Ed25519) with… A partner without your token checks the `signature` field (Ed25519) with Telegram's public key; give them `initData` and your bot id.
Watch out
- `initDataUnsafe` is the same data unchecked: fine to show, never to decide on.
- From a keyboard button or inline mode, `initData` is empty.
- The check uses your bot token, so it runs on your server, never in the page.
- The docs set no age limit for `auth_date`; choose your own.
With Gem
Gem's welcome in each project's Mini App asks the person's language and permission to message, and saves their progress. Gem then writes only to people who allowed this project, in their language, with a Stop button on every message.
Sources
- https://core.telegram.org/bots/webapps#validating-data-received-via-the-mini-app
- https://core.telegram.org/bots/webapps#webappinitdata