Интеграция Telegram Mini Apps в бота: от кнопки до полноценного приложения

Telegram Mini Apps превратили мессенджер в платформу: внутри бота теперь работает полноценный фронтенд с платежами, датчиками, геолокацией и хранилищем данных. В этом руководстве — полный цикл интеграции Mini App в Telegram-бота на Python: от первой кнопки до приёма оплаты через Stars. Все примеры актуальны для Bot API 9.5 (март 2026)

Содержание
  1. Зачем интегрировать Mini App в бота
  2. Бот — это бэкенд, Mini App — это фронтенд
  3. Примеры использования
  4. Mini App без бота невозможен
  5. Быстрый старт: минимальный пример
  6. Шаг 1. Создание бота и регистрация Mini App
  7. Шаг 2. Три способа открытия Mini App
  8. Шаг 3. Полный рабочий пример на python-telegram-bot
  9. Аналогичный пример на aiogram 3.x
  10. Приём данных от Mini App
  11. Способ 1. Через sendData() (клиентский)
  12. Способ 2. Через бэкенд (рекомендуется)
  13. Валидация initData (HMAC-SHA256)
  14. Новые возможности Bot API 9.0–9.5 для Mini Apps
  15. Bot API 9.0 (март 2025): бизнес-боты и подарки
  16. Bot API 9.1: чеклисты и расширенные подарки
  17. Bot API 9.2: прямые сообщения и рекомендации
  18. Bot API 9.3 (декабрь 2025): sendMessageDraft для ИИ-ботов
  19. Bot API 9.4: цветные кнопки и премиум-эмодзи
  20. Bot API 9.5 (март 2026): форматирование, теги, sendMessageDraft для всех
  21. Платежи через Stars в Mini App
  22. Шаг 1. Создание ссылки на инвойс (Python)
  23. Шаг 2. Открытие инвойса из Mini App (JavaScript)
  24. Шаг 3. Обработка успешной оплаты (Python)
  25. Возврат средств
  26. Fullscreen-режим
  27. Запрос полноэкранного режима
  28. Выход из полноэкранного режима
  29. Безопасные зоны (Safe Area)
  30. Работа с датчиками
  31. Акселерометр
  32. Гироскоп
  33. Ориентация устройства (DeviceOrientation)
  34. Геолокация
  35. Инициализация и получение координат
  36. Требования
  37. DeviceStorage и SecureStorage
  38. DeviceStorage (CloudStorage)
  39. SecureStorage
  40. Шаринг контента
  41. Отправка сообщения (shareMessage)
  42. Скачивание файлов (downloadFile)
  43. Тестирование и отладка
  44. @WebAppTestBot
  45. Telegram Desktop: инструменты разработчика
  46. Eruda.js для мобильной отладки
  47. Советы по отладке
  48. Ответы на эти вопросы могут быть для вас полезными
  49. Можно ли создать Mini App без бота?
  50. Как передать данные из Mini App в бота?
  51. Как принимать оплату в Mini App?
  52. Работают ли датчики в десктопной версии?
  53. Что такое initData и зачем его валидировать?
  54. Как сделать Mini App полноэкранным?
  55. Сколько данных можно хранить в SecureStorage?

Зачем интегрировать Mini App в бота

Бот — это бэкенд, Mini App — это фронтенд

Telegram-бот сам по себе ограничен текстовыми командами, inline-кнопками и callback-запросами. Для сложных интерфейсов этого недостаточно. Mini App решает проблему: бот остаётся серверной частью (обрабатывает логику, хранит данные, принимает платежи), а Mini App становится полноценным веб-интерфейсом, встроенным прямо в окно чата.

Архитектура выглядит так:

  • Бот (Python / Node.js / любой язык) — обрабатывает команды, валидирует данные, управляет бизнес-логикой.
  • Mini App (HTML + CSS + JS) — рендерит UI, собирает ввод пользователя, отправляет данные боту через sendData() или через бэкенд-API.
  • Telegram клиент — связующее звено: открывает Mini App, передаёт initData, обеспечивает нативные API (платежи, датчики, геолокация)

Примеры использования

  • Интернет-магазин. Каталог товаров с карточками, фильтрами и корзиной. Оплата через Telegram Stars — без перехода на внешний сайт.
  • Форма записи. Выбор даты, времени, специалиста — всё в удобном календаре вместо набора inline-кнопок.
  • Аналитический дашборд. Графики, таблицы, фильтры по периодам — то, что невозможно реализовать текстовыми сообщениями.
  • Игра. Canvas-рендеринг, акселерометр, полноэкранный режим — Mini App поддерживает всё это нативно. Подробнее о создании игр читайте в нашем руководстве по разработке тапалки для Telegram
  • CRM / ERP. Управление заказами, клиентами, задачами — прямо из мессенджера.

