Полное руководство по созданию Mini App в Telegram
Mini App (ранее известные как Web App) — это веб-приложения, которые запускаются прямо внутри Telegram и выглядят как нативная часть мессенджера. Они используют стандартные веб-технологии (HTML, CSS и JavaScript), но при этом имеют доступ к специальным API Telegram.
Ключевые особенности Mini App:
Mini App могут использоваться для множества сценариев: магазины, формы опросов, игры, дашборды, редакторы, каталоги и многое другое.
BotHost — это специализированная платформа для хостинга ботов и мини-приложений Telegram, которая существенно упрощает процесс их создания и поддержки:
Перед началом создания Mini App на BotHost, вам понадобятся:
Для локального тестирования (опционально):
Первым шагом будет создание Telegram бота, через которого пользователи будут получать доступ к вашему мини-приложению:
/newbot
Для корректной работы Mini App на BotHost важно правильно организовать структуру файлов. Вот рекомендуемая структура:
repository/
├── app.js # Серверный код Node.js
├── package.json # Настройки проекта
└── public/ # Папка с файлами мини-приложения
├── index.html # Основной HTML файл
├── style.css # Стили
├── script.js # Клиентский JavaScript
└── images/ # Папка для изображений
public, а не в корне репозитория.
Файл app.js в корне проекта отвечает за раздачу статических файлов из папки public. Вот готовый код сервера на Node.js:
// Сервер для раздачи статических файлов
const http = require('http');
const fs = require('fs');
const path = require('path');
const PORT = process.env.PORT || 3000;
const mimeTypes = {
'.html': 'text/html',
'.css': 'text/css',
'.js': 'text/javascript',
'.json': 'application/json',
'.png': 'image/png',
'.jpg': 'image/jpeg',
'.gif': 'image/gif',
'.ico': 'image/x-icon'
};
const server = http.createServer((req, res) => {
console.log(`Запрос: ${req.method} ${req.url}`);
let url = req.url;
if (url === '/' || url === '') {
url = '/index.html';
}
const filePath = path.join(__dirname, 'public', url);
const extname = path.extname(filePath);
const contentType = mimeTypes[extname] || 'text/plain';
fs.readFile(filePath, (error, content) => {
if (error) {
if (error.code === 'ENOENT') {
res.writeHead(404);
res.end('Файл не найден');
} else {
res.writeHead(500);
res.end(`Ошибка сервера: ${error.code}`);
}
} else {
res.writeHead(200, { 'Content-Type': contentType });
res.end(content, 'utf-8');
}
});
});
server.listen(PORT, '0.0.0.0', () => {
console.log(`✅ Сервер запущен на порту ${PORT}`);
});
Этот код создает простой HTTP-сервер, который отдает файлы из папки public, определяя правильный Content-Type для разных типов файлов.
Файл package.json содержит метаданные проекта и используется Node.js для управления зависимостями и скриптами:
{
"name": "bothost-miniapp",
"version": "1.0.0",
"description": "Telegram Mini App на BotHost",
"main": "app.js",
"scripts": {
"start": "node app.js",
"dev": "nodemon app.js"
},
"dependencies": {},
"devDependencies": {
"nodemon": "^2.0.20"
}
}
Для простого статического мини-приложения нам не требуются внешние зависимости. nodemon добавлен как dev-зависимость для удобства локальной разработки.
Файл index.html — это основной файл вашего мини-приложения. Вот минимальный шаблон:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Мое мини-приложение</title>
<script src="https://telegram.org/js/telegram-web-app.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<header>
<h1>Мое Mini App</h1>
<p>Разработано на BotHost</p>
</header>
<main>
<div class="card">
<h2>Добро пожаловать!</h2>
<p>Это ваше первое мини-приложение в Telegram.</p>
<button id="mainButton" class="button">Нажмите меня</button>
</div>
</main>
</div>
<script src="script.js"></script>
</body>
</html>
telegram-web-app.js обязательно должен быть подключен в head документа для корректной работы с Telegram!
Файл style.css содержит стили вашего мини-приложения. Вот базовый шаблон с поддержкой светлой и темной темы Telegram:
:root {
--bg-color: #ffffff;
--text-color: #1f2937;
--hint-color: #6b7280;
--button-color: #6366f1;
--button-text-color: #ffffff;
--card-bg: #f9fafb;
}
body {
background-color: #ffffff;
color: #1f2937;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
margin: 0;
padding: 0;
font-size: 16px;
line-height: 1.6;
}
.container {
max-width: 450px;
margin: 0 auto;
padding: 20px 16px;
}
header {
text-align: center;
margin-bottom: 24px;
}
header h1 {
margin-bottom: 8px;
font-size: 24px;
font-weight: 700;
color: #6366f1;
}
header p {
color: #6b7280;
margin: 0;
}
.card {
background-color: #f9fafb;
border-radius: 12px;
padding: 20px;
margin-bottom: 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
.card h2 {
margin-top: 0;
margin-bottom: 12px;
font-size: 18px;
}
.button {
background-color: #6366f1;
color: #ffffff;
border: none;
border-radius: 8px;
padding: 12px 20px;
font-size: 15px;
font-weight: 600;
cursor: pointer;
display: block;
width: 100%;
margin-top: 16px;
transition: opacity 0.2s;
}
.button:active {
opacity: 0.8;
}
Файл script.js содержит логику взаимодействия с Telegram API:
const tg = window.Telegram.WebApp;
tg.ready();
tg.expand();
document.addEventListener('DOMContentLoaded', function() {
const mainButton = document.getElementById('mainButton');
if (mainButton) {
mainButton.addEventListener('click', function() {
if (tg.HapticFeedback) {
tg.HapticFeedback.impactOccurred('medium');
}
tg.MainButton.setText('ГОТОВО');
tg.MainButton.show();
tg.MainButton.onClick(function() {
const data = {
action: 'button_pressed',
timestamp: new Date().toISOString()
};
tg.sendData(JSON.stringify(data));
setTimeout(() => tg.close(), 1000);
});
});
}
if (tg.initDataUnsafe.user) {
const user = tg.initDataUnsafe.user;
console.log('Пользователь:', user.first_name, user.last_name);
}
});
console.log('Mini App загружена!');
console.log('Текущая тема:', tg.colorScheme);
Этот базовый скрипт инициализирует мини-приложение, показывает как использовать MainButton и отправлять данные в бота.
GitHub будет использоваться как хранилище для исходного кода и для автоматической интеграции с BotHost. Вот как создать и настроить репозиторий:
После создания репозитория вы получите URL, который понадобится для интеграции с BotHost.
Существует несколько способов загрузить файлы в репозиторий:
# Клонируем пустой репозиторий
git clone https://github.com/username/telegram-miniapp.git
cd telegram-miniapp
# Создаем структуру папок
mkdir -p public/images
# Создаем файлы (или копируем их)
touch app.js package.json public/index.html public/style.css public/script.js
# Добавляем и коммитим изменения
git add .
git commit -m "Initial commit"
git push origin main
Перед интеграцией с BotHost важно убедиться, что файлы размещены правильно. Структура должна выглядеть следующим образом:
telegram-miniapp/
├── app.js
├── package.json
└── public/
├── index.html
├── style.css
└── script.js
После подготовки репозитория на GitHub, пора создать бот на BotHost:
Для работы Mini App необходим HTTPS-домен. BotHost предлагает несколько вариантов:
myapp)https://myapp.bothost.ru
После создания бота, BotHost автоматически клонирует ваш репозиторий и запускает приложение:
Если вы видите сообщение ✅ Сервер запущен на порту 3000 (или другой порт), значит все работает правильно.
BotHost поддерживает автоматическое обновление при изменениях в репозитории:
Теперь при каждом push в репозиторий, BotHost автоматически обновит ваше приложение.
Чтобы пользователи могли легко открыть ваше Mini App из меню бота, настройте кнопку в BotFather:
/mybots/setmenubuttonhttps://myapp.bothost.ru)
После этого в меню бота появится кнопка, при нажатии на которую будет открываться ваше Mini App.
Вы также можете отправлять кнопки, открывающие Mini App, прямо в сообщениях бота.
Пример JavaScript-кода для бота на Node.js:
// Пример с использованием node-telegram-bot-api
const TelegramBot = require('node-telegram-bot-api');
const bot = new TelegramBot('YOUR_TOKEN', {polling: true});
bot.onText(/\/start/, (msg) => {
const chatId = msg.chat.id;
bot.sendMessage(chatId, 'Привет! Нажмите на кнопку, чтобы открыть мини-приложение:', {
reply_markup: {
inline_keyboard: [
[{
text: 'Открыть приложение',
web_app: {url: 'https://myapp.bothost.ru'}
}]
]
}
});
});
Такой код отправляет сообщение с кнопкой, которая открывает ваше мини-приложение при нажатии.
Mini App может отправлять данные обратно в бота с помощью метода sendData(). Вот как это работает:
// В script.js мини-приложения
const tg = window.Telegram.WebApp;
// Отправка данных в бота
function sendFormData() {
const data = {
name: document.getElementById('name').value,
email: document.getElementById('email').value,
feedback: document.getElementById('feedback').value
};
tg.sendData(JSON.stringify(data));
tg.close();
}
// В коде бота
bot.on('web_app_data', (msg) => {
const chatId = msg.chat.id;
const data = JSON.parse(msg.web_app_data.data);
bot.sendMessage(chatId,
`Спасибо за отправку формы!\n\nИмя: ${data.name}\nEmail: ${data.email}\nОтзыв: ${data.feedback}`
);
});
Таким образом вы можете создать полноценную форму в Mini App и получить заполненные данные в боте для дальнейшей обработки.
Telegram имеет светлую и темную темы, и ваше Mini App должно корректно адаптироваться под обе:
/* Автоматическая адаптация к теме Telegram */
:root {
--my-background: var(--tg-theme-bg-color, #ffffff);
--my-text: var(--tg-theme-text-color, #1f2937);
--my-hint: var(--tg-theme-hint-color, #6b7280);
--my-link: var(--tg-theme-link-color, #6366f1);
--my-button: var(--tg-theme-button-color, #6366f1);
--my-button-text: var(--tg-theme-button-text-color, #ffffff);
--my-secondary-bg: var(--tg-theme-secondary-bg-color, #f9fafb);
}
body {
background-color: var(--my-background);
color: var(--my-text);
}
const tg = window.Telegram.WebApp;
const isDarkTheme = tg.colorScheme === 'dark';
if (isDarkTheme) {
}
MainButton — это нативный элемент интерфейса Telegram, который появляется внизу экрана:
const tg = window.Telegram.WebApp;
tg.MainButton.setText('ОТПРАВИТЬ');
tg.MainButton.setParams({
color: '#6366f1',
text_color: '#ffffff',
is_active: true
});
tg.MainButton.show();
tg.MainButton.onClick(function() {
sendData();
});
tg.MainButton.enable();
MainButton отлично подходит для основных действий в приложении, таких как отправка формы или переход к оплате.
Mini App может получать базовую информацию о пользователе:
const tg = window.Telegram.WebApp;
const user = tg.initDataUnsafe.user;
if (user) {
console.log('ID:', user.id);
console.log('Имя:', user.first_name);
console.log('Фамилия:', user.last_name);
console.log('Юзернейм:', user.username);
console.log('Язык:', user.language_code);
document.getElementById('greeting').textContent =
`Привет, ${user.first_name}!`;
}
Эти данные можно использовать для персонализации интерфейса или для автозаполнения форм.
На мобильных устройствах вы можете использовать тактильную обратную связь:
const tg = window.Telegram.WebApp;
if (tg.HapticFeedback) {
tg.HapticFeedback.impactOccurred('light');
tg.HapticFeedback.impactOccurred('medium');
tg.HapticFeedback.impactOccurred('heavy');
tg.HapticFeedback.notificationOccurred('success');
tg.HapticFeedback.notificationOccurred('warning');
tg.HapticFeedback.notificationOccurred('error');
}
Haptic Feedback делает взаимодействие с вашим приложением более естественным и приятным.
При работе с Mini App на BotHost могут возникать следующие проблемы:
Причины:
Решения:
Причины:
telegram-web-app.jsРешения:
Причины:
Решения:
Для отладки Mini App можно использовать несколько подходов:
Откройте мини-приложение в браузере и используйте DevTools:
Вы можете просматривать логи, сетевые запросы и отлаживать JS.
BotHost предоставляет доступ к логам сервера:
console.log из серверного кодаДобавьте отладочную информацию в свое приложение:
function createDebugPanel() {
const debugPanel = document.createElement('div');
debugPanel.id = 'debug-panel';
debugPanel.style.position = 'fixed';
debugPanel.style.bottom = '10px';
debugPanel.style.left = '10px';
debugPanel.style.background = 'rgba(0,0,0,0.8)';
debugPanel.style.color = 'white';
debugPanel.style.padding = '10px';
debugPanel.style.borderRadius = '5px';
debugPanel.style.fontSize = '12px';
debugPanel.style.zIndex = '9999';
const tg = window.Telegram.WebApp;
debugPanel.innerHTML = `
Версия WebApp: ${tg.version}
Тема: ${tg.colorScheme}
Платформа: ${tg.platform}
Пользователь: ${tg.initDataUnsafe.user ? tg.initDataUnsafe.user.id : 'Нет'}
`;
document.body.appendChild(debugPanel);
}
Если вы столкнулись с проблемой, которую не можете решить самостоятельно, наш технический бот поддержки поможет вам разобраться!
Написать в поддержку