From 77d370490992c403bd3e827dcb650d13f07767f3 Mon Sep 17 00:00:00 2001 From: vrubelroman Date: Fri, 12 Dec 2025 12:39:11 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=B0=D1=80=D1=85=D0=B8=D1=82=D0=B5=D0=BA=D1=82?= =?UTF-8?q?=D1=83=D1=80=D0=B0=20=D0=B8=20=D0=B4=D0=BE=D0=BA=D1=83=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D1=82=D0=B0=D1=86=D0=B8=D1=8F:=20=D0=B4=D0=BE?= =?UTF-8?q?=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D1=8B=D0=B5=20=D1=81=D0=B5=D1=80=D0=B2=D0=B8=D1=81=D1=8B=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20TikTok=20=D0=B8=20Yapfiles,=20=D0=BE=D0=B1?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BF=D0=BE=D1=80?= =?UTF-8?q?=D1=82=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D0=B2=D1=81=D0=B5=D1=85=20?= =?UTF-8?q?=D0=B7=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D1=87=D0=B8=D0=BA=D0=BE?= =?UTF-8?q?=D0=B2,=20=D1=83=D0=BB=D1=83=D1=87=D1=88=D0=B5=D0=BD=D0=B0=20?= =?UTF-8?q?=D0=BB=D0=BE=D0=BA=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=B8=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D0=BA=D0=BE=D0=BC=D0=B0=D0=BD=D0=B4=D1=8B=20?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D0=B0.=20=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=B8=D0=BD=D1=81=D1=82=D1=80=D1=83?= =?UTF-8?q?=D0=BA=D1=86=D0=B8=D0=B8=20=D0=BF=D0=BE=20=D0=B7=D0=B0=D0=BF?= =?UTF-8?q?=D1=83=D1=81=D0=BA=D1=83=20=D0=B8=20=D0=BD=D0=B0=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=BE=D0=B9=D0=BA=D0=B5.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ARCHITECTURE.md | 608 ++++++++++++++---------------------------------- README.md | 255 +++++++------------- 2 files changed, 252 insertions(+), 611 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index a9a8210..c0df605 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -6,10 +6,12 @@ Система состоит из микросервисной архитектуры с раздельными сервисами для каждого источника видео: -1. **Основной бот** (`bot.py` в корне проекта) — Telegram бот, обрабатывающий запросы пользователей и оркестрирующий запросы к сервисам -2. **YouTube Downloader Service** (`youtube-downloader/`) — микросервис для скачивания видео с YouTube -3. **Instagram Downloader Service** (`instagram-downloader/`) — микросервис для скачивания видео с Instagram -4. **VK Downloader Service** (`vk-downloader/`) — микросервис для скачивания видео с VK +1. **Основной бот** (`bot.py`) — Telegram бот, обрабатывающий запросы пользователей +2. **YouTube Downloader Service** (`youtube-downloader/`) — порт 5557 +3. **Instagram Downloader Service** (`instagram-downloader/`) — порт 5556 +4. **VK Downloader Service** (`vk-downloader/`) — порт 5555 +5. **Yapfiles Downloader Service** (`yapfiles-downloader/`) — порт 5558 +6. **TikTok Downloader Service** (`tiktok-downloader/`) — порт 5559 ``` ┌─────────────────┐ @@ -17,231 +19,112 @@ └────────┬────────┘ │ ▼ -┌─────────────────────────────────────┐ -│ Основной бот (bot.py) │ -│ ┌───────────────────────────────┐ │ -│ │ Message Handler │ │ -│ │ - URL extraction │ │ -│ │ - Source detection │ │ -│ └───────────────────────────────┘ │ -│ ┌───────────────────────────────┐ │ -│ │ HTTP API Clients │──┼──┐ -│ │ - YouTube API Client │ │ │ -│ │ - Instagram API Client │ │ │ -│ │ - VK API Client │ │ │ -│ └───────────────────────────────┘ │ │ -│ ┌───────────────────────────────┐ │ │ -│ │ SQLite Database │ │ │ -│ │ - Users │ │ │ -│ │ - Stats │ │ │ -│ └───────────────────────────────┘ │ │ -│ ┌───────────────────────────────┐ │ │ -│ │ Video Storage │ │ │ -│ │ - video/ directory │ │ │ -│ └───────────────────────────────┘ │ │ -└─────────────────────────────────────┘ │ - │ HTTP API - │ POST /download/stream - │ - ┌──────────────────────────────────┼──────────────────┐ - │ │ │ - ▼ ▼ ▼ -┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ -│ YouTube Downloader│ │Instagram Download│ │ VK Downloader │ -│ Service │ │ Service │ │ Service │ -│ ┌──────────────┐ │ │ ┌──────────────┐ │ │ ┌──────────────┐│ -│ │ Flask API │ │ │ │ Flask API │ │ │ │ Flask API ││ -│ └──────────────┘ │ │ └──────────────┘ │ │ └──────────────┘│ -│ ┌──────────────┐ │ │ ┌──────────────┐ │ │ ┌──────────────┐│ -│ │ yt-dlp │ │ │ │ yt-dlp │ │ │ │ yt-dlp ││ -│ │ (YouTube) │ │ │ │ (Instagram) │ │ │ │ (VK only) ││ -│ └──────────────┘ │ │ └──────────────┘ │ │ └──────────────┘│ -│ Port: 5557 │ │ Port: 5556 │ │ Port: 5555 │ -└──────────────────┘ └──────────────────┘ └──────────────────┘ +┌─────────────────────────────────────────────────────────┐ +│ Основной бот (bot.py) │ +│ ┌────────────────────────────────────────────────────┐ │ +│ │ Message Handler │ │ +│ │ - URL extraction │ │ +│ │ - Source detection (YouTube/Instagram/TikTok/VK/ │ │ +│ │ Yapfiles) │ │ +│ │ - Localization (ru/en) │ │ +│ └────────────────────────────────────────────────────┘ │ +│ ┌────────────────────────────────────────────────────┐ │ +│ │ HTTP API Clients (httpx) │ │ +│ │ - YouTube, Instagram, TikTok, VK, Yapfiles │ │ +│ └────────────────────────────────────────────────────┘ │ +│ ┌────────────────────────────────────────────────────┐ │ +│ │ SQLite Database (data/bot.db) │ │ +│ │ - users (chat_id, username, locale, ...) │ │ +│ │ - stats (total_downloads) │ │ +│ └────────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────┘ + │ HTTP POST /download/stream + ▼ +┌────────┬────────┬────────┬────────┬────────┐ +│YouTube │Instagram│ TikTok │ VK │Yapfiles│ +│ :5557 │ :5556 │ :5559 │ :5555 │ :5558 │ +│ │ │ │ │ │ +│yt-dlp │yt-dlp │yt-dlp │yt-dlp │requests│ +│ │+cookies│ │ │+parsing│ +└────────┴────────┴────────┴────────┴────────┘ ``` ## Компоненты системы ### 1. Основной бот (bot.py) -**Расположение:** Корень проекта - **Технологии:** -- `python-telegram-bot` (v20.7) — асинхронный фреймворк для Telegram Bot API -- `httpx` — асинхронный HTTP клиент для запросов к сервисам загрузчиков -- `sqlite3` — база данных для хранения статистики +- `python-telegram-bot` — асинхронный фреймворк для Telegram Bot API +- `httpx` — асинхронный HTTP клиент +- `sqlite3` — база данных -**Архитектурные решения:** - -#### Обработка сообщений -- Асинхронная обработка через `asyncio` -- Каждый пользовательский запрос обрабатывается независимой корутиной -- Параллельная обработка нескольких запросов -- Автоматическое извлечение URL из текста сообщений (работа в группах) - -#### Скачивание видео -- **Все источники**: HTTP запросы к соответствующим микросервисам через `httpx` -- **YouTube**: `POST http://youtube-downloader:5000/download/stream` -- **Instagram**: `POST http://instagram-downloader:5000/download/stream` -- **VK**: `POST http://vk-downloader:5000/download/stream` -- Получение бинарных данных и сохранение во временный файл -- Отправка через Telegram API - -#### Хранение видео -- Все скачанные видео сохраняются в папке `video/` на хосте -- Файлы не удаляются автоматически (сохраняются для пользователей) -- Автоматическая очистка только `.part` файлов (недокачанные) - -#### База данных -- SQLite с двумя таблицами: - - `users` — информация о пользователях (chat_id, username, first_name, first_seen, last_seen) - - `stats` — статистика (total_downloads) -- Инициализация при запуске через `init_database()` -- Файл базы: `data/bot.db` - -#### Обработка ошибок -- Retry механизм для всех источников (3 попытки по умолчанию) -- Логирование всех ошибок -- Информативные сообщения пользователю -- Автоматическая очистка `.part` файлов при ошибках - -### 2. YouTube Downloader Service - -**Расположение:** `youtube-downloader/` - -**Технологии:** -- Flask — веб-фреймворк для REST API -- `yt-dlp` — библиотека для скачивания видео с YouTube -- Flask-CORS — для поддержки CORS - -**API Endpoints:** - -1. `GET /health` — проверка работоспособности сервиса - - Возвращает: `{"status": "ok", "service": "youtube-downloader"}` - -2. `POST /download/stream` — скачивание видео - - Request: `{"url": "https://youtube.com/watch?v=..."}` - - Response: Бинарные данные видео (200 OK) или JSON с ошибкой (400/500) - -**Особенности:** -- Использует специальные настройки yt-dlp для YouTube (player_client, headers) -- Поддержка различных форматов видео (mp4, webm, mkv) -- Временные файлы сохраняются в `downloads/` и удаляются после отправки - -**Порт:** 5557 (внешний) → 5000 (внутренний) - -### 3. Instagram Downloader Service - -**Расположение:** `instagram-downloader/` - -**Технологии:** -- Flask — веб-фреймворк для REST API -- `yt-dlp` — библиотека для скачивания видео с Instagram -- Flask-CORS — для поддержки CORS - -**API Endpoints:** - -1. `GET /health` — проверка работоспособности сервиса - - Возвращает: `{"status": "ok", "service": "instagram-downloader"}` - -2. `POST /download/stream` — скачивание видео - - Request: `{"url": "https://instagram.com/p/..."}` - - Response: Бинарные данные видео (200 OK) или JSON с ошибкой (400/500) - -**Особенности:** -- Требует файл с cookies Instagram (`instagram_cookies.txt` в папке сервиса) -- Автоматическая проверка срока действия cookies -- Поддержка CSRF токенов и session cookies -- Скрипты для получения/обновления cookies в папке сервиса - -**Порт:** 5556 (внешний) → 5000 (внутренний) - -### 4. VK Downloader Service - -**Расположение:** `vk-downloader/` - -**Технологии:** -- 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) - -**Особенности:** -- Специальные заголовки для VK (User-Agent, Referer) -- Обработка кириллицы в именах файлов -- Временные файлы сохраняются в `downloads/` и удаляются после отправки - -**Порт:** 5555 (внешний) → 5000 (внутренний) - -### 5. Определение источника видео - -Функция `detect_video_source(url)` анализирует домен URL: +**Ключевые функции:** +#### Локализация ```python -- youtube.com / youtu.be → 'youtube' -- instagram.com → 'instagram' -- vk.com / vkontakte.ru → 'vk' -- иначе → 'unknown' +TEXTS = { + 'ru': { 'start': '...', 'support': '...', ... }, + 'en': { 'start': '...', 'support': '...', ... } +} + +def get_locale_from_language_code(language_code: str) -> str: + # 'ru*' → 'ru', иначе → 'en' ``` -### 6. Потоки данных - -#### Общий поток скачивания - -``` -User → Bot → extract_urls_from_text() → detect_video_source() - ↓ - HTTP POST /download/stream → [YouTube/Instagram/VK] Service - ↓ - yt-dlp → video file → HTTP Response (binary) - ↓ - Bot receives binary → saves to video/ → Telegram API → User +#### Определение источника +```python +def detect_video_source(url: str) -> str: + # youtube.com, youtu.be → 'youtube' + # instagram.com → 'instagram' + # tiktok.com → 'tiktok' + # vk.com, vkontakte.ru → 'vk' + # yapfiles.ru → 'yapfiles' + # иначе → 'unknown' ``` -#### Детальный поток для каждого источника +#### Команды +- `/start` — приветствие с локализацией +- `/stat` — статистика бота +- `/support` — информация о боте и контакт автора -**YouTube:** -``` -User → Bot → download_youtube_video() - ↓ - httpx.AsyncClient → POST http://youtube-downloader:5000/download/stream - ↓ - YouTube Service → yt-dlp → binary data - ↓ - Bot saves to video/ → sends to User +### 2. Сервисы загрузчиков + +Все сервисы имеют единый API: + +| Endpoint | Метод | Описание | +|----------|-------|----------| +| `/health` | GET | Проверка работоспособности | +| `/download/stream` | POST | Скачивание видео | + +**Request:** +```json +{"url": "https://..."} ``` -**Instagram:** -``` -User → Bot → download_instagram_video() - ↓ - httpx.AsyncClient → POST http://instagram-downloader:5000/download/stream - ↓ - Instagram Service → yt-dlp (with cookies) → binary data - ↓ - Bot saves to video/ → sends to User -``` +**Response:** Бинарные данные видео или JSON с ошибкой. -**VK:** -``` -User → Bot → download_vk_video() - ↓ - httpx.AsyncClient → POST http://vk-downloader:5000/download/stream - ↓ - VK Service → yt-dlp → binary data - ↓ - Bot saves to video/ → sends to User -``` +#### YouTube Downloader (порт 5557) +- Использует `yt-dlp` с настройками для YouTube +- Поддержка shorts, плейлистов -### 7. База данных +#### Instagram Downloader (порт 5556) +- Использует `yt-dlp` с cookies +- Требует `instagram_cookies.txt` + +#### TikTok Downloader (порт 5559) +- Использует `yt-dlp` +- Поддержка коротких и полных ссылок + +#### VK Downloader (порт 5555) +- Использует `yt-dlp` с русскими заголовками +- Не требует VPN в РФ + +#### Yapfiles Downloader (порт 5558) +- Парсит HTML страницу +- Извлекает прямую ссылку на видео +- Использует `requests` + `BeautifulSoup` + +### 3. База данных **Схема:** @@ -251,7 +134,8 @@ CREATE TABLE users ( username TEXT, first_name TEXT, first_seen TEXT NOT NULL, - last_seen TEXT NOT NULL + last_seen TEXT NOT NULL, + locale TEXT DEFAULT 'en' -- ru/en ); CREATE TABLE stats ( @@ -260,255 +144,105 @@ CREATE TABLE stats ( ); ``` -**Операции:** -- `add_user()` — добавление/обновление пользователя (при каждом взаимодействии) -- `get_total_users()` — получение количества уникальных пользователей -- `increment_downloads()` — увеличение счетчика скачанных видео -- `get_total_downloads()` — получение количества скачанных видео +**Миграция:** При запуске бот автоматически добавляет колонку `locale` если её нет (для совместимости со старой базой). -**Персистентность:** -- База хранится в `data/bot.db` на хосте -- Монтируется как volume в Docker -- Сохраняется между перезапусками контейнера +### 4. Скрипт рассылки (broadcast.py) + +Консольная утилита для отправки сообщений всем пользователям: + +```bash +./broadcast.py -y "Текст сообщения" +./broadcast.py -y --html "Жирный текст" +./broadcast.py -y --file message.txt +./broadcast.py --list # показать пользователей +``` + +Автоматически читает `.env` для получения токена бота. ## Docker архитектура -### Основной бот +### Порты -**Расположение:** Корень проекта +| Сервис | Внешний порт | Внутренний порт | +|--------|--------------|-----------------| +| VK | 5555 | 5000 | +| Instagram | 5556 | 5000 | +| YouTube | 5557 | 5000 | +| Yapfiles | 5558 | 5000 | +| TikTok | 5559 | 5000 | -**Образ:** -- Базовый: `python:3.11-slim` -- Python пакеты из `requirements.txt` (python-telegram-bot, httpx) +### Volumes -**Volumes:** -- `./video:/app/video` — сохраненные видео (не удаляются) -- `./data:/app/data:Z` — база данных (SELinux relabel) +**Основной бот:** +- `./video:/app/video` — скачанные видео +- `./data:/app/data` — база данных -**Network:** -- `network_mode: host` — для доступа к сервисам по localhost или IP +**Сервисы загрузчиков:** +- `./downloads:/app/downloads` — временные файлы +- (Instagram) `./instagram_cookies.txt:/app/instagram_cookies.txt:ro` + +## Потоки данных + +``` +User → Telegram → Bot + ↓ + detect_video_source(url) + ↓ + download_{source}_video() + ↓ + HTTP POST → Service → yt-dlp/parser + ↓ + binary video data + ↓ + save to video/ → send to User + ↓ + increment_downloads() +``` + +## Развертывание + +### Вариант 1: Все на одном хосте -**Запуск:** ```bash +# Запуск всех сервисов +for dir in youtube instagram vk yapfiles tiktok; do + cd ${dir}-downloader && docker compose up -d && cd .. +done docker compose up -d ``` -### YouTube Downloader Service +### Вариант 2: Раздельное развертывание -**Расположение:** `youtube-downloader/` +**Хост 1 (с VPN для YouTube/Instagram/TikTok):** +- Основной бот +- YouTube, Instagram, TikTok сервисы -**Образ:** -- Базовый: `python:3.11-slim` -- Зависимости: `ffmpeg`, `wget` -- Python пакеты: Flask, flask-cors, yt-dlp +**Хост 2 (без VPN):** +- VK, Yapfiles сервисы -**Volumes:** -- `./downloads:/app/downloads` — временные файлы - -**Ports:** -- `5557:5000` — внешний порт 5557, внутренний 5000 - -**Запуск:** -```bash -cd youtube-downloader && docker compose up -d -``` - -### Instagram Downloader Service - -**Расположение:** `instagram-downloader/` - -**Образ:** -- Базовый: `python:3.11-slim` -- Зависимости: `ffmpeg`, `wget` -- Python пакеты: Flask, flask-cors, yt-dlp - -**Volumes:** -- `./downloads:/app/downloads` — временные файлы -- `./instagram_cookies.txt:/app/instagram_cookies.txt:ro` — cookies (read-only) - -**Environment:** -- `INSTAGRAM_COOKIES_FILE=/app/instagram_cookies.txt` - -**Ports:** -- `5556:5000` — внешний порт 5556, внутренний 5000 - -**Запуск:** -```bash -cd instagram-downloader && docker compose up -d -``` - -### VK Downloader Service - -**Расположение:** `vk-downloader/` - -**Образ:** -- Базовый: `python:3.11-slim` -- Зависимости: `ffmpeg`, `wget` -- Python пакеты: Flask, flask-cors, yt-dlp, requests - -**Volumes:** -- `./downloads:/app/downloads` — временные файлы - -**Ports:** -- `5555:5000` — внешний порт 5555, внутренний 5000 - -**Запуск:** -```bash -cd vk-downloader && docker compose up -d +В `.env` на хосте 1: +```env +VK_DOWNLOADER_URL=http://:5555 +YAPFILES_DOWNLOADER_URL=http://:5558 ``` ## Безопасность -### Переменные окружения -- Токен бота хранится в `.env` (не коммитится в Git) -- Cookies для Instagram хранятся в файле `instagram-downloader/instagram_cookies.txt` (не коммитится) -- URL сервисов настраиваются через `.env` - -### Ограничения доступа -- Сервисы загрузчиков доступны только по указанным IP/URL -- Нет аутентификации между ботом и сервисами (можно добавить API key) -- Cookies файл монтируется read-only - -### Файловая система -- Видео сохраняются в `video/` и не удаляются автоматически -- Временные файлы в сервисах удаляются после отправки -- Автоматическая очистка только `.part` файлов - -## Масштабирование - -### Текущие ограничения - -1. **Основной бот:** - - Один экземпляр (можно запустить несколько с разными токенами) - - Параллельная обработка запросов через asyncio - - Ограничения: ресурсы CPU/сети - -2. **Сервисы загрузчиков:** - - Flask dev server — последовательная обработка - - Один экземпляр контейнера каждого сервиса - - Можно масштабировать горизонтально - -### Рекомендации для масштабирования - -1. **Сервисы загрузчиков:** - - Использовать 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 +- Токен бота в `.env` (не коммитится) +- Cookies Instagram в отдельном файле (не коммитится) +- Сервисы доступны только по указанным URL +- Можно добавить API key между сервисами ## Мониторинг -### Логирование -- Все компоненты логируют в stdout/stderr -- Docker автоматически собирает логи -- Уровни: INFO, WARNING, ERROR - -### Метрики (можно добавить) -- Количество запросов в секунду -- Время обработки запроса -- Количество ошибок -- Размер скачанных файлов - -### Health checks -- Все сервисы: `GET /health` -- Основной бот: проверка через статус контейнера - -## Производительность - -### Оптимизации - -1. **Асинхронная обработка:** - - Основной бот использует asyncio для неблокирующих операций - - HTTP запросы к сервисам через httpx (асинхронный) - -2. **Хранение видео:** - - Видео сохраняются на хосте (volume), не в образе контейнера - - Файлы доступны для пользователей после скачивания - -3. **Кеширование:** - - Можно добавить кеш информации о видео (title, duration) - - Кеш для часто запрашиваемых видео - -### Узкие места - -1. **Сервисы загрузчиков:** - - Последовательная обработка запросов (Flask dev server) - - Скачивание файла перед отправкой (занимает память) - -2. **Сеть:** - - Зависимость от скорости интернета - - Задержки при обращении к внешним сервисам - - Задержки между ботом и сервисами загрузчиков - -## Развертывание - -### Локальная разработка - -```bash -# Запуск сервисов загрузчиков (каждый в своей папке) -cd youtube-downloader && docker compose up -d -cd ../instagram-downloader && docker compose up -d -cd ../vk-downloader && docker compose up -d - -# Запуск основного бота (из корня проекта) -cd .. -docker compose up -d -``` - -### Продакшен (раздельное развертывание) - -**Хост 1 (с VPN для YouTube/Instagram):** -- Основной бот -- YouTube сервис (порт 5557) -- Instagram сервис (порт 5556) -- VPN для доступа к YouTube/Instagram -- `.env`: - - `YOUTUBE_DOWNLOADER_URL=http://localhost:5557` - - `INSTAGRAM_DOWNLOADER_URL=http://localhost:5556` - - `VK_DOWNLOADER_URL=http://:5555` - -**Хост 2 (без VPN для VK):** -- VK Downloader Service (порт 5555) -- Доступен по IP для хоста 1 -- Можно масштабировать горизонтально - -### CI/CD (опционально) - -1. Автоматический build Docker образов -2. Тестирование перед деплоем -3. Автоматический деплой при коммите в main +- Все сервисы логируют в stdout +- Health check: `GET /health` на каждом сервисе +- Логи Docker: `docker compose logs -f` ## Будущие улучшения -1. **Аутентификация между сервисами:** - - API key для сервисов загрузчиков - - JWT токены - -2. **Очередь задач:** - - Celery/RQ для фоновой обработки - - Retry механизм через очередь - -3. **Мониторинг:** - - Prometheus метрики - - Grafana дашборды - -4. **Улучшение сервисов:** - - Переход на FastAPI (более производительный) - - Поддержка WebSockets для прогресса - - Stream ответа вместо полной загрузки в память - -5. **Хранение видео:** - - Организация по датам/пользователям - - Автоматическая очистка старых файлов (опционально) - - Интеграция с облачным хранилищем +1. **Аутентификация между сервисами** — API key/JWT +2. **Очередь задач** — Celery для фоновой обработки +3. **Prometheus метрики** — мониторинг производительности +4. **Кеширование** — Redis для частых запросов +5. **Поддержка новых источников** — Twitter, Facebook, etc. diff --git a/README.md b/README.md index ab1ede7..4af5908 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Telegram Video Download Bot -Telegram бот для скачивания видео с YouTube, Instagram и VK. Микросервисная архитектура с раздельными сервисами для каждого источника. +Telegram бот для скачивания видео с YouTube, Instagram, TikTok, VK и Yapfiles. Микросервисная архитектура с раздельными сервисами для каждого источника. ## Архитектура @@ -10,6 +10,8 @@ Telegram бот для скачивания видео с YouTube, Instagram и - **youtube-downloader** - сервис для скачивания с YouTube (порт 5557) - **instagram-downloader** - сервис для скачивания с Instagram (порт 5556) - **vk-downloader** - сервис для скачивания с VK (порт 5555) +- **yapfiles-downloader** - сервис для скачивания с Yapfiles (порт 5558) +- **tiktok-downloader** - сервис для скачивания с TikTok (порт 5559) Каждый сервис работает в отдельном Docker контейнере и может быть развернут независимо. @@ -17,10 +19,20 @@ Telegram бот для скачивания видео с YouTube, Instagram и - 📹 Скачивание видео с YouTube - 📸 Скачивание видео с Instagram (требуются cookies) +- 🎵 Скачивание видео с TikTok - 🎬 Скачивание видео с VK +- 📁 Скачивание видео с Yapfiles +- 🌍 Локализация интерфейса (русский/английский) на основе языка пользователя - 📊 Статистика скачанных видео и пользователей - 🔄 Автоматическое сохранение статистики в базу данных - 👥 Работа в группах с автоматическим обнаружением ссылок +- 📢 Рассылка сообщений всем пользователям (`broadcast.py`) + +## Команды бота + +- `/start` — начало работы с ботом +- `/stat` — статистика: количество пользователей и скачанных видео +- `/support` — информация о боте и контакт автора ## Требования @@ -53,173 +65,97 @@ TELEGRAM_BOT_TOKEN=your_telegram_bot_token_here TELEGRAM_BOT_USERNAME=your_bot_username # Downloader Services URLs -# Для локальной разработки через docker-compose используются внутренние имена сервисов -YOUTUBE_DOWNLOADER_URL=http://youtube-downloader:5000 -INSTAGRAM_DOWNLOADER_URL=http://instagram-downloader:5000 -VK_DOWNLOADER_URL=http://vk-downloader:5000 +YOUTUBE_DOWNLOADER_URL=http://localhost:5557 +INSTAGRAM_DOWNLOADER_URL=http://localhost:5556 +VK_DOWNLOADER_URL=http://localhost:5555 +YAPFILES_DOWNLOADER_URL=http://localhost:5558 +TIKTOK_DOWNLOADER_URL=http://localhost:5559 ``` -- **TELEGRAM_BOT_TOKEN** — токен бота от @BotFather -- **TELEGRAM_BOT_USERNAME** — username бота (без @), используется в подписи видео -- **YOUTUBE_DOWNLOADER_URL** — URL YouTube сервиса (для docker-compose: `http://youtube-downloader:5000`, для продакшена: `http://:5557`) -- **INSTAGRAM_DOWNLOADER_URL** — URL Instagram сервиса (для docker-compose: `http://instagram-downloader:5000`, для продакшена: `http://:5556`) -- **VK_DOWNLOADER_URL** — URL VK сервиса (для docker-compose: `http://vk-downloader:5000`, для продакшена: `http://:5555`) - ### 3. Настройка Instagram (опционально) Если планируете скачивать видео с Instagram: 1. Экспортируйте cookies из браузера (см. `instagram-downloader/INSTAGRAM_COOKIES_INSTRUCTIONS.md`) 2. Сохраните файл как `instagram_cookies.txt` в папке `instagram-downloader/` -3. Формат: Netscape cookies file - -**Быстрое получение cookies через скрипт:** ```bash cd instagram-downloader ./get_instagram_cookies.sh ``` -Или обновление существующих cookies: - -```bash -cd instagram-downloader -./update_instagram_cookies.sh -``` - -**Примечание:** Без cookies Instagram может блокировать запросы. При первом запуске обновите cookies вручную. - ### 4. Запуск сервисов -**Важно:** Каждый сервис запускается отдельно на своем хосте (или на одном хосте, но отдельными командами). - -#### Запуск основного бота +**Каждый сервис запускается отдельно:** ```bash -# Из корня проекта +# Запуск сервисов загрузчиков +cd youtube-downloader && docker compose up -d && cd .. +cd instagram-downloader && docker compose up -d && cd .. +cd vk-downloader && docker compose up -d && cd .. +cd yapfiles-downloader && docker compose up -d && cd .. +cd tiktok-downloader && docker compose up -d && cd .. + +# Запуск основного бота (из корня проекта) docker compose up -d ``` -Это запустит только основной Telegram бот. - -#### Запуск сервисов загрузчиков - -Каждый сервис запускается отдельно в своей папке: - -```bash -# Запуск YouTube сервиса (порт 5557) -cd youtube-downloader -docker compose up -d - -# Запуск Instagram сервиса (порт 5556) -cd ../instagram-downloader -docker compose up -d - -# Запуск VK сервиса (порт 5555) -cd ../vk-downloader -docker compose up -d -``` - -**Порядок запуска:** Сначала запустите сервисы загрузчиков, затем основной бот. - -#### Раздельное развертывание на разных хостах (рекомендуется для продакшена) - -**Хост 1 (с VPN для YouTube/Instagram):** -- YouTube сервис (порт 5557) -- Instagram сервис (порт 5556) -- Основной бот - -**Хост 2 (без VPN для VK):** -- VK сервис (порт 5555) - -В `.env` файле в корне проекта на хосте 1 укажите IP адреса сервисов: -```env -YOUTUBE_DOWNLOADER_URL=http://localhost:5557 -INSTAGRAM_DOWNLOADER_URL=http://localhost:5556 -VK_DOWNLOADER_URL=http://:5555 -``` - ### 5. Проверка статуса -Проверить статус сервисов: - ```bash -# Основной бот (из корня проекта) -docker compose ps - -# Сервисы загрузчиков (из соответствующих папок) -cd youtube-downloader && docker compose ps -cd ../instagram-downloader && docker compose ps -cd ../vk-downloader && docker compose ps +# Проверка всех сервисов +docker ps | grep -E "(video_download_bot|youtube|instagram|vk|yapfiles|tiktok)" ``` -Просмотр логов: +## Порты сервисов + +| Сервис | Порт | +|--------|------| +| VK Downloader | 5555 | +| Instagram Downloader | 5556 | +| YouTube Downloader | 5557 | +| Yapfiles Downloader | 5558 | +| TikTok Downloader | 5559 | + +## Рассылка сообщений + +Скрипт `broadcast.py` позволяет отправить сообщение всем пользователям бота: ```bash -# Основной бот (из корня проекта) -docker compose logs -f bot +# Простое сообщение +./broadcast.py -y "Текст сообщения" -# Сервисы загрузчиков (из соответствующих папок) -cd youtube-downloader && docker compose logs -f -cd ../instagram-downloader && docker compose logs -f -cd ../vk-downloader && docker compose logs -f +# С HTML-разметкой +./broadcast.py -y --html 'Важно! Новая функция добавлена.' + +# Из файла +./broadcast.py -y --file announcement.txt --html + +# Посмотреть список пользователей +./broadcast.py --list ``` -## Использование - -1. Найдите вашего бота в Telegram по username -2. Отправьте команду `/start` -3. Отправьте ссылку на видео (YouTube, Instagram или VK) -4. Дождитесь скачивания и получите файл - -### Работа в группах - -Добавьте бота в группу и дайте ему права администратора (нужно право на удаление сообщений). После этого бот будет автоматически находить ссылки на видео в сообщениях участников, скачивать их и отправлять прямо в группу, заменяя исходное сообщение со ссылкой. - -### Команды - -- `/start` — начало работы с ботом -- `/stat` — статистика: количество пользователей и скачанных видео - ## Структура проекта ``` videoDownloadBot/ ├── bot.py # Код основного Telegram бота +├── broadcast.py # Скрипт для рассылки сообщений ├── requirements.txt # Python зависимости бота ├── Dockerfile # Образ для бота -├── docker-compose.yml # Оркестратор всех сервисов -├── .env.example # Пример конфигурации +├── docker-compose.yml # Конфигурация бота +├── .env.example # Пример конфигурации +├── data/ # База данных (bot.db) +├── video/ # Скачанные видео ├── youtube-downloader/ # Сервис для YouTube -│ ├── app.py # Flask API сервис -│ ├── requirements.txt # Python зависимости -│ ├── Dockerfile # Образ для YouTube сервиса -│ └── docker-compose.yml # Конфигурация YouTube сервиса ├── instagram-downloader/ # Сервис для Instagram -│ ├── app.py # Flask API сервис -│ ├── requirements.txt # Python зависимости -│ ├── Dockerfile # Образ для Instagram сервиса -│ ├── docker-compose.yml # Конфигурация Instagram сервиса -│ ├── instagram_cookies.txt # Cookies для Instagram (создать вручную) -│ ├── get_instagram_cookies.sh # Скрипт для получения cookies -│ ├── update_instagram_cookies.sh # Скрипт для обновления cookies -│ ├── INSTAGRAM_COOKIES_INSTRUCTIONS.md # Инструкции по cookies -│ └── README.md # Документация сервиса -├── vk-downloader/ # Сервис для VK -│ ├── app.py # Flask API сервис -│ ├── requirements.txt # Python зависимости -│ ├── Dockerfile # Образ для VK сервиса -│ └── docker-compose.yml # Конфигурация VK сервиса -└── README.md # Этот файл +├── vk-downloader/ # Сервис для VK +├── yapfiles-downloader/ # Сервис для Yapfiles +├── tiktok-downloader/ # Сервис для TikTok +├── README.md # Этот файл +└── ARCHITECTURE.md # Описание архитектуры ``` -## Порты сервисов - -- **Основной бот**: не требует внешних портов (работает через Telegram API) -- **YouTube Downloader**: порт 5557 -- **Instagram Downloader**: порт 5556 -- **VK Downloader**: порт 5555 - ## API Endpoints Все сервисы загрузчиков предоставляют одинаковый API: @@ -227,7 +163,6 @@ videoDownloadBot/ - `GET /health` - проверка здоровья сервиса - `POST /download/stream` - скачивание видео (возвращает бинарные данные) -Пример запроса: ```json POST /download/stream Content-Type: application/json @@ -242,51 +177,24 @@ Content-Type: application/json ```bash git pull -# Пересобрать и перезапустить основной бот (из корня проекта) -docker compose build && docker compose up -d +# Пересобрать и перезапустить основной бот +docker compose down && docker compose up -d --build -# Пересобрать и перезапустить каждый сервис загрузчика отдельно -cd youtube-downloader && docker compose build && docker compose up -d -cd ../instagram-downloader && docker compose build && docker compose up -d -cd ../vk-downloader && docker compose build && docker compose up -d +# Пересобрать сервисы загрузчиков +cd youtube-downloader && docker compose up -d --build && cd .. +cd instagram-downloader && docker compose up -d --build && cd .. +cd vk-downloader && docker compose up -d --build && cd .. +cd yapfiles-downloader && docker compose up -d --build && cd .. +cd tiktok-downloader && docker compose up -d --build && cd .. ``` -## Остановка +## Локализация -```bash -# Остановить основной бот (из корня проекта) -docker compose down +Бот автоматически определяет язык пользователя из настроек Telegram: +- Если язык начинается с `ru` — интерфейс на русском +- Иначе — интерфейс на английском -# Остановить каждый сервис загрузчика отдельно -cd youtube-downloader && docker compose down -cd ../instagram-downloader && docker compose down -cd ../vk-downloader && docker compose down -``` - -## Развертывание на продакшене - -### Вариант 1: Все на одном хосте (с VPN) - -1. Настройте VPN для доступа к YouTube и Instagram -2. Запустите каждый сервис отдельно в своей папке -3. В `.env` в корне проекта укажите: `http://localhost:5557`, `http://localhost:5556`, `http://localhost:5555` - -### Вариант 2: Раздельное развертывание (рекомендуется) - -**Хост 1 (с VPN):** -- Основной бот -- YouTube сервис -- Instagram сервис -- В `.env` в корне: `YOUTUBE_DOWNLOADER_URL=http://localhost:5557`, `INSTAGRAM_DOWNLOADER_URL=http://localhost:5556`, `VK_DOWNLOADER_URL=http://:5555` - -**Хост 2 (без VPN):** -- VK сервис -- В `.env` corebot на хосте 1: IP этого хоста - -**Преимущества:** -- VK работает быстрее без VPN -- Меньше нагрузка на VPN канал -- Возможность масштабирования сервисов отдельно +Язык сохраняется в базе данных для каждого пользователя. ## Troubleshooting @@ -295,14 +203,13 @@ cd ../vk-downloader && docker compose down - Убедитесь, что токен правильный в `.env` - Проверьте, что все сервисы запущены и доступны -### YouTube/Instagram/VK не работает -- Проверьте, что соответствующий сервис запущен: `docker compose ps` -- Проверьте URL в `.env` corebot -- Проверьте логи сервиса: `docker compose logs -f` -- Для Instagram: проверьте наличие и валидность `instagram-downloader/instagram_cookies.txt` +### Сервис не работает +- Проверьте логи сервиса: `cd -downloader && docker compose logs -f` +- Проверьте URL в `.env` +- Для Instagram: проверьте валидность cookies ### База данных не сохраняется -- Проверьте права на папку `data/` в корне проекта +- Проверьте права на папку `data/` - Убедитесь, что volume смонтирован в `docker-compose.yml` ## Лицензия @@ -311,4 +218,4 @@ MIT ## Поддержка -При возникновении проблем создайте issue в репозитории. +При возникновении проблем создайте issue в репозитории или свяжитесь с автором: @rvrubel