# Combot Automation Compact v3: LLM 지침과 형식 설명

규칙 요청과 함께 이 파일 전체를 모델에 제공하세요. 자동화 편집기가 가져오는 형식을 설명합니다. 규칙 언어는 Compact v3 JSON이며 Python, YAML, JavaScript, 이전 Triggers v2, 임의의 “조건 → 작업” 의사 코드가 아닙니다.
인터페이스의 항목 이름은 번역되지만 JSON 값은 바뀌지 않습니다. 예를 들어 `Known Combot links`는 편집기의 “Combot 초대 링크”, `Combot custom admins`는 “Combot 관리자”에 해당합니다. JSON 값을 인터페이스의 항목 이름으로 바꾸지 마세요.

문서 개정: 2026년 9월 9일. 자동화 편집기와 처리 코드를 기준으로 확인했습니다. 완료된 가져오기 및 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` | 이벤트를 확인할 곳: 원본 채팅, General, 선택한 주제 |
| `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` | OR 대안 조건 묶음, 복잡한 경우 내보내기 사용 |

모든 필드를 채우지 마세요. 선택한 이벤트와 관련된 요청 조건만 추가하세요. 예를 들어 가입에 메시지 키워드는 필요 없고, 합산 반응 수에는 자동으로 보상할 특정 사용자가 없습니다.

## 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`에는 라틴 소문자, 숫자, `_`를 사용하는 슬래시 명령어의 비어 있지 않은 목록을 주세요. 만든 명령어를 Combot 기본 명령어로 소개하지 마세요. 답장 명령어는 `ctm`을 생략하고 `reply_target`, `r`, 사람 이름을 넣지 마세요.

일반 명령어에는 사용자 작업의 수신자가 없습니다. 메시지 전송과, 명시적으로 요청한 경우에만 명령어 메시지 삭제를 사용하세요. 음소거, 경고, XP 등 사람에게 적용하는 작업에는 답장 명령어가 필요합니다.

답장 명령어에서 `wh`는 명령어 전송자를, `twh`와 다른 `t...` 필드는 답장받은 메시지 작성자를 검사합니다. 후자에 적용하려면 `v.tg: "t"`를 쓰세요. 안나가 일리야에게 `/team_pause`로 답장했다면 안나가 아닌 일리야를 제한해야 합니다.

`twh`만 확인하면 명령어 실행자를 제한하지 못합니다. 관리자 명령어에는 요청에 따른 `wh`가 있어야 합니다. 작업 `d`는 일리야의 메시지가 아니라 명령어 자체를 삭제합니다.

명령어 모드를 `tv`의 `/team_pause` 문자열 검색으로 대체하지 마세요. 확인된 내보내기 없이 일정 등 편집기가 숨기는 명령어 조건을 추가하지 마세요.

## 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`는 Telegram 관리자가 아닌 Combot 권한입니다. 처리 코드의 `Admins`는 `Telegram admins`처럼 소유자를 포함한 Telegram 관리자를 검사하며 Combot 관리자를 추가하지 않습니다. 두 그룹 모두 허용하려면 `Telegram admins`와 `Combot custom admins`를 `wm: "o"`로 나열하세요. `Regular members`는 확인된 현재 회원이며 가입 기간이나 메시지 수가 많은 사람이 아닙니다. `New members`는 채팅의 기존 새 회원 설정과 면제를 사용하며 고정된 “처음 7일”이 아닙니다. 정확한 기간에는 `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"`를 지원합니다. 간단한 조건에는 AND를 명시하고 복잡한 AND/OR 연결에는 실제 내보내기를 쓰세요. `cgr.logic: "All" | "Any"`는 섹션을 결합합니다. 숫자 제외 행은 금지입니다. 같은 조건 대안의 다른 섹션에서 포함이 일치해도 우회할 수 없습니다.

첫 메시지나 다른 첫 활동 이후 시간 검사를 만들지 마세요. `firstMessageAge`와 `firstOtherActivityAge`는 사용할 수 없습니다. 총 `messageCount`로 “지난주 활동”을 약속하지 마세요. 없는 데이터를 자동으로 0으로 바꾸면 안 됩니다.

