Telegram Mini App

6 июня 2026 · ~13 мин чтения

мессенджер веб javascript мобильные-приложения инструмент

Telegram Mini App

Telegram Mini App (ранее Web App) — это обычная веб-страница (HTML/CSS/JS), которая открывается внутри Telegram через встроенный браузер и автоматически получает данные об аккаунте пользователя через специальный SDK, без регистрации и логина.

История

Telegram несколько раз переименовывал технологию, прежде чем она стала тем, чем является сейчас.

Проблема, которую решали: боты в мессенджерах умели только слать текст, картинки и кнопки. Для нормального UI — выбора квартиры, оформления заказа, квиза с фильтрами — этого катастрофически мало. Mini Apps дали полноценный веб-интерфейс без необходимости делать нативное мобильное приложение или уводить пользователя в браузер.

Что это такое

Представь обычный сайт. Ты открываешь его в браузере — он не знает, кто ты. Нужно зарегистрироваться или войти через Google/Facebook.

Mini App — тот же сайт, но открытый внутри Telegram. Ключевое отличие: Telegram «рукопожатием» передаёт сайту данные пользователя ещё до того, как страница что-либо сделала. Не нужен логин, не нужна регистрация — пользователь уже авторизован через свой Telegram-аккаунт.

Технически мини-приложение получает доступ к объекту window.Telegram.WebApp, через который читает:
- initDataUnsafe.user — объект с id, именем, username, языком пользователя;
- initDataUnsafe.start_param — произвольный параметр, переданный при открытии (например, id квартиры или рекламной кампании);
- initData — сырая подписанная строка для проверки на сервере.

И вызывает методы:
- WebApp.expand() — развернуть на весь экран;
- WebApp.ready() — сообщить Telegram, что загрузка завершена (убрать плейсхолдер);
- WebApp.showAlert(), WebApp.showPopup() — показать диалоги в стиле Telegram;
- WebApp.HapticFeedback — тактильная обратная связь на мобильных.

Чем отличается от iframe: обычный iframe встраивает страницу внутрь другой страницы, но из-за политики SOP (Same-Origin Policy) они изолированы — родительская страница не может просто так передать данные во вложенный домен. В Telegram Mini App «родительская» часть — это нативный код Telegram, который имеет прямой доступ к WebView и инжектирует переменные в JS-среду страницы в обход браузерных ограничений.

Чем отличается от PWA (Progressive Web App): PWA — это способ «установить» сайт как приложение на телефон, он работает в браузере телефона и не привязан к мессенджеру. Mini App работает только внутри Telegram/MAX, зато автоматически знает пользователя без дополнительных шагов.

Аналогии из жизни

Аналогия 1: Корпоративный пропуск

В уличном кафе ты пришёл с улицы — тебя не знают. В корпоративной столовой ты прикладываешь пропуск — и кассир сразу видит твоё имя, отдел, баланс карточки. Mini App — вторая ситуация: Telegram выступает «вахтёром», который передаёт столовой информацию о тебе.

Где ломается: пропуск можно подделать. Поле initDataUnsafe лежит в открытом виде в JS и легко подменяется прямо в браузере. Если сервер принимает данные оттуда без проверки подписи — злоумышленник может выдать себя за любого пользователя.

Аналогия 2: Встроенный киоск в торговом центре

ТЦ (Telegram) ставит в своём холле киоск (Mini App). Управляет киоском арендатор (разработчик), но физически он стоит внутри ТЦ. Посетители находят киоск через ТЦ, а не ищут его адрес самостоятельно.

Где ломается: ТЦ устанавливает правила. Если Telegram забанит бота, заблокирует домен или изменит API — арендатор ничего не сделает. Зависимость от платформы — главный архитектурный риск любого Mini App.

Аналогия 3: Телефонный оператор-секретарь

Раньше, чтобы соединить клиента с нужным менеджером, секретарь спрашивал имя и переключал. Telegram — автоматический секретарь: он устанавливает соединение между твоим приложением и пользователем, уже зная обоих и не спрашивая имя второй раз.

Где ломается: секретарь всё слышит. Telegram технически знает, какие Mini Apps открывает пользователь и как долго. Для чувствительных бизнес-данных это нужно учитывать в модели угроз.

Как это работает

Пошагово — от клика по ссылке до работающего приложения.

Шаг 1. Пользователь открывает Mini App

