2025-12-10 14:46:09 +03:00
# Telegram Video Download Bot
2025-12-12 12:39:11 +03:00
Telegram бот для скачивания видео с YouTube, Instagram, TikTok, VK и Yapfiles. Микросервисная архитектура с раздельными сервисами для каждого источника.
2025-12-11 01:07:04 +03:00
## Архитектура
Проект разделен на микросервисы:
- **Основной бот** (в корне проекта) - Telegram бот, обрабатывает сообщения и оркестрирует запросы к сервисам
- **youtube-downloader** - сервис для скачивания с YouTube (порт 5557)
- **instagram-downloader** - сервис для скачивания с Instagram (порт 5556)
- **vk-downloader** - сервис для скачивания с VK (порт 5555)
2025-12-12 12:39:11 +03:00
- **yapfiles-downloader** - сервис для скачивания с Yapfiles (порт 5558)
- **tiktok-downloader** - сервис для скачивания с TikTok (порт 5559)
2025-12-11 01:07:04 +03:00
Каждый сервис работает в отдельном Docker контейнере и может быть развернут независимо.
2025-12-10 14:46:09 +03:00
2025-12-10 16:22:18 +03:00
## Возможности
- 📹 Скачивание видео с YouTube
- 📸 Скачивание видео с Instagram (требуются cookies)
2025-12-12 12:39:11 +03:00
- 🎵 Скачивание видео с TikTok
2025-12-11 01:07:04 +03:00
- 🎬 Скачивание видео с VK
2025-12-12 12:39:11 +03:00
- 📁 Скачивание видео с Yapfiles
- 🌍 Локализация интерфейса (русский/английский) на основе языка пользователя
2025-12-10 16:22:18 +03:00
- 📊 Статистика скачанных видео и пользователей
- 🔄 Автоматическое сохранение статистики в базу данных
2025-12-11 01:07:04 +03:00
- 👥 Работа в группах с автоматическим обнаружением ссылок
2025-12-12 12:39:11 +03:00
- 📢 Рассылка сообщений всем пользователям (`broadcast.py` )
## Команды бота
- `/start` — начало работы с ботом
- `/stat` — статистика: количество пользователей и скачанных видео
- `/support` — информация о боте и контакт автора
2025-12-10 16:22:18 +03:00
## Требования
- Docker и Docker Compose
- Telegram Bot Token (получить у [@BotFather ](https://t.me/BotFather ))
- Для Instagram: файл с cookies (см. раздел Instagram ниже)
## Быстрый старт
### 1. Клонирование репозитория
2025-12-10 14:46:09 +03:00
```bash
2025-12-10 16:22:18 +03:00
git clone < repository_url >
cd videoDownloadBot
2025-12-10 14:46:09 +03:00
```
2025-12-10 16:22:18 +03:00
### 2. Настройка переменных окружения
2025-12-11 01:07:04 +03:00
Скопируйте `.env.example` в `.env` в корне проекта и заполните:
2025-12-10 16:22:18 +03:00
```bash
cp .env.example .env
nano .env # или используйте любой редактор
```
**Необходимые переменные:**
```env
TELEGRAM_BOT_TOKEN=your_telegram_bot_token_here
TELEGRAM_BOT_USERNAME=your_bot_username
2025-12-11 01:07:04 +03:00
# Downloader Services URLs
2025-12-12 12:39:11 +03:00
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
2025-12-10 16:22:18 +03:00
```
### 3. Настройка Instagram (опционально)
Если планируете скачивать видео с Instagram:
fix(downloaders): Deno runtime, свежий yt-dlp, честный health-check, смоук-тест
Возрастные YouTube-видео не скачивались: с cookies yt-dlp отбрасывает клиент
android и остаётся web, которому нужно решить n-challenge, а в образе стоял
Node 20 при требуемом минимуме 22 ("JS runtimes: node-20.19.2 (unsupported)").
Ставим Deno — рекомендованный yt-dlp рантайм и один статический бинарник.
Instagram падал с "empty media response" одинаково с cookies и без них —
дело было не в сессии, а в устаревшем экстракторе: слой pip был закеширован
на yt-dlp 2026.06.09. Поднимаем нижнюю границу до 2026.7.4.
/cookies/check помечал проблемой с cookies ЛЮБОЙ сбой, из-за чего на поломку
JS-рантайма прилетел алерт про протухшие cookies и увёл разбор не туда.
Теперь ответ содержит status: ok | cookies_invalid | extraction_failed |
no_cookies, и админ-бот шлёт разные сообщения. Разбор ответа в bot.py
сохраняет совместимость со старым форматом без поля status.
Добавлен smoke_test.py — гоняет реальные ссылки (включая обе регрессии выше)
через запущенные сервисы и печатает таблицу. Запускать после каждой правки.
Схема получения cookies переведена с крона на разовый ручной экспорт:
cookies-cron/ -> cookies/, удалены скрипты с анти-паттерном
`--cookies-from-browser BROWSER --cookies FILE`, который wiki yt-dlp прямо
запрещает и который сам ломал YouTube-сессию ротацией. Ключевые cookies живут
около года, поэтому обновление по расписанию не нужно — триггером служит алерт
health-check. deliver_cookies.sh только доставляет файлы по scp.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 00:31:16 +00:00
1. Экспортируйте cookies из браузера расширением для `cookies.txt` — процедура в [`cookies/README.md` ](cookies/README.md )
2025-12-11 01:07:04 +03:00
2. Сохраните файл как `instagram_cookies.txt` в папке `instagram-downloader/`
2025-12-10 17:02:01 +03:00
2025-12-11 01:07:04 +03:00
### 4. Запуск сервисов
2026-06-30 22:16:40 +00:00
В с е 7 сервисов (бот, admin-бот, 5 загрузчиков) собираются и запускаются одной командой из корня проекта — единый `docker-compose.yml` уже содержит build-контексты для всех подпапок:
2025-12-10 16:22:18 +03:00
```bash
2026-06-30 22:16:40 +00:00
docker compose up -d --build
```
Перезапустить/пересобрать только один сервис (например, при правке `youtube-downloader/app.py` ):
```bash
docker compose up -d --build youtube-downloader
2025-12-10 16:22:18 +03:00
```
2025-12-12 12:39:11 +03:00
### 5. Проверка статуса
2025-12-10 16:22:18 +03:00
```bash
2025-12-12 12:39:11 +03:00
# Проверка всех сервисов
docker ps | grep -E "(video_download_bot|youtube|instagram|vk|yapfiles|tiktok)"
2025-12-11 01:07:04 +03:00
```
2025-12-12 12:39:11 +03:00
## Порты сервисов
2025-12-11 01:07:04 +03:00
2025-12-12 12:39:11 +03:00
| Сервис | Порт |
|--------|------|
| VK Downloader | 5555 |
| Instagram Downloader | 5556 |
| YouTube Downloader | 5557 |
| Yapfiles Downloader | 5558 |
| TikTok Downloader | 5559 |
2025-12-11 01:07:04 +03:00
2025-12-12 12:39:11 +03:00
## Рассылка сообщений
2025-12-11 01:07:04 +03:00
2025-12-12 12:39:11 +03:00
Скрипт `broadcast.py` позволяет отправить сообщение всем пользователям бота:
2025-12-11 01:07:04 +03:00
```bash
2025-12-12 12:39:11 +03:00
# Простое сообщение
./broadcast.py -y "Текст сообщения"
2025-12-11 01:07:04 +03:00
2025-12-12 12:39:11 +03:00
# С HTML-разметкой
./broadcast.py -y --html '< b > Важно!< / b > Новая функция добавлена.'
2025-12-11 01:07:04 +03:00
2025-12-12 12:39:11 +03:00
# Из файла
./broadcast.py -y --file announcement.txt --html
2025-12-11 01:07:04 +03:00
2025-12-12 12:39:11 +03:00
# Посмотреть список пользователей
./broadcast.py --list
2025-12-11 01:07:04 +03:00
```
2025-12-10 14:46:09 +03:00
## Структура проекта
2025-12-10 16:22:18 +03:00
```
videoDownloadBot/
2025-12-11 01:07:04 +03:00
├── bot.py # Код основного Telegram бота
2025-12-12 12:39:11 +03:00
├── broadcast.py # Скрипт для рассылки сообщений
2025-12-11 01:07:04 +03:00
├── requirements.txt # Python зависимости бота
├── Dockerfile # Образ для бота
2025-12-12 12:39:11 +03:00
├── docker-compose.yml # Конфигурация бота
├── .env.example # Пример конфигурации
├── data/ # База данных (bot.db)
├── video/ # Скачанные видео
2025-12-11 01:07:04 +03:00
├── youtube-downloader/ # Сервис для YouTube
├── instagram-downloader/ # Сервис для Instagram
2025-12-12 12:39:11 +03:00
├── vk-downloader/ # Сервис для VK
├── yapfiles-downloader/ # Сервис для Yapfiles
├── tiktok-downloader/ # Сервис для TikTok
├── README.md # Этот файл
└── ARCHITECTURE.md # Описание архитектуры
2025-12-10 16:22:18 +03:00
```
2025-12-11 01:07:04 +03:00
## API Endpoints
2025-12-10 16:22:18 +03:00
2025-12-11 01:07:04 +03:00
В с е сервисы загрузчиков предоставляют одинаковый API:
- `GET /health` - проверка здоровья сервиса
- `POST /download/stream` - скачивание видео (возвращает бинарные данные)
```json
POST /download/stream
Content-Type: application/json
{
"url": "https://youtube.com/watch?v=..."
}
2025-12-10 16:22:18 +03:00
```
2026-06-30 22:16:40 +00:00
## Cookies на проде (YouTube/Instagram)
В проде `youtube_cookies.txt` /`instagram_cookies.txt` монтируются в контейнеры с хоста (`docker-compose.prod.yml` ), а не запекаются в образ — это позволяет обновлять их без пересборки/передеплоя. `yt-dlp` /`app.py` читают файл с диска при каждом запросе — рестарт контейнера не требуется.
fix(downloaders): Deno runtime, свежий yt-dlp, честный health-check, смоук-тест
Возрастные YouTube-видео не скачивались: с cookies yt-dlp отбрасывает клиент
android и остаётся web, которому нужно решить n-challenge, а в образе стоял
Node 20 при требуемом минимуме 22 ("JS runtimes: node-20.19.2 (unsupported)").
Ставим Deno — рекомендованный yt-dlp рантайм и один статический бинарник.
Instagram падал с "empty media response" одинаково с cookies и без них —
дело было не в сессии, а в устаревшем экстракторе: слой pip был закеширован
на yt-dlp 2026.06.09. Поднимаем нижнюю границу до 2026.7.4.
/cookies/check помечал проблемой с cookies ЛЮБОЙ сбой, из-за чего на поломку
JS-рантайма прилетел алерт про протухшие cookies и увёл разбор не туда.
Теперь ответ содержит status: ok | cookies_invalid | extraction_failed |
no_cookies, и админ-бот шлёт разные сообщения. Разбор ответа в bot.py
сохраняет совместимость со старым форматом без поля status.
Добавлен smoke_test.py — гоняет реальные ссылки (включая обе регрессии выше)
через запущенные сервисы и печатает таблицу. Запускать после каждой правки.
Схема получения cookies переведена с крона на разовый ручной экспорт:
cookies-cron/ -> cookies/, удалены скрипты с анти-паттерном
`--cookies-from-browser BROWSER --cookies FILE`, который wiki yt-dlp прямо
запрещает и который сам ломал YouTube-сессию ротацией. Ключевые cookies живут
около года, поэтому обновление по расписанию не нужно — триггером служит алерт
health-check. deliver_cookies.sh только доставляет файлы по scp.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 00:31:16 +00:00
Куки обновляются **вручную и редко** — по алерту `🍪⚠️ COOKIES ПРОТУХЛИ` из админ-бота, а не по расписанию. Ключевые куки живут около года, поэтому регулярный экспорт не нужен; за состоянием следит фоновая проверка в `bot.py` (`check_cookies_health` , раз в 30 минут дёргает `POST /cookies/check` у youtube- и instagram-downloader).
Экспорт делается с машины с браузером (на проде нет GUI) и требует точной процедуры — для YouTube только через приватное окно, иначе сессия ротируется и куки протухают. Пошаговая инструкция и скрипт доставки — в [`cookies/` ](cookies/README.md ).
## Смоук-тест
После любой правки, до коммита, на поднятом тестовом контуре:
```bash
python3 smoke_test.py
```
Гоняет реальные ссылки через запущенные сервисы и печатает таблицу: `/cookies/check` обоих загрузчиков, `/formats` на возрастном YouTube-видео (ловит отсутствие рабочего JS-рантайма) и реальные скачивания YouTube и Instagram. Код возврата `0` — всё прошло, `1` — есть падения. Адреса переопределяются через `YOUTUBE_DOWNLOADER_URL` /`INSTAGRAM_DOWNLOADER_URL` .
Если сервисы пересобирались — поднимать их через `docker compose up -d --force-recreate <service>` : без флага `up -d` просто стартует старый контейнер, и правка в проверку не попадёт.
2026-06-30 22:16:40 +00:00
2025-12-11 01:07:04 +03:00
## Обновление
2026-06-30 22:16:40 +00:00
Деплой на прод выполняется автоматически через Forgejo CI/CD (`.forgejo/workflows/deploy.yml` ) при пуше в `main` : сборка всех 7 образов → push в registry → `docker save` /`ssh` /`docker load` на прод-хост (registry не доступен с внешнего VPS напрямую) → `docker compose up -d --remove-orphans` .
2025-12-11 01:07:04 +03:00
2026-06-30 22:16:40 +00:00
Для ручного локального обновления:
2025-12-11 01:07:04 +03:00
2026-06-30 22:16:40 +00:00
```bash
git pull
docker compose up -d --build
2025-12-10 16:22:18 +03:00
```
2025-12-12 12:39:11 +03:00
## Локализация
2025-12-10 16:22:18 +03:00
2025-12-12 12:39:11 +03:00
Бот автоматически определяет язык пользователя из настроек Telegram:
- Если язык начинается с `ru` — интерфейс на русском
- Иначе — интерфейс на английском
2025-12-10 16:22:18 +03:00
2025-12-12 12:39:11 +03:00
Язык сохраняется в базе данных для каждого пользователя.
2025-12-10 16:22:18 +03:00
## Troubleshooting
### Бот не отвечает
- Проверьте логи: `docker compose logs bot`
- Убедитесь, что токен правильный в `.env`
2025-12-11 01:07:04 +03:00
- Проверьте, что все сервисы запущены и доступны
2025-12-10 16:22:18 +03:00
2025-12-12 12:39:11 +03:00
### Сервис не работает
2026-06-30 22:16:40 +00:00
- Проверьте логи сервиса: `docker compose logs -f <service>-downloader`
2025-12-12 12:39:11 +03:00
- Проверьте URL в `.env`
- Для Instagram: проверьте валидность cookies
2025-12-10 16:22:18 +03:00
### База данных не сохраняется
2025-12-12 12:39:11 +03:00
- Проверьте права на папку `data/`
2025-12-10 16:22:18 +03:00
- Убедитесь, что volume смонтирован в `docker-compose.yml`
## Лицензия
MIT
## Поддержка
2025-12-10 14:46:09 +03:00
2025-12-12 12:39:11 +03:00
При возникновении проблем создайте issue в репозитории или свяжитесь с автором: @rvrubel