Search
Write a publication
Pull to refresh

Youtube TG бот на GO cо всеми «прелестями»

Level of difficultyMedium
Reading time3 min
Views1.6K

Привет, Хабр! Сегодня хочу поделиться с сообществом TG ботом, которого я написал пару лет назад и который до сих пор актуален и работает.

Немного истории

Свое знакомство с телеграмм ботами я начал как раз с разработки ютуббота, было это около 5 лет назад. Первая версия этого бота была реализована на php, реализовывалась она на коленке и скорее ради интереса пощупать что такое боты и закрыть мою потребность в удобном скачивании роликов с ютуба. Версия на php прожила около 2-х лет, бот рос, был неудобен в плане поддержки и какого то расширения и я решил сделать не рефакторинг, а полное переосмысление бота, но только не на php, а уже на GO, тогда я активно знакомился с языком и мне нужна была какая‑то практика.

Далее буду рассказывать о боте и для контекста оставлю ссылку на его github: https://github.com/xman12/youtube_bot

А что он может?

В боте реализована скачка роликов средствами 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. Спасибо тем кто дочитал до конца. Буду признателен за идеи и комментарии.

Tags:
Hubs:
-2
Comments7

Articles