# Combot Automation Compact v3: инструкция и схема для LLM

Этот файл можно целиком передать модели вместе с запросом на создание правила. Он описывает формат, который редактор Automation использует при импорте. Язык условий — JSON Compact v3, не Python, YAML, JavaScript, старый Triggers v2 или произвольный псевдокод «если → то».
Названия в интерфейсе переведены, а значения JSON — нет. Например, `Known Combot links` соответствует пункту «Пригласительные ссылки Combot», а `Combot custom admins` — пункту «Админы Combot». Не заменяйте значения JSON названиями из интерфейса.

Версия документа: 9 сентября 2026 года. Описание сверено с редактором и обработчиком Automation. В конце отдельно перечислены выполненные проверки импорта и работы в Telegram: проверка исходников сама по себе не подтверждает версию работающего сервиса.

## 1. Инструкция модели

Твоя задача — перевести запрос человека в правило Automation, сохранив его смысл.

1. Сначала установи событие, условия, исключения, действие, адресата действия и место ответа. Для расписания выясни часовой пояс; для команды — обычный запуск или ответ на чужое сообщение. Не добавляй модерацию, награды, случайность или удаление, если человек их не просил.
2. Не угадывай ID пользователей, темы, адреса чатов, приглашения, ранги и включённые возможности. Название темы не превращается в ID. Если существенных данных не хватает, задай вопросы. Допущения в формулировке ответа можно предложить отдельно, но нельзя выдавать неполное правило за точное выполнение запроса.
3. Новые правила всегда создавай с `en: false`. Это правило безопасной подготовки, а не ограничение Automation. Пропущенное `en` означает включённое правило.
4. Используй только описанные поля. Для вложенных фильтров, отмеченных «по экспорту», запроси настоящий экспорт похожей настройки; не конструируй предполагаемую структуру. Если сценарий не поддерживается, объясни ограничение. Не маскируй его удалением условий.
5. Ответ: краткое объяснение → один JSON-блок для импорта → ручные настройки и проверки. В JSON не должно быть комментариев, многоточий, шаблонных ID, пояснительных строк вне полей, лишних запятых или ключей вроде `when`, `if`, `then`, `conditions`, `actions`, `event`.
6. До выдачи результата мысленно проверь один подходящий и один неподходящий случай. Для команды с ответом проверь отдельно автора команды и автора исходного сообщения. Не утверждай, что правило испытано в Combot, если это не происходило.

Сопроводительная JSON Schema — вспомогательный профиль генерации новых выключенных правил. Он намеренно строже импорта в части обязательных полей и не принимает все старые экспорты. Сложные вложенные фильтры в нём проверяются только как объекты. Прохождение схемы не доказывает совместимость всех условий, наличие ресурсов, соблюдение тарифа или успешное действие Telegram.

## 2. Что вставлять в окно импорта

Корень — объект с числом `v: 3` и массивом правил `t`. Обычно возвращай одно правило. Не отправляй голый массив и не используй объект `{"triggers": [...]}`: это не формат окна импорта.

Полностью готовый минимальный пример:

```json
{
  "v": 3,
  "t": [
    {
      "n": "Памятка по команде",
      "en": false,
      "k": "c",
      "ctm": "p",
      "cm": ["/course_info"],
      "a": {
        "m": "a",
        "r": [
          {
            "i": "course_reply",
            "t": "s",
            "v": {
              "tx": "Записи занятий — в закреплённом сообщении чата.",
              "rp": "r"
            }
          }
        ]
      }
    }
  ]
}
```

`dv: "t3.compact.3"` — необязательная метка схемы. Для новых результатов достаточно `v` и `t`. Обёртка `bundle` распознаётся существующим импортом, но для генерации она не нужна.

Не добавляй серверный `id`, `revision`, `chat_id`, вычисляемый `ck` или `$schema` внутрь импортируемого пакета. Сервер назначит правилу новый ID. `i` внутри действия — другое поле: локальный идентификатор строки, например `course_reply`; он должен быть уникальным среди действий одного правила, состоять из 1–80 латинских букв, цифр, `_` или `-`.

Один и тот же короткий ключ имеет разный смысл на разных уровнях: корневой `t` — список правил, `a.r[].t` — вид действия, а `a.r[].v` — его параметры. Не перемешивай уровни.

## 3. Основные поля правила

