Розробка 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.