## 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`은 메시지 코드 `f`, `p`, `r`가 아닌 전체 문자열 `Exact match`, `Partial match`, `Regular expression`을 사용합니다. 한 행의 값들은 대안이고 행 사이에는 `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`는 텍스트 길이를 제한합니다. 경계가 비거나 0이면 그쪽 제한이 없습니다. 길이를 단어 수와 혼동하지 마세요.

간단한 일치로 부족할 때만 정규식을 쓰세요. 역슬래시를 이스케이프한 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`은 General, `st`는 선택 주제입니다. 마지막 경우 `ti`에 양의 주제 ID가 들어갑니다.

가져오기는 선택 원본 주제를 전체 원본 채팅으로, 선택 전송 주제를 현재 주제로 초기화합니다. ID가 정확해도 일어나며 OR 대안에도 적용됩니다. 주제에 의존하는 시나리오는 설명과 필수 수동 설정에 이름을 적으세요. 다시 선택하기 전에는 켜도 되는 결과라고 말하지 마세요.

`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입니다. 주간 구간은 마지막 1분을 포함합니다. 자정을 넘는 구간은 시작이 끝보다 클 수 있습니다. 요일은 “근무” 시작일이 아닌 현재 UTC 날짜를 사용합니다. 필요한 요일을 추측하지 말고 자정 양쪽을 확인하세요.

모스크바 09:00과 18:00은 UTC 06:00과 15:00이며 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`가 있어야 합니다.

처리기는 Telegram이 `user`를 제공할 때만 `mr`을 실행합니다. `actor_chat`으로 채널이나 익명 관리자 이름으로 보낸 반응은 이 이벤트를 실행하지 않습니다. 합산 반응 수 `rc`와 다릅니다.

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

반응 값은 일반 이모지, 사용자 지정 이모지 ID 문자열, `paid`입니다. `rnt`는 차이만이 아니라 새로운 전체 상태를 확인합니다. 👍가 이미 있는데 다른 반응을 더하면 또 일치할 수 있습니다. 여기서 작업 수신자 `u`는 반응을 바꾼 사람이며 메시지 작성자를 자동으로 보상하지 않습니다.

### 합산 반응 수

이벤트 `["rc"]`. `rcy`/`rcx`는 셀 반응 유형을 선택합니다. `rcn`/`rcm`는 0 이상의 정수로 하한과 상한을 정합니다. 0 또는 생략은 해당 쪽 경계 없음입니다.

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

업데이트의 현재 값을 확인하며 “처음 열 개에 도달함”이 아닙니다. 다음 일치 업데이트에도 작업이 다시 실행될 수 있습니다. 익명 합산 수에는 특정 반응 사용자가 없습니다.

### 체크리스트

`["cd"]`와 `["ca"]`에서 `chl`은 목록 하나로 제한합니다. 특정 목록이 필요하다면 메시지 직접 링크를 요청하세요. 채팅이나 주제의 모든 일치 목록이 필요하다면 `chl`을 추가하지 마세요.

주제 번호를 포함한 Telegram 직접 링크를 지원하며 `?comment=` 링크는 지원하지 않습니다. 주소를 만들어 내지 마세요. 공개 링크에는 처리기가 채팅 사용자 이름을 알고 있어야 합니다. 겉으로 유효한 URL만으로 일치를 확정할 수 없습니다.

## 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`, −99999~99999의 0이 아닌 정수 `v` |
| `r` | 평판 변경 | `tg`, −999~999의 0이 아닌 정수 `v` |
| `ja` | 가입 요청 승인 | `jr` 이벤트 전용, 매개변수 없음 |
| `jd` | 가입 요청 거절 | `jr` 이벤트 전용, 매개변수 없음 |

