Как работает бот — схемы процессов

Документ для Дениса. Семь схем — как бот находит дела, следит за ними и готовит рассылку. Без кода, простым языком. Текстовое описание каждого шага — в АЛГОРИТМ.md; здесь то же самое, но картинками.

Цвета на схемах: - 🔵 синий — вход / начало - 🟡 жёлтый — развилка (бот принимает решение) - 🟢 зелёный — дело движется дальше / лид - ⚪ серый — дело отсеяно - 🟣 бирюзовый — уведомление тебе в Telegram - ⬜ пунктир — ещё не запущено (в работе / план)


0. Общая картина

Бот работает в двух режимах одновременно: Discovery (раз в сутки ищет новые дела) и Monitor (каждые 15 минут следит за отобранными). Дальше из дел рождаются лиды для рассылки.

flowchart LR
    CB[("casebook.ru<br/>новые дела за сутки")]:::start
    KAD[("kad.arbitr.ru<br/>каждые 15 минут")]:::start
    CB --> DISC[Discovery<br/>отбор по выручке]:::decision
    DISC --> W[В мониторинге<br/>watching]:::good
    W --> MON[Monitor<br/>следим за судом]:::decision
    KAD --> MON
    MON --> ALERT[Telegram-алерт]:::alert
    MON --> OBEZ[Обездвижка<br/>слабый заявитель]:::good
    MON --> RET[Возврат заявления]:::good
    OBEZ --> RASS[Рассылка писем<br/>5 кампаний · идёт]:::good
    RET --> RASS
    classDef start fill:#dbeafe,stroke:#60a5fa,color:#1e3a5f
    classDef decision fill:#fef3c7,stroke:#fbbf24,color:#78350f
    classDef good fill:#dcfce7,stroke:#4ade80,color:#14532d
    classDef skip fill:#f1f5f9,stroke:#cbd5e1,color:#475569
    classDef alert fill:#ccfbf1,stroke:#2dd4bf,color:#134e4a
    classDef planned fill:#f5f3ff,stroke:#c4b5fd,color:#4c1d95,stroke-dasharray: 5 5

1. Discovery — поиск новых дел (раз в сутки)

Каждое утро бот забирает из casebook все вчерашние заявления о банкротстве юрлиц, проверяет ИНН и отсеивает мелкие компании. Проходят только крупные — их и берём в мониторинг.

flowchart TD
    A[("casebook: все банкротства<br/>юрлиц за вчера")]:::start --> B{ИНН должника<br/>корректный?}:::decision
    B -->|"мусорный ИНН"| S1[Отсеять:<br/>невалидный ИНН]:::skip
    B -->|"12 цифр — физлицо/ИП"| S2[Отсеять:<br/>физлицо]:::skip
    B -->|"да, юрлицо"| C{Достаточно<br/>крупная?}:::decision
    C -->|"выручка ≥ 300 млн ₽<br/>ИЛИ активы ≥ 1 млрд ₽"| W[В мониторинг<br/>watching]:::good
    C -->|"меньше порога"| S3[Отсеять:<br/>низкие показатели]:::skip
    C -.->|"«живой» гейт<br/>(готов, ждёт включения)"| U{"3 условия:<br/>работает + нужная форма +<br/>выручка ≥ 300 млн ИЛИ активы ≥ 1 млрд<br/>(по свежим данным bo.nalog)"}:::planned
    U -.->|"всё совпало"| W
    U -.->|"нет"| S4[Отсеять:<br/>не прошла по живым данным]:::skip
    classDef start fill:#dbeafe,stroke:#60a5fa,color:#1e3a5f
    classDef decision fill:#fef3c7,stroke:#fbbf24,color:#78350f
    classDef good fill:#dcfce7,stroke:#4ade80,color:#14532d
    classDef skip fill:#f1f5f9,stroke:#cbd5e1,color:#475569
    classDef planned fill:#f5f3ff,stroke:#c4b5fd,color:#4c1d95,stroke-dasharray: 5 5

