БФЛ КонтентДокументация проекта
Разделы документации
Для разработчика

Команды и действия: фактический контракт

Обновлено 16 сентября 2026БФЛ Контент
На этой странице
  1. Допуск
  2. Текстовые команды
  3. Кнопки
  4. Ответ с замечаниями
  5. Служебные входы
  6. Доставка и согласование двух участников
  7. Уточнение /post после исправления

Источник: опубликованный BFL-content, узлы «Telegram — участники проекта», «Распознать команду или решение», оба Switch, проверки кнопок/замечаний/восстановления. Это контракт кода, а не меню BotFather. Обозначения: DRAFT_ID — идентификатор материала, V — положительный номер версии; в сообщениях ошибки бот подставляет настоящие значения.

Допуск

Внешний Trigger принимает message/callback_query; до бизнес-маршрутов внутренний сервис проверяет настоящий numeric from.id, private chat.id=from.id, is_bot=false и active в реестре. Проверки повторяются перед внешними запросами. Unknown допускается только на безопасный /start. Владелец и редактор имеют одинаковые перечисленные ниже действия с общими материалами; управление правами остаётся у владельца.

Текстовые команды

ВводФактическая обработкаАргументы / отказ
/post ТемаНовый собственный пост, версия 1, ключ события u:update_id.Тема — весь непустой хвост; отдельного ограничения длины темы в парсере нет. Команда нечувствительна к регистру.
/postСообщение «Добавьте тему после команды. Например: /post Что важно знать перед обращением за банкротством».Пробелы без темы также дают подсказку.
/post@bflcontentbot ТемаПоддерживается актуальным regex.Тема непустая; эта строка исправляет ошибку прежнего экспорта.
/newsПоиск за 7 календарных дней, без тематического фильтра.Окно включает сегодняшний день в Europe/Moscow.
/news кредиты7 дней, тема «кредиты».Тема максимум 200 UTF-16 единиц после NFC/trim; управляющие символы запрещены.
/news 7 [тема]Явно 7 дней.Допустимый период.
/news 30 [тема]Явно 30 дней.Например /news 30 МФО.
/news 14news_help, бот перечисляет правильные команды.Начальный целый числовой токен допускает только 7 или 30; слишком длинная/недопустимая тема тоже даёт подсказку.
/news@bflcontentbot 30Поддерживается, имя бота и команда сравниваются без учёта регистра.Чужой @username не считается /news.
/retry DRAFT_ID VПродолжение известного text_failed без новых редакционных замечаний.Только последняя версия общего проекта, без preview/approval/published ID и без outcome_unknown. Создаёт новую версию; старую сохраняет.
/retry DRAFT_ID V замечанияТо же с новыми замечаниями.ID: [A-Za-z0-9_-]{1,40}; V: [1-9]\d{0,8}. Команда регистрозависима; допускается @bflcontentbot.
/resume DRAFT_ID VВозобновляет импорт PNG, рендер или подготовку превью той же версии.Только последняя photo_caption_v1, без approval/published, status из image_upload_failed, render_failed, preview_failed. Не разрешает повтор неопределённой генерации/отправки. Синтаксис ID/V как у /retry, без хвоста замечаний.

/retry не является универсальным повтором. Для первой собственной темы после text_failed обработчик требует подходящего родителя правки, которого может не быть; сообщение предлагает новый /post. Для первой новости предусмотрено продолжение сохранённого source/fact_pack и пригодного текста. Для неудачной доработки нужны подходящий родитель superseded/awaiting_feedback, сохранённая подпись и тот же исходник изображения.

Неправильный синтаксис /retry//resume не порождает отдельную подсказку. Распознанная команда с неподходящим состоянием заканчивает ветку без новых API и сообщений. Switch.fallbackOutput=none.

/start реализован: разрешённому участнику роль/команды, неизвестному собственный ID и сообщение об отсутствии доступа. /help и /cancel не реализованы. Вне reply-контекста неизвестный текст/команда обычно получает null и остаётся без ответа. Если неизвестный текст, включая строку вида /help, отправлен ответом на сообщение, парсер может передать его как feedback; затем проверяется ID именно ожидаемого force-reply сообщения. Это не реализация команды помощи.

Кнопки

