Обновить

Telegram-бот, который молча скачивает видео по ссылкам в групповых чатах: как это сделать, не ломая приватность

Уровень сложностиПростой
Время на прочтение6 мин
Охват и читатели9.5K
Всего голосов 5: ↑5 и ↓0+9
Комментарии5

Комментарии 5

Спасибо за статью, очень годный разбор архитектурных нюансов. Есть соображения на Ваши вопросы и пара наблюдений:

1. Про file_id и "протухание"
У file_id в Telegram Bot API нет официального TTL. Идентификатор привязан к токену бота и остаётся валидным, пока файл физически не удалён с серверов TG или не изменится его внутренняя сигнатура. Ваш TTL в 7 дней это корректная стратегия bounded cache для контроля потребления памяти/Redis, а не защита от автоматической инвалидации. На больших объёмах WrongFileId будет возникать именно при удалении контента или смене формата, а не "по времени". Можно оставить TTL, но добавить ленивую инвалидацию: при поимке InvalidFileId просто сбрасывать кэш по URL, перекачивать файл и сохранять новый file_id. Для продакшена кэш лучше выносить в Redis с maxmemory-policy и TTL.

2. Очередь и масштабирование
In-process asyncio.Queue с одним воркером отлично работает, пока нагрузка не упирается в лимиты API или I/O. "Стена" обычно наступает при стабильной глубине очереди > 50–100 задач, p95 латентности > 3 сек или частых 429 от ботов. До перехода на внешнюю очередь достаточно ввести контроль параллелизма через asyncio.Semaphore. Рекомендую два раздельных семафора: один на операции скачивания (ограничивает одновременные соединения к донорам и расход CPU/памяти), второй - на отправку в Telegram API (гарантирует, что вы не превысите глобальные лимиты ~30 req/sec и мягкие ограничения на чаты). В паре с exponential backoff + jitter это даёт стабильную работу при всплесках запросов без усложнения архитектуры. Когда метрики стабильно выходят за пороги - пайплайн стоит развязать: шлюз приёма → Redis/RabbitMQ → пул воркеров → отправка.

3. Privacy и UX: активный по дефолту или тихий?
Дилемма "полезный ↔ навязчивый" действительно субъективна. Но универсального решения нет: то, что удобно в ламповом чате, раздражает в крупном канале.

Вместо бинарного выбора "активный/тихий" можно дать инструменты настройки админам чатов/каналов. Т.е. лёгкая "админ-панель» прямо в Телеграме, где админ может, например:

  • Включать/отключать авто-скачивание по источникам (только YouTube, без TikTok и т.д.).

  • Переключать режим: "авто" ↔ "только по команде" (например, /dl <ссылка>)

  • Настраивать "тихие часы" или лимиты: не больше N видео в час, не постить в ночь.

  • Добавлять чёрный список аккаунтов/хэштегов, если бот реагирует на спам.

Реализация - через инлайн-кнопки или команды /settings, всё без отдельного веб-интерфейса.


Кстати. А что вы используете для скачивания: yt-dlp, несколько специализированных библиотек типа instagrapi, или собственные скрипты? Для Instagram и YouTube на почти неизбежно требуется проброс cookies-файла с активной сессией (даже с ротацией аккаунтов), иначе быстро прилетают 403, капчи или блокировки Reels/Shorts.
Я смотрел похожие проекты с yt-dlp, там решают этот вопрос по-разному: держат изолированные пулы сессий по донорам, делают автообновление библиотек, используют прокси-ротацию для снижения риска shadow-ban.

Буду рад, если поделитесь деталями реализации. Спасибо за материал!

В телеграме недавно разрешили ботам общаться между собой, может быть теперь можно сделать группу из ботов, один(или даже не один) качает и складывает в группу-хранилище, другой только ссылки туда раздает.

зы про высокую нагрузку не понял. 380 юзеров в 31 чате это звучит примерно как 0, стоит ли заморачиваться с какими то очередями или можно просто запускать на каждый запрос асинхронный обработчик который при получении "429 подождите 30 секунд и попробуйте снова" просто будет ждать 30 секунд и пробовать снова?

Про бот2бот - идея интересная, да и архитектурно красивая. Но если честно я пока не вижу, что мне это даёт по сравнению с file_id кэшем внутри одного бота. У меня и так "скачал один раз - раздал 50 раз во все чаты через file_id". Группа-хранилище добавит лишний хоп (бот-раздатчик идёт в группу-хранилище за file_id вместо локального Redis), а профита по латентности или экономии не даст. Где это реально могло бы выстрелить - если бы качающих было несколько разных, и они шарили общий пул file_id между независимыми проектами. Вот тогда да, для общего инфраструктурного слоя на несколько ботов - имеет смысл подумать. Но сейчас как будто нет смысла.

Про нагрузку - ну да, прав, я согласен. 380 юзеров в 31 чате это не нагрузка, я написал "нагрузки на разрыв нет". Очередь у меня сейчас простая, in-process asyncio.Queue с одним воркером - ровно потому, что больше пока не нужно. Я не пытался утверждать, что мне это сейчас критично, скорее разбирал паттерн "вот эти грабли вылезут когда нагрузка появится". И да, "async handler + ловим RetryAfter + спим" - это полностью рабочая схема на моём масштабе, и я не вижу причин усложнять, пока не упрусь. Очередь у меня в реальности живёт скорее как точка для будущих фич (приоритезация, retry с backoff, dedup), чем как защита от текущей нагрузки.

Кстати, сейчас уже 1200+ юзеров и 100+ чатов, нагрузки, конечно, нет, тут больше с точки зрения бесплатных способов вытягивать видео из Инсты проблемы.

А код открытый? У себя можно развернуть?

К сожалению, нет. Да и с ним же работать постоянно надо, т.к. нет стабильных бесплатных способов вытягивать видео из Инсты - я пока их искал, то посадил бота на собственные куки, и в итоге личный аккаунт ушёл в бан :)

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации