добавлено описание архитектуры
This commit is contained in:
parent
d05fc6f522
commit
ab82f94032
3 changed files with 535 additions and 14 deletions
|
|
@ -1,2 +1,10 @@
|
|||
# Токен Telegram бота (получить у @BotFather)
|
||||
TELEGRAM_BOT_TOKEN=your_telegram_bot_token_here
|
||||
|
||||
# Имя бота (username без @, используется в подписи видео)
|
||||
TELEGRAM_BOT_USERNAME=vrubelVideoDownload_bot
|
||||
|
||||
# URL VK сервиса для скачивания видео (должен быть на хосте без VPN)
|
||||
# Для локальной разработки: http://localhost:5555
|
||||
# Для продакшена: http://<ip_хоста_с_vk_сервисом>:5555
|
||||
VK_DOWNLOADER_URL=http://localhost:5555
|
||||
|
|
|
|||
346
ARCHITECTURE.md
Normal file
346
ARCHITECTURE.md
Normal file
|
|
@ -0,0 +1,346 @@
|
|||
# Архитектура системы
|
||||
|
||||
Документ описывает внутреннюю архитектуру и принципы работы Telegram Video Download Bot.
|
||||
|
||||
## Общая архитектура
|
||||
|
||||
Система состоит из двух основных компонентов:
|
||||
|
||||
1. **Основной бот** (`bot.py`) — Telegram бот, обрабатывающий запросы пользователей
|
||||
2. **VK Downloader Service** (`vk-downloader/`) — отдельный микросервис для скачивания видео с VK
|
||||
|
||||
```
|
||||
┌─────────────────┐
|
||||
│ Telegram User │
|
||||
└────────┬────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────┐
|
||||
│ Основной бот (bot.py) │
|
||||
│ ┌───────────────────────────────┐ │
|
||||
│ │ YouTube Download Handler │ │
|
||||
│ └───────────────────────────────┘ │
|
||||
│ ┌───────────────────────────────┐ │
|
||||
│ │ Instagram Download Handler │ │
|
||||
│ └───────────────────────────────┘ │
|
||||
│ ┌───────────────────────────────┐ │
|
||||
│ │ VK API Client │──┼──┐
|
||||
│ └───────────────────────────────┘ │ │
|
||||
│ ┌───────────────────────────────┐ │ │
|
||||
│ │ SQLite Database │ │ │
|
||||
│ │ - Users │ │ │
|
||||
│ │ - Stats │ │ │
|
||||
│ └───────────────────────────────┘ │ │
|
||||
└─────────────────────────────────────┘ │
|
||||
│ HTTP API
|
||||
│ POST /download/stream
|
||||
▼
|
||||
┌──────────────────────┐
|
||||
│ VK Downloader │
|
||||
│ Service │
|
||||
│ ┌────────────────┐ │
|
||||
│ │ Flask API │ │
|
||||
│ └────────────────┘ │
|
||||
│ ┌────────────────┐ │
|
||||
│ │ yt-dlp │ │
|
||||
│ │ (VK only) │ │
|
||||
│ └────────────────┘ │
|
||||
└──────────────────────┘
|
||||
```
|
||||
|
||||
## Компоненты системы
|
||||
|
||||
### 1. Основной бот (bot.py)
|
||||
|
||||
**Технологии:**
|
||||
- `python-telegram-bot` (v20.7) — асинхронный фреймворк для Telegram Bot API
|
||||
- `yt-dlp` — библиотека для скачивания видео
|
||||
- `httpx` — асинхронный HTTP клиент для запросов к VK сервису
|
||||
- `sqlite3` — база данных для хранения статистики
|
||||
|
||||
**Архитектурные решения:**
|
||||
|
||||
#### Обработка сообщений
|
||||
- Асинхронная обработка через `asyncio`
|
||||
- Каждый пользовательский запрос обрабатывается независимой корутиной
|
||||
- Параллельная обработка нескольких запросов
|
||||
|
||||
#### Скачивание видео
|
||||
- **YouTube/Instagram**: Прямое скачивание через `yt-dlp` в executor (не блокирует event loop)
|
||||
- **VK**: HTTP запрос к внешнему микросервису через `httpx`
|
||||
|
||||
#### База данных
|
||||
- SQLite с двумя таблицами:
|
||||
- `users` — информация о пользователях (chat_id, username, first_name, first_seen, last_seen)
|
||||
- `stats` — статистика (total_downloads)
|
||||
- Инициализация при запуске через `init_database()`
|
||||
- Файл базы: `data/bot.db`
|
||||
|
||||
#### Обработка ошибок
|
||||
- Retry механизм для всех источников (3 попытки по умолчанию)
|
||||
- Логирование всех ошибок
|
||||
- Информативные сообщения пользователю
|
||||
|
||||
### 2. VK Downloader Service
|
||||
|
||||
**Технологии:**
|
||||
- Flask — веб-фреймворк для REST API
|
||||
- `yt-dlp` — библиотека для скачивания видео с VK
|
||||
- Flask-CORS — для поддержки CORS (если нужно)
|
||||
|
||||
**API Endpoints:**
|
||||
|
||||
1. `GET /health` — проверка работоспособности сервиса
|
||||
- Возвращает: `{"status": "ok", "service": "vk-downloader"}`
|
||||
|
||||
2. `POST /download/stream` — скачивание видео
|
||||
- Request: `{"url": "https://vk.com/clip-..."}`
|
||||
- Response: Бинарные данные видео (200 OK) или JSON с ошибкой (400/500)
|
||||
|
||||
**Особенности реализации:**
|
||||
|
||||
#### Обработка кириллицы
|
||||
- Имена файлов с кириллицей конвертируются в ASCII для HTTP заголовков
|
||||
- Оригинальное имя сохраняется в файловой системе
|
||||
|
||||
#### Управление файлами
|
||||
- Временные файлы сохраняются в `downloads/`
|
||||
- Файлы удаляются после отправки клиенту
|
||||
- Использование UUID для уникальности имен
|
||||
|
||||
#### Ограничения
|
||||
- Flask dev server (однопоточный) — обрабатывает запросы последовательно
|
||||
- Для продакшена рекомендуется использовать Gunicorn с несколькими worker'ами
|
||||
|
||||
### 3. Определение источника видео
|
||||
|
||||
Функция `detect_video_source(url)` анализирует домен URL:
|
||||
|
||||
```python
|
||||
- youtube.com / youtu.be → 'youtube'
|
||||
- instagram.com → 'instagram'
|
||||
- vk.com / vkontakte.ru → 'vk'
|
||||
- иначе → 'unknown'
|
||||
```
|
||||
|
||||
### 4. Потоки данных
|
||||
|
||||
#### Скачивание с YouTube/Instagram
|
||||
|
||||
```
|
||||
User → Bot → detect_video_source() → download_youtube_video() / download_instagram_video()
|
||||
↓
|
||||
yt-dlp (executor) → video file → Telegram API → User
|
||||
```
|
||||
|
||||
#### Скачивание с VK
|
||||
|
||||
```
|
||||
User → Bot → detect_video_source() → download_vk_video()
|
||||
↓
|
||||
HTTP POST /download/stream → VK Service
|
||||
↓
|
||||
yt-dlp → video file → HTTP Response (binary)
|
||||
↓
|
||||
Bot receives binary → saves to disk → Telegram API → User
|
||||
```
|
||||
|
||||
### 5. База данных
|
||||
|
||||
**Схема:**
|
||||
|
||||
```sql
|
||||
CREATE TABLE users (
|
||||
chat_id INTEGER PRIMARY KEY,
|
||||
username TEXT,
|
||||
first_name TEXT,
|
||||
first_seen TEXT NOT NULL,
|
||||
last_seen TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE stats (
|
||||
id INTEGER PRIMARY KEY CHECK (id = 1),
|
||||
total_downloads INTEGER DEFAULT 0
|
||||
);
|
||||
```
|
||||
|
||||
**Операции:**
|
||||
- `add_user()` — добавление/обновление пользователя (при каждом взаимодействии)
|
||||
- `get_total_users()` — получение количества уникальных пользователей
|
||||
- `increment_downloads()` — увеличение счетчика скачанных видео
|
||||
- `get_total_downloads()` — получение количества скачанных видео
|
||||
|
||||
**Персистентность:**
|
||||
- База хранится в `data/bot.db` на хосте
|
||||
- Монтируется как volume в Docker
|
||||
- Сохраняется между перезапусками контейнера
|
||||
|
||||
## Docker архитектура
|
||||
|
||||
### Основной бот
|
||||
|
||||
**Образ:**
|
||||
- Базовый: `python:3.11-slim`
|
||||
- Зависимости: `ffmpeg`, `wget`
|
||||
- Python пакеты из `requirements.txt`
|
||||
|
||||
**Volumes:**
|
||||
- `./video:/app/video` — временные файлы видео
|
||||
- `./instagram_cookies.txt:/app/instagram_cookies.txt` — cookies для Instagram
|
||||
- `./data:/app/data:Z` — база данных (SELinux relabel)
|
||||
|
||||
**Network:**
|
||||
- `network_mode: host` — для доступа к VK сервису через localhost
|
||||
|
||||
### VK Downloader Service
|
||||
|
||||
**Образ:**
|
||||
- Базовый: `python:3.11-slim`
|
||||
- Зависимости: `ffmpeg`, `wget`
|
||||
- Python пакеты: Flask, flask-cors, yt-dlp, requests
|
||||
|
||||
**Volumes:**
|
||||
- `./downloads:/app/downloads` — временные файлы
|
||||
|
||||
**Ports:**
|
||||
- `5555:5000` — внешний порт 5555, внутренний 5000
|
||||
|
||||
**Network:**
|
||||
- Отдельная сеть `vk_network` (можно использовать host network для доступа)
|
||||
|
||||
## Безопасность
|
||||
|
||||
### Переменные окружения
|
||||
- Токен бота хранится в `.env` (не коммитится в Git)
|
||||
- Cookies для Instagram хранятся в файле (не коммитится)
|
||||
|
||||
### Ограничения доступа
|
||||
- VK сервис доступен только по указанному IP/URL
|
||||
- Нет аутентификации между ботом и VK сервисом (можно добавить API key)
|
||||
|
||||
### Файловая система
|
||||
- Временные файлы удаляются после отправки
|
||||
- Cookies файл монтируется read-only (опционально)
|
||||
|
||||
## Масштабирование
|
||||
|
||||
### Текущие ограничения
|
||||
|
||||
1. **Основной бот:**
|
||||
- Один экземпляр (можно запустить несколько с разными токенами)
|
||||
- Параллельная обработка запросов ограничена ресурсами CPU/сети
|
||||
|
||||
2. **VK сервис:**
|
||||
- Flask dev server — последовательная обработка
|
||||
- Один экземпляр контейнера
|
||||
|
||||
### Рекомендации для масштабирования
|
||||
|
||||
1. **VK сервис:**
|
||||
- Использовать Gunicorn с несколькими worker'ами:
|
||||
```bash
|
||||
gunicorn -w 4 -b 0.0.0.0:5000 app:app
|
||||
```
|
||||
- Горизонтальное масштабирование: несколько контейнеров за nginx/HAProxy
|
||||
- Load balancing для распределения нагрузки
|
||||
|
||||
2. **Основной бот:**
|
||||
- Webhook режим вместо polling (для больших нагрузок)
|
||||
- Кеширование информации о видео
|
||||
- Очередь задач (Celery) для скачивания
|
||||
|
||||
3. **База данных:**
|
||||
- Миграция на PostgreSQL для многопользовательской нагрузки
|
||||
- Connection pooling
|
||||
|
||||
## Мониторинг
|
||||
|
||||
### Логирование
|
||||
- Все компоненты логируют в stdout/stderr
|
||||
- Docker автоматически собирает логи
|
||||
- Уровни: INFO, WARNING, ERROR
|
||||
|
||||
### Метрики (можно добавить)
|
||||
- Количество запросов в секунду
|
||||
- Время обработки запроса
|
||||
- Количество ошибок
|
||||
- Размер скачанных файлов
|
||||
|
||||
### Health checks
|
||||
- VK сервис: `GET /health`
|
||||
- Основной бот: проверка через статус контейнера
|
||||
|
||||
## Производительность
|
||||
|
||||
### Оптимизации
|
||||
|
||||
1. **Асинхронная обработка:**
|
||||
- Основной бот использует asyncio для неблокирующих операций
|
||||
- yt-dlp запускается в executor для YouTube/Instagram
|
||||
|
||||
2. **Временные файлы:**
|
||||
- Хранение в памяти (tmpfs) для быстрого доступа (опционально)
|
||||
- Автоматическая очистка после отправки
|
||||
|
||||
3. **Кеширование:**
|
||||
- Можно добавить кеш информации о видео (title, duration)
|
||||
- Кеш для часто запрашиваемых видео
|
||||
|
||||
### Узкие места
|
||||
|
||||
1. **VK сервис:**
|
||||
- Последовательная обработка запросов
|
||||
- Скачивание файла перед отправкой (занимает память)
|
||||
|
||||
2. **Сеть:**
|
||||
- Зависимость от скорости интернета
|
||||
- Задержки при обращении к внешнему VK сервису
|
||||
|
||||
## Развертывание
|
||||
|
||||
### Локальная разработка
|
||||
```bash
|
||||
# Основной бот
|
||||
docker compose up -d
|
||||
|
||||
# VK сервис
|
||||
cd vk-downloader && docker compose up -d
|
||||
```
|
||||
|
||||
### Продакшен (раздельное развертывание)
|
||||
|
||||
**Хост 1 (с VPN):**
|
||||
- Основной бот
|
||||
- VPN для доступа к YouTube/Instagram
|
||||
- `.env`: `VK_DOWNLOADER_URL=http://<host2_ip>:5555`
|
||||
|
||||
**Хост 2 (без VPN):**
|
||||
- VK Downloader Service
|
||||
- Доступен по IP для хоста 1
|
||||
- Можно масштабировать горизонтально
|
||||
|
||||
### CI/CD (опционально)
|
||||
|
||||
1. Автоматический build Docker образов
|
||||
2. Тестирование перед деплоем
|
||||
3. Автоматический деплой при коммите в main
|
||||
|
||||
## Будущие улучшения
|
||||
|
||||
1. **Аутентификация между сервисами:**
|
||||
- API key для VK сервиса
|
||||
- JWT токены
|
||||
|
||||
2. **Очередь задач:**
|
||||
- Celery/RQ для фоновой обработки
|
||||
- Retry механизм через очередь
|
||||
|
||||
3. **Мониторинг:**
|
||||
- Prometheus метрики
|
||||
- Grafana дашборды
|
||||
|
||||
4. **Улучшение VK сервиса:**
|
||||
- Переход на FastAPI (более производительный)
|
||||
- Поддержка WebSockets для прогресса
|
||||
- Stream ответа вместо полной загрузки в память
|
||||
|
||||
195
README.md
195
README.md
|
|
@ -1,30 +1,197 @@
|
|||
# Telegram Video Download Bot
|
||||
|
||||
Бот для скачивания видео из различных источников (YouTube, Instagram, VK).
|
||||
Telegram бот для скачивания видео с YouTube, Instagram и VK. Поддерживает раздельное развертывание сервисов для работы с VPN и без VPN.
|
||||
|
||||
## Запуск
|
||||
## Возможности
|
||||
|
||||
- 📹 Скачивание видео с YouTube
|
||||
- 📸 Скачивание видео с Instagram (требуются cookies)
|
||||
- 🎬 Скачивание видео с VK (через отдельный микросервис)
|
||||
- 📊 Статистика скачанных видео и пользователей
|
||||
- 🔄 Автоматическое сохранение статистики в базу данных
|
||||
|
||||
## Требования
|
||||
|
||||
- Docker и Docker Compose
|
||||
- Telegram Bot Token (получить у [@BotFather](https://t.me/BotFather))
|
||||
- Для Instagram: файл с cookies (см. раздел Instagram ниже)
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
### 1. Клонирование репозитория
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
git clone <repository_url>
|
||||
cd videoDownloadBot
|
||||
```
|
||||
|
||||
## Поддерживаемые источники
|
||||
### 2. Настройка переменных окружения
|
||||
|
||||
- YouTube (youtube.com, youtu.be)
|
||||
- Instagram (instagram.com)
|
||||
- VK (vk.com, vkontakte.ru)
|
||||
Скопируйте `.env.example` в `.env` и заполните:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
nano .env # или используйте любой редактор
|
||||
```
|
||||
|
||||
**Необходимые переменные:**
|
||||
|
||||
```env
|
||||
TELEGRAM_BOT_TOKEN=your_telegram_bot_token_here
|
||||
TELEGRAM_BOT_USERNAME=your_bot_username
|
||||
VK_DOWNLOADER_URL=http://localhost:5555
|
||||
```
|
||||
|
||||
- **TELEGRAM_BOT_TOKEN** — токен бота от @BotFather
|
||||
- **TELEGRAM_BOT_USERNAME** — username бота (без @), используется в подписи видео
|
||||
- **VK_DOWNLOADER_URL** — URL VK сервиса (для локальной разработки: `http://localhost:5555`, для продакшена: `http://<ip>:5555`)
|
||||
|
||||
### 3. Настройка Instagram (опционально)
|
||||
|
||||
Если планируете скачивать видео с Instagram:
|
||||
|
||||
1. Экспортируйте cookies из браузера (см. `INSTAGRAM_COOKIES_INSTRUCTIONS.md`)
|
||||
2. Сохраните файл как `instagram_cookies.txt` в корне проекта
|
||||
3. Формат: Netscape cookies file
|
||||
|
||||
**Примечание:** Без cookies Instagram может блокировать запросы.
|
||||
|
||||
### 4. Запуск основного бота
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Бот запустится и будет готов к работе!
|
||||
|
||||
Проверить статус:
|
||||
```bash
|
||||
docker compose ps
|
||||
docker compose logs -f bot
|
||||
```
|
||||
|
||||
### 5. Запуск VK сервиса (опционально)
|
||||
|
||||
VK сервис можно запустить на том же хосте или на отдельном хосте без VPN:
|
||||
|
||||
```bash
|
||||
cd vk-downloader
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Для работы на отдельном хосте:
|
||||
1. Скопируйте папку `vk-downloader` на целевой хост
|
||||
2. Запустите: `docker compose up -d`
|
||||
3. Обновите `VK_DOWNLOADER_URL` в `.env` основного бота: `http://<ip_хоста>:5555`
|
||||
|
||||
## Использование
|
||||
|
||||
1. Найдите бота в Telegram
|
||||
1. Найдите вашего бота в Telegram по username
|
||||
2. Отправьте команду `/start`
|
||||
3. Отправьте ссылку на видео
|
||||
4. Получите скачанное видео
|
||||
3. Отправьте ссылку на видео (YouTube, Instagram или VK)
|
||||
4. Дождитесь скачивания и получите файл
|
||||
|
||||
### Команды
|
||||
|
||||
- `/start` — начало работы с ботом
|
||||
- `/stat` — статистика: количество пользователей и скачанных видео
|
||||
|
||||
## Структура проекта
|
||||
|
||||
- `bot.py` - основной код бота
|
||||
- `docker-compose.yml` - конфигурация Docker Compose
|
||||
- `Dockerfile` - образ Docker для бота
|
||||
- `requirements.txt` - зависимости Python
|
||||
```
|
||||
videoDownloadBot/
|
||||
├── bot.py # Основной код бота
|
||||
├── requirements.txt # Python зависимости
|
||||
├── Dockerfile # Образ для основного бота
|
||||
├── docker-compose.yml # Конфигурация основного бота
|
||||
├── .env.example # Пример конфигурации
|
||||
├── instagram_cookies.txt # Cookies для Instagram (создать вручную)
|
||||
├── data/ # База данных SQLite (создается автоматически)
|
||||
├── video/ # Временные файлы видео (создается автоматически)
|
||||
└── vk-downloader/ # Микросервис для VK
|
||||
├── app.py # Flask API сервис
|
||||
├── Dockerfile # Образ для VK сервиса
|
||||
└── docker-compose.yml # Конфигурация VK сервиса
|
||||
```
|
||||
|
||||
## Обновление
|
||||
|
||||
```bash
|
||||
git pull
|
||||
docker compose build
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## Логи
|
||||
|
||||
Просмотр логов основного бота:
|
||||
```bash
|
||||
docker compose logs -f bot
|
||||
```
|
||||
|
||||
Просмотр логов VK сервиса:
|
||||
```bash
|
||||
cd vk-downloader
|
||||
docker compose logs -f
|
||||
```
|
||||
|
||||
## Остановка
|
||||
|
||||
```bash
|
||||
# Основной бот
|
||||
docker compose down
|
||||
|
||||
# VK сервис
|
||||
cd vk-downloader
|
||||
docker compose down
|
||||
```
|
||||
|
||||
## Развертывание на продакшене
|
||||
|
||||
### Вариант 1: Все на одном хосте (с VPN)
|
||||
|
||||
1. Настройте VPN для доступа к YouTube и Instagram
|
||||
2. Запустите основной бот и VK сервис на одном хосте
|
||||
3. В `.env` укажите: `VK_DOWNLOADER_URL=http://localhost:5555`
|
||||
|
||||
### Вариант 2: Раздельное развертывание (рекомендуется)
|
||||
|
||||
**Хост 1 (с VPN):**
|
||||
- Основной бот (YouTube, Instagram)
|
||||
- В `.env`: `VK_DOWNLOADER_URL=http://<ip_хоста_2>:5555`
|
||||
|
||||
**Хост 2 (без VPN):**
|
||||
- VK сервис (`vk-downloader/`)
|
||||
- В `.env` основного бота: IP этого хоста
|
||||
|
||||
**Преимущества:**
|
||||
- VK работает быстрее без VPN
|
||||
- Меньше нагрузка на VPN канал
|
||||
- Возможность масштабирования VK сервиса отдельно
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Бот не отвечает
|
||||
- Проверьте логи: `docker compose logs bot`
|
||||
- Убедитесь, что токен правильный в `.env`
|
||||
|
||||
### Instagram не работает
|
||||
- Проверьте наличие `instagram_cookies.txt`
|
||||
- Обновите cookies (они могут истечь)
|
||||
|
||||
### VK не работает
|
||||
- Проверьте, что VK сервис запущен: `cd vk-downloader && docker compose ps`
|
||||
- Проверьте URL в `.env`: `VK_DOWNLOADER_URL`
|
||||
- Проверьте доступность порта 5555
|
||||
|
||||
### База данных не сохраняется
|
||||
- Проверьте права на папку `data/`
|
||||
- Убедитесь, что volume смонтирован в `docker-compose.yml`
|
||||
|
||||
## Лицензия
|
||||
|
||||
MIT
|
||||
|
||||
## Поддержка
|
||||
|
||||
При возникновении проблем создайте issue в репозитории.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue