// личный проект
GitNotifyBot
Telegram-бот, который следит за публичными GitHub-репозиториями и присылает в чат короткие сводки об их обновлениях. Сводки готовит LLM на выбранном языке - как только выходит новый релиз или меняется отслеживаемый файл. Не нужно листать ленту релизов или подписываться на watcher: добавил репо командой в чате и читаешь только то, что тебе важно.
// зачем
Что приходит в чат
У GitHub есть свой watcher на релизы, но он шлёт в почту голый changelog. Хотелось получать короткую сводку, по делу, прямо в Telegram - и чтобы можно было задать стиль и язык под себя. Бот делает это: парсит обновление, прогоняет его через LLM с настройками чата и шлёт уведомление.
✨ Обновился репозиторий cli/cli (v2.45.0)
Релиз cli/cli v2.45.0
Что нового:
• Добавлена команда `gh repo lock` для блокировки новых issues.
• Исправлен сбой при отправке PR review через JSON pipe.
🔗 https://github.com/cli/cli/releases/tag/v2.45.0
Постоянное меню: пять основных действий, всегда внизу чата
Подписка добавлена: репозиторий, режим, ветка, файл, baseline sha
// как работает
От подписки до уведомления
Подписка
Пользователь добавляет репозиторий прямо в чате через меню. Выбирает режим (релизы или файл), язык и стиль сводки. Подписка пишется в PostgreSQL.
Опрос GitHub
Воркер циклом обходит подписки, у которых наступило время проверки, и дёргает GitHub REST API. Для релизов сравнивает id, для файлов - blob sha.
Сводка от LLM
Если что-то изменилось, изменение уходит в OpenAI Responses API. Промт подставляет язык, стиль и пожелания чата. Ответ возвращается строгим json_schema.
Уведомление
Готовая сводка публикуется через бот-токен в чат. Параллельно она кэшируется в БД - чтобы не звать LLM повторно для других чатов с теми же настройками.
// режимы
Два режима отслеживания
Releases
Опрашивает GET /releases/latest, фиксирует baseline по id текущего релиза и шлёт уведомление только при появлении нового. Тело релиза идёт в LLM как есть.
File
Следит за одним файлом на default-ветке. Сравнивает blob sha, и если он изменился - забирает у GitHub патч последнего коммита, затронувшего этот путь. Хорошо подходит для CHANGELOG.md.
// возможности
Что ещё умеет
Настройки на чат
Свой язык сводки (ru/en), стиль (кратко/подробно) и свободные пожелания: например, «выделяй изменения CLI и API». Для каждого чата отдельно.
Кэш LLM-ответов
Один и тот же апдейт с одинаковыми настройками - один вызов OpenAI, шерится между чатами. Ключ кэша: id обновления + язык + стиль + хеш пожеланий + версия промта.
Постоянное меню
Reply-клавиатура с пятью основными действиями всегда внизу чата: добавить, список, проверить сейчас, настройки, помощь. Подфлоу - через инлайн-клавиатуры с FSM.
Ручная проверка
Кнопка «Проверить сейчас» сбрасывает next_check_at у подписок чата. Воркер подхватывает их на ближайшем цикле, без ожидания интервала.
// под капотом
Технические детали
Два процесса, одна БД
Бот и воркер - отдельные процессы, делят PostgreSQL. Бот отвечает за Telegram-трафик. Воркер опрашивает GitHub, зовёт OpenAI и шлёт уведомления через тот же бот-токен.
OpenAI Responses API
Использую новый Responses API с reasoning и строгим json_schema на выходе. Промты лежат в YAML с версионированием через prompt_version и подстановкой переменных.
SQLAlchemy 2 async + Alembic
Полный async-стек: asyncpg как драйвер, SQLAlchemy 2.0 ORM в async-режиме, Alembic для миграций. Никаких блокирующих вызовов в основном цикле.
aiogram 3 c FSM
Все диалоги добавления и настроек - через FSM aiogram 3. Reply-меню всегда снизу чата, инлайн-клавиатуры на подшаги. Команды и обработчики разделены по роутерам.
Pydantic 2
Конфигурация, схемы LLM-ответов и шаблоны промтов - всё на Pydantic 2 с валидацией на старте. Если в .env что-то не так, процесс падает сразу с понятной ошибкой.
Тесты и линт
pytest с фейками для GitHub и OpenAI - пайплайны прогоняются без сети. Линт через ruff, зависимости через uv. Структура слоёв: bot / worker / application / domain / integrations / storage.