Mini App без бота невозможен

Это принципиальный момент: Mini App не существует сам по себе. Он всегда привязан к боту. Именно бот регистрирует URL приложения, именно через бота пользователь открывает Mini App, и именно боту приходят данные после закрытия приложения. Без бота Mini App — просто веб-страница, не имеющая доступа к Telegram API.


Быстрый старт: минимальный пример

Шаг 1. Создание бота и регистрация Mini App

  1. Откройте @BotFather и отправьте /newbot.
  2. Задайте имя и username бота. Сохраните полученный токен.
  3. Отправьте /newapp и выберите своего бота.
  4. Укажите URL вашего Mini App (HTTPS обязателен, можно использовать ngrok для разработки).
  5. Задайте короткое имя (short_name) — оно будет использоваться в ссылке t.me/yourbot/appname.

Альтернативно можно установить URL через /setmenubutton — тогда Mini App откроется при нажатии на кнопку меню рядом с полем ввода.

Шаг 2. Три способа открытия Mini App

В Telegram есть три основных способа запустить Mini App из бота:

1. KeyboardButton с web_app — кнопка в обычной клавиатуре (ReplyKeyboard):

from telegram import KeyboardButton, ReplyKeyboardMarkup, WebAppInfo

web_app = WebAppInfo(url="https://your-app.example.com")
keyboard = ReplyKeyboardMarkup([
    [KeyboardButton("Открыть приложение", web_app=web_app)]
], resize_keyboard=True)

await update.message.reply_text("Нажмите кнопку:", reply_markup=keyboard)

2. InlineKeyboardButton с web_app — кнопка в inline-клавиатуре:

from telegram import InlineKeyboardButton, InlineKeyboardMarkup, WebAppInfo

web_app = WebAppInfo(url="https://your-app.example.com")
keyboard = InlineKeyboardMarkup([
    [InlineKeyboardButton("Открыть магазин", web_app=web_app)]
])

await update.message.reply_text("Добро пожаловать!", reply_markup=keyboard)

3. MenuButtonWebApp — кнопка меню (слева от поля ввода):

from telegram import MenuButtonWebApp, WebAppInfo

await bot.set_chat_menu_button(
    chat_id=chat_id,
    menu_button=MenuButtonWebApp(
        text="Меню",
        web_app=WebAppInfo(url="https://your-app.example.com")
    )
)

Подробнее о настройке кнопок и клавиатур — в нашей статье об использовании новых методов Bot API для создания кастомных клавиатур

Шаг 3. Полный рабочий пример на python-telegram-bot

import logging
from telegram import (
    Update, KeyboardButton, ReplyKeyboardMarkup,
    InlineKeyboardButton, InlineKeyboardMarkup, WebAppInfo
)
from telegram.ext import (
    ApplicationBuilder, CommandHandler, MessageHandler,
    filters, ContextTypes
)

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

BOT_TOKEN = "YOUR_BOT_TOKEN"
WEBAPP_URL = "https://your-app.example.com"

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Отправляет клавиатуру с кнопкой Mini App."""
    web_app = WebAppInfo(url=WEBAPP_URL)

    # Reply-кнопка (KeyboardButton)
    reply_keyboard = ReplyKeyboardMarkup(
        [[KeyboardButton("Открыть приложение", web_app=web_app)]],
        resize_keyboard=True
    )

    # Inline-кнопка
    inline_keyboard = InlineKeyboardMarkup([
        [InlineKeyboardButton("Открыть в инлайне", web_app=web_app)]
    ])

    await update.message.reply_text(
        "Выберите способ открытия Mini App:",
        reply_markup=reply_keyboard
    )
    await update.message.reply_text(
        "Или нажмите inline-кнопку:",
        reply_markup=inline_keyboard
    )

async def handle_web_app_data(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Обрабатывает данные, отправленные из Mini App через sendData()."""
    data = update.effective_message.web_app_data.data
    logger.info(f"Получены данные из Mini App: {data}")
    await update.message.reply_text(f"Данные получены: {data}")

def main():
    app = ApplicationBuilder().token(BOT_TOKEN).build()
    app.add_handler(CommandHandler("start", start))
    app.add_handler(MessageHandler(filters.StatusUpdate.WEB_APP_DATA, handle_web_app_data))
    app.run_polling()

