videoDownloadTGbot/cookies/README.md
vrubelroman d597a5e1c5
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 2m36s
fix(downloaders): Deno runtime, свежий yt-dlp, честный health-check, смоук-тест
Возрастные YouTube-видео не скачивались: с cookies yt-dlp отбрасывает клиент
android и остаётся web, которому нужно решить n-challenge, а в образе стоял
Node 20 при требуемом минимуме 22 ("JS runtimes: node-20.19.2 (unsupported)").
Ставим Deno — рекомендованный yt-dlp рантайм и один статический бинарник.

Instagram падал с "empty media response" одинаково с cookies и без них —
дело было не в сессии, а в устаревшем экстракторе: слой pip был закеширован
на yt-dlp 2026.06.09. Поднимаем нижнюю границу до 2026.7.4.

/cookies/check помечал проблемой с cookies ЛЮБОЙ сбой, из-за чего на поломку
JS-рантайма прилетел алерт про протухшие cookies и увёл разбор не туда.
Теперь ответ содержит status: ok | cookies_invalid | extraction_failed |
no_cookies, и админ-бот шлёт разные сообщения. Разбор ответа в bot.py
сохраняет совместимость со старым форматом без поля status.

Добавлен smoke_test.py — гоняет реальные ссылки (включая обе регрессии выше)
через запущенные сервисы и печатает таблицу. Запускать после каждой правки.

Схема получения cookies переведена с крона на разовый ручной экспорт:
cookies-cron/ -> cookies/, удалены скрипты с анти-паттерном
`--cookies-from-browser BROWSER --cookies FILE`, который wiki yt-dlp прямо
запрещает и который сам ломал YouTube-сессию ротацией. Ключевые cookies живут
около года, поэтому обновление по расписанию не нужно — триггером служит алерт
health-check. deliver_cookies.sh только доставляет файлы по scp.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 00:31:16 +00:00

6.4 KiB
Raw Blame History

cookies

Как обновлять youtube_cookies.txt/instagram_cookies.txt для прода и тестового стенда.

Куки обновляются вручную и редко — по алерту от проактивной проверки, а не по расписанию. Раньше здесь жил крон, который каждые 2030 минут экспортировал куки из постоянно запущенного браузера; эта схема убрана, ниже объяснено почему.

Почему больше нет крона и постоянно открытого браузера

  1. Экспорт через --cookies-from-browser ломает YouTube-сессию. Wiki yt-dlp прямо запрещает связку --cookies COOKIEFILE --cookies-from-browser BROWSER — именно она даёт ошибку The provided YouTube account cookies are no longer valid. They have likely been rotated in the browser as a security measure. Пока браузер держит живую сессию, YouTube её ротирует, и любой снятый снимок куков протухает.

  2. Обновлять раз в 30 минут нечего. Ключевые куки живут около года: Instagram sessionid и YouTube SID/__Secure-1PSID на момент разбора имели срок ≈344376 дней. Крон сотни раз в сутки копировал одни и те же значения.

  3. Открытый браузер сам провоцировал блокировки. Вкладка Instagram, висящая сутками, непрерывно ходит в сеть (лента, сторис, автоплей, телеметрия) — тысячи запросов, которые повышают шанс, что Instagram пометит сессию. Это ровно тот симптом, который мы ловили: Main webpage is locked behind the login page при формально валидных по сроку куках.

Когда обновлять

Когда админ-бот пришлёт 🍪⚠️ ПРОАКТИВНАЯ ПРОВЕРКА COOKIES по нужному сервису. Проверка живёт в bot.py (check_cookies_health, раз в 30 минут дёргает POST /cookies/check у youtube- и instagram-downloader) и шлёт алерт при переходе healthy→broken, потом не чаще раза в сутки, а при восстановлении — ✅ Cookies восстановлены.

Проверить состояние вручную в любой момент:

ssh germany "curl -s -X POST localhost:5557/cookies/check"  # YouTube
ssh germany "curl -s -X POST localhost:5556/cookies/check"  # Instagram

Экспорт cookies

Нужен браузер с графическим окружением и расширение для экспорта в формате cookies.txt (Netscape). На проде это сделать нельзя — там нет GUI.

YouTube — обязательно через приватное окно

Официальный способ из wiki yt-dlp, именно он снимает ротацию:

  1. Открыть приватное окно и залогиниться на YouTube.
  2. В той же вкладке перейти на https://www.youtube.com/robots.txt. Это должна быть единственная открытая приватная вкладка.
  3. Экспортировать куки youtube.com расширением в youtube_cookies.txt.
  4. Сразу закрыть приватное окно, не разлогиниваясь. Сессия больше никогда не открывается — значит, YouTube её не ротирует, и куки живут месяцами.

Не использовать --cookies-from-browser: он заберёт обычные куки профиля, а не куки приватной сессии.

Instagram

Экспортировать куки instagram.com расширением в instagram_cookies.txt, после чего вкладку закрыть и сессию в браузере не трогать. Формальной гарантии, как у YouTube, документация не даёт, но принцип тот же: сессию, которой браузер не пользуется, не ротируют и не помечают за подозрительную активность.

В файле должен быть sessionid — без него Instagram отдаёт login required:

grep -c sessionid instagram_cookies.txt   # должно быть >= 1

После экспорта

Браузер не оставлять запущенным. Профиль на диске для этой схемы больше не нужен — куки уже лежат в файлах.

Доставка

Положить оба файла рядом с deliver_cookies.sh и запустить:

./deliver_cookies.sh

Скрипт проверит, что файлы непустые, и разольёт их по scp:

  • на прод (REMOTE_HOST=germany) — обязательный шаг, при ошибке падает;
  • на тестовый стенд (DEV_HOST=hermesDev) — необязательный, при недоступности пишет warning и продолжает.

Хосты и пути захардкожены под текущую инфраструктуру (SSH-алиасы из ~/.ssh/config машины, где запускаете) — при переезде поправить переменные в начале скрипта.

Перезапускать контейнеры после доставки не нужно: yt-dlp читает файл с диска при каждом запросе. Монтирование в контейнеры — см. docker-compose.prod.yml/docker-compose.yml.

Проверка результата

После доставки дёрнуть /cookies/check (команды выше) — ожидаем "cookies_valid": true у обоих сервисов. На следующем цикле проверки в админ-бот придёт ✅ Cookies восстановлены.