Сейчас: по умолчанию работает классический фильтр — проходит, если выручка ≥ 300 млн ₽ ИЛИ активы ≥ 1 млрд ₽ (берёт свежие цифры из bo.nalog, где они есть, иначе локальную налоговую базу). «Живой» гейт (пунктир) дополнительно проверяет, что компания действующая и нужной организационно-правовой формы, и квалифицирует строго по свежим данным. Он готов; включим после ретро-проверки уже отобранных дел, чтобы не выкинуть нужное вслепую.


2. Monitor — слежка за делом (каждые 15 минут)

Бот обходит дела в мониторинге и смотрит, что суд сделал с заявлением. Частота зависит от возраста дела — свежие проверяем чаще, старые реже.

flowchart TD
    W[Дело в мониторинге]:::good --> AGE{Возраст дела}:::decision
    AGE -->|"0–3 дня"| WAIT[Ждём,<br/>суд ещё не вынес]:::skip
    AGE -->|"3–7 дней"| CARD
    AGE -->|"7–15 дней"| CARD
    AGE -->|"15–30 дней"| CARD
    AGE -->|"30+ дней без движения"| STALE[Снять с слежки<br/>stale]:::skip
    CARD[Открыть карточку<br/>kad.arbitr]:::decision --> GHOST{"Страница<br/>не найдена?"}:::decision
    GHOST -->|"да — дело объединили"| LINK[Привязать к<br/>головному делу]:::skip
    GHOST -->|"нет"| ACT{Последний акт<br/>суда?}:::decision
    ACT -->|"принятие"| SRO[Извлечь СРО → §3]:::alert
    ACT -->|"оставление<br/>без движения"| OB[Обездвижка → §4<br/>дело остаётся в слежке]:::good
    ACT -->|"возврат"| RT[10-дневное окно → §5<br/>дело остаётся в слежке]:::good
    ACT -->|"прекращение / отказ"| REJ[Закрыть дело<br/>rejected]:::skip
    classDef good fill:#dcfce7,stroke:#4ade80,color:#14532d
    classDef decision fill:#fef3c7,stroke:#fbbf24,color:#78350f
    classDef skip fill:#f1f5f9,stroke:#cbd5e1,color:#475569
    classDef alert fill:#ccfbf1,stroke:#2dd4bf,color:#134e4a

3. Алерт о принятии — извлечение СРО

Когда суд принял заявление, бот скачивает определение и ищет в нём название СРО. От того, какая СРО (или её нет) — зависит, придёт ли тебе алерт.

flowchart TD
    A[Определение о принятии]:::good --> B[Скачать PDF]:::decision
    B --> C[Метод 1: словарь<br/>73 известных СРО]:::decision
    C -->|"не нашёл"| D[Метод 2: общий шаблон<br/>«СРО «...»»]:::decision
    D -->|"не нашёл"| E[Метод 3: ИИ читает PDF]:::decision
    C --> R{Какая СРО?}:::decision
    D --> R
    E --> R
    R -->|"наша — ЦФОП АПК"| T1[Telegram:<br/>ЦЕЛЕВОЙ алерт]:::alert
    R -->|"СРО не указана<br/>(суд адресует всем)"| T2[Telegram:<br/>«случайная выборка»]:::alert
    R -->|"любая другая СРО"| S[Тихо отметить,<br/>не беспокоить]:::skip
    classDef good fill:#dcfce7,stroke:#4ade80,color:#14532d
    classDef decision fill:#fef3c7,stroke:#fbbf24,color:#78350f
    classDef skip fill:#f1f5f9,stroke:#cbd5e1,color:#475569
    classDef alert fill:#ccfbf1,stroke:#2dd4bf,color:#134e4a

4. Обездвижка — слабый заявитель → будущее письмо

«Оставление без движения» значит, что у заявителя недочёты в заявлении. Это потенциальный клиент: ему можно предложить помощь. Бот ловит каждое такое определение, определяет причину (основание), а дальше готовится письмо.