if __name__ == "__main__":
    main()

Аналогичный пример на aiogram 3.x

import logging
from aiogram import Bot, Dispatcher, types, F
from aiogram.types import (
    WebAppInfo, KeyboardButton, ReplyKeyboardMarkup,
    InlineKeyboardButton, InlineKeyboardMarkup
)
from aiogram.filters import CommandStart
import asyncio

BOT_TOKEN = "YOUR_BOT_TOKEN"
WEBAPP_URL = "https://your-app.example.com"

bot = Bot(token=BOT_TOKEN)
dp = Dispatcher()

@dp.message(CommandStart())
async def start(message: types.Message):
    web_app = WebAppInfo(url=WEBAPP_URL)
    keyboard = ReplyKeyboardMarkup(
        keyboard=[[KeyboardButton(text="Открыть приложение", web_app=web_app)]],
        resize_keyboard=True
    )
    await message.answer("Нажмите кнопку для запуска Mini App:", reply_markup=keyboard)

@dp.message(F.web_app_data)
async def handle_web_app_data(message: types.Message):
    data = message.web_app_data.data
    await message.answer(f"Получены данные: {data}")

async def main():
    await dp.start_polling(bot)

if __name__ == "__main__":
    asyncio.run(main())

Приём данных от Mini App

Существует два основных способа передать данные из Mini App в бота. Выбор зависит от объёма данных и требований к безопасности.

Способ 1. Через sendData() (клиентский)

На стороне Mini App (JavaScript):

// Отправляем данные боту и закрываем Mini App
Telegram.WebApp.sendData(JSON.stringify({
    action: "order",
    product_id: 42,
    quantity: 2
}));

На стороне бота данные придут в update.message.web_app_data.data:

async def handle_web_app_data(update: Update, context: ContextTypes.DEFAULT_TYPE):
    import json
    data = json.loads(update.effective_message.web_app_data.data)
    product_id = data["product_id"]
    quantity = data["quantity"]
    await update.message.reply_text(
        f"Заказ принят: товар #{product_id}, количество: {quantity}"
    )

Ограничения: максимум 4096 байт, Mini App закрывается после отправки, работает только для KeyboardButton (не inline).

Способ 2. Через бэкенд (рекомендуется)

Для production-решений данные лучше отправлять напрямую на ваш сервер через fetch, а Mini App при этом может оставаться открытым.

На стороне Mini App:

const initData = Telegram.WebApp.initData;

fetch("https://your-api.example.com/api/order", {
    method: "POST",
    headers: {
        "Content-Type": "application/json",
        "X-Telegram-Init-Data": initData
    },
    body: JSON.stringify({
        product_id: 42,
        quantity: 2
    })
});

На сервере обязательно валидируйте initData, чтобы убедиться, что запрос пришёл из настоящего Telegram-клиента.

Валидация initData (HMAC-SHA256)

Telegram подписывает initData с помощью HMAC-SHA256. Вот полная функция валидации на Python:

import hmac
import hashlib
from urllib.parse import unquote


def validate_init_data(init_data: str, bot_token: str) -> bool:
    """
    Валидирует initData из Telegram Mini App.
    Возвращает True, если подпись верна.
    """
    # Парсим параметры
    params = dict(p.split('=', 1) for p in init_data.split('&'))
    received_hash = params.pop('hash', None)

    if not received_hash:
        return False

    # Формируем строку для проверки: параметры в алфавитном порядке
    data_check_string = '\n'.join(
        f'{k}={v}' for k, v in sorted(params.items())
    )

    # Вычисляем секретный ключ
    secret_key = hmac.new(
        b'WebAppData',
        bot_token.encode(),
        hashlib.sha256
    ).digest()

    # Вычисляем хеш
    calculated_hash = hmac.new(
        secret_key,
        data_check_string.encode(),
        hashlib.sha256
    ).hexdigest()

    return calculated_hash == received_hash

Пример использования в FastAPI:

from fastapi import FastAPI, Request, HTTPException

app = FastAPI()

@app.post("/api/order")
async def create_order(request: Request):
    init_data = request.headers.get("X-Telegram-Init-Data", "")

    if not validate_init_data(init_data, BOT_TOKEN):
        raise HTTPException(status_code=403, detail="Invalid initData")

    body = await request.json()
    # Обрабатываем заказ...
    return {"status": "ok"}

Важно: initData имеет ограниченный срок жизни. Рекомендуется проверять поле auth_date и отклонять запросы старше 5 минут.


