Add /cookies/check to youtube-downloader and instagram-downloader,
polled every 30 min from bot.py; alerts the admin bot on
healthy->broken transitions (with a 24h re-reminder cap while still
broken) and on recovery. Also stop leaking raw exception text to end
users - they now see a plain, friendly English message while the
admin bot still gets full technical detail via notify_admin_error.
Notify admin (URL + error text + user info) on any download failure
across all sources, and on the file-too-large case, mirroring the
existing successful-download notification.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
chat_id is shared by every member of a group chat, so all group
messages incremented one shared row and username kept getting
overwritten by whoever sent last. Track link counts in a new
user_links table keyed by the real from_user.id instead.
Adds users.link_count, incremented in bot.py whenever a user submits
a recognized link (regardless of eventual download success), and
surfaces it in admin_bot's /stat as a count of users who ever sent a
link plus a top-5 leaderboard by link count.
send_video_to_admin_bot() had no retry, unlike the client-facing
reply_video() path fixed earlier — a transient httpx.ReadError during
upload silently dropped the admin copy while the user still got their
video, since this function swallows its own exceptions.
EXTRACTOR_ARGS used ':' instead of ';' between player_client and skip
fields, so yt-dlp parsed "android:skip=translated_subs" and "hls" as
bogus player_client values and silently fell back to the web client
only, which fails the n-challenge and returns no formats.
--max-requests=1 fully restarted the gunicorn worker after every
single request, opening a race window that could drop the response
connection right after a successful download; raised to 20 with
jitter to keep the periodic-recycle safety net without doing it on
every request.
reply_video() to Telegram had no retry, so a transient httpx
transport error during upload discarded an already-downloaded video;
added the same 3-attempt retry pattern already used for the
downloader services.
- Замена reply_video() на reply_document() в bot.py — Telegram больше не сжимает видео
- Исправление format_id в get_youtube_formats(): конкретные format codes + fallback best[height<=N]
- Замена bestvideo[height<=N]+bestaudio на best[height<=N] — гарантированно работает когда
YouTube не отдаёт отдельные video-only потоки для низких разрешений
- Добавлено логирование реально скачанного формата для диагностики
- Разделение на микросервисы: youtube-downloader, instagram-downloader, vk-downloader
- Основной бот в корне проекта, работает через HTTP API с сервисами
- Каждый сервис запускается отдельно в своей папке
- Видео сохраняются в папке video/ и не удаляются
- Обновлена документация и архитектура
- Скрипты для Instagram cookies перенесены в instagram-downloader/
- Автоматическая проверка срока действия cookies каждые 24 часа
- Автоматическое обновление cookies за 3 дня до истечения из браузера
- Поддержание активности сессии через периодические запросы
- Поддержка Chrome, Firefox, Edge, Opera для обновления cookies
- Добавлена функция update_instagram_cookies_from_browser()
- Добавлена функция check_instagram_cookies_expiry()
- Фоновая задача keep_instagram_session_alive() для поддержания сессии
- Обновлена документация в README.md
- Добавлена переменная INSTAGRAM_AUTO_UPDATE_DAYS в .env.example