| Поле | Значение |
| --- | --- |
| `n` | Непустое название, до 80 символов для редактора |
| `d` | Необязательное описание, до 280 символов для редактора |
| `en` | `false` для нового выключенного правила |
| `e` | Массив кодов событий, если это не команда |
| `k`, `cm`, `ctm` | Режим команды; см. следующий раздел |
| `a` | План действий: `{"m":"a","r":[...]}` или `{"m":"r","r":[...]}` |
| `s`, `ti` | Где проверять событие: весь исходный чат, общая или выбранная тема |
| `at` | Когда разрешено срабатывание; это фильтр времени, не таймер |
| `wh`, `wx`, `wm` | Кто вызвал событие: подходящие группы, исключения и способ объединения |
| `cgr` | Числовые условия: время в чате, сообщения, предупреждения, XP, репутация |
| `ua`, `ux`, `uar`, `ul`, `ulx` | Признаки, значения полей и язык участника |
| `twh`, `twx`, `tcg`, `tua`, `tux`, `tur`, `tlg`, `tlx` | Проверки другого пользователя события: например, автора сообщения из ответа или вступившего участника |
| `tv`, `tr`, `ty`, `cs`, `lmin`, `lmax` | Условия на текст |
| `mti`, `mtx`, `me`, `mex` | Типы сообщений и элементы текста |
| `il`, `ilc`, `ilx` | Пригласительные ссылки для заявки на вступление |
| `rct`, `rnt`, `rnx`, `rcy`, `rcx`, `rcn`, `rcm` | Условия на реакции |
| `chl` | Прямая ссылка на нужный чек-лист для событий изменения его задач |
| `cl` | Удаление предыдущего ответа по умолчанию: `n` или `ps` |
| `ov` | Альтернативные наборы условий «ИЛИ»; для сложного случая используй экспорт |

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

## 4. События

| `e` | Когда срабатывать |
| --- | --- |
| `["m"]` | Новое сообщение в чате |
| `["em"]` | Редактирование сообщения |
| `["m","em"]` | Новое сообщение или его редактирование |
| `["lc"]`, `["el"]`, `["lc","el"]` | Комментарий к связанному каналу, его редактирование или оба события |
| `["cp"]`, `["ec"]`, `["cp","ec"]` | Пост в связанном канальном контексте, его редактирование или оба события |
| `["jr"]` | Заявка на вступление |
| `["nm"]` | Участник вступил |
| `["ml"]` | Участник вышел или был удалён |
| `["cb"]`, `["rb"]` | Добавлен или снят буст |
| `["mr"]` | Изменились реакции конкретного пользователя |
| `["rc"]` | Обновились общие анонимные счётчики реакций в связанном канальном контексте |
| `["ck"]` | Появился новый чек-лист |
| `["cd"]` | В чек-листе отметили задачи выполненными |
| `["ca"]` | В чек-лист добавили задачи |

Не объединяй разные виды событий, например `["m","nm"]`. Для них нужны разные правила. Допустимы перечисленные пары «новое + отредактированное». Не генерируй скрытый режим гостевых ботов `gm`.

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

## 5. Обычная команда и команда ответом

Обычная команда, например выдача памятки:

```json
{"k":"c","ctm":"p","cm":["/course_info"]}
```

Команда, которую модератор отправляет ответом на сообщение участника:

```json
{"k":"c","cm":["/team_pause"]}
```

Эти два блока — фрагменты полей правила, не самостоятельные пакеты импорта.

Для команды не добавляй `e`. В `cm` передавай непустой список собственных slash-команд в нижнем регистре; используй латинские буквы, цифры и `_`. Не выдавай придуманную команду за встроенную команду Combot. У команды ответом поле `ctm` просто отсутствует: не пиши туда `reply_target`, `r` или имя участника.

У обычной команды нет адресата пользовательских действий. Используй отправку сообщения и, если это явно попросили, удаление сообщения-команды. Для мьюта, предупреждения, XP и других действий над человеком нужна команда ответом.

В таком сценарии `wh` проверяет автора команды, а `twh` и остальные поля `t...` — автора сообщения, на которое ответили. Для действия над последним указывай `v.tg: "t"`. Пример: Анна пишет `/team_pause` ответом Илье; ограничить нужно Илью, не Анну.

Проверка только `twh` не ограничивает круг тех, кто может запускать команду. Для модераторской команды обязательно задай `wh` согласно запросу. Удаление действием `d` удаляет саму команду, а не сообщение Ильи.

Не заменяй режим команды поиском строки `/team_pause` в `tv`. Скрытые в редакторе условия команды, например расписание, не добавляй без подтверждённого экспорта.

## 6. Участники и исключения

В `wh` и `wx` используются точные строки, а не переведённые подписи:

`New members`, `Regular members`, `Ex-members`, `Whitelisted users`, `Admins`, `Telegram admins`, `Combot custom admins`, `Owner`.

Пустой список включений означает отсутствие этого ограничения. `Anyone` обычно можно просто не указывать. `wm: "o"` — достаточно одной группы, `wm: "a"` — нужны все указанные группы. Исключения в `wx` запрещают совпадение независимо от положительных групп.

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

```json
{"wx":["Telegram admins","Combot custom admins","Owner"]}
```

Пример: команду разрешено вызывать только администратору Telegram или владельцу:

```json
{"wh":["Telegram admins","Owner"],"wm":"o"}
```

Не путай роли. `Combot custom admins` — полномочия Combot, не то же самое, что администраторы Telegram. В обработчике `Admins`, как и `Telegram admins`, проверяет администраторов Telegram, включая владельца; эта строка не добавляет администраторов Combot. Для допуска обеих групп перечисли `Telegram admins` и `Combot custom admins` с `wm: "o"`. `Regular members` означает известных текущих участников, а не людей с большим стажем или количеством сообщений. `New members` использует существующие настройки новичков и исключения чата; это не фиксированное «первые семь дней». Для точного срока используй `cgr`.

Не генерируй `Core members` и `Non-members`: надёжные определения для новых правил не предоставлены. Отсутствие сведений об участнике не доказывает, что он никогда не состоял в чате.

Для адресата используй `twh`, `twx`, `twm`. Дополнительные контекстные значения вроде `Target self`, `Target bots`, `Target Combot`, `Target linked channel post` бери из экспорта подходящего сценария, не подставляй в фильтр отправителя наугад.

У `nm` и `ml` поля `wh`/`wx` относятся к тому, кто инициировал вступление или удаление, а `twh`/`twx` — к участнику, чей статус изменился. Например, Анна добавила Илью: условия новичка задаются для Ильи через поля `t...`, не для Анны. Выбор `v.tg` у действия не переставляет эти условия местами.

`am: "o"` — проверка администратора Telegram; `am: "n"` — исключение администратора Telegram. Это не замена объединению ролей в `wh`/`wx`. Для новых правил предпочитай явно заданные группы.

## 7. Стаж, активность, XP и репутация

Числовые условия находятся в `cgr`, а для адресата — в `tcg`. Следующий фрагмент означает: участник находится в чате не больше часа и у него не больше пяти учтённых сообщений.

```json
{
  "cgr": {
    "logic": "All",
    "statistics": {
      "rules": [
        {"metric":"joinedDays","unit":"h","op":"lte","value":"1"},
        {"metric":"messageCount","unit":"c","join":"and","op":"lte","value":"5"}
      ]
    }
  }
}
```

Операторы: `eq` — равно, `gte` — не меньше, `lte` — не больше. Всегда указывай оператор явно. Не заменяй «меньше пяти» на `lte: 5`: для целочисленного счётчика это `lte: 4`. Не заменяй точный стаж проверкой `eq`, если человек подразумевает «не меньше»: время продолжает идти.

Метрики статистики:

- `joinedDays` — время после вступления именно в этот чат, не возраст аккаунта и не возраст человека. Единицы: `s`, `m`, `h`, `d`, `w`, `mo`. День равен 24 часам, неделя — 7 дням, месяц здесь — 30 дням. Новые правила всегда должны содержать единицу.
- `messageCount` — число учтённых сообщений в этом чате; единица `c`.
- `warns` — число активных предупреждений; единица `c`.

Условие «учтено одно сообщение» — `{"metric":"messageCount","unit":"c","op":"eq","value":"1"}`. Это не обещание выполнения строго один раз: обновление счётчика и обработка событий могут происходить отдельно.

Другие разделы:

```json
{
  "cgr": {
    "logic": "All",
    "xp": {
      "xp": {"rules":[{"op":"gte","value":"100"}]}
    },
    "reputation": {
      "reputation": {"rules":[{"op":"gte","value":"5"}]}
    }
  }
}
```

Порог ранга находится в `cgr.xp.rank.rules`, но значение нужно брать из реальных рангов чата, не из придуманного названия. В строках доступны `join: "and" | "or"` и `mode: "include" | "exclude"`. Для простых условий используй явное «И»; сложную цепочку «И/ИЛИ» строй по экспорту. `cgr.logic: "All" | "Any"` объединяет разделы. Исключающая числовая строка — запрет, её нельзя обойти положительным совпадением в другом разделе того же варианта условия.

Не создавай проверки времени после первого сообщения или другой первой активности: `firstMessageAge` и `firstOtherActivityAge` недоступны. Не обещай активность «за последнюю неделю» через общий `messageCount`. Недоступные сведения нельзя автоматически считать нулём.

## 8. Признаки и поля пользователя

`ua` — требуемые признаки, `ux` — исключаемые. Точные значения: `Any username`, `Telegram Premium`, `Bot account`, `Any last name`. Например, `{"ux":["Bot account"]}` исключает ботов.

`ul` и `ulx` — включённые и исключённые коды языка пользователя, если Telegram их передал. Это не язык написанного сообщения и не гражданство. Не делай вывод о языке по имени участника.

Условия на конкретные значения находятся в `uar`; для адресата — в `tur`. Поддерживаемые поля: `user_id`, `name`, `username`, `last_name`, `bio`. Bio относится к контексту заявки на вступление, не к постоянно доступному профилю всех участников.

Форма условия на username:

```json
{
  "uar": {
    "username": {
      "rules": [
        {"mode":"include","matchType":"Exact match","values":["example_member"]}
      ]
    }
  }
}
```

Это учебный фрагмент структуры, а не реальный участник. Для результата по запросу подставляй только переданный человеком username, без `@`; если его нет, спроси. ID передавай строками внутри `values`. Для ограничения доступа предпочтительнее явно предоставленный ID: имя и username могут измениться.

Здесь `matchType` использует полные строки `Exact match`, `Partial match`, `Regular expression` — не коды `f`, `p`, `r` из проверки текста сообщения. Значения внутри строки — альтернативы; между строками есть `join`. Не выдумывай `Starts with` и `Ends with` для этих полей.

`ual` и `tul`: `a` — все правила, `o` — любая группа. Структуры групп `uag` и `tug` в профиле генерации используются по экспорту.

## 9. Текст и вид сообщения

Для поиска фраз используй `tv` — массив строк. Достаточно совпадения с одной строкой. Например:

```json
{"tv":["где запись","запись занятия"],"tr":"p","ty":"p","cs":false}
```

`tr`: `p` — фразы, `w` — слова, `r` — регулярные выражения. В режиме слов это не обязательное присутствие всех слов. Обычный частичный поиск также не гарантирует границы слов: «кот» может совпасть внутри «котик».

`ty`: `f` — весь текст целиком, `p` — часть текста, `s` — начало, `e` — конец, `r` — регулярное выражение. `cs: true` включает учёт регистра, `false` или отсутствие поля выключает. Для простого FAQ достаточно `tv`: поиск фразы без учёта регистра — стандартное поведение.

`lmin` и `lmax` ограничивают длину текста. Пустая или нулевая граница не задаёт ограничение. Не путай длину с количеством слов.

Регулярные выражения нужны только там, где простого поиска недостаточно. Передавай шаблон строкой JSON, экранируя обратные косые черты; не добавляй JavaScript-разделители `/.../i` автоматически. Для требования точных слов или сложного отрицания поясни примеры совпадения и несовпадения.

`mti` — включённые типы сообщений, `mtx` — исключённые. Основные значения: `photo`, `video`, `animation`, `audio`, `document`, `sticker`, `voice`, `video_note`, `contact`, `location`, `poll`, `dice`, `game`, `paid_media`. Например, `{"mti":["voice"]}` — голосовые сообщения; `{"mti":["photo","video"]}` — фото или видео, не одновременно оба вложения.

В редакторе также есть `text` и `caption`. Они участвуют в настройках текстового содержимого; не используй `caption` как самостоятельный тип Telegram-вложения. Для запроса «только подписи к фото» или строгого отличия текста от подписи возьми экспорт соответствующей настройки. Кодек может опускать стандартные значения, включая одиночный `text`; наличие такого значения в исходном JSON само по себе не доказывает ограничение после импорта.

`me` и `mex` требуют или исключают элементы текста. Значения: `bot_command`, `url`, `text_link`, `mention`, `hashtag`, `cashtag`, `email`, `phone_number`, `emoji`, `custom_emoji`, `bold`, `italic`, `underline`, `strikethrough`, `code`, `pre`, `spoiler`, `blockquote`, `expandable_blockquote`. `mel: "a"` — все включённые элементы, `"o"` — хотя бы один. Для любой обычной или скрытой ссылки: `{"me":["url","text_link"],"mel":"o"}`.

`mef` — уточнения конкретных ссылок, команд и других элементов; `mmo` — свойства медиа; `mtg` и `mog` — группы условий; `csx`/`cse` — наборы символов. Эти сложные поля генерируй по реальному экспорту. Нельзя вместо них придумывать ключи `max_file_size`, `allowed_domains`, `mime`, `language` или `contains_all`.

## 10. Время и темы чата

`s`: `sc` — исходный чат, `gn` — общая тема, `st` — выбранные темы. В последнем случае `ti` содержит список положительных ID тем.

При импорте выбранные исходные темы сбрасываются на весь исходный чат, а выбранные темы отправки — на текущую тему. Это происходит даже с правильными ID и относится также к вариантам «ИЛИ». Если сценарий зависит от темы, укажи её в описании и обязательном списке ручных настроек. Не объявляй результат готовым к включению до повторного выбора темы.

Поля `at` задают разрешённое время события, а не самостоятельную отправку по часам. «Отвечать вечером на вопрос» возможно; «публиковать каждый день в 19:00 без входящего события» требует планировщика, а не такого триггера.

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

Еженедельное окно, понедельник–пятница, 09:00–18:00 UTC:

```json
{"at":{"m":"w","wd":[0,1,2,3,4],"tw":[{"startMinute":540,"endMinute":1080}]}}
```

`wd`: 0 — понедельник, 6 — воскресенье. Время — целое число минут с полуночи UTC, от 0 до 1439. У недельных окон конечная минута включена. Ночное окно возможно, когда начало больше конца; день недели проверяется по текущей дате UTC, а не по дню начала «смены». При переходе через полночь не угадывай требуемые дни — проверь обе стороны границы.

Московским 09:00 и 18:00 соответствуют 06:00 и 15:00 UTC, то есть 360 и 900 минут. Если правило должно перестать подходить ровно в 18:00, последней разрешённой минутой будет 14:59 UTC — `endMinute: 899`. Для других часовых поясов учитывай смещение и возможный сезонный перевод. Не записывай локальное время как UTC без пересчёта.

Интервал дат:

```json
{"at":{"m":"d","s":"2026-10-01T00:00:00Z","e":"2026-10-07T23:59:59Z"}}
```

Это пример формы, не даты пользовательской кампании. Начало должно предшествовать концу. В этом режиме обе границы включены. `Z` обозначает UTC.

Часы закрытия берутся из существующих настроек чата: `{"at":{"m":"c"}}`; вне этих часов — `{"at":{"m":"c","i":true}}`. В режиме закрытия начало включено, конец не включён. Сам триггер не настраивает расписание закрытия. Без корректного расписания не обещай работу ни прямого, ни обратного условия.

## 11. Пригласительные ссылки, реакции и чек-листы

### Приглашения

Для заявки `["jr"]` поле `il` принимает `Known Combot links`, `External invite link` или `Any source`. Без ограничения поле можно опустить.

`Known Combot links` означает ссылки из каталога Combot этого чата. `ilc` и `ilx` — списки кодов включённых и исключённых ссылок внутри этого каталога; точные коды бери из экспорта или предоставленных данных. Если списки пусты, остаётся проверка категории в целом.

`External invite link` означает определённую ссылку вне полного каталога Combot, а не «всё, кроме выбранных двух ссылок». Неизвестный источник или недоступный каталог нельзя считать внешней ссылкой. Не обещай, что это условие поймает каждую заявку без известного приглашения.

### Реакции пользователя

Событие `["mr"]`. `rct` — `added` и/или `removed`. `rnt` и `rnx` — включённые и исключённые реакции в новом состоянии пользователя. Если заполнено одно из этих полей, `rct` должен включать `added`.

Обработчик запускает `mr`, только когда Telegram передаёт `user`. Реакция от имени канала или анонимного администратора с `actor_chat` не запускает это событие. Это не то же самое, что общий счётчик реакций `rc`.

```json
{"e":["mr"],"rct":["added"],"rnt":["👍"]}
```

Значения реакций — обычные emoji, строковые ID пользовательских emoji или строка `paid`. `rnt` проверяет новое полное состояние, а не только разницу с предыдущим. Если 👍 уже была и пользователь добавил другую реакцию, условие может снова подойти. Получатель пользовательского действия `u` здесь — человек, изменивший реакцию; это не автоматическая награда автору сообщения.

### Общее количество реакций

Событие `["rc"]`. `rcy`/`rcx` выбирают виды учитываемых реакций, `rcn`/`rcm` задают нижнюю и верхнюю границы количества, неотрицательные целые числа. Ноль или отсутствие границы означает отсутствие ограничения с этой стороны.

```json
{"e":["rc"],"rcy":["👍"],"rcn":10}
```

Это проверка текущего значения при обновлении, не событие «впервые достигли десяти». Следующее подходящее обновление может вызвать действие ещё раз. Конкретного автора реакции в общем анонимном счётчике нет.

### Чек-листы

Для `["cd"]` и `["ca"]` поле `chl` ограничивает правило одним чек-листом. Если человек просит следить за конкретным списком, запроси прямую ссылку на его сообщение. Если нужны все подходящие чек-листы чата или темы, не добавляй `chl`.

Допустимы прямые ссылки Telegram, в том числе с номером темы; ссылка с `?comment=` не подходит. Не подставляй выдуманный адрес. Для публичной ссылки имя чата должно быть известно обработчику события; одной внешне правильной строки недостаточно, чтобы обещать совпадение.

## 12. Действия

`a.m: "a"` выполняет все строки по порядку. `a.m: "r"` выполняет все строки с `fr: 1` и ровно одну случайную строку без этого флага, если такие строки есть. Выбранные строки сохраняют исходный порядок. Без запроса случайности используй режим `a`; `fr` вне случайного режима не добавляй.

| Код `a.r[].t` | Что делает | Параметры `v` |
| --- | --- | --- |
| `s` | Отправить сообщение | `tx` и оформление; см. следующий раздел |
| `d` | Удалить сообщение, вызвавшее правило | Параметры не нужны |
| `w` | Добавить предупреждения | `tg`, `c` — положительное число, обычно 1 |
| `rw` | Снять предупреждения | `tg`, `c` — положительное число, обычно 1 |
| `m` | Ограничить отправку сообщений | `tg`, `du` — срок в секундах |
| `b` | Забанить | `tg`, `du` — срок в секундах |
| `k` | Удалить из чата с возможностью вернуться | `tg` |
| `um` | Снять ограничение отправки | `tg` |
| `ub` | Снять бан | `tg` |
| `du` | Удалить доступные боту сохранённые сообщения пользователя | `tg` |
| `x` | Изменить XP | `tg`, `v` — ненулевое целое от −99999 до 99999 |
| `r` | Изменить репутацию | `tg`, `v` — ненулевое целое от −999 до 999 |
| `ja` | Одобрить заявку на вступление | Только событие `jr`, параметры не нужны |
| `jd` | Отклонить заявку на вступление | Только событие `jr`, параметры не нужны |

Не путай код действия `du` и поле срока `v.du`. Срок — секунды, не минуты: час — 3600. Ноль для мьюта/бана — без заданного срока окончания; никогда не выбирай его вместо неизвестного срока. Причину можно написать отдельным сообщением, если это попросили; не обещай настраиваемую причину санкции через недокументированное поле.

Адресат пользовательского действия `v.tg`:

- `u` — участник, вызвавший событие.
- `t` — адресат, определённый контекстом: например, автор сообщения, на которое ответили командой. Это не буквальный ID.
- `l` — создатель пригласительной ссылки из каталога Combot, в контексте заявки.
- `b` — оба доступных участника соответствующего контекста. Не означает «все в чате».

Всегда задавай адресата явно. В обычной команде пользовательские действия недоступны. В команде ответом доступны автор команды, адресат и оба. Для заявки задавай отдельно действие над заявителем (`u`) и действие над известным создателем ссылки (`l`), если нужны оба: `b` не означает «заявитель плюс создатель ссылки». В редакторе создатель ссылки выбирается для заявки, поэтому не предлагай тот же выбор в пошаговой настройке события вступления. Для остальных событий используй только адресатов, доступных выбранному событию.

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

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

Для события заявки разрешены отправка сообщения, действия над доступными пользователями и `ja`/`jd`; удаление сообщения `d` не подходит. Для событий без сообщения не добавляй удаление или ответ на несуществующее сообщение.

## 13. Текст ответа и место отправки

Параметры действия `s`:

| Поле | Смысл |
| --- | --- |
| `tx` | Непустой текст до 4096 символов; можно использовать поддерживаемое Telegram HTML |
| `d` | `sc` — исходный чат, `lg` — настроенный канал логов; по умолчанию `sc` |
| `tp` | `ct` — текущая тема, `gn` — общая, `st` — выбранные темы; по умолчанию `ct` |
| `to` | Положительные ID выбранных тем; импорт их сбросит |
| `rp` | `r` — ответ на вызвавшее сообщение; без поля — обычное сообщение |
| `cl` | `n` — не удалять предыдущий ответ, `ps` — удалять предыдущий ответ этой строки |
| `bt` | Ряды URL-кнопок: массив массивов объектов с `text` и `url` |
| `ph` | Массив URL изображений для предпросмотра ссылки |
| `pa` | `true` — размещение предпросмотра выше текста |

`rp: "r"` сохраняется для исходного чата и текущей темы. Не обещай такой же ответ-связку в канале логов или другой теме. Не подставляй произвольный внешний чат, канал или личные сообщения в `d`.

Если `cl` у строки отсутствует, она наследует настройку правила. `cl: "ps"` у правила задаёт общий режим удаления предыдущего ответа; явный `cl: "n"` у строки его отменяет. Удаление привязано к конкретным правилу, строке действия и месту отправки. Разные случайные строки не превращаются от этого в одно общее «последнее приветствие».

Для обычного ответа можно использовать, например, `<b>Памятка</b>\nЗаписи — в закреплённом сообщении.` Не подставляй Markdown-оформление как HTML. Ссылки и текст нужно корректно экранировать. Кнопки и картинки добавляй только с реальными URL, предоставленными человеком; `ph` — не отправка фотоальбома.

Подтверждённые шаблонные переменные для контекста сообщения: `{name}`, `{uid}`, `{name_link}`, `{from.id}`, `{from.title}`, `{from.username}`, `{chat.id}`, `{chat.title}`, `{chat.username}`, `{message.id}`, `{message.timestamp}`, `{timestamp}`, `{group_name}`, `{reply_to_uid}`, `{reply_to_name}`, `{reply_to_name_link}`. Доступность значения зависит от события. Не придумывай `{target.name}`, `{user.first_name}`, `{reaction_count}` и подобные переменные.

В команде ответом `{from.title}` относится к автору команды, не к наказанному или награждённому участнику. Выбор `tg: "t"` не меняет смысл переменных. Если не уверен, что в событии есть нужное имя, используй нейтральный текст.

При вступлении `{from.title}` тоже не гарантирует имя новичка: если Анна добавила Илью, автор события — Анна. Для универсального приветствия используй, например, «Добро пожаловать в {chat.title}!» без имени.

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

## 14. Альтернативы, ограничения и неподдерживаемые обещания

`ov` — альтернативные условия того же правила. Они используют событие и действия родительского правила, а не собственный независимый сценарий. Исключение внутри одного варианта не становится глобальным исключением для всех вариантов. Если запрет должен действовать всегда, он должен сохраняться в каждом варианте. Выключенный вариант `en: false` не участвует в совпадении.

Для нового сложного `ov`, а также `mtg`, `mog`, `uag`, `tug`, `mef` и `mmo` используй настоящий экспорт редактора. Не создавай рекурсивные деревья «ИЛИ» и не размещай отдельные цепочки действий внутри вариантов в расчёте на их независимое исполнение.

Поля совместимости `mt`, `mtl`, `t`, `rmi`, `rme` могут присутствовать в экспорте. Не добавляй их вместо описанных основных настроек без необходимости. Для простого ограничения ответов достаточно `rm`: `a` — любой тип сообщения, `r` — только ответы, `rb` — ответы боту, `rc` — ответы Combot, `nr` — не ответы. Режим `rm: "cr"` не используй вместо полей новой команды.

Не генерируй старые или служебные поля `lf`, `fc`, `lo`, а также поля UI `actions`, `destination`, `topic`, `applyTarget`, `alwaysRun`. В компактном формате у них другие представления, а некоторые настройки вообще не являются действующими возможностями.

Границы планирования:

- Free — до 2 сохранённых правил, Pro — до 50, Business — до 100. Выключенные тоже считаются. Свободные места нужно считать с учётом уже существующих правил.
- Дополнительных вариантов «ИЛИ»: Free — 0, Pro — 2, Business — 5 на правило.
- До 100 строк действий на правило, но одновременно действует отдельный расчётный бюджет действий — 20 на одно исполнение плана.
- Отправка стоит 1 на каждое уникальное место назначения; с удалением предыдущего ответа — 2. Пользовательские Telegram-действия считаются по адресатам, для `b` резерв может быть двойным. XP и репутация в этом расчёте стоят 0. Для случайного режима учитываются обязательные строки плюс самая дорогая случайная.
- Это внутренний расчёт, не обещание строго двадцати сетевых запросов с учётом всех вспомогательных действий Telegram. Если очередная строка не помещается в остаток, дальнейшее выполнение плана прекращается; уже сделанное не откатывается.

Не обещай: запуск без события по таймеру, «не чаще раза в час», однократную награду за реакцию, защиту от накрутки повторными событиями, строгое первое пересечение порога, исполнение ровно один раз, автоматическую обработку произвольных внешних чатов, возраст аккаунта или статистику активности за произвольный прошлый период. Если это ключевое требование, сообщи, что одного описанного правила недостаточно.

Импорт добавляет правила новыми копиями и не выполняет миграцию старого Triggers v2. Переписать смысл старого правила в Compact v3 можно; напрямую выдавать его прежний JSON за готовый импорт нельзя.

## 15. Контрольные сценарии для готовых примеров

Соседняя папка `examples` содержит шесть самостоятельных пакетов по одному выключенному правилу:

| Файл | Подходящий случай | Что проверить дополнительно |
| --- | --- | --- |
| `01-course-command.json` | Участник вводит `/course_info` | Обычный текст без команды не должен вызывать ответ |
| `02-recording-faq.json` | В тексте есть «где запись» | Другой вопрос не должен вызывать ответ; частичный поиск может совпасть и в более длинной фразе |
| `03-random-welcome.json` | Вступает новый участник | При вступлении должен выбираться один вариант приветствия, не все три |
| `04-moderator-reply-mute.json` | Администратор Telegram или владелец вызывает `/team_pause` ответом участнику | Обычный участник не должен запускать команду; адресат-администратор исключён; команда без ответа не должна ограничивать автора |
| `05-known-link-join-request.json` | Пришла заявка по ссылке из каталога Combot | Внешний или неизвестный источник не должен подходить; все известные ссылки подходят, если не выбраны конкретные |
| `06-thumbs-up-reaction.json` | Пользователь добавил реакцию, и в новом состоянии есть 👍 | Снятие 👍 не подходит; повторные подходящие изменения могут вызвать сообщение снова |

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

## 16. Источник формата и выполненная проверка

Формат сверен с Rails `0d80ce4788ef5adc5c7c1b79e85c6b8be27cc00e` и ботом `ddc1a8a6b6ab99bd2517d783870495990c7058e5`. В этих основных ветках присутствуют согласованные исправления редактора и Automation. Слияние Rails PR #78 и bot PR #56 подтверждено в Codeberg; точные версии развёрнутых процессов отдельно не установлены.

Основные источники: `trigger_compact_codec_helpers.js`, `trigger_import_export_helpers.js`, `trigger_validation_helpers.js`, реестры событий и действий, `user_attribute_model_helpers.js`, `AutomationController`, подробный контракт Automation в `docs/MONGODB.md`, обработка условий и действий в `automation.py`.

Шесть примеров проверены в памяти через исходный кодек редактора: декодирование, повторная сборка, повторное декодирование и стабильность нормализованного результата; действия и выключенное состояние сохранены. Кодек опускает часть стандартных значений, поэтому сравнивался нормализованный результат, а не побайтовое равенство исходного JSON.

8 сентября проверено выключенное состояние всех шести примеров после импорта через рабочий редактор на combot.org, сохранения на сервере и перезагрузки страницы. Эта проверка не заменяет проверку всех условий и действий каждого правила в Telegram.

В Telegram проверены команда и FAQ: подходящий запрос вызывает нужный ответ, контрольный — нет. Для команды изменено только имя `/course_info` на уникальное тестовое имя, разрешённое защитой тестера; остальные настройки примера сохранены. Эти результаты не подтверждают остальные события и действия автоматически.

Для `06-thumbs-up-reaction.json` проверены добавление 👍 от личного профиля — один ожидаемый ответ — и снятие 👍 — без ответа. Личность и старый/новый набор реакций подтверждены через отдельного Bot API-наблюдателя. Случайное приветствие при вступлении, применение мьюта и одобрение реальной заявки в этом прогоне не проверялись; их импорт не считается доказательством выполнения действий.

Созданные тестовые правила удалены с проверкой восстановления исходного списка; сообщения с результатами оставлены в тестовой группе. JSON Schema подготовлена как сопроводительная документация, не подключена к продукту и не выдаётся за существующий встроенный валидатор.

9 сентября выполнена редакторская сверка с Rails `0d80ce4788ef5adc5c7c1b79e85c6b8be27cc00e` и ботом `0a491a6ee50c57e98c1d9de04819253d15214506`. Уточнены лимит названия в редакторе, административные группы, участники события, получатели действий и необязательность ссылки на чек-лист. Это проверка описания по исходникам, не новый прогон примеров в Telegram.
