# Combot Automation Compact v3: інструкція для LLM і довідка формату

Передайте моделі весь цей файл разом із запитом на правило. Він описує формат, який імпортує редактор Автоматизації. Мова правил — JSON Compact v3, а не Python, YAML, JavaScript, старі Triggers v2 чи довільний псевдокод «якщо → то».
Назви в інтерфейсі перекладені, а значення JSON — ні. Наприклад, `Known Combot links` відповідає пункту «Посилання на запрошення Combot», а `Combot custom admins` — пункту «Адміністратори Combot». Не замінюйте значення JSON назвами з інтерфейсу.

Редакція документа: 9 вересня 2026 року. Довідку звірено з редактором і обробником Автоматизації. Виконані перевірки імпорту та Telegram окремо наведені наприкінці: перегляд вихідного коду не встановлює версію запущеного сервісу.

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

Перетвори запит людини на правило Автоматизації, не змінюючи його змісту.

1. З'ясуй подію, умови, винятки, дію, її адресата й місце відповіді. Для розкладу з'ясуй часовий пояс, для команди — чи її надсилають окремо, чи відповіддю. Не додавай модерацію, винагороди, випадковість або видалення без запиту.
2. Не вгадуй ID користувачів, теми, адреси чатів, запрошення, ранги чи ввімкнені функції. Назва теми — не її ID. Якщо бракує необхідних відомостей, запитай. Припущення щодо тексту відповіді можна запропонувати окремо, але неповне правило не можна подавати як точне рішення.
3. Завжди генеруй нові правила з `en: false`. Це домовленість для безпечної підготовки, а не обмеження Автоматизації. Якщо `en` пропущено, правило ввімкнене.
4. Використовуй лише задокументовані поля. Для вкладених фільтрів із позначкою «використовуйте експорт» попроси справжній експорт схожого налаштування; не вигадуй структуру. Якщо сценарій не підтримується, поясни обмеження, а не приховуй його видаленням умов.
5. Відповідай у порядку: коротке пояснення → один блок JSON для імпорту → ручні налаштування й перевірки. JSON не має містити коментарів, трикрапок, вигаданих ID-заглушок, пояснювальних рядків поза полями, кінцевих ком або вигаданих ключів на кшталт `when`, `if`, `then`, `conditions`, `actions` чи `event`.
6. Перед відповіддю розбери один відповідний і один невідповідний випадок. Для команди-відповіді перевір автора команди окремо від автора початкового повідомлення. Не стверджуй, що правило перевірене в Combot, якщо цього насправді не було.

Додана JSON Schema допомагає генерувати нові вимкнені правила. Її обов'язкові поля навмисно суворіші за імпорт, і вона приймає не кожен старий експорт. Складні вкладені фільтри перевіряються лише як об'єкти. Відповідність схемі не доводить сумісності умов, доступності ресурсів, дотримання тарифних лімітів чи успішного виконання дій у Telegram.

## 2. Що вставляти в Імпорт (Import)

Корінь — об'єкт із числовим `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. Прості команди та команди-відповіді

Проста команда (Plain command), наприклад інформаційна відповідь:

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

Команда, яку модератор надсилає відповіддю на повідомлення учасника, у режимі Адресат відповіді (Reply target):

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

Це фрагменти полів правила, а не самостійні набори для імпорту.

Не додавай `e` до команди. У `cm` передай непорожній список власних команд зі скісною рискою, малими латинськими літерами, цифрами та `_`. Не подавай вигадану команду як вбудовану в 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"` виключає його. Це не заміна поєднанню ролей у `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`. Біографія належить до контексту заявки на вступ; це не постійно доступне поле профілю кожного учасника.

Умова імені користувача має таку форму:

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

Це показує структуру, а не справжнього учасника. У реальному запиті використовуй лише надане людиною ім'я користувача, без `@`; якщо його немає, запитай. ID передавай як рядки у `values`. Для контролю доступу віддавай перевагу явно наданому ID: імена та імена користувачів можуть змінюватися.

