📱
Хостинг

Telegram Mini App: как создать и разместить на хостинге (HTTPS, BotFather, initData)

08.11.2026
← Все статьи

Telegram Mini App позволяет пользователю работать с полноценным интерфейсом, не выходя из бота: смотреть каталог, собирать корзину, бронировать время или заполнять анкету. Технически это обычная веб-страница, которую Telegram открывает во встроенном браузере и которой через специальный JavaScript-объект даёт доступ к данным пользователя, цветам темы и кнопкам. Значит, для Mini App не нужен какой-то особый «сервер Telegram» — её можно разместить на хостинге, как обычный сайт. Разберём весь процесс на примере приложения для заказов пекарни из Самарканда.

Из чего состоит Mini App

Обычно Mini App состоит из двух частей. Первая — фронтенд: HTML, CSS и JavaScript, написанные на React, Vue или чистом JavaScript. Вторая — бэкенд: API, который принимает заказы, пишет их в базу и проверяет пользователя. В небольших проектах обе части живут на одном домене: например, фронтенд в корне app.misol.uz, а API по адресу app.misol.uz/api/. Такая схема избавляет от лишних проблем с настройкой CORS.

Фронтенд — это набор статических файлов, поэтому его можно разместить практически на любом хостинге. Если бэкенд написан на PHP, хватит и обычного shared-хостинга; если на Node.js или Python, для постоянно работающего процесса удобнее VPS. В примере с пекарней фронтенд собран через Vite, а бэкенд — несколько PHP-скриптов с базой MySQL.

Подготовка хостинга и HTTPS

Адрес Mini App обязательно должен быть HTTPS — обычный HTTP BotFather не примет. Поэтому первый шаг — создать поддомен и выпустить для него SSL-сертификат. На хостинге sayt.uz это делается через кабинет: добавляется поддомен, к нему подключается бесплатный сертификат Let's Encrypt, который автоматически продлевается до истечения срока. Если сертификат не продлится, у пользователей Mini App откроется белым экраном, поэтому автопродление здесь особенно важно.

После сборки фронтенда загрузите файлы из папки dist в корневой каталог поддомена. Если приложение использует маршрутизацию на стороне клиента, все неизвестные адреса нужно перенаправлять на index.html. На хостинге с Apache это делается файлом .htaccess:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/api/
RewriteRule ^ index.html [L]

Фронтенд: работа с telegram-web-app.js

Связь с Telegram устанавливается через официальный скрипт, который добавляет на страницу объект window.Telegram.WebApp. Метод ready() сообщает Telegram, что приложение загрузилось, а expand() раскрывает окно на всю высоту. Главная кнопка внизу управляется через MainButton и выглядит в стиле Telegram.

<script src="https://telegram.org/js/telegram-web-app.js"></script>
<script>
  const tg = window.Telegram.WebApp;
  tg.ready();
  tg.expand();
  tg.MainButton.setText("Оформить заказ").show();
  tg.MainButton.onClick(async () => {
    await fetch("/api/order.php", {
      method: "POST",
      headers: { "Content-Type": "application/json", "X-Init-Data": tg.initData },
      body: JSON.stringify({ items: cart })
    });
    tg.close();
  });
</script>

Вместо того чтобы подбирать цвета вручную, используйте значения tg.themeParams. Тогда Mini App подстроится под светлую или тёмную тему пользователя и не будет выглядеть чужеродно внутри Telegram.

Самое важное: проверка initData на сервере

Фронтенд получает данные о пользователе в двух видах: объект initDataUnsafe и строку initData. Как видно из названия, первому доверять нельзя — любое значение в браузере можно подделать. Правильный путь — отправить строку initData на сервер и проверить её подпись с помощью токена бота. Согласно документации Telegram, ключ получается через HMAC-SHA256 от токена бота с ключом WebAppData, а затем этим ключом подписывается строка из отсортированных полей.

function tg_check_init_data(string $initData, string $botToken): ?array {
    parse_str($initData, $data);
    if (empty($data['hash'])) return null;
    $hash = $data['hash'];
    unset($data['hash']);
    ksort($data);
    $pairs = [];
    foreach ($data as $k => $v) $pairs[] = $k . '=' . $v;
    $secret = hash_hmac('sha256', $botToken, 'WebAppData', true);
    $calc = hash_hmac('sha256', implode("\n", $pairs), $secret);
    if (!hash_equals($calc, $hash)) return null;
    if (time() - (int)($data['auth_date'] ?? 0) > 86400) return null;
    return $data;
}

При верной подписи функция возвращает массив полей; поле user приходит в формате JSON и читается через json_decode. Проверка auth_date защищает от повторного использования старых перехваченных запросов. Токен бота должен храниться только на сервере — например, в конфигурационном файле вне веб-каталога.

Подключение к боту через BotFather

Когда приложение готово, остаётся связать его с ботом. Способов несколько, и их можно комбинировать:

Во время тестов встроенный браузер Telegram может кешировать страницу, поэтому следите, чтобы после новой сборки в именах файлов был хеш — Vite и другие современные сборщики делают это автоматически. Для отладки загляните в официальную документацию: там описано, как включить инструменты веб-разработчика в Telegram Desktop и приложении для Android.

Похожие статьи

🤖 Python-бот 24/7: запуск через systemd и PM2 🧠 Нехватка памяти (OOM): почему завершаются процессы PHP и Python 🧠 «Allowed memory size exhausted»: ошибка памяти PHP и как её правильно решить 🚀 Полностраничный кеш: когда он полезен, а когда мешает
🌐 Язык
🇺🇿 O'zbek 🇺🇿 Ўзбек 🇷🇺 Русский ✓ 🇬🇧 English