Новые возможности Bot API 9.0–9.5 для Mini Apps

С марта 2025 по март 2026 Telegram выпустил шесть обновлений Bot API, каждое из которых расширяет возможности ботов и Mini Apps. Разберём ключевые нововведения каждой версии.

Bot API 9.0 (март 2025): бизнес-боты и подарки

Версия 9.0 сфокусирована на бизнес-ботах и экосистеме подарков:

  • BusinessBotRights — новый объект, описывающий права бота в бизнес-аккаунте. Бот теперь может управлять чатами, читать сообщения и работать с балансом Stars от имени бизнеса.
  • readBusinessMessage — метод для пометки входящих бизнес-сообщений как прочитанных. Полезно для CRM-ботов, которые обрабатывают обращения клиентов.
  • deleteBusinessMessages — пакетное удаление сообщений в бизнес-чатах.
  • Операции с подарками: convertGiftToStars (конвертация подарка в Stars), transferGift (передача подарка другому пользователю), upgradeGift (апгрейд подарка до уникального).
  • getBusinessAccountStarBalance — проверка баланса Stars бизнес-аккаунта прямо из бота.

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

Bot API 9.1: чеклисты и расширенные подарки

  • Добавлены чеклисты (checklists) — новый тип контента, который бот может отправлять.
  • Расширены операции с подарками: возможность массовой конвертации, фильтрация по типу.
  • Улучшена работа с медиафайлами в бизнес-контексте.

Bot API 9.2: прямые сообщения и рекомендации

  • Прямые сообщения — боты получили возможность отправлять сообщения пользователям без предварительного /start, если пользователь дал согласие через Mini App.
  • Рекомендуемые посты — новый механизм для продвижения контента через ботов.
  • Улучшена обработка inline-запросов с поддержкой новых типов результатов.

Bot API 9.3 (декабрь 2025): sendMessageDraft для ИИ-ботов

Одно из самых значимых обновлений для разработчиков ИИ-ботов:

  • sendMessageDraft — метод, позволяющий боту предложить черновик сообщения в поле ввода пользователя. Пользователь видит текст, может отредактировать и отправить сам.
await bot.send_message_draft(
    business_connection_id=connection_id,
    chat_id=chat_id,
    text="Спасибо за ваш заказ! Доставка займёт 2-3 рабочих дня."
)

Это идеально для ИИ-ассистентов: бот генерирует ответ, стримит его в поле ввода, а оператор проверяет и отправляет. В версии 9.3 метод был доступен только для бизнес-ботов.

Bot API 9.4: цветные кнопки и премиум-эмодзи

  • button_color — параметр для задания цвета inline-кнопок. Теперь кнопки можно стилизовать под бренд.
button = InlineKeyboardButton(
    text="Купить",
    callback_data="buy",
    button_color=ButtonColor(
        light_color=0x2E7D32,  # зелёный для светлой темы
        dark_color=0x66BB6A    # зелёный для тёмной темы
    )
)
  • Премиум-эмодзи в кнопках — inline-кнопки теперь поддерживают кастомные эмодзи из набора Telegram Premium.
  • Улучшена производительность рендеринга Mini App на мобильных устройствах.

Bot API 9.5 (март 2026): форматирование, теги, sendMessageDraft для всех

Свежее обновление, вышедшее в марте 2026:

  • Форматирование даты и времени — новые методы для локализованного отображения дат в сообщениях бота. Telegram автоматически адаптирует формат под часовой пояс и локаль пользователя.
  • Пользовательские теги — возможность назначать теги чатам и пользователям для организации и фильтрации.
  • sendMessageDraft для всех ботов — метод, ранее доступный только бизнес-ботам, теперь работает для любых ботов. Это открывает возможности стриминга текста для всех ИИ-ботов в Telegram.
# Теперь работает для любого бота, не только бизнес-бота
await bot.send_message_draft(
    chat_id=user_id,
    text="Вот ваш сгенерированный текст..."
)

Подробнее о создании собственного приложения в Telegram читайте в нашем руководстве по созданию Web App


Платежи через Stars в Mini App

Telegram Stars — внутренняя валюта Telegram, которая позволяет принимать платежи без внешних платёжных систем. Для Mini App это самый простой способ монетизации.

Шаг 1. Создание ссылки на инвойс (Python)

from telegram import LabeledPrice