Тут `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.

Години закриття (Closing hours) використовують наявні налаштування чату: `{"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":["👍"]}
```

Значення реакцій — звичайні емодзі, рядкові ID власних емодзі або `paid`. `rnt` перевіряє повний новий стан, а не лише різницю. Якщо 👍 уже була й користувач додає іншу реакцію, умова може спрацювати знову. Адресат дії `u` тут — людина, яка змінила реакцію; автора повідомлення він автоматично не винагороджує.

### Сукупна кількість реакцій

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

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

Це перевіряє поточне значення під час оновлення, а не «вперше досягло десяти». Інше відповідне оновлення може виконати дію знову. Сукупний анонімний лічильник не має конкретного користувача, який відреагував.

### Списки завдань

Для `["cd"]` та `["ca"]` поле `chl` обмежує правило одним списком. Якщо людині потрібен конкретний список, попроси пряме посилання на його повідомлення. Якщо потрібні всі відповідні списки в чаті чи темі, не додавай `chl`.

Прямі посилання Telegram, зокрема з номером теми, підтримуються; посилання з `?comment=` — ні. Не вигадуй адресу. Для публічного посилання обробник події має знати ім'я користувача чату; самого зовні коректного URL недостатньо для підтвердження збігу.

## 12. Дії

`a.m: "a"` виконує всі рядки по черзі — Виконати всі (Run all). `a.m: "r"` виконує всі рядки з `fr: 1` та рівно один випадковий непозначений рядок, якщо такі є, — Одну випадкову (Random one). Вибрані рядки зберігають початковий порядок. Використовуй режим `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` або поля інтерфейсу `actions`, `destination`, `topic`, `applyTarget` та `alwaysRun`. Compact представляє їх інакше, а деякі налаштування взагалі не є активними можливостями.

Ліміти для планування:

- Free: до 2 збережених правил; Pro: до 50; Business: до 100. Вимкнені теж враховуються. Оцінюючи вільні місця, враховуй наявні правила.
- Додаткові альтернативи АБО на правило: Free — 0, Pro — 2, Business — 5.
- До 100 рядків дій на правило, з окремим розрахунковим бюджетом 20 дій на виконання плану.
- Надсилання коштує 1 на унікальне місце призначення або 2 з очищенням попередньої відповіді. Дії Telegram над користувачами рахуються за адресатами, тому `b` може резервувати вдвічі більше. XP і репутація коштують 0 у цьому розрахунку. Випадковий режим враховує обов'язкові рядки та найдорожчий випадковий вибір.
- Це внутрішній розрахунок, а не обіцянка рівно двадцяти мережевих запитів з усіма допоміжними операціями. Якщо наступний рядок перевищує залишок бюджету, виконання зупиняється; виконані дії не скасовуються.

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

Імпорт додає нові копії правил, а не переносить старі 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`. Ці ревізії основних гілок містять узгоджені виправлення редактора й Автоматизації. Злиття 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`, докладний контракт Автоматизації в `docs/MONGODB.md` та обробка умов і дій в `automation.py`.

Шість початкових прикладів перевірили в пам'яті вихідним кодеком редактора: декодування, повторна побудова, ще одне декодування та стабільність нормалізованого результату. Дії та вимкнений стан збереглися. Кодек пропускає деякі типові значення, тому порівнювали нормалізовані результати, а не побайтову тотожність вхідному JSON.

8 вересня вимкнений стан усіх шести початкових прикладів перевірили після імпорту через робочий редактор на combot.org, збереження на сервері та перезавантаження сторінки. Це не замінює перевірки кожної умови й дії в Telegram.

Випадки команди та FAQ перевірили в Telegram: відповідні запити отримали потрібні відповіді, контрольні — ні. Лише `/course_info` змінили на унікальну тестову назву, дозволену запобіжниками засобу перевірки; інші налаштування прикладів зберегли. Ці результати автоматично не підтверджують інші події та дії.

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

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

9 вересня редакційну довідку звірено з Rails `0d80ce4788ef5adc5c7c1b79e85c6b8be27cc00e` та ботом `0a491a6ee50c57e98c1d9de04819253d15214506`. Уточнення охоплюють ліміт назви в редакторі, групи адміністраторів, учасників подій, адресатів дій і необов'язкові посилання на списки завдань. Це перевірка документації за вихідним кодом, а не новий запуск у Telegram. Локалізовані тексти прикладів незалежно наживо не перевірялися.
