Привет, Хабр! Сегодня хочу поделиться с сообществом 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. Спасибо тем кто дочитал до конца. Буду признателен за идеи и комментарии.
ссылка на оригинал статьи https://habr.com/ru/articles/939436/
Добавить комментарий