flowchart TD
    A[Определение об оставлении<br/>без движения]:::good --> G{Это правда обездвижка,<br/>не отложение?}:::decision
    G -->|"нет"| X[Пропустить]:::skip
    G -->|"да"| SAVE[Сохранить КАЖДУЮ обездвижку<br/>во вкладку «Обездвижка»]:::good
    SAVE --> REASON[Пометить основание<br/>причину обездвижки]:::good
    REASON -.-> CAL[/"Сейчас: калибруем точную разметку<br/>по 5 основаниям Дениса —<br/>прогнали 100 дел, размечаем вместе"/]:::planned
    CAL -.-> R1[Госпошлина]:::planned
    CAL -.-> R2["Форма / содержание / приложения"]:::planned
    CAL -.-> R3[Нет публикации на ЕФРСБ]:::planned
    CAL -.-> R4[Не направлена копия]:::planned
    CAL -.-> R5[Нет депозита суда]:::planned
    R1 -.-> LET[Шаблон письма под<br/>основание + тип заявителя]:::planned
    R2 -.-> LET
    R3 -.-> LET
    R4 -.-> LET
    R5 -.-> LET
    LET -.-> OUT[В рассылку → §7]:::planned
    classDef good fill:#dcfce7,stroke:#4ade80,color:#14532d
    classDef decision fill:#fef3c7,stroke:#fbbf24,color:#78350f
    classDef skip fill:#f1f5f9,stroke:#cbd5e1,color:#475569
    classDef planned fill:#f5f3ff,stroke:#c4b5fd,color:#4c1d95,stroke-dasharray: 5 5

Где мы сейчас: бот уже ловит все обездвижки и проставляет основание. Идёт калибровка — прогнали 100 определений, ты с нами размечаешь правильность, по итогам донастраиваем. Следующий шаг (пунктир) — шаблоны писем под каждое основание (должник по ст. 37 / кредитор по ст. 39 — письма разные) и автоподготовка рассылки.


5. Возврат — 10-дневное окно

Если суд вернул одно из заявлений, дело может быть ещё живо (другие кредиторы могли подать свои). Поэтому бот не закрывает дело сразу, а ждёт 10 дней.

flowchart TD
    A[Определение о возврате]:::good --> B[Не закрываем сразу.<br/>Ставим окно 10 дней,<br/>дело остаётся в слежке]:::good
    B --> C[Проверяем каждые 12 часов]:::decision
    C --> D{Что произошло<br/>за 10 дней?}:::decision
    D -->|"новое принятие"| E[Перевести в notified<br/>дело живо]:::alert
    D -->|"новая обездвижка"| F[Зафиксировать обездвижку → §4]:::good
    D -->|"прекращение / отказ"| G[Закрыть, rejected]:::skip
    D -->|"ничего за 10 дней"| H[Финал: возвращено<br/>returned → лид на помощь]:::good
    H -.-> OUT[В рассылку → §7]:::planned
    B --> CHIP["На вкладке «Возвраты» помечаем<br/>формулировки: подсудность · ст.7 ·<br/>30 дней · публикация · 15 дней"]:::good
    classDef good fill:#dcfce7,stroke:#4ade80,color:#14532d
    classDef decision fill:#fef3c7,stroke:#fbbf24,color:#78350f
    classDef skip fill:#f1f5f9,stroke:#cbd5e1,color:#475569
    classDef alert fill:#ccfbf1,stroke:#2dd4bf,color:#134e4a
    classDef planned fill:#f5f3ff,stroke:#c4b5fd,color:#4c1d95,stroke-dasharray: 5 5

6. Заявители — несколько заявителей в одном деле (план)