Способов несколько:
- Кнопка меню бота (Menu Button) — постоянно видна в чате бота;
- Inline-кнопка в сообщении — бот отправляет сообщение с кнопкой типа web_app;
- Прямая ссылка: https://t.me/BotUsername/AppName?startapp=some_paramsome_param окажется в start_param;
- Ссылка на бота с командой: https://t.me/BotUsername?start=some_data.

Шаг 2. Telegram подготавливает initData

Telegram генерирует URL-encoded строку с данными пользователя:

user={"id":123456,"first_name":"Павел","language_code":"ru"}&start_param=apt_42&hash=abc123...

Поле hash — HMAC-SHA256 подпись всей строки, вычисленная с токеном бота как секретом. Без токена подделать hash нельзя. Это механизм, позволяющий серверу убедиться, что данные пришли от Telegram, а не выдуманы злоумышленником.

Шаг 3. WebView открывается

Telegram открывает URL в своём встроенном браузере:
- Android — Chrome WebView (Chromium);
- iOS — WKWebView (движок Safari);
- Desktop — встроенный Chromium-движок;
- web.telegram.org — обычный iframe в браузере пользователя.

Шаг 4. Инжекция SDK

На мобильных клиентах Telegram инжектирует объект window.Telegram.WebApp напрямую в среду WebView до выполнения скриптов страницы. Это значит, что даже до загрузки telegram-web-app.js объект уже существует.

На web.telegram.org такой возможности нет, поэтому SDK грузится через отдельный <script src="...telegram-web-app.js">. Скрипт, подгрузившись, создаёт window.Telegram.WebApp с нуля.

Это важный нюанс: в мобильном клиенте ты можешь читать window.Telegram.WebApp сразу при запуске любого скрипта. В веб-версии — только после загрузки SDK.

Шаг 5. Приложение инициализируется

function initApp() {
  const tg = window.Telegram?.WebApp;
  if (tg) {
    tg.ready();   // Telegram убирает загрузочный экран
    tg.expand();  // разворачиваем на весь экран
  }
  const userId = tg?.initDataUnsafe?.user?.id;
  const param  = tg?.initDataUnsafe?.start_param;
  // дальше — загружаем данные, строим UI
}

Никогда не доверяй initDataUnsafe на сервере

initDataUnsafe — разобранный JSON на клиентской стороне. Его можно изменить в консоли браузера за секунду. Для серверной авторизации передавай сырую строку initData в заголовке запроса и проверяй HMAC-подпись, используя токен бота как ключ. Телеграм описывает алгоритм в документации.

Шаг 6. Загрузка внешних скриптов и белый экран

Если в <head> страницы стоит:

<script src="https://telegram.org/js/telegram-web-app.js"></script>

без атрибута async, браузер блокирует рендер страницы до полной загрузки скрипта. Если Telegram CDN доступен быстро — всё хорошо. Если медленно (например, с российских IP в некоторых сетях) — пользователь видит белый экран несколько секунд или дольше.

Атрибут async говорит браузеру: «Загружай скрипт параллельно, не блокируй рендер»:

<script src="https://telegram.org/js/telegram-web-app.js" async></script>

Но тогда нужно учесть: скрипт может загрузиться после выполнения app.js. Решение — вызвать функцию инициализации Telegram-контекста дважды: сразу при старте (если SDK уже есть — mobile-клиент) и внутри init() после DOMContentLoaded (если SDK появится позже — web-версия).

Где встречается в обычной жизни

  1. Онлайн-оплата прямо в боте — когда нажимаешь кнопку «Купить» в боте и перед тобой появляется форма с полями карты — это или нативный Telegram Payments, или сторонний Mini App.
  2. Квизы и анкеты — «Помощник по подбору квартиры от застройщика» в боте открывает мини-приложение с фильтрами, схемами этажей, 3D-планировками.
  3. Розыгрыши и игры — «Нажми кнопку быстрее» или «Собери монеты» — в основе Mini App с JavaScript-логикой.
  4. Заказ еды — Delivery Club, «ВкусВилл» и другие тестировали приём заказов прямо в Telegram без установки нативного приложения.
  5. Реферальные программы — «Пригласи друга и получи бонус» с интерфейсом начисления бонусов: обычных кнопок бота для этого не хватает, а делать мобильное приложение ради одного экрана — дорого.

