import os import asyncio from aiogram import Bot, Dispatcher, types, F from aiogram.filters import Command import yt_dlp TOKEN = os.getenv("TG_BOT_TOKEN") MUSIC_DIR = os.getenv("MUSIC_DIR", "./music") # Читаем ваш ID из переменных среды (по умолчанию 0) ADMIN_ID = int(os.getenv("ADMIN_ID", 0)) bot = Bot(token=TOKEN) dp = Dispatcher() def download_youtube(url: str): ydl_opts = { 'format': 'bestaudio/best', 'postprocessors': [{ 'key': 'FFmpegExtractAudio', 'preferredcodec': 'mp3', 'preferredquality': '192', }], 'outtmpl': f'{MUSIC_DIR}/Youtube/%(uploader)s/%(title)s.%(ext)s', 'noplaylist': False, 'quiet': False, # --- НОВЫЕ НАСТРОЙКИ --- 'proxy': 'socks5://host.docker.internal:1080', # Идем через Германию 'socket_timeout': 30, # Даем больше времени на ответ 'source_address': '0.0.0.0', # Отключаем IPv6 } with yt_dlp.YoutubeDL(ydl_opts) as ydl: ydl.download([url]) # Создаем удобный фильтр: "сообщение от админа" is_admin = F.from_user.id == ADMIN_ID # --- ОБРАБОТЧИКИ ТОЛЬКО ДЛЯ ВАС (работают, если is_admin == True) --- @dp.message(is_admin, Command("start")) async def start_cmd(message: types.Message): await message.reply("Привет, хозяин! Скинь ссылку на YouTube или аудиофайл, и я закину его в Navidrome.") @dp.message(is_admin, F.text.regexp(r'https?://(?:www\.)?youtu')) async def handle_youtube(message: types.Message): msg = await message.reply("⏳ Начинаю скачивание...") try: await asyncio.to_thread(download_youtube, message.text) await msg.edit_text("✅ Успешно скачано и добавлено в Navidrome!") except Exception as e: await msg.edit_text(f"❌ Ошибка:\n{str(e)[:500]}") @dp.message(is_admin, F.audio) async def handle_audio(message: types.Message): msg = await message.reply("📥 Сохраняю трек...") try: file_name = message.audio.file_name or f"track_{message.message_id}.mp3" destination = os.path.join(MUSIC_DIR, "Telegram", file_name) os.makedirs(os.path.dirname(destination), exist_ok=True) await bot.download(message.audio, destination=destination) await msg.edit_text("✅ Трек добавлен в Navidrome!") except Exception as e: await msg.edit_text(f"❌ Ошибка:\n{str(e)[:500]}") # --- ОБРАБОТЧИК ДЛЯ ЧУЖАКОВ --- # Сработает, если ни один из верхних обработчиков не подошел (например, другой ID) @dp.message() async def reject_stranger(message: types.Message): await message.reply(f"⛔ Извините, этот бот приватный.\n\nВаш Telegram ID: {message.from_user.id}", parse_mode="HTML") async def main(): print("Бот запущен...") await dp.start_polling(bot) if __name__ == "__main__": asyncio.run(main())