작업 코드 `du`와 기간 필드 `v.du`를 혼동하지 마세요. 기간은 분이 아닌 초이므로 한 시간은 3600입니다. 음소거나 차단의 0은 끝을 정하지 않았다는 뜻입니다. 모르는 기간 대신 절대로 0을 쓰지 마세요. 요청하면 이유를 별도 메시지로 적을 수 있지만 문서에 없는 필드로 사용자 지정 처분 사유를 약속하지 마세요.

사용자 작업 수신자 `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`: General, `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`에는 실제 편집기 내보내기를 쓰세요. 재귀 OR 트리를 만들거나 대안 안에 별도 작업 체인을 넣어 독립 실행을 기대하지 마세요.

내보내기에 호환성 필드 `mt`, `mtl`, `t`, `rmi`, `rme`가 있을 수 있습니다. 이유 없이 문서의 주요 설정 대신 추가하지 마세요. 간단한 답장 제한에는 `rm`을 사용합니다. `a`는 모든 메시지, `r`는 답장만, `rb`는 봇에 대한 답장, `rc`는 Combot에 대한 답장, `nr`는 답장 아님입니다. 새 명령어 필드 대신 `rm: "cr"`를 쓰지 마세요.

이전 또는 내부 필드 `lf`, `fc`, `lo`와 UI 필드 `actions`, `destination`, `topic`, `applyTarget`, `alwaysRun`을 생성하지 마세요. Compact에서는 다르게 표현하며 일부 설정은 실제 활성 기능조차 아닙니다.

설계 한도:

- Free: 저장 규칙 최대 2개, Pro: 최대 50개, Business: 최대 100개. 비활성 규칙도 셉니다. 남은 자리를 판단할 때 기존 규칙을 고려하세요.
- 규칙별 추가 OR 대안: 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`를 기준으로 형식을 확인했습니다. 이 main 브랜치 리비전에는 조율된 편집기 및 자동화 수정이 포함됩니다. Codeberg에서 Rails PR #78과 봇 PR #56 병합을 확인했지만 실제 배포 프로세스의 정확한 리비전은 독립적으로 확정하지 않았습니다.

주요 소스: `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과 바이트 단위 비교가 아닌 정규화 결과를 비교했습니다.

9월 8일 combot.org 운영 편집기에서 가져오기, 서버 저장, 페이지 새로고침 후 원본 예시 여섯 개의 비활성 상태를 확인했습니다. 이것이 Telegram에서 모든 조건과 작업을 검증한 것을 대신하지는 않습니다.

명령어와 FAQ 사례를 Telegram에서 확인했습니다. 일치 요청은 예상 답장을 받았고 비교 사례는 받지 않았습니다. 테스터의 보호 규칙에 맞는 고유 시험 이름으로 `/course_info`만 바꾸었고 나머지 예시 설정은 유지했습니다. 이 결과가 다른 이벤트와 작업까지 자동으로 증명하지는 않습니다.

`06-thumbs-up-reaction.json`에서는 개인 프로필의 👍 추가에 예상 답장 하나가 나왔고 제거에는 나오지 않았습니다. 별도 Bot API 관찰기로 신원과 이전/새 반응 상태를 확인했습니다. 당시 가입 시 무작위 환영, 음소거 적용, 실제 가입 요청 승인은 시험하지 않았습니다. 가져오기가 작업 실행을 증명하지는 않습니다.

만든 시험 규칙을 제거하고 원래 목록의 복원을 확인했습니다. 결과 메시지는 테스트 그룹에 남아 있습니다. JSON Schema는 제품에 연결되거나 기존 내장 검증기로 제시되는 것이 아닌 보조 문서입니다.

9월 9일 Rails `0d80ce4788ef5adc5c7c1b79e85c6b8be27cc00e`와 봇 `0a491a6ee50c57e98c1d9de04819253d15214506`를 기준으로 편집용 참조 문서를 확인했습니다. 편집기 이름 한도, 관리자 그룹, 이벤트 참가자, 작업 수신자, 선택적인 체크리스트 링크를 명확히 했습니다. 이는 소스 기반 문서 검토이며 새 Telegram 실행 확인이 아닙니다. 번역된 예시 문구는 독립적으로 실환경 시험하지 않았습니다.
