Telegram Mini App на React: разработка с @twa-dev/sdk, валидация initData и MainButton

Разработка Telegram Mini App открывает новые возможности для создания полнофункциональных веб-приложений прямо внутри Telegram. Для разработчиков на React существует несколько подходов к интеграции с Telegram WebApp API. Мы рассмотрим наиболее эффективный способ с использованием библиотеки @twa-dev/sdk, а также уделим особое внимание критически важным аспектам безопасности, таким как валидация initData на бэкенде.

Использование @twa-dev/sdk для React

Библиотека @twa-dev/sdk значительно упрощает взаимодействие с Telegram WebApp API, предоставляя удобные React-хуки и компоненты. Она абстрагирует низкоуровневые детали работы с window.Telegram.WebApp, делая разработку более приятной и менее подверженной ошибкам.

Для начала установите библиотеку:

npm install @twa-dev/sdk

После установки вы можете использовать хуки для доступа к объекту WebApp и его методам. Например, для получения initDataUnsafe и настройки MainButton:

import React, { useEffect } from 'react';
import { useWebApp, useInitData, useMainButton } from '@twa-dev/sdk/react';

function App() {
const webApp = useWebApp();
const initData = useInitData();
const mainButton = useMainButton();

useEffect(() => {
if (webApp) {
webApp.ready();
webApp.expand(); // Расширяем Mini App на весь экран
}
}, [webApp]);

useEffect(() => {
if (mainButton) {
mainButton.setText('Отправить данные');
mainButton.onClick(() => {
// Обработка клика по MainButton
console.log('MainButton clicked!');
webApp.showAlert('Данные отправлены!');
// Здесь можно отправить initData на ваш бэкенд
});
mainButton.show();
mainButton.enable();
}
}, [mainButton, webApp]);

return (
<div>
<h1>Добро пожаловать в Mini App!</h1>
<p>Ваши данные: {initData ? initData.user?.first_name : 'Загрузка...'}</p>
<button onClick={() => webApp.showAlert('Привет от кнопки!')}>Показать Alert</button>
</div>
);
}

export default App;

useWebApp() предоставляет доступ к объекту window.Telegram.WebApp, useInitData() — к разобранным данным initDataUnsafe, а useMainButton() — к управлению основной кнопкой в интерфейсе Mini App.

Валидация initData на бэкенде

Ключевым аспектом безопасности любого Telegram Mini App является валидация initData. Эти данные содержат информацию о пользователе, боте и сессии, и их подлинность должна быть подтверждена на вашем бэкенде. Telegram Bot API генерирует hash на основе всех параметров initData и секретного ключа бота. Вы должны пересчитать этот hash на своей стороне и сравнить его с тем, что пришёл от клиента.

Вот пример реализации валидации initData на PHP:

<?php

/**
* Валидация initData из Telegram Mini App.
* @param string $initDataString Строка initData, полученная от клиента.
* @param string $botToken Токен вашего Telegram бота.
* @return array|false Ассоциативный массив с данными, если валидация успешна, иначе false.
*/
function validateTelegramInitData(string $initDataString, string $botToken): array|false
{
$data = [];
parse_str($initDataString, $data);

if (!isset($data['hash'])) {
return false;
}

$hash = $data['hash'];
unset($data['hash']);

// Сортируем данные по ключам и формируем строку для проверки
ksort($data);
$checkString = [];
foreach ($data as $key => $value) {
$checkString[] = $key . '=' . $value;
}
$checkString = implode("\n", $checkString);

// Вычисляем секретный ключ
$secretKey = hash_hmac('sha256', $botToken, 'WebAppData', true);

// Вычисляем HMAC-SHA256 хеш
$calculatedHash = hash_hmac('sha256', $checkString, $secretKey);

// Сравниваем хеши
// Используем timing-safe сравнение для предотвращения атак по времени
if (hash_equals($calculatedHash, $hash)) {
// Проверяем срок действия auth_date (опционально, но рекомендуется)
// По умолчанию Telegram устанавливает auth_date со сроком жизни 24 часа.
// Можно задать свой лимит, например, 1 час.
if (isset($data['auth_date']) && (time() - (int)$data['auth_date']) > 3600) { // 1 час
// echo "Warning: initData is too old.\n";
// return false; // или обрабатываем как устаревшие данные
}
return $data;
}

return false;
}

// Пример использования:
$initDataFromClient = getenv('TELEGRAM_INIT_DATA'); // Из заголовка, POST-параметра и т.п.
$botToken = getenv('TELEGRAM_BOT_TOKEN');

if (!$initDataFromClient || !$botToken) {
die("Environment variables TELEGRAM_INIT_DATA and TELEGRAM_BOT_TOKEN must be set.\n");
}

$validatedData = validateTelegramInitData($initDataFromClient, $botToken);

if ($validatedData) {
echo "InitData успешно валидирована!\n";
// print_r($validatedData);
// Теперь можно безопасно использовать данные пользователя, например: $validatedData['user']
} else {
echo "Ошибка валидации InitData.\n";
// Логируем попытку невалидного доступа
}

?>

Важно помнить, что initDataUnsafe на фронтенде содержит данные, которые ещё не были валидированы. Всегда отправляйте полную строку initData на ваш бэкенд и проводите валидацию там. Только после успешной валидации можно доверять этим данным.

MainButton: Основная кнопка Mini App

MainButton — это специальная кнопка, расположенная в нижней части Mini App, которая является частью интерфейса Telegram, а не вашего веб-приложения. Она предназначена для выполнения основных действий, таких как отправка формы, подтверждение заказа и т.п. Управление ею осуществляется через WebApp API.

  • mainButton.setText(text): Устанавливает текст кнопки.
  • mainButton.show(): Показывает кнопку.
  • mainButton.hide(): Скрывает кнопку.
  • mainButton.enable(): Активирует кнопку (делает кликабельной).
  • mainButton.disable(): Деактивирует кнопку (делает некликабельной).
  • mainButton.showProgress(leaveActive): Показывает индикатор загрузки. leaveActive (boolean) — если true, кнопка останется активной во время показа прогресса.
  • mainButton.hideProgress(): Скрывает индикатор загрузки.
  • mainButton.onClick(callback): Добавляет обработчик клика.

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

Жизненный цикл Mini App и полезные методы

Mini App имеет свой жизненный цикл и набор методов для взаимодействия с Telegram-клиентом:

  • webApp.ready(): Обязательный вызов, который сообщает Telegram, что ваше приложение загружено и готово к работе.
  • webApp.expand() / webApp.viewportStable(): Расширяет Mini App на весь экран. viewportStable вызывается, когда размер viewport стабилизируется.
  • webApp.close(): Закрывает Mini App.
  • webApp.showAlert(message): Показывает нативный alert Telegram.
  • webApp.showConfirm(message, callback): Показывает нативный confirm Telegram.
  • webApp.showPopup(params, callback): Показывает кастомизируемый popup.
  • webApp.openLink(url): Открывает ссылку во внешнем браузере.
  • webApp.openTelegramLink(url): Открывает ссылку в приложении Telegram (например, t.me/bot_name).

Эти методы позволяют создавать нативное и предсказуемое взаимодействие пользователя с вашим приложением внутри Telegram.

Ошибки и лимиты

При разработке Mini App важно учитывать потенциальные ошибки и лимиты:

  • Размер Mini App: Хотя Telegram не накладывает строгих лимитов на размер загружаемого контента, слишком большие приложения будут медленно загружаться, что негативно скажется на UX. Оптимизируйте бандлы, используйте ленивую загрузку.
  • Доступ к API: Некоторые методы WebApp API могут быть недоступны в старых версиях Telegram-клиентов. Всегда проверяйте наличие методов перед использованием (например, if (webApp.isVersionAtLeast('6.1'))).
  • Безопасность initData: Как уже упоминалось, не доверяйте данным initDataUnsafe без валидации на бэкенде.
  • Сетевые запросы: Mini App работает как обычное веб-приложение, поэтому все сетевые запросы к вашему бэкенду должны быть защищены (HTTPS) и обрабатывать возможные ошибки сети.

Разработка Mini App на React с использованием @twa-dev/sdk предоставляет мощный инструментарий для создания интерактивных и безопасных приложений внутри Telegram. Не забывайте о валидации данных на бэкенде и тестируйте ваше приложение на разных устройствах и версиях Telegram-клиента.

Если вы ищете готовые решения или помощь в разработке Telegram ботов и Mini Apps, посетите BotCreator.

Новые статьи — в Telegram

Разбираем, что автоматизировать в бизнесе и как это работает на практике. Без спама.