Youtube TG бот на GO cо всеми «прелестями»
- пятница, 22 августа 2025 г. в 00:00:09
Привет, Хабр! Сегодня хочу поделиться с сообществом TG ботом, которого я написал пару лет назад и который до сих пор актуален и работает.
Свое знакомство с телеграмм ботами я начал как раз с разработки ютуббота, было это около 5 лет назад. Первая версия этого бота была реализована на php, реализовывалась она на коленке и скорее ради интереса пощупать что такое боты и закрыть мою потребность в удобном скачивании роликов с ютуба. Версия на php прожила около 2-х лет, бот рос, был неудобен в плане поддержки и какого то расширения и я решил сделать не рефакторинг, а полное переосмысление бота, но только не на php, а уже на GO, тогда я активно знакомился с языком и мне нужна была какая‑то практика.
Далее буду рассказывать о боте и для контекста оставлю ссылку на его github: https://github.com/xman12/youtube_bot
Работающий пример @GetYoutubeMp3Bot
В боте реализована скачка роликов средствами yt‑dlp. После скачки средствами ffmpeg извлекается аудиодорожка и отправляется пользователю. Так же доступна скачать видео и превью видео по соответствующим кнопкам, ну и все).
Бот написал на языке GO, база данных Mysql, для статистики и мониторинга используется Prometheus + Grafana и все это упаковано в Docker.
Бэкенд бота написан на Go и реализует следующую функциональность:
Обработка сообщений Telegram Bot API
Загрузка видео с YouTube через yt-dlp
Управление пользователями, информация о загруженных видео
Сбор метрик для Prometheus
Ротация HTTP-прокси
Вся логика реализована в internal/app/server.go
Хотел бы немного рассказать о ротации проксей. Она происходит таким образом, берется пулл прокси из файла и по очередно происходит выборка прокси и подставляется в yt-dlp
выглядит это так:
По такой логике все прокси из файла получат равномерное количество скачек и равномерно "сдохнут".
В коде это выглядит так:
в server.go
инициализируется структура прокси
proxyKey := youtube.ProxyOption{
Key: 0,
Path: os.Getenv("PATH_TO_PROXY"),
}
ProxyOption передается по ссылке и попадает в функцию
func GetProxy(option *ProxyOption) Proxy {
collection := ParsFile(option.Path)
if len(collection)-1 == option.Key {
proxy := collection[option.Key]
option.Key = 0
return proxy
} else {
proxy := collection[option.Key]
option.Key++
return proxy
}
}
На выходе имеем Объект Proxy и работаем с ним.
proxy := GetProxy(proxyOption)
args := fmt.Sprintf("yt-dlp --no-mtime --proxy %s -o \"%s/%%(id)s.%%(ext)s\" \"%s\" --merge-output-format=\"mp4/mkv\" -f w", proxy.GetProxyString(), pathLoad, urlDownload)
Бот позволяет работать в связке с TelegramBotAPIServer, что позволяет расширять ограничения по загрузке файлов.
В Docker настроены:
Автоматическое обновление yt-dlp раз в 6 часов
Автоматическое очищение роликов раз в час
Автоматический импорт схемы БД при первом запуске
Возможность создавать бэкапы и их загружать (тут все ручками через bash скрипты)
Возможность ограничить подключение к Mysql, Grafana, Prometheus по IP
Развертывание запустив 1 команду
Бот собирает основные метрики:
request_total
– Общее количество запросов к боту
register_users_total
– Количество зарегистрированных пользователей
video_loads
– Количество успешных загрузок видео
video_loads_error
– Количество ошибок загрузки
Для того, чтобы развернуть проект достаточно выполнить команду в корне проекта:
chmod +x start.sh
./start.sh
Репозиторий: https://github.com/xman12/youtube_bot
PS. Спасибо тем кто дочитал до конца. Буду признателен за идеи и комментарии.