Твоя идея: в одном деле несколько заявителей, у каждого свой акт суда, и каждый — отдельный лид. Сейчас бот видит дело как «один должник — один заявитель». Эта схема — то, что мы проектируем (тикет #313).

flowchart TD
    A[Дело в банкротстве]:::start -.-> B[Заявитель 1]:::planned
    A -.-> C[Заявитель 2]:::planned
    A -.-> D[Заявитель 3 ...]:::planned
    B -.-> B1{Статус<br/>заявителя?}:::planned
    C -.-> C1{Статус<br/>заявителя?}:::planned
    D -.-> D1{Статус<br/>заявителя?}:::planned
    B1 -.->|"обездвижен"| L1[Лид: помощь<br/>по обездвижу]:::planned
    C1 -.->|"возвращён"| L2[Лид: помощь<br/>по возврату]:::planned
    D1 -.->|"принят"| L3[Процедура пошла,<br/>не лид]:::skip
    B1 -.->|"пока никого не приняли"| POLL["Опрашивать 2–3 раза в неделю:<br/>новые заявители + статусы"]:::planned
    L1 -.-> OUT[В рассылку → §7]:::planned
    L2 -.-> OUT
    classDef start fill:#dbeafe,stroke:#60a5fa,color:#1e3a5f
    classDef skip fill:#f1f5f9,stroke:#cbd5e1,color:#475569
    classDef planned fill:#f5f3ff,stroke:#c4b5fd,color:#4c1d95,stroke-dasharray: 5 5

Статус: проектируем. Нужно от тебя: как опознавать заявителя (по ИНН?), какие статусы считаем лидом, как часто опрашивать. По этому — отдельный разбор.


7. Рассылка — как из дела получается письмо

Рассылка работает — идёт с 21 июня. Из дел рождаются пять потоков писем: по тому, что суд сделал с делом и кто заявитель. Дальше бот сам находит правильный адрес, проверяет его, ставит письмо в очередь и следит за качеством. Ниже — по-человечески, что под капотом.

Пять кампаний — кому и когда пишем

Кампания Когда срабатывает Кому пишем Про что письмо
Флагман суд принял дело, в определении названа одна СРО должнику помощь / инвестиции / реструктуризация (мы знаем вашу СРО)
ФНС заявитель — налоговая должнику защита по налоговым делам (доначисления, субсидиарка)
Фолбэк принято, но СРО не названа или их несколько должнику общее письмо-предложение
Обездвижка суд оставил заявление кредитора без движения заявителю-кредитору поможем устранить недочёты
Возврат суд вернул заявление заявителю-кредитору поможем подать заново / сопровождение

Первые три — письма должнику, последние две — заявителю-кредитору.

Как бот готовит письмо

flowchart TD
    A[Лид из любой<br/>из 5 кампаний]:::good --> ADDR[Найти ПРАВИЛЬНЫЙ адрес<br/>только проверенные источники<br/>по ИНН: Роскомнадзор, DataNewton]:::decision
    ADDR --> CHECK[Проверить: живой ли ящик<br/>чтобы письмо дошло]:::decision
    CHECK --> DEDUP{Уже писали<br/>по этому делу?}:::decision
    DEDUP -->|"да"| SKIP1[Не дублируем]:::skip
    DEDUP -->|"нет"| STATE{Статус дела<br/>ещё подходит?}:::decision
    STATE -->|"появилось наблюдение /<br/>прекращение / возврат"| SKIP2[Не шлём]:::skip
    STATE -->|"всё ещё подходит"| SEND[Отправка через Smartlead<br/>окно 10 дней от акта ·<br/>новым в первую очередь ·<br/>25 писем в день с ящика]:::good
    SEND --> ST{Статус письма}:::decision
    ST -->|"в очереди"| S1[Готово,<br/>ещё не ушло]:::good
    ST -->|"идёт"| S2[Ушло ≥1 письмо,<br/>идут повторные]:::good
    ST -->|"пауза"| S3[Робот увидел много<br/>недоставленных → пауза]:::skip
    classDef good fill:#dcfce7,stroke:#4ade80,color:#14532d
    classDef decision fill:#fef3c7,stroke:#fbbf24,color:#78350f
    classDef skip fill:#f1f5f9,stroke:#cbd5e1,color:#475569

Правила отправки

Что бот делает, чтобы не навредить

Два слова, которые встретятся

Где мы сейчас: рассылка идёт с 21 июня, есть первый живой отклик (кредитор спросил про выкуп долга). Что докручиваем: (1) отдельный ящик под самый объёмный тип (ФНС) — заводится, прогрев ~3 недели; (2) тексты писем под каждое основание обездвижки — калибруем вместе.


Что нужно от тебя (короткий список)

Для чего Что нужно
§4 Письма Тексты под каждое из 5 оснований (должник / кредитор)
§4 Калибровка Разметить грейд-лист на 100 обездвижках
§6 Заявители Алгоритм: как опознавать, какие статусы — лид, частота опроса
§1 Выручка Границы тиров (упоминал 900 млн – 1,155 млрд)
§7 Рассылка Идёт с 21 июня. Осталось за тобой: тексты под основания обездвижки

Текстовая версия со всеми деталями и глоссарием — в АЛГОРИТМ.md.