Где встречается в IT и бизнесе

  1. Лидогенерация и онбординг клиентов — провести пользователя через анкету внутри мессенджера, не уводя его в браузер. Конверсия в заполнение выше, потому что нет барьера «открыть отдельную вкладку».
  2. Внутренние инструменты компании — корпоративный бот с Mini App для согласования отпусков, статусов задач, дашборда KPI — можно без выхода из рабочего чата.
  3. E-commerce в СНГ — в регионах, где Telegram — основной мессенджер, Mini App заменяет мобильное приложение целиком: каталог, корзина, оплата.
  4. Web3/DeFi — криптокошельки (TON Wallet, Tonkeeper), NFT-маркетплейсы, P2P-биржи работают как Mini Apps: пользователь не уходит из экосистемы мессенджера.
  5. Геймификация — рейтинги, челленджи, опросы NPS с красивым UI — дешевле и быстрее сделать как Mini App, чем как нативное приложение.

Кто пользуется

Альтернативы и конкуренты

PWA (Progressive Web App)
- Плюсы: не зависит от Telegram, работает в любом браузере, можно «установить» на главный экран смартфона.
- Минусы: нет автоматической авторизации через мессенджер, нет готовой аудитории — пользователи должны найти сайт самостоятельно.

Нативное мобильное приложение (iOS/Android)
- Плюсы: полный доступ к железу телефона, лучший UX, push-уведомления без мессенджера.
- Минусы: нужна установка (серьёзный барьер для разовых задач), разработка дороже в 3–5 раз, App Store и Google Play могут отказать в публикации.

VK Mini Apps
- Плюсы: аналогичная концепция для аудитории ВКонтакте.
- Минусы: только ВКонтакте, минимальная международная аудитория.

MAX Mini Apps
- Плюсы: российский мессенджер, не зависит от западных блокировок Telegram, схожий SDK.
- Минусы: аудитория значительно меньше Telegram, SDK менее зрелый и хуже документирован.

Двойная поддержка (Telegram + MAX) — это дёшево

Оба SDK используют схожий интерфейс: window.Telegram.WebApp и window.WebApp. Логика простая: проверяешь наличие window.Telegram.WebApp — используешь его (Telegram), иначе — window.WebApp (MAX). Это несколько часов работы, а охват удваивается.

Когда НЕ стоит использовать

1. Сложный мультимедиа-контент
Потоковое видео, AR, тяжёлые 3D-модели — WebView в Telegram работает хуже нативного браузера: меньше оперативной памяти, ограниченная поддержка WebGL, агрессивное фоновое ограничение. Для таких задач нужно нативное приложение.

2. Аудитория не в Telegram
Если твои клиенты — люди старшего возраста, не использующие мессенджеры, или корпоративная среда с запретом на Telegram — Mini App физически не достучится до них. Нужен универсальный канал: сайт, email, SMS.

3. Нужна офлайн-работа
Mini App — это веб-приложение, интернет обязателен. Service Workers в Telegram WebView поддерживаются частично и нестабильно (по состоянию на 2025 год). Для полевых сотрудников, складских операций, зон с плохим покрытием — выбирай нативное решение или PWA с надёжным офлайн-режимом.

Связанные понятия

Литература и источники

  1. Официальная документация Telegram Mini Appscore.telegram.org/bots/webapps (англ.). Полное описание API, initData, методов WebApp и жизненного цикла приложения.
  2. Telegram Bot API Referencecore.telegram.org/bots/api (англ.). Как открывать mini-app через inline-кнопки: тип InlineKeyboardButton с полем web_app.
  3. TON Documentation: Mini Appsdocs.ton.org (англ.). Специфика mini-apps в TON-экосистеме: встроенные платежи, TON Connect.
  4. Хабр: «Разработка мини-приложений для Telegram» — ищи по этому запросу на habr.com. Несколько хороших разборов 2022–2024 годов с примерами кода на Python и JS.
  5. Библиотека python-telegram-bot (GitHub) — в примерах есть шаблоны для ботов с mini-app: github.com/python-telegram-bot/python-telegram-bot.
  6. MDN Web Docs: «async attribute»developer.mozilla.org, статья «script: The Script element» — объясняет разницу между async, defer и синхронной загрузкой скриптов.

Где встретилось у меня

Работал с BrendBot — мини-приложением для квалификации потенциальных покупателей недвижимости. Приложение работает в обоих мессенджерах: Telegram и MAX. Пришёл баг: при открытии по ссылкам из рекламной кампании на некоторых устройствах появлялся белый экран. Причина оказалась в том, что telegram-web-app.js грузился синхронно — без async — и блокировал рендер страницы. После добавления async и небольшого рефакторинга логики определения платформы (из анонимного IIFE в именованную функцию, которую вызываем дважды) белый экран исчез.

Краткое резюме