<!-- Bothost docs | HTML: https://bothost.ru/docs/manual-mini-app | Markdown: https://bothost.ru/docs/manual-mini-app.md | Index: https://bothost.ru/llms.txt -->

# BotHost Mini App — Полное руководство

*Источник: [https://manual.bothost.ru/](https://manual.bothost.ru/)*

---

## Содержание

1. [Что такое Mini App](#что-такое-mini-app)
2. [Подготовка к работе](#подготовка-к-работе)
3. [Создание файлов](#создание-файлов)
4. [Загрузка на GitHub](#загрузка-на-github)
5. [Настройка на BotHost](#настройка-на-bothost)
6. [Интеграция с Telegram](#интеграция-с-telegram)
7. [Продвинутые функции](#продвинутые-функции)
8. [Решение проблем](#решение-проблем)
9. [Примеры проектов](#примеры-проектов)

---

## Что такое Mini App

### Обзор технологии

Mini App (ранее известные как Web App) — это веб-приложения, которые запускаются прямо внутри Telegram и выглядят как нативная часть мессенджера. Они используют стандартные веб-технологии (HTML, CSS и JavaScript), но при этом имеют доступ к специальным API Telegram.

![Рис. 1: Пример мини-приложения в Telegram](/docs/images/miniapp/miniapp_dark_theme.png "Пример мини-приложения в Telegram")

Ключевые особенности Mini App:

* **Быстрый доступ:** Открываются через кнопку меню в боте, прямые ссылки или через кнопки в сообщениях
* **Адаптивный дизайн:** Автоматически подстраиваются под светлую и темную тему Telegram
* **Доступ к данным:** Могут получать информацию о пользователе (с его согласия)
* **Нативные элементы:** Используют компоненты интерфейса Telegram, например MainButton
* **Безопасность:** Работают только по HTTPS и имеют ограничения для безопасности пользователей

Mini App могут использоваться для множества сценариев: магазины, формы опросов, игры, дашборды, редакторы, каталоги и многое другое.

### Преимущества использования BotHost

BotHost — это специализированная платформа для хостинга ботов и мини-приложений Telegram, которая существенно упрощает процесс их создания и поддержки:

* **Комплексное решение:** Одна платформа для размещения как бота, так и мини-приложения
* **Автоматизация:** Интеграция с GitHub для мгновенного обновления при изменении кода
* **SSL из коробки:** Все домены автоматически получают HTTPS-сертификаты (обязательны для Mini App)
* **Домены:** Возможность использовать поддомены bothost.ru или подключить свой домен
* **Мониторинг и логи:** Удобный доступ к логам и статистике использования
* **Масштабирование:** Простое увеличение ресурсов при росте нагрузки

![Рис. 2: Интерфейс панели управления BotHost](/docs/images/miniapp/bothost_setup.png "Панель управления BotHost")

---

## Подготовка к работе

### Необходимые инструменты

Перед началом создания Mini App на BotHost, вам понадобятся:

* **Аккаунт BotHost:** Зарегистрируйтесь на [bothost.ru](https://bothost.ru/) и выберите подходящий тарифный план
* **GitHub аккаунт:** Репозиторий для хранения кода вашего приложения
* **Telegram бот:** Созданный через @BotFather с полученным токеном
* **Базовые знания:** HTML, CSS и JavaScript (минимальный уровень)
* **Редактор кода:** VS Code, Sublime Text или любой другой текстовый редактор

Для локального тестирования (опционально):

* **Node.js:** Версия 18.x или выше (рекомендуется LTS)
* **Git:** Для управления версиями кода

### Создание бота в Telegram

Первым шагом будет создание Telegram бота, через который пользователи будут получать доступ к вашему мини-приложению:

1. Откройте [@BotFather](https://t.me/BotFather) в Telegram
2. Отправьте команду `/newbot`
3. Введите **название** бота (может содержать любые символы)
4. Введите **username** бота (должен заканчиваться на "bot" и быть уникальным)
5. Получите и сохраните **токен** бота — он понадобится для настройки на BotHost

![Рис. 3: Процесс создания бота через BotFather](/docs/images/miniapp/botfather_create.png "Создание бота в BotFather")

> ⚠️ **Важно:** Никогда не публикуйте токен вашего бота в открытом доступе. Храните его в безопасном месте, так как он предоставляет полный доступ к управлению ботом.

---

## Создание файлов

### Структура проекта

Для корректной работы Mini App на BotHost важно правильно организовать структуру файлов. Вот рекомендуемая структура:

```
repository/
├── app.js           # Серверный код Node.js
├── package.json     # Настройки проекта
└── public/          # Папка с файлами мини-приложения
    ├── index.html   # Основной HTML файл
    ├── style.css    # Стили
    ├── script.js    # Клиентский JavaScript
    └── images/      # Папка для изображений
```

> ⚠️ Расположение файлов критически важно! HTML/CSS/JS файлы **обязательно** должны находиться в папке `public`, а не в корне репозитория.

### Серверная часть (app.js)

Файл `app.js` в корне проекта отвечает за раздачу статических файлов из папки `public`. Вот готовый код сервера на Node.js:

```javascript
// Сервер для раздачи статических файлов
const http = require('http');
const fs = require('fs');
const path = require('path');

// Порт из переменных окружения BotHost или 3000 по умолчанию
const PORT = process.env.PORT || 3000;

// MIME-типы для разных файлов
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'
};

// Создаем HTTP-сервер
const server = http.createServer((req, res) => {
  console.log(`Запрос: ${req.method} ${req.url}`);
  
  // Нормализуем URL (убираем query string, убираем ведущие слэши для безопасного join)
  let url = (req.url || '/').split('?')[0].replace(/^\/+/, '') || 'index.html';
  
  // Определяем путь к файлу и проверяем, что он внутри public (защита от path traversal)
  const publicDir = path.join(__dirname, 'public');
  const filePath = path.join(publicDir, path.normalize(url));
  const resolvedPath = path.resolve(filePath);
  const resolvedPublic = path.resolve(publicDir);
  if (!resolvedPath.startsWith(resolvedPublic + path.sep) && resolvedPath !== resolvedPublic) {
    res.writeHead(403);
    res.end('Доступ запрещён');
    return;
  }
  const extname = path.extname(resolvedPath);
  const contentType = mimeTypes[extname] || 'text/plain';
  
  // Читаем файл
  fs.readFile(resolvedPath, (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)

```json
{
  "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-зависимость для удобства локальной разработки.

### HTML-страница (public/index.html)

```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>
    
    <!-- Обязательный скрипт Telegram Web App -->
    <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!

### Стили (public/style.css)

```css
:root {
    --bg-color: #ffffff;
    --text-color: #222222;
    --hint-color: #999999;
    --button-color: #50a8eb;
    --button-text-color: #ffffff;
    --card-bg: #f5f5f7;
}

body {
    background-color: var(--tg-theme-bg-color, var(--bg-color));
    color: var(--tg-theme-text-color, var(--text-color));
    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 h1 { font-size: 24px; font-weight: 700; }
.card {
    background-color: var(--tg-theme-secondary-bg-color, var(--card-bg));
    border-radius: 12px;
    padding: 20px;
}
.button {
    background-color: var(--tg-theme-button-color, var(--button-color));
    color: var(--tg-theme-button-text-color, var(--button-text-color));
    border: none;
    border-radius: 8px;
    padding: 12px 20px;
}
```

CSS-переменные `--tg-theme-*` автоматически адаптируют приложение под светлую и темную тему пользователя в Telegram.

### JavaScript-логика (public/script.js)

```javascript
const tg = window.Telegram.WebApp;
tg.ready();
tg.expand();

// Обработчик MainButton настраиваем один раз (иначе при каждом клике добавлялся бы новый)
tg.MainButton.onClick(function() {
    const data = {
        action: 'button_pressed',
        timestamp: new Date().toISOString()
    };
    tg.sendData(JSON.stringify(data));
    setTimeout(() => tg.close(), 1000);
});

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();
        });
    }
    
    if (tg.initDataUnsafe.user) {
        const user = tg.initDataUnsafe.user;
        console.log('Пользователь:', user.first_name, user.last_name);
    }
});
```

---

## Загрузка на GitHub

### Создание репозитория

1. Зайдите на [GitHub](https://github.com/) и авторизуйтесь
2. Нажмите кнопку "+" в правом верхнем углу и выберите "New repository"
3. Введите имя для репозитория (например, "telegram-miniapp")
4. Установите видимость "Public"
5. Нажмите "Create repository"

### Загрузка файлов

#### Способ 1: Через веб-интерфейс GitHub

1. В репозитории нажмите "Add file" → "Upload files"
2. Создайте папку `public` (введя "public/file.txt" в имени файла)
3. Загрузите все файлы в соответствующие папки
4. Обязательно соблюдайте структуру: app.js и package.json в корне, остальные — в `public`

![Рис. 4: Интерфейс загрузки файлов на GitHub](/docs/images/miniapp/github_upload.png "Загрузка на GitHub")

#### Способ 2: Через Git (рекомендуется)

```bash
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
```

### Проверка структуры

```
telegram-miniapp/
├── app.js
├── package.json
└── public/
    ├── index.html
    ├── style.css
    └── script.js
```

---

## Настройка на BotHost

### Создание бота на платформе

1. Войдите в аккаунт на BotHost
2. Нажмите "Создать бота" или "Добавить бота"
3. Заполните форму:
   - **Название:** Имя для внутренней идентификации
   - **Платформа:** Telegram
   - **Библиотека/язык:** Node.js
   - **Bot Token:** Токен от BotFather
   - **Git URL репозитория:** URL вашего GitHub репозитория
   - **Локация:** Ближайшая к пользователям
4. Нажмите "Создать бота"

![Рис. 5: Форма создания бота на платформе BotHost](/docs/images/miniapp/bothost_create_bot.png "Создание бота на BotHost")

### Настройка домена

#### Вариант 1: Поддомен bothost.ru

1. В панели найдите поле для ввода домена
2. Введите имя (например, `myapp`)
3. Получите адрес `https://myapp.bothost.ru`

#### Вариант 2: Собственный домен

1. Приобретите домен
2. Настройте DNS (A-запись на IP BotHost)
3. Введите домен в панели
4. BotHost выпустит SSL-сертификат

![Рис. 6: Настройка домена для мини-приложения](/docs/images/miniapp/bothost_domain_setup.png "Настройка домена")

> ⚠️ Telegram Mini App работает **ТОЛЬКО** по HTTPS!

### Конфигурация и запуск

BotHost автоматически клонирует репозиторий и запускает приложение. Проверьте логи — должно быть сообщение `✅ Сервер запущен на порту 3000`.

#### Автообновление из GitHub

1. В панели бота найдите раздел "Автообновление"
2. Скопируйте Webhook URL
3. В GitHub: Settings → Webhooks → Add webhook
4. Вставьте URL, формат "application/json"

---

## Интеграция с Telegram

### Настройка кнопки Web App в меню бота

1. Откройте [@BotFather](https://t.me/BotFather)
2. Отправьте `/mybots` и выберите бота
3. Bot Settings → Menu Button (или `/setmenubutton`)
4. Введите текст кнопки (например, "Открыть приложение")
5. Введите URL приложения (например, `https://myapp.bothost.ru`)

![Рис. 7: Настройка кнопки меню Mini App в BotFather](/docs/images/miniapp/botfather_menu_button.png "Кнопка меню в BotFather")

### Кнопка Web App в сообщениях

**Вариант 1 — Inline-кнопка** (быстрый запуск, без отправки данных из приложения):

```javascript
bot.sendMessage(chatId, 'Нажмите, чтобы открыть приложение:', {
  reply_markup: {
    inline_keyboard: [[{
      text: 'Открыть приложение',
      web_app: { url: 'https://myapp.bothost.ru' }
    }]]
  }
});
```

**Вариант 2 — Клавиатурная кнопка** (нужна, если Mini App будет отправлять данные через `sendData`):

```javascript
bot.sendMessage(chatId, 'Нажмите, чтобы открыть приложение:', {
  reply_markup: {
    keyboard: [[{
      text: 'Открыть приложение',
      web_app: { url: 'https://myapp.bothost.ru' }
    }]],
    resize_keyboard: true
  }
});
```

> ⚠️ **Важно:** метод `sendData()` работает **только** при запуске Mini App с клавиатурной кнопки (`keyboard`), а не с inline-кнопки (`inline_keyboard`).

### Получение данных из Mini App

Для приёма данных Mini App должна быть открыта **с клавиатурной кнопки** (см. выше).

**В Mini App (sendData):**
```javascript
const data = {
  name: document.getElementById('name').value,
  email: document.getElementById('email').value
};
tg.sendData(JSON.stringify(data));
tg.close();
```

**В боте (web_app_data):**
```javascript
bot.on('message', (msg) => {
  if (msg.web_app_data) {
    const data = JSON.parse(msg.web_app_data.data);
    bot.sendMessage(msg.chat.id, `Получено: ${data.name}, ${data.email}`);
  }
});
```

---

## Продвинутые функции

### Адаптация под темы Telegram

```css
:root {
  --my-background: var(--tg-theme-bg-color, #ffffff);
  --my-text: var(--tg-theme-text-color, #222222);
  --my-button: var(--tg-theme-button-color, #50a8eb);
}
```

```javascript
const isDarkTheme = tg.colorScheme === 'dark';
```

### Использование MainButton

```javascript
tg.MainButton.setText('ОТПРАВИТЬ');
tg.MainButton.setParams({ color: '#2481cc', text_color: '#ffffff' });
tg.MainButton.show();
tg.MainButton.onClick(sendData);
```

### Получение данных о пользователе

```javascript
const user = tg.initDataUnsafe.user;
if (user) {
  console.log(user.id, user.first_name, user.username);
}
```

> ⚠️ **Безопасность:** данные из `initDataUnsafe` нельзя доверять на сервере — их можно подделать. Для проверки подлинности используйте поле `initData` и валидацию по [документации Telegram](https://core.telegram.org/bots/webapps#validating-data-received-via-the-mini-app).

### Haptic Feedback

```javascript
if (tg.HapticFeedback) {
  tg.HapticFeedback.impactOccurred('medium');
  tg.HapticFeedback.notificationOccurred('success');
}
```

---

## Решение проблем

### Ошибка "The web app was not found"

- Проверьте URL в браузере
- Убедитесь в использовании HTTPS
- Проверьте логи сервера на BotHost

### Ошибка "White screen"

- Проверьте консоль браузера
- Убедитесь, что подключен `telegram-web-app.js`
- Проверьте структуру HTML

### Проблемы с автообновлением из GitHub

- Проверьте настройки webhook в GitHub
- Убедитесь, что репозиторий публичный

### Отладка

- **Chrome/Firefox:** F12 или Ctrl+Shift+I
- **Safari:** Option+Command+I
- Логи сервера в панели BotHost

---

## Примеры проектов

### AI Support Bot

Бот технической поддержки с ИИ для ответов на вопросы.

- [Открыть бота](https://t.me/BotHostAI_Support_bot)
- [GitHub](https://github.com/Nikolay1123770/ai-support-bot.git)

### Mini App Manual

Интерактивное руководство по созданию Mini App.

- [Открыть бота](https://t.me/BotHostManualMiniApp_bot)
- [GitHub](https://github.com/Nikolay1123770/Bothostapp.git)

---

**🤖 Нужна помощь?** [Написать в поддержку](https://t.me/BotHostAI_Support_bot)

© 2025 BotHost.ru — Платформа для хостинга ботов и Mini App