Надписьcallback_dataУсловия и действие
Подготовить постnews:BATCH_ID:ITEM_IDBATCH_ID 1–16, ITEM_ID 1–12 ASCII букв/цифр/_/-. Активный участник, private, зарегистрированная доставленная ему копия карточки, связанная ready-подборка, offered-карточка, срок не истёк. Атомарный claim по статье и выбору до подготовки.
Опубликоватьp|DRAFT_ID|VПоследняя awaiting_approval, правильное сообщение согласования, целостный текст/обложка, нет публикации/дубля; CAS переводит в publishing перед sendPhoto.
Доработатьr|DRAFT_ID|VТе же guards готовой версии; перевод в awaiting_feedback и force-reply приглашение.
Отклонитьx|DRAFT_ID|VТе же guards; status=rejected. Данные и картинка остаются; публикации нет.

Кнопка относится к комплекту конкретной версии. Дополнительно проверяются preview_photo_state=sent, совпадение approval/preview message ID, хеши, размер/шаблон, подпись и источник, отсутствие отправок в канал и повторного event_key. Для новостей нужен news_validation=verified.

Неверные форматы callback отбрасываются. Для корректного старого callback бот показывает всплывающий ответ о неактивной версии либо о текущей работе. Для повторного выбора статьи — отдельный ответ о том, что статья уже выбрана. Удаление кнопок Telegram не служит защитой: защита основана на БД.

Ответ с замечаниями

Нужно отвечать на сообщение «Напишите замечания к версии v{V} ответом на это сообщение.», а не просто писать боту. Проверяются reply_to_message.message_id, сохранённый feedback_prompt_message_id, инициатор закреплённой сессии, его private-чат, awaiting_feedback и последняя версия. update_id защищён от повторного использования.

Точная замена без исходной генерации текста распознаётся для форм вроде Замени «старая фраза» на «новая фраза» или Замени последнее предложение на: «новое предложение». Картинку и остальной текст сохранить. Нужен единственный точный исходный фрагмент; принимаются кавычки «…» или "…". Это узкий regex, не любой свободный пересказ инструкции. Для новости меняется body, ссылка добавляется обратно и сохраняется смысловая проверка.

Изменение заголовка — обычное замечание, отдельной команды нет. Явная смена картинки определяется regex: «измени/поменяй/замени/перерисуй [саму/эту/исходную/только] картинку/иллюстрацию/изображение», «создай/сгенерируй/сделай/нарисуй новую/другую …» и обратный порядок «картинку измени». Перед этим удаляются фразы «не изменяй/меняй/заменяй/трогай картинку…». Произвольные синонимы и отрицания не гарантированы; см. findings.md.

Служебные входы

Основной workflow имеет Execute Workflow Trigger «Внутреннее задание БФЛ». В текущих settings callerIds указаны BFLNewsInitial04, BFLNewsInitial041, BFLNewsRouteResume, BFLEditorPostResume339. Наличие имени в allowlist не доказывает его активность; новый экспорт включает только последний из этих служебных workflow, и он неактивен.

technical_retry использует сохранённый материал и обычный маршрут восстановления; это не команда Telegram. Одноразовое продолжение execution 339 дополнительно требует серверного доказательства остановки до внешнего запроса, действующей роли и успешного атомарного захвата. Доказательство уже использовано.

В экспортированных схемах нет Schedule Trigger/Cron. Wait относятся к ограниченному повтору уведомления после подтверждённого 429. Публикация по расписанию не настроена.

Доставка и согласование двух участников

Новые карточки и готовые версии получают оба. Callback форматы прежние, но проверяется своя зарегистрированная копия. Старая owner-копия может использоваться владельцем по прежним полям; редактор не получает автоматического доступа к недоставленной истории. Одновременные действия проходят общий захват версии/статьи. Одобрения одного участника достаточно, расписаний нет.

Уточнение /post после исправления

/post тема — самостоятельная команда владельца или редактора. Роль проверяется по numeric ID и active; подборка /news заранее не нужна. Создаётся одна общая версия, статус получает инициатор до платной генерации, превью — оба. Служебный мост BFLEditorPostResume339 не является командой пользователя и не создаёт Telegram update. Его доказательство восстановления уже использовано; повторный вызов блокируется.

Стандартные /retry и /resume не были расширены для слепого повтора. Подтверждённая оператором остановка до запроса — отдельная исключительная процедура с доказательством и одноразовым захватом; неизвестный исход внешнего запроса её не допускает.