В компании есть технический Telegram-канал, и посты для него пишут сами сотрудники. Порядок такой: автор готовит материал, коллеги-критики голосуют «за» или «против», администратор выбирает лучшее и публикует. Рубрики постоянные: быстрый приём, разбор чужой ошибки, микро-кейс, опрос или квиз, анонс, развлекательный пост.
Этот конвейер был собран на no-code платформе n8n и со временем стал мешать сильнее, чем помогать.
— Правила жили только в связях между блоками. Нигде не было записано, кто что может делать, в каком порядке идут шаги и что происходит с отклонённым постом.
— Любое условие сложнее «если — то» превращалось в гроздь узлов, а поломку в длинном сценарии приходилось искать вслепую.
— Весь процесс зависел от сторонней платформы.
ЗАДАЧА
Перенести процесс в собственный код так, чтобы для редакции порядок работы не изменился: тот же Telegram, те же роли, тот же путь поста от черновика до канала. Дальше развивать его как обычный продукт: правка поста после ревью, повторное голосование, надёжная отправка постов с картинкой и форматированием.
Ограничения: сотрудники работают только в Telegram, никаких новых интерфейсов; подпись к фото в Telegram ограничена 1024 знаками; разметка автора не должна ломаться по дороге в канал.
Спроектировал и написал бота один — от разбора исходного сценария до автоматической выкладки на сервер. Весь репозиторий мой: перенос, тесты, развёртывание и все доработки.
Восстановил правила. Логика n8n жила в связях между блоками, поэтому сначала я разобрал сценарий и записал правила явно: какие есть роли, кто что видит, в каком порядке идут шаги. Дальше они стали кодом и таблицами PostgreSQL.
Три роли по коду-приглашению. Критик голосует, автор ещё и пишет, администратор ещё и публикует — права вложены друг в друга. Роль выдаётся кодом, который человек отправляет боту, базу никто не правит руками. Роли хранятся в базе и переживают перезапуск.
Черновик в пять шагов: рубрика из шести, заголовок, текст, картинка или пропуск, автор. Лимит текста — 1024 знака, это потолок подписи к фото в Telegram: бот показывает счётчик и при превышении говорит, на сколько сократить. После сохранения служебные сообщения диалога удаляются. Любая команда посреди диалога — законный выход: бот отменяет черновик и сразу выполняет команду.
Форматирование доходит до канала. Жирный, курсив и ссылки, которые автор поставил средствами Telegram, сохраняются и корректно экранируются. Если разметку всё же не примут, бот отправит пост заново без неё — сообщение не теряется. Для проверки есть режим предпросмотра разметки.
Ревью без накруток. Новый пост сразу уходит всем критикам с кнопками «за» и «против». Один человек — один голос, повторное нажатие отклоняется, в очереди критик видит только то, что ещё не оценил. После голосования сообщение убирается из чата.
Правка и повторный круг. Автор меняет текст или картинку своего неопубликованного поста и может отправить его на повторное ревью: оценки обнуляются, пост уходит критикам заново. Чужой или уже опубликованный пост изменить нельзя — это проверяется и в обработчике кнопки, и ещё раз на уровне базы.
Публикация. Администратор открывает десять лучших неопубликованных постов по числу голосов «за» и публикует нужный одной кнопкой. Повторная публикация того же поста заблокирована.
Выкладка без ручных шагов. Docker Compose поднимает три сервиса по порядку: база с проверкой готовности, отдельный контейнер миграций Alembic и только после его успешного завершения — бот. Секреты хранятся в Doppler, а не в репозитории. Пуш в основную ветку собирает образ и выкатывает его на сервер через GitHub Actions, тесты прогоняются на каждый пул-реквест.
Устойчивый старт. Бот ждёт базу до 20 секунд с повторными попытками, контейнер миграций — до 30 попыток, поэтому медленный старт PostgreSQL не роняет систему.
Сроки. 17 июня 2025 года в репозиторий вошли перенос логики, тесты, CI и автодеплой. 18 июня — устойчивый старт и логирование, 24–26 июня — правка постов, повторное ревью, отправка постов с картинкой и форматирование.
Для редакции порядок работы остался прежним: тот же Telegram, те же роли, тот же путь поста от черновика до канала. Поменялось то, что под капотом.
Процесс больше не зависит от сторонней платформы. Бот, база и выкладка свои и работают на собственном сервере, поэтому стоимость работы не зависит от того, сколько постов пишет редакция.
Логику можно прочитать. Правила, которые раньше приходилось восстанавливать по связям между блоками, записаны в коде, покрыты тестами и меняются обычным пул-реквестом. Новая функция — это правка в репозитории, а не перестройка схемы.
Процесс стал честнее. Голос нельзя отдать дважды, чужой пост нельзя поправить, опубликованный нельзя опубликовать повторно. Чаты участников не зарастают служебными сообщениями, а администратор не листает всё подряд: перед ним десять лучших черновиков.
Обновление стало рутиной. Изменение уходит на сервер само после пуша, миграции применяются до старта бота, секреты не лежат в репозитории — обновление не оставит бота с несовместимой базой.
Сроки: перенос, тесты и автодеплой — в первый же день, вся работа вместе с доработками — 10 дней.
Так же можно перенести любой процесс, который перерос no-code: согласования, заявки, модерацию, публикации.