async def create_payment(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Создаёт ссылку на оплату через Stars."""
    invoice_link = await context.bot.create_invoice_link(
        title="Подписка Premium",
        description="Доступ ко всем функциям на 30 дней",
        payload="premium_30d",
        currency="XTR",  # XTR = Telegram Stars
        prices=[LabeledPrice(label="Premium 30 дней", amount=100)]
    )

    # Отправляем ссылку пользователю
    await update.message.reply_text(
        "Оформите подписку:",
        reply_markup=InlineKeyboardMarkup([
            [InlineKeyboardButton("Оплатить 100 Stars", url=invoice_link)]
        ])
    )

Шаг 2. Открытие инвойса из Mini App (JavaScript)

Если оплата инициируется из интерфейса Mini App, используйте метод openInvoice:

// Получаем ссылку на инвойс от бэкенда
const response = await fetch("/api/create-invoice", { method: "POST" });
const { invoice_link } = await response.json();

// Открываем нативное окно оплаты Telegram
Telegram.WebApp.openInvoice(invoice_link, function(status) {
    if (status === "paid") {
        // Оплата прошла успешно
        showSuccessScreen();
        // Обновляем данные на бэкенде
        fetch("/api/activate-premium", { method: "POST" });
    } else if (status === "cancelled") {
        showMessage("Оплата отменена");
    } else if (status === "failed") {
        showMessage("Ошибка оплаты. Попробуйте позже.");
    }
});

Шаг 3. Обработка успешной оплаты (Python)

from telegram.ext import PreCheckoutQueryHandler, MessageHandler, filters

async def pre_checkout(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Подтверждаем готовность принять платёж."""
    query = update.pre_checkout_query
    # Здесь можно проверить наличие товара, валидность payload и т.д.
    await query.answer(ok=True)

async def successful_payment(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Обрабатываем успешную оплату."""
    payment = update.message.successful_payment
    payload = payment.invoice_payload
    total_amount = payment.total_amount
    telegram_payment_charge_id = payment.telegram_payment_charge_id

    if payload == "premium_30d":
        # Активируем подписку
        await activate_premium(update.effective_user.id, days=30)
        await update.message.reply_text(
            f"Подписка Premium активирована на 30 дней!\n"
            f"Списано: {total_amount} Stars\n"
            f"ID транзакции: {telegram_payment_charge_id}"
        )

# Регистрация обработчиков
app.add_handler(PreCheckoutQueryHandler(pre_checkout))
app.add_handler(MessageHandler(filters.SUCCESSFUL_PAYMENT, successful_payment))

Возврат средств

Если нужно вернуть Stars покупателю:

await bot.refund_star_payment(
    user_id=user_id,
    telegram_payment_charge_id=charge_id
)

Fullscreen-режим

Начиная с Bot API 8.0, Mini App может запрашивать полноэкранный режим. Это особенно полезно для игр, видеоплееров и иммерсивных интерфейсов.

Запрос полноэкранного режима

// Проверяем поддержку
if (Telegram.WebApp.isVersionAtLeast("8.0")) {
    // Запрашиваем fullscreen
    Telegram.WebApp.requestFullscreen();
}

// Отслеживаем изменение состояния
Telegram.WebApp.onEvent('fullscreenChanged', () => {
    const isFullscreen = Telegram.WebApp.isFullscreen;
    console.log('Fullscreen:', isFullscreen);

    if (isFullscreen) {
        // Адаптируем интерфейс: скрываем шапку, расширяем canvas
        document.body.classList.add('fullscreen-mode');
        resizeCanvas();
    } else {
        document.body.classList.remove('fullscreen-mode');
        resizeCanvas();
    }
});

// Обработка ошибок
Telegram.WebApp.onEvent('fullscreenFailed', (error) => {
    console.error('Fullscreen failed:', error.error);
    // error.error может быть: UNSUPPORTED, ALREADY_FULLSCREEN
});

Выход из полноэкранного режима

Telegram.WebApp.exitFullscreen();

Безопасные зоны (Safe Area)

В полноэкранном режиме необходимо учитывать вырезы экрана (notch) и системные элементы. Telegram предоставляет информацию о безопасных зонах:

// Безопасная зона контента (учитывает notch, статус-бар и т.д.)
const safeArea = Telegram.WebApp.safeAreaInset;
// { top: 44, bottom: 34, left: 0, right: 0 }

// Безопасная зона с учётом UI Telegram
const contentSafeArea = Telegram.WebApp.contentSafeAreaInset;
// { top: 0, bottom: 0, left: 0, right: 0 }

// Применяем отступы
document.documentElement.style.setProperty('--safe-top', safeArea.top + 'px');
document.documentElement.style.setProperty('--safe-bottom', safeArea.bottom + 'px');

Работа с датчиками

Mini App может получать данные с датчиков устройства: акселерометра, гироскопа и компаса. Это необходимо для игр, фитнес-приложений и AR-интерфейсов.

Акселерометр

const accelerometer = Telegram.WebApp.Accelerometer;

// Запуск с частотой обновления (мс)
accelerometer.start({ refresh_rate: 100 });

// Обработка данных
Telegram.WebApp.onEvent('accelerometerChanged', () => {
    const { x, y, z } = accelerometer;
    console.log(`Ускорение — X: ${x.toFixed(2)}, Y: ${y.toFixed(2)}, Z: ${z.toFixed(2)}`);

    // Пример: определение тряски устройства
    const totalAcceleration = Math.sqrt(x * x + y * y + z * z);
    if (totalAcceleration > 20) {
        onShake();
    }
});

// Остановка при выходе
accelerometer.stop();

Гироскоп

const gyroscope = Telegram.WebApp.Gyroscope;

gyroscope.start({ refresh_rate: 100 });

Telegram.WebApp.onEvent('gyroscopeChanged', () => {
    const { x, y, z } = gyroscope;
    console.log(`Угловая скорость — X: ${x.toFixed(3)}, Y: ${y.toFixed(3)}, Z: ${z.toFixed(3)}`);
});

// Не забудьте остановить при закрытии
Telegram.WebApp.onEvent('deactivated', () => {
    gyroscope.stop();
});

Ориентация устройства (DeviceOrientation)

const orientation = Telegram.WebApp.DeviceOrientation;

// Запуск с включённым абсолютным режимом (относительно магнитного севера)
orientation.start({ refresh_rate: 100, need_absolute: true });

Telegram.WebApp.onEvent('deviceOrientationChanged', () => {
    const alpha = orientation.alpha; // Вращение вокруг оси Z (0-360)
    const beta = orientation.beta;   // Наклон вперёд-назад (-180 to 180)
    const gamma = orientation.gamma; // Наклон влево-вправо (-90 to 90)

    // Пример: компас
    const compassHeading = (360 - alpha) % 360;
    updateCompassUI(compassHeading);

    // Пример: управление 3D-объектом
    update3DRotation(alpha, beta, gamma);
});

orientation.stop();

Примечание: датчики работают только на мобильных устройствах. В десктопной версии Telegram данные датчиков недоступны — обязательно предусмотрите fallback в интерфейсе.


Геолокация

Mini App может запрашивать геолокацию пользователя. Это полезно для сервисов доставки, такси, поиска ближайших точек.

Инициализация и получение координат

const locationManager = Telegram.WebApp.LocationManager;

// Инициализация (запрашивает разрешение у пользователя)
locationManager.init(function() {
    if (!locationManager.isInited) {
        showMessage("Геолокация недоступна");
        return;
    }

    if (!locationManager.isLocationAvailable) {
        showMessage("Разрешите доступ к геолокации в настройках");
        return;
    }

    // Получаем текущую позицию
    locationManager.getLocation(function(location) {
        if (!location) {
            showMessage("Не удалось получить координаты");
            return;
        }

        const { latitude, longitude, altitude, course, speed, horizontal_accuracy } = location;
        console.log(`Координаты: ${latitude}, ${longitude}`);
        console.log(`Точность: ${horizontal_accuracy} м`);

        // Передаём координаты на сервер
        fetch("/api/set-location", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({ latitude, longitude })
        });

        // Показываем на карте
        showOnMap(latitude, longitude);
    });
});

Требования

  • Пользователь должен явно разрешить доступ к геолокации.
  • Работает только через HTTPS.
  • На десктопе геолокация определяется по IP (менее точно).
  • Бот должен иметь специальный флаг, разрешающий использование геолокации (устанавливается через @BotFather).

DeviceStorage и SecureStorage

Mini App предоставляет два типа хранилища для сохранения данных на устройстве пользователя.

DeviceStorage (CloudStorage)

Общее облачное хранилище, синхронизируемое между устройствами пользователя. Подходит для настроек, предпочтений, кешированных данных.

const storage = Telegram.WebApp.CloudStorage;

// Сохранение данных
storage.setItem("theme", "dark", function(error, success) {
    if (error) {
        console.error("Ошибка сохранения:", error);
        return;
    }
    console.log("Тема сохранена");
});

// Чтение данных
storage.getItem("theme", function(error, value) {
    if (error) {
        console.error("Ошибка чтения:", error);
        return;
    }
    console.log("Текущая тема:", value); // "dark"
    applyTheme(value);
});

// Чтение нескольких ключей
storage.getItems(["theme", "language", "notifications"], function(error, values) {
    if (!error) {
        console.log(values); // { theme: "dark", language: "ru", notifications: "true" }
    }
});

// Удаление
storage.removeItem("theme", function(error, success) {
    console.log("Удалено");
});

// Получение всех ключей
storage.getKeys(function(error, keys) {
    console.log("Все ключи:", keys); // ["theme", "language", "notifications"]
});

SecureStorage

Защищённое хранилище, использующее нативные механизмы безопасности ОС:

  • iOS — данные хранятся в Keychain.
  • Android — данные хранятся в Android Keystore.

Подходит для токенов авторизации, приватных ключей, чувствительных настроек.

const secureStorage = Telegram.WebApp.SecureStorage;

// Сохранение секретных данных (требует биометрическую аутентификацию)
secureStorage.setItem("auth_token", "eyJhbGciOiJIUzI1NiIs...", function(error, success) {
    if (error) {
        console.error("Ошибка:", error);
        // Возможные ошибки: UNSUPPORTED, AUTH_FAILED, STORAGE_FULL
        return;
    }
    console.log("Токен сохранён в защищённое хранилище");
});

// Чтение (также требует аутентификацию)
secureStorage.getItem("auth_token", function(error, value) {
    if (error) {
        console.error("Ошибка:", error);
        return;
    }
    // Используем токен для авторизации
    setupApiClient(value);
});

// Удаление
secureStorage.removeItem("auth_token", function(error, success) {
    console.log("Токен удалён");
});

// Восстановление значений
secureStorage.restoreItems(function(error, values) {
    if (!error) {
        console.log("Восстановленные данные:", values);
    }
});

Ограничения SecureStorage:

  • Максимум 10 элементов на одного бота.
  • Размер значения — до 4096 символов.
  • Доступ требует биометрической аутентификации (отпечаток пальца, Face ID).
  • Недоступен в десктопной версии Telegram.
  • Данные привязаны к устройству и не синхронизируются.

Шаринг контента

Mini App позволяет делиться контентом с другими пользователями и скачивать файлы.

Отправка сообщения (shareMessage)

// Подготавливаем сообщение для шаринга (необходимо prepared_message_id от бэкенда)
Telegram.WebApp.shareMessage(preparedMessageId, function(success) {
    if (success) {
        console.log("Сообщение успешно отправлено");
        showNotification("Отправлено!");
    } else {
        console.log("Пользователь отменил отправку");
    }
});

Для подготовки сообщения на стороне бота используйте метод savePreparedInlineMessage:

from telegram import InlineQueryResultArticle, InputTextMessageContent

result = InlineQueryResultArticle(
    id="share_1",
    title="Поделиться результатом",
    input_message_content=InputTextMessageContent(
        message_text="Посмотри мой результат в игре: 1500 очков!"
    )
)

prepared = await bot.save_prepared_inline_message(
    user_id=user_id,
    result=result,
    allow_user_chats=True,
    allow_group_chats=True
)
# prepared.id — передаём в Mini App

Скачивание файлов (downloadFile)

// Скачиваем файл на устройство пользователя
Telegram.WebApp.downloadFile({
    url: "https://your-api.example.com/reports/monthly.pdf",
    file_name: "report_march_2026.pdf"
}, function(accepted) {
    if (accepted) {
        showNotification("Файл скачивается...");
    } else {
        showNotification("Скачивание отклонено");
    }
});

Ограничения: URL должен быть HTTPS, максимальный размер файла — 50 МБ.


Тестирование и отладка

Отладка Mini App имеет свои особенности, потому что приложение работает внутри WebView Telegram, а не в обычном браузере.

@WebAppTestBot

Telegram предоставляет официального бота для тестирования Mini App — @WebAppTestBot. С его помощью можно быстро проверить вашу страницу без создания собственного бота: просто отправьте URL и бот откроет его как Mini App.

Telegram Desktop: инструменты разработчика

В десктопной версии Telegram доступен встроенный инспектор:

  1. Откройте Mini App в Telegram Desktop.
  2. Нажмите Ctrl+Shift+I (Windows/Linux) или Cmd+Option+I (macOS).
  3. Откроется панель DevTools, аналогичная Chrome DevTools.

Здесь можно:

  • Просматривать DOM-дерево и CSS.
  • Отслеживать сетевые запросы.
  • Устанавливать breakpoints в JavaScript.
  • Смотреть логи console.log.

Eruda.js для мобильной отладки

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

<!-- Добавьте в <head> вашего Mini App (только для отладки!) -->
<script src="https://cdn.jsdelivr.net/npm/eruda"></script>
<script>
    eruda.init();
</script>

После подключения в правом нижнем углу появится кнопка, открывающая панель с консолью, вкладками Elements, Network, Storage и другими.

Важно: не забудьте удалить Eruda перед публикацией в production. Можно управлять подключением через URL-параметр:

if (new URLSearchParams(window.location.search).has('debug')) {
    const script = document.createElement('script');
    script.src = 'https://cdn.jsdelivr.net/npm/eruda';
    script.onload = () => eruda.init();
    document.head.appendChild(script);
}

Советы по отладке

  • Используйте Telegram.WebApp.showAlert() вместо alert() — стандартный alert может не работать в WebView.
  • Логируйте Telegram.WebApp.initDataUnsafe в консоли, чтобы видеть данные пользователя.
  • Тестируйте на реальных устройствах — поведение WebView отличается от браузера.
  • Проверяйте тёмную и светлую тему: Telegram.WebApp.colorScheme.

Ответы на эти вопросы могут быть для вас полезными

Можно ли создать Mini App без бота?

Нет. Mini App всегда привязан к боту. Бот регистрирует URL приложения через @BotFather, предоставляет кнопки для запуска и получает данные от Mini App. Без бота невозможно ни открыть Mini App, ни подписать initData.

Как передать данные из Mini App в бота?

Два способа. Первый — Telegram.WebApp.sendData(data): данные приходят боту в update.message.web_app_data, но Mini App при этом закрывается, а лимит — 4096 байт. Второй (рекомендуемый) — отправить данные через fetch на ваш бэкенд-сервер, передав initData в заголовке для валидации. Подробные примеры кода — в разделе «Приём данных от Mini App» выше.

Как принимать оплату в Mini App?

Используйте Telegram Stars (валюта XTR). На стороне бота создайте ссылку на инвойс через create_invoice_link(), а в Mini App откройте её через Telegram.WebApp.openInvoice(url, callback). Обработайте pre_checkout_query и successful_payment на стороне бота. Полный пример с кодом — в разделе «Платежи через Stars».

Работают ли датчики в десктопной версии?

Нет. Акселерометр, гироскоп и DeviceOrientation доступны только на мобильных устройствах (iOS и Android). В десктопном Telegram эти API возвращают нулевые значения или вызывают ошибку. Всегда предусматривайте fallback-логику для десктопа, например, управление мышью вместо наклона.

Что такое initData и зачем его валидировать?

initData — строка, которую Telegram передаёт в Mini App при открытии. Она содержит информацию о пользователе (user), времени авторизации (auth_date) и подпись (hash). Валидация через HMAC-SHA256 гарантирует, что запрос действительно пришёл из Telegram, а не был подделан. Без валидации злоумышленник может подставить чужой user_id и получить доступ к чужим данным.

Как сделать Mini App полноэкранным?

Вызовите Telegram.WebApp.requestFullscreen(). Для выхода — Telegram.WebApp.exitFullscreen(). Отслеживайте событие fullscreenChanged, чтобы адаптировать интерфейс. Не забудьте учесть safeAreaInset для корректного отображения на устройствах с вырезами экрана. Fullscreen доступен начиная с Bot API 8.0.

Сколько данных можно хранить в SecureStorage?

SecureStorage позволяет сохранить максимум 10 элементов на одного бота, каждый размером до 4096 символов. Данные защищены iOS Keychain / Android Keystore и требуют биометрической аутентификации для доступа. Данные не синхронизируются между устройствами. Для больших объёмов используйте CloudStorage (без ограничения на количество записей, но с лимитом на размер значения).


Telegram Mini Apps в 2026 году — это полноценная платформа для создания приложений внутри мессенджера. Bot API 9.0–9.5 добавил бизнес-инструменты, стриминг черновиков через sendMessageDraft, цветные кнопки и расширенное форматирование. В связке с платежами через Stars, доступом к датчикам и защищённым хранилищем, Mini App закрывает большинство задач, для которых раньше требовалось отдельное мобильное приложение.

Начните с минимального примера из этой статьи: создайте бота, зарегистрируйте Mini App, добавьте кнопку — и постепенно наращивайте функциональность. Код из всех разделов можно использовать как основу для вашего проекта

Оцените статью
5 1 голос
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x