Как создать Telegram-канал с автоматическим постингом: мой опыт сборки пайплайна с Codex на Python и GitHub Actions

Как создать Telegram-канал с автоматическим постингом: мой опыт сборки пайплайна с Codex на Python и GitHub Actions

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

Не просто канал, где нужно каждый день вручную искать тему, собирать пост и следить за временем публикации, а систему, которая сама формирует контентный план на день и публикует его по расписанию.

Темой я выбрал кино и сериалы. Причина очень простая: я сам трачу довольно много времени на поиск того, что посмотреть, и мне казалось, что этот формат хорошо подходит для автоматизации. У него понятный источник данных, регулярный поток новинок и достаточно структурированная карточка контента: название, описание, рейтинг, постер, актеры, жанры.

Я прекрасно понимаю, что сама по себе идея канала про кино и сериалы не выглядит как что-то уникальное. Таких каналов в Telegram много. Авторского контента вокруг этой темы тоже более чем достаточно.

Но моя задача была не в том, чтобы придумать новую медиа-нишу. Мне было интереснее собрать полностью автоматизированный workflow, который каждый день выдает рекомендации без ручного участия. А еще это был хороший способ научиться новому и на практике поработать с Codex не на абстрактной демо-задаче, а на живом проекте.

Если захотите посмотреть, как это устроено в коде, вот репозиторий проекта: github

Почему я не хотел делать просто “бота, который постит”

Самый очевидный путь в такой задаче выглядит так: взять API, написать скрипт, который раз в день получает несколько фильмов, собирает текст и отправляет его в Telegram.

На уровне MVP это действительно работает. Но довольно быстро выясняется, что этого недостаточно.

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

  • одни и те же тайтлы начинают повторяться
  • часть карточек приходит без нормального русского описания
  • в постах могут быть странные имена актеров или неаккуратные жанры
  • план на день может получаться неполным
  • уже собранную очередь легко случайно пересобрать или испортить
  • если публикации размазаны по времени, нужен отдельный слой состояния: что уже вышло, что еще нет и что делать, если наступил новый день

Поэтому довольно быстро стало понятно, что нужен не “скрипт для отправки постов”, а маленький контентный пайплайн.

Что в итоге получилось

Лента фильмов из тг канала "Пока грузится чай"
Лента фильмов из тг канала "Пока грузится чай"

Я собрал проект на Python, который работает в два этапа.

Сначала утром он готовит очередь на день:

  • собирает кандидатов из TMDb
  • фильтрует их
  • выбирает лучшие
  • раскладывает их по слотам публикации

Потом в течение дня система проверяет время и публикует только следующий пост, когда наступает нужный слот.

Сейчас логика такая:

  • 3 фильма в день
  • 3 сериала в день
  • чередование фильм/сериал
  • фиксированные временные слоты по Москве

То есть в ленте получается предсказуемый ритм, а не случайный набор карточек.

Откуда берутся данные

В качестве источника я использовал TMDb.

Главный экран сайта https://www.themoviedb.org/
Главный экран сайта https://www.themoviedb.org/

Для фильмов сейчас используется movie/popular, для сериалов tv/on_the_air.

Важно, что проект не парсит HTML-страницы сайта, а работает через API. Для автоматизации это намного надежнее: меньше хрупких мест, проще поддержка, понятнее структура данных.

Кандидаты ищутся не по одной странице, а глубже:

  • до 10 страниц по фильмам
  • до 10 страниц по сериалам

Но если нужное количество уже найдено, дальнейший поиск останавливается. Это позволяет не тратить лишние запросы и не раздувать выполнение workflow без пользы.

Технически проект собран на простом и понятном стеке: Python отвечает за бизнес-логику пайплайна, TMDb API дает данные по фильмам и сериалам, Telegram Bot API публикует посты, GitHub Actions запускает подготовку очереди и публикации по расписанию, а Codex я использовал как рабочий инструмент для анализа, правок, отладки и постепенной эволюции проекта.

Почему пришлось добавлять quality gate

Красивый API не означает, что все данные в нем одинаково пригодны для публикации.

Если не фильтровать карточки, в канал довольно быстро начинает попадать то, что выглядит неаккуратно:

  • нет русского описания
  • нет нормального русского названия
  • слишком низкий рейтинг
  • нет постера
  • смешанный язык в метаданных

Поэтому тайтл проходит в очередь только если:

  • есть постер
  • есть русское название
  • есть русское описание
  • рейтинг выше заданного порога
  • по фильму нормально определяется дата релиза
  • это не adult-контент

Отдельно пришлось поработать и с сериалами. Изначально в подборку попадали проекты из разных стран, потому что tv/on_the_air сам по себе не означает “только США”. В итоге я добавил безопасный фильтр по origin_country = US, чтобы сильнее сфокусировать выдачу на американском рынке.

Почему важна дедупликация

Если просто брать популярные тайтлы из API, одни и те же фильмы и сериалы будут возвращаться снова и снова.

Чтобы канал не зацикливался, я сделал дедупликацию в двух слоях:

  • по точному событию
  • по самому тайтлу в рамках временного окна

Сейчас логика такая:

  • фильмы не повторяются раньше, чем через 120 дней
  • сериалы не повторяются раньше, чем через 60 дней

За счет этого канал не выглядит так, будто он каждый раз советует одно и то же, если TMDb снова поднимает те же карточки в выдаче.

Зачем вообще понадобилась отдельная очередь на день

Это, пожалуй, одна из самых полезных частей проекта.

Я не хотел, чтобы система каждый раз в момент публикации заново пересчитывала весь мир. Если утром мы уже нашли хорошие карточки, логичнее один раз зафиксировать план на день и потом спокойно исполнять его по времени.

Поэтому проект сначала собирает очередь и сохраняет ее в отдельный state-файл. Внутри для каждого элемента есть:

  • слот публикации
  • сама карточка
  • флаг публикации
  • время, когда пост реально вышел

Это дает несколько плюсов:

  • план на день можно проверить заранее
  • в течение дня публикация не зависит от изменений в TMDb
  • проще понимать, что уже вышло, а что еще ждет своей очереди
  • если что-то нужно отлаживать, state лежит прозрачно и читаемо

Как публикуются посты

Для отправки используется Telegram Bot API через sendPhoto.

То есть каждый пост — это постер плюс caption. В caption я оставил только самую полезную структуру:

  • тип: фильм или сериал
  • оригинальное и русское название
  • tagline
  • дата
  • рейтинг
  • жанры
  • актеры
  • длительность или количество сезонов
  • короткое описание

По пути пришлось отдельно полировать формат:

  • перевести дату в привычный европейский вид
  • убрать лишнее из подписи к рейтингу
  • привести жанры к нижнему регистру
  • сделать их списком через запятую
  • добавить транслитерацию имен актеров, если TMDb отдает их латиницей

То есть проект постепенно эволюционировал из “что-то уже постится” в более аккуратный редакционный инструмент.

Почему я использовал GitHub Actions

Вместо отдельного сервера я решил построить все на GitHub Actions.

Для такого проекта это оказалось очень удобным вариантом:

  • код и логика workflow лежат рядом
  • не нужно поднимать лишнюю инфраструктуру
  • проще видеть историю запусков
  • можно хранить состояние публикаций прямо в репозитории

Сейчас у проекта два workflow.

Первый утром собирает очередь на день:

  • поднимает окружение
  • прогоняет тесты
  • запускает сборку очереди
  • проверяет, что очередь создана именно на сегодняшнюю дату
  • коммитит обновленный queue-state обратно в репозиторий

Второй workflow запускается каждые 5 минут:

  • проверяет, не наступил ли следующий слот
  • если время еще не пришло, ничего не делает
  • если пришло, публикует ровно один пост
  • сохраняет обновленное состояние очереди и историю публикаций

Но именно здесь и всплыл важный практический нюанс.

На бумаге cron в GitHub Actions выглядит очень удобно. Можно поставить workflow хоть на каждые 5 минут, и документация GitHub это допускает. Но на практике scheduled jobs не стоит воспринимать как жесткую гарантию запуска минута в минуту.

У меня были случаи, когда workflow, который должен был срабатывать каждые 5 минут, по факту запускался раз в 1–2 часа, а иногда и реже. И это важное ограничение, которое нужно учитывать заранее, если вы строите что-то похожее.

Как создать Telegram-канал с автоматическим постингом: мой опыт сборки пайплайна с Codex на Python и GitHub Actions

Для меня это стало отдельным уроком. Автоматизация — это не только написать код, но и понимать ограничения платформы, на которой этот код живет.

То есть GitHub Actions отлично подходит для недорогой и простой автоматизации, но если проекту нужна жесткая гарантия публикации в точную минуту, это уже стоит учитывать отдельно на уровне архитектуры.

Почему для меня это был полезный проект

Для меня это был не просто еще один маленький pet-проект.

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

Во-вторых, это был удобный полигон для того, чтобы учиться новому. Я использовал Codex не как “генератор кода ради генерации”, а как рабочий инструмент в живом цикле:

  • разобраться в проблеме
  • проверить гипотезу
  • поправить логику
  • прогнать dry run
  • не сломать state
  • аккуратно закоммитить и отправить изменения

Для обучения такой формат оказался гораздо полезнее абстрактных упражнений. Когда у тебя есть настоящий workflow, реальное расписание, живое состояние и понятный результат на выходе, ты намного лучше начинаешь понимать, что именно строишь и зачем.

Что я понял по итогам

Главная мысль у меня сейчас такая: автоматизация Telegram-канала — это не про “подключить API и codex+бот сам все сделает”.

На самом деле самая ценная часть тут — это процесс:

  • как отбирать тайтлы
  • как не допускать дублей
  • как не публиковать мусор
  • как раскладывать контент по времени
  • как переживать смену дня
  • как хранить и обновлять состояние без хаоса

Сделать “бота, который умеет постить” несложно. Намного интереснее сделать систему, которая несколько дней подряд ведет себя предсказуемо и не требует постоянного ручного вмешательства.

Именно это мне и хотелось собрать.

Что дальше

Если энтузиазм не угаснет, то впереди у проекта еще много вещей, которые можно улучшать:

  • формат длинных постов
  • более умный отбор рекомендаций
  • дополнительные фильтры и источники
  • улучшение оформления
  • новые сценарии автоматизации

Если вам интересно, что в итоге получилось, можно посмотреть по ссылке на канал:

Аватарка канала в тг
Аватарка канала в тг

Ну и конечно, пробуйте сами, процесс довольно интересный.
Всем добра!

3
1 комментарий