# Combot Automation Compact v3: instrucciones para LLM y referencia del formato

Dale este archivo completo al modelo junto con tu petición. Describe el formato que importa el editor de Automation. El lenguaje es JSON Compact v3, no Python, YAML, JavaScript, el antiguo Triggers v2 ni pseudocódigo arbitrario de «si → entonces».
Las etiquetas de la interfaz se traducen; los valores JSON no. Por ejemplo, `Known Combot links` corresponde a «Enlaces de invitación de Combot» y `Combot custom admins` a «Admins de Combot» en el editor. No sustituyas esos valores JSON por las etiquetas de la interfaz.

Revisión: 9 de septiembre de 2026. La referencia se contrastó con el editor y el procesamiento de Automation. Las comprobaciones de importación y Telegram figuran por separado al final: inspeccionar código no establece la versión de un servicio en ejecución.

## 1. Instrucciones para el modelo

Convierte la petición en una regla sin cambiar su significado.

1. Determina evento, condiciones, exclusiones, acción, destinatario y destino de la respuesta. Para horarios, determina la zona; para comandos, si se envían solos o como respuesta. No añadas moderación, premios, aleatoriedad ni borrado si no se piden.
2. No adivines ID de usuarios, temas, direcciones, invitaciones, rangos ni funciones activas. El nombre de un tema no es su ID. Pregunta si faltan datos esenciales. Puedes sugerir aparte supuestos de redacción, pero no presentar una regla incompleta como solución exacta.
3. Genera siempre reglas nuevas con `en: false`. Es una convención de preparación segura, no una limitación de Automation. Omitir `en` significa activada.
4. Usa solo campos documentados. Para filtros anidados indicados como «usar una exportación», pide un archivo real de una configuración similar; no inventes la estructura. Si un caso no es compatible, explica la limitación en vez de ocultarla quitando condiciones.
5. Responde con explicación breve → un bloque JSON importable → ajustes y comprobaciones manuales. El JSON no debe tener comentarios, puntos suspensivos, ID de relleno, explicaciones fuera de campos, comas finales ni claves inventadas como `when`, `if`, `then`, `conditions`, `actions` o `event`.
6. Antes de devolverlo, razona un caso que coincida y otro que no. En comandos de respuesta, comprueba por separado al remitente del comando y al autor del mensaje original. No afirmes haber probado una regla en Combot si no ocurrió.

El JSON Schema adjunto ayuda a generar reglas nuevas desactivadas. Sus campos obligatorios son intencionadamente más estrictos que el importador y no acepta todas las exportaciones antiguas. Los filtros anidados complejos solo se comprueban como objetos. Cumplir el esquema no demuestra compatibilidad de condiciones, disponibilidad de recursos, cumplimiento del plan ni éxito de acciones en Telegram.

## 2. Qué pegar en Import

La raíz es un objeto con `v: 3` numérico y un array de reglas `t`. Normalmente devuelve una regla. No devuelvas un array suelto ni `{"triggers": [...]}`: no es el formato del diálogo.

Ejemplo mínimo completo:

```json
{
  "v": 3,
  "t": [
    {
      "n": "Comando de información del curso",
      "en": false,
      "k": "c",
      "ctm": "p",
      "cm": ["/course_info"],
      "a": {
        "m": "a",
        "r": [
          {
            "i": "course_reply",
            "t": "s",
            "v": {
              "tx": "Las grabaciones de clase están en el mensaje fijado del chat.",
              "rp": "r"
            }
          }
        ]
      }
    }
  ]
}
```

`dv: "t3.compact.3"` es un marcador opcional del esquema. Los resultados nuevos solo necesitan `v` y `t`. El importador reconoce un envoltorio `bundle`, pero no es necesario al generar.

No añadas `id`, `revision`, `chat_id`, el valor calculado `ck` ni `$schema` dentro del paquete. El servidor asigna un ID nuevo. El campo `i` de la acción es distinto: identifica localmente una fila, como `course_reply`. Debe ser único dentro de las acciones y contener entre 1 y 80 letras latinas, dígitos, `_` o `-`.

Una misma clave corta significa cosas diferentes según el nivel: `t` en la raíz es la lista de reglas; `a.r[].t`, el tipo de acción; `a.r[].v`, sus parámetros. No mezcles niveles.

## 3. Campos principales de la regla

| Campo | Significado |
| --- | --- |
| `n` | Nombre no vacío, hasta 80 caracteres en el editor |
| `d` | Descripción opcional, hasta 280 caracteres en el editor |
| `en` | `false` para una regla nueva desactivada |
| `e` | Array de códigos de evento, salvo en comandos |
| `k`, `cm`, `ctm` | Modo de comando; ver abajo |
| `a` | Plan de acciones: `{"m":"a","r":[...]}` o `{"m":"r","r":[...]}` |
| `s`, `ti` | Dónde comprobar: chat de origen, General o temas seleccionados |
| `at` | Cuándo se permiten coincidencias; filtro de tiempo, no temporizador |
| `wh`, `wx`, `wm` | Autor del evento: grupos incluidos, exclusiones y combinación |
| `cgr` | Condiciones numéricas: tiempo en el chat, mensajes, advertencias, XP, reputación |
| `ua`, `ux`, `uar`, `ul`, `ulx` | Atributos, valores de campos e idioma del miembro |
| `twh`, `twx`, `tcg`, `tua`, `tux`, `tur`, `tlg`, `tlx` | Comprobaciones de la otra persona del evento, como autor del mensaje respondido o miembro que ingresa |
| `tv`, `tr`, `ty`, `cs`, `lmin`, `lmax` | Condiciones de texto |
| `mti`, `mtx`, `me`, `mex` | Tipos de mensaje y entidades de texto |
| `il`, `ilc`, `ilx` | Enlaces de invitación para solicitudes de ingreso |
| `rct`, `rnt`, `rnx`, `rcy`, `rcx`, `rcn`, `rcm` | Condiciones de reacciones |
| `chl` | Enlace directo a una lista concreta para eventos de cambios de tareas |
| `cl` | Limpieza predeterminada de la respuesta anterior: `n` o `ps` |
| `ov` | Alternativas O de condiciones; usar exportación en casos complejos |

No rellenes todos los campos. Añade solo condiciones pedidas y relevantes para el evento. Un ingreso no necesita palabras clave y un recuento agregado de reacciones no identifica a alguien para premiarlo automáticamente.

## 4. Eventos

| `e` | Cuándo se ejecuta |
| --- | --- |
| `["m"]` | Nuevo mensaje de chat |
| `["em"]` | Edición de mensaje |
| `["m","em"]` | Nuevo mensaje o edición |
| `["lc"]`, `["el"]`, `["lc","el"]` | Comentario del canal vinculado, edición o ambos |
| `["cp"]`, `["ec"]`, `["cp","ec"]` | Publicación en el contexto del canal vinculado, edición o ambos |
| `["jr"]` | Solicitud de ingreso |
| `["nm"]` | Ingreso de un miembro |
| `["ml"]` | Un miembro salió o fue eliminado |
| `["cb"]`, `["rb"]` | Mejora añadida o retirada |
| `["mr"]` | Cambiaron las reacciones de un usuario concreto |
| `["rc"]` | Se actualizaron contadores anónimos agregados en el contexto del canal vinculado |
| `["ck"]` | Nueva lista de tareas |
| `["cd"]` | Tareas marcadas como completadas |
| `["ca"]` | Tareas añadidas |

No combines eventos sin relación como `["m","nm"]`; usa reglas separadas. Se permiten los pares indicados de nuevo y editado. No generes el modo oculto de bot invitado `gm`.

Una edición es otro activador. No la añadas automáticamente a XP, reputación, advertencias ni a acciones que se esperan una sola vez.

## 5. Comandos simples y comandos de respuesta

Un comando simple, como respuesta informativa:

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

Un comando que un moderador envía respondiendo a un miembro:

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

Son fragmentos de campos, no paquetes independientes para importar.

No añadas `e` a un comando. Proporciona en `cm` una lista no vacía de comandos personalizados con barra, en minúsculas, con letras latinas, números y `_`. No presentes un comando inventado como integrado en Combot. Para respuestas, omite `ctm`; no pongas `reply_target`, `r` ni un nombre personal.

Un comando simple no tiene destinatario para acciones sobre usuarios. Usa un envío y, solo si se solicita, el borrado del comando. Silencios, advertencias, XP y otras acciones personales requieren un comando de respuesta.

En una respuesta, `wh` comprueba al remitente del comando, y `twh` y demás campos `t...` al autor del mensaje respondido. Usa `v.tg: "t"` para actuar sobre este último. Si Anna responde `/team_pause` a Ilya, restringe a Ilya, no a Anna.

Comprobar solo `twh` no limita quién ejecuta. Un comando de moderación debe incluir `wh` según lo pedido. La acción `d` borra el comando, no el mensaje de Ilya.

No sustituyas el modo de comando por buscar `/team_pause` en `tv`. No añadas condiciones ocultas por el editor para comandos, como horarios, sin una exportación verificada.

## 6. Miembros y exclusiones

`wh` y `wx` usan estas cadenas exactas, no etiquetas traducidas:

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

Una lista de inclusión vacía no limita grupos. Normalmente puedes omitir `Anyone`. `wm: "o"` exige un grupo que coincida; `wm: "a"`, todos los elegidos. Las exclusiones de `wx` impiden coincidir independientemente de grupos positivos.

Ejemplo: cualquier persona excepto administradores puede enviar el mensaje que coincida:

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

Ejemplo: solo un administrador de Telegram o el propietario puede ejecutar:

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

No confundas roles. `Combot custom admins` describe permisos de Combot, no administradores de Telegram. En el procesamiento, `Admins`, como `Telegram admins`, comprueba administradores de Telegram incluido el propietario; no añade administradores de Combot. Para permitir ambos grupos, enumera `Telegram admins` y `Combot custom admins` con `wm: "o"`. `Regular members` son miembros actuales conocidos, no personas antiguas o con muchos mensajes. `New members` usa ajustes y excepciones del chat, no «primeros siete días» fijos. Usa `cgr` para una duración exacta.

No generes `Core members` ni `Non-members`: no se dan definiciones fiables para reglas nuevas. La falta de información no prueba que alguien nunca perteneciera al chat.

Para el objetivo usa `twh`, `twx` y `twm`. Toma valores contextuales adicionales como `Target self`, `Target bots`, `Target Combot` y `Target linked channel post` de una exportación adecuada; no los adivines en filtros de remitente.

Para `nm` y `ml`, `wh`/`wx` describen a quien inició el ingreso o eliminación; `twh`/`twx`, al miembro cuyo estado cambió. Si Anna añade a Ilya, las condiciones de recién llegado van en `t...` para Ilya. Elegir `v.tg` de una acción no intercambia condiciones.

`am: "o"` exige administrador de Telegram; `am: "n"` lo excluye. No sustituye la combinación de roles en `wh`/`wx`. Prefiere grupos explícitos en reglas nuevas.

## 7. Tiempo en el chat, actividad, XP y reputación

Las condiciones numéricas van en `cgr`, o `tcg` para el objetivo. Este fragmento significa como máximo una hora en el chat y cinco mensajes registrados:

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

Operadores: `eq` es igual, `gte` como mínimo y `lte` como máximo. Indícalo siempre. No traduzcas «menos de cinco» como `lte: 5`: para un contador entero es `lte: 4`. No uses duración exacta con `eq` cuando se pide «al menos»: el tiempo sigue pasando.

Métricas estadísticas:

- `joinedDays`: tiempo desde el ingreso a este chat, no edad de cuenta o persona. Unidades: `s`, `m`, `h`, `d`, `w`, `mo`. Un día son 24 horas, una semana 7 días y aquí un mes 30 días. Las reglas nuevas siempre deben incluir unidad.
- `messageCount`: mensajes registrados en este chat; unidad `c`.
- `warns`: advertencias activas; unidad `c`.

«Un mensaje registrado» es `{"metric":"messageCount","unit":"c","op":"eq","value":"1"}`. No garantiza ejecución única: contador y eventos pueden actualizarse por separado.

Otras secciones:

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

Los umbrales de rango usan `cgr.xp.rank.rules`, con valores de rangos reales del chat, no nombres inventados. Las filas admiten `join: "and" | "or"` y `mode: "include" | "exclude"`. Usa Y explícito para condiciones simples y una exportación real para cadenas complejas. `cgr.logic: "All" | "Any"` combina secciones. Una fila numérica de exclusión es una prohibición: una coincidencia positiva en otra sección de la misma variante no la elude.

No crees condiciones de tiempo desde primer mensaje u otra primera actividad: `firstMessageAge` y `firstOtherActivityAge` no están disponibles. No prometas «actividad de la semana pasada» usando `messageCount` total. Los datos no disponibles no deben convertirse automáticamente en cero.

## 8. Atributos y campos de usuario

`ua` exige atributos; `ux` los excluye. Valores exactos: `Any username`, `Telegram Premium`, `Bot account`, `Any last name`. Por ejemplo, `{"ux":["Bot account"]}` excluye bots.

`ul` y `ulx` incluyen y excluyen códigos de idioma si Telegram los proporciona. No es idioma del mensaje ni nacionalidad. No lo deduzcas del nombre.

Las condiciones de valores concretos van en `uar`, o `tur` para el objetivo. Campos: `user_id`, `name`, `username`, `last_name`, `bio`. La biografía pertenece a solicitudes de ingreso; no es un campo continuamente disponible de todos los miembros.

Una condición de nombre de usuario tiene esta forma:

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

Muestra la estructura, no un miembro real. Usa solo el nombre proporcionado por la persona, sin `@`; pregunta si falta. Pon los ID como cadenas en `values`. Para acceso, prefiere un ID dado explícitamente: nombres y alias cambian.

Aquí `matchType` usa las cadenas completas `Exact match`, `Partial match` y `Regular expression`, no códigos de texto `f`, `p` y `r`. Los valores de una fila son alternativas; las filas tienen `join`. No inventes `Starts with` ni `Ends with` para estos campos.

`ual` y `tul`: `a` exige todas las reglas; `o`, cualquier grupo. Usa una exportación para estructuras de grupos `uag` y `tug` en este perfil de generación.

## 9. Texto y tipo de mensaje

Usa `tv`, un array de cadenas, para frases. Basta una coincidencia. Por ejemplo:

```json
{"tv":["dónde está la grabación","grabación de la clase"],"tr":"p","ty":"p","cs":false}
```

`tr`: `p` son frases, `w` palabras y `r` expresiones regulares. El modo de palabras no exige todas las listadas. La coincidencia parcial normal tampoco garantiza límites de palabra: «gato» puede coincidir en «gatopardo».

`ty`: `f` es texto completo; `p`, parte; `s`, inicio; `e`, final; `r`, expresión regular. `cs: true` distingue mayúsculas; `false` u omitirlo no. Una FAQ sencilla solo necesita `tv`: buscar frases sin distinguir mayúsculas es el valor predeterminado.

`lmin` y `lmax` limitan longitud. Un límite vacío o cero no limita ese lado. No confundas caracteres con palabras.

Usa expresiones regulares solo si no basta la búsqueda simple. Da el patrón como cadena JSON, escapando barras inversas; no añadas automáticamente delimitadores JavaScript `/.../i`. Para palabras exactas o negación compleja, explica ejemplos que coincidan y que no.

`mti` incluye tipos; `mtx` excluye. Valores principales: `photo`, `video`, `animation`, `audio`, `document`, `sticker`, `voice`, `video_note`, `contact`, `location`, `poll`, `dice`, `game`, `paid_media`. Por ejemplo, `{"mti":["voice"]}` significa mensajes de voz; `{"mti":["photo","video"]}`, foto O vídeo, no ambos adjuntos a la vez.

El editor también tiene `text` y `caption`. Participan en ajustes de contenido textual; no trates `caption` como adjunto Telegram independiente. Para «solo pies de foto» o separación estricta entre texto y pies, obtén una exportación. El códec puede omitir valores predeterminados, incluido `text` solo; verlo en el JSON de entrada no demuestra que se conserve la restricción tras importar.

`me` y `mex` exigen o excluyen entidades de texto. Valores: `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"` exige todas las incluidas; `"o"`, al menos una. Para cualquier enlace visible u oculto: `{"me":["url","text_link"],"mel":"o"}`.

`mef` acota enlaces, comandos y otras entidades; `mmo` describe propiedades multimedia; `mtg` y `mog` son grupos de condiciones; `csx`/`cse`, conjuntos de caracteres. Genera estos campos complejos desde una exportación real. No inventes sustitutos como `max_file_size`, `allowed_domains`, `mime`, `language` o `contains_all`.

## 10. Horarios y temas del chat

`s`: `sc` es chat de origen, `gn` General y `st` temas seleccionados. En este último caso, `ti` contiene ID positivos de temas.

Importar restablece los temas de origen a todo el chat y los destinos seleccionados al tema actual. Ocurre incluso con ID correctos y en alternativas O. Si el caso depende de un tema, nómbralo en la explicación y en los ajustes manuales obligatorios. No lo llames listo para activar hasta seleccionar de nuevo los temas.

`at` establece la hora permitida del evento; no programa un envío independiente. Es posible «responder a una pregunta por la tarde». «Publicar cada día a las 19:00 sin un evento entrante» necesita un programador, no este activador.

El bot comprueba la hora actual al procesar, no la del mensaje original. Una edición por la mañana comprueba el horario de la mañana aunque el mensaje original fuera nocturno.

Franja semanal de lunes a viernes, 09:00–18:00 UTC:

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

`wd`: 0 es lunes y 6 domingo. Las horas son minutos enteros desde medianoche UTC, entre 0 y 1439. Las franjas incluyen el último minuto. Una nocturna puede empezar con un valor mayor que su final; el día usa la fecha UTC actual, no la del comienzo del «turno». Comprueba ambos lados de medianoche en lugar de adivinar días.

Las 09:00 y 18:00 de Moscú corresponden a 06:00 y 15:00 UTC: minutos 360 y 900. Para dejar de coincidir exactamente a las 18:00, el último minuto es 14:59 UTC, `endMinute: 899`. En otras zonas, considera desplazamiento y horario de verano. No introduzcas horas locales como UTC sin convertirlas.

Intervalo de fechas:

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

Ilustra la forma, no las fechas de campaña de la persona. El inicio debe preceder al final. En este modo se incluyen ambas fronteras. `Z` significa UTC.

Las horas de cierre usan los ajustes existentes: `{"at":{"m":"c"}}`; fuera de ellas: `{"at":{"m":"c","i":true}}`. El modo de cierre incluye el inicio y excluye el final. El activador no configura el horario de cierre del chat. Sin un horario válido, no prometas que funcionen la condición directa o la invertida.

## 11. Enlaces, reacciones y listas de tareas

### Invitaciones

Para `["jr"]`, `il` acepta `Known Combot links`, `External invite link` o `Any source`. Omítelo si no hay restricción.

`Known Combot links` son enlaces del catálogo del chat. `ilc` e `ilx` enumeran códigos incluidos y excluidos dentro de él; toma códigos exactos de una exportación o datos aportados. Listas vacías mantienen la comprobación de categoría general.

`External invite link` es un enlace identificado fuera de todo el catálogo, no «todo excepto mis dos enlaces». Un origen desconocido o catálogo no disponible no se trata como externo. No prometas que capture cualquier solicitud sin invitación conocida.

### Reacciones de usuarios

Evento `["mr"]`. `rct` contiene `added` y/o `removed`. `rnt` y `rnx` incluyen y excluyen reacciones en el nuevo estado del usuario. Si alguno tiene valores, `rct` debe incluir `added`.

El procesamiento ejecuta `mr` solo cuando Telegram da `user`. Una reacción como canal o administrador anónimo con `actor_chat` no lo activa. Es distinto de los recuentos agregados `rc`.

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

Los valores son emoji normales, ID de emoji personalizados como cadenas o `paid`. `rnt` comprueba todo el nuevo estado, no solo la diferencia. Si ya había 👍 y se añade otra reacción, puede volver a coincidir. Aquí el destinatario `u` es quien cambió la reacción; no premia automáticamente al autor del mensaje.

### Recuentos agregados

Evento `["rc"]`. `rcy`/`rcx` eligen tipos contados. `rcn`/`rcm` ponen límites inferior y superior como enteros no negativos. Cero u omisión significa sin límite en ese lado.

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

Comprueba el valor actual al actualizar, no «llegó a diez por primera vez». Otra actualización puede ejecutar de nuevo. El contador anónimo agregado no identifica un usuario que reaccionó.

### Listas de tareas

Para `["cd"]` y `["ca"]`, `chl` limita a una lista. Si se quiere una lista concreta, pide su enlace directo al mensaje. Para todas las listas que coincidan en un chat o tema, no añadas `chl`.

Se admiten enlaces directos de Telegram, incluidos los de número de tema; no los que contienen `?comment=`. No inventes una dirección. Para enlaces públicos, el procesamiento debe conocer el nombre de usuario del chat; una URL aparentemente válida no establece la coincidencia.

## 12. Acciones

`a.m: "a"` ejecuta todas las filas en orden. `a.m: "r"` ejecuta las marcadas con `fr: 1` y exactamente una no marcada al azar, si existen. Se mantiene el orden original. Usa `a` salvo que se pida azar; no añadas `fr` fuera del modo aleatorio.

| Código `a.r[].t` | Acción | Parámetros `v` |
| --- | --- | --- |
| `s` | Enviar mensaje | `tx` y formato; ver abajo |
| `d` | Borrar el mensaje que activó la regla | Sin parámetros |
| `w` | Añadir advertencias | `tg`, `c` positivo, normalmente 1 |
| `rw` | Quitar advertencias | `tg`, `c` positivo, normalmente 1 |
| `m` | Restringir mensajes | `tg`, duración `du` en segundos |
| `b` | Expulsar bloqueando el regreso | `tg`, duración `du` en segundos |
| `k` | Eliminar del chat permitiendo regresar | `tg` |
| `um` | Levantar restricciones de escritura | `tg` |
| `ub` | Levantar bloqueo de ingreso | `tg` |
| `du` | Borrar mensajes guardados del usuario disponibles para el bot | `tg` |
| `x` | Cambiar XP | `tg`, entero `v` distinto de cero entre −99999 y 99999 |
| `r` | Cambiar reputación | `tg`, entero `v` distinto de cero entre −999 y 999 |
| `ja` | Aprobar ingreso | Solo evento `jr`, sin parámetros |
| `jd` | Rechazar ingreso | Solo evento `jr`, sin parámetros |

No confundas acción `du` con duración `v.du`. La duración está en segundos, no minutos: una hora es 3600. Cero para silencio o bloqueo significa sin final indicado; nunca lo uses para una duración desconocida. Puedes escribir un motivo en un mensaje separado si se pide; no prometas personalizar el motivo de sanción con un campo no documentado.

Destinatario `v.tg`:

- `u`: participante que causó el evento.
- `t`: objetivo definido por el contexto, como autor del mensaje respondido. No es un ID literal.
- `l`: creador del enlace en el catálogo de Combot, en una solicitud de ingreso.
- `b`: ambas personas disponibles en ese contexto. No «todo el chat».

Indica siempre el destinatario. Los comandos simples no admiten acciones personales. Los de respuesta admiten remitente, objetivo y ambos. Para solicitudes, usa acciones separadas para solicitante (`u`) y creador conocido (`l`) si hacen falta ambos: `b` no significa solicitante más creador. El editor ofrece creador para solicitudes; no lo ofrezcas en instrucciones paso a paso de ingreso de miembros. Para otros eventos usa solo destinatarios disponibles.

Un objetivo desconocido no debe convertir una acción en castigo al remitente. No prometas sustituirlo por otra persona. `du` no garantiza borrar toda la historia: lo limitan mensajes disponibles y capacidades de Telegram.

Advertencias, niveles y reputación deben estar activos cuando el caso dependa de ellos, y la moderación necesita permisos del bot. Quitar silencio, levantar expulsión y aprobar ingreso son acciones separadas.

Las solicitudes permiten envíos, acciones sobre usuarios disponibles y `ja`/`jd`; borrar mensaje con `d` no corresponde. Para eventos sin mensaje, no añadas borrado ni respuesta a un mensaje inexistente.

## 13. Texto y destino de la respuesta

Parámetros de `s`:

| Campo | Significado |
| --- | --- |
| `tx` | Texto no vacío hasta 4096 caracteres; admite HTML compatible con Telegram |
| `d` | `sc`: origen; `lg`: registros configurados; predeterminado `sc` |
| `tp` | `ct`: actual; `gn`: General; `st`: seleccionados; predeterminado `ct` |
| `to` | ID positivos de temas elegidos; se restablecen al importar |
| `rp` | `r`: responder al mensaje activador; omisión: independiente |
| `cl` | `n`: conservar anterior; `ps`: borrar la respuesta anterior de esta fila |
| `bt` | Filas de botones URL: array de arrays de objetos con `text` y `url` |
| `ph` | Array de URL de imágenes para vistas previas |
| `pa` | `true`: poner vista previa sobre el texto |

`rp: "r"` se conserva para origen y tema actual. No prometas el mismo vínculo en registros u otro tema. No pongas chats, canales o mensajes privados externos arbitrarios en `d`.

Si falta `cl` en la fila, hereda el ajuste de la regla. `cl: "ps"` de la regla activa limpieza; `cl: "n"` explícito en la fila la anula. La limpieza pertenece a una regla, fila y destino concretos. Las filas aleatorias distintas no pasan a tener una «última bienvenida» común.

Para una respuesta normal puedes usar `<b>Información del curso</b>\nLas grabaciones están en el mensaje fijado.` No entregues Markdown como HTML. Escapa enlaces y texto correctamente. Añade botones e imágenes solo con URL reales proporcionadas; `ph` no envía un álbum.

Variables confirmadas en contexto de mensaje: `{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}`. Dependen del evento. No inventes `{target.name}`, `{user.first_name}`, `{reaction_count}` ni similares.

En un comando de respuesta, `{from.title}` describe al remitente, no al miembro castigado o premiado. Elegir `tg: "t"` no cambia significados. Si no sabes si existe el nombre necesario, usa redacción neutral.

En un ingreso, `{from.title}` tampoco garantiza el nombre del recién llegado: si Anna añade a Ilya, Anna origina el evento. Usa algo genérico como «¡Bienvenido a {chat.title}!» sin nombre personal.

Las acciones no son una transacción. Un mensaje después de un silencio no demuestra que Telegram lo aplicó. No redactes una confirmación incondicional de sanción como resultado verificado: aquí no se documenta una condición separada de éxito.

## 14. Alternativas, límites y promesas no compatibles

`ov` contiene condiciones alternativas de la misma regla. Comparten evento y acciones principales, no definen casos independientes. Una exclusión en una alternativa no es global. Si una prohibición siempre debe aplicarse, consérvala en todas. Una alternativa con `en: false` no participa en la coincidencia.

Usa exportaciones reales para nuevos `ov`, `mtg`, `mog`, `uag`, `tug`, `mef` y `mmo` complejos. No crees árboles O recursivos ni cadenas de acciones separadas dentro de alternativas esperando ejecución independiente.

Pueden aparecer campos de compatibilidad `mt`, `mtl`, `t`, `rmi` y `rme`. No los añadas en lugar de los principales documentados sin motivo. Para restricciones simples de respuestas usa `rm`: `a` cualquier mensaje, `r` solo respuestas, `rb` a un bot, `rc` a Combot, `nr` sin respuesta. No uses `rm: "cr"` en lugar de los nuevos campos de comandos.

No generes campos antiguos o internos `lf`, `fc`, `lo` ni campos de UI `actions`, `destination`, `topic`, `applyTarget` y `alwaysRun`. Compact los representa de otra forma y algunos no son funciones activas.

Límites para planificar:

- Free: hasta 2 reglas; Pro: hasta 50; Business: hasta 100. Las desactivadas cuentan. Considera las existentes al calcular plazas libres.
- Alternativas O adicionales por regla: Free 0, Pro 2, Business 5.
- Hasta 100 filas por regla y un presupuesto calculado aparte de 20 por ejecución del plan.
- Enviar cuesta 1 por destino único, o 2 con limpieza anterior. Las acciones de Telegram sobre usuarios cuentan por destinatario, así que `b` puede reservar el doble. XP y reputación cuestan 0 en este cálculo. El azar cuenta filas obligatorias más la opción más cara.
- Es un cálculo interno, no una promesa de veinte solicitudes exactas de red con todas las operaciones auxiliares. Si la siguiente fila supera el resto, se detiene; lo completado no se revierte.

No prometas ejecutar solo por tiempo sin evento, «como máximo una vez por hora», recompensa única por reacción, protección contra abuso por eventos repetidos, solo el primer cruce de umbral, ejecución exactamente única, procesamiento de chats externos arbitrarios, edad de cuenta ni estadísticas de un período pasado arbitrario. Si algo de esto es esencial, explica que la regla descrita no basta.

Importar añade copias nuevas; no migra Triggers v2. Puedes reescribir el significado de una regla antigua en Compact v3, pero no presentar su JSON antiguo como importable directamente.

## 15. Casos de aceptación de los ejemplos

El directorio `examples` contiene seis paquetes independientes, cada uno con una regla desactivada:

| Archivo | Caso que coincide | Comprobaciones adicionales |
| --- | --- | --- |
| `01-course-command.json` | Un miembro escribe `/course_info` | Texto sin comando no debe responder |
| `02-recording-faq.json` | El texto contiene «dónde está la grabación» | Una consulta distinta no debe responder; la búsqueda parcial puede coincidir dentro de una frase mayor |
| `03-random-welcome.json` | Entra un nuevo miembro | Debe elegirse un saludo, no los tres |
| `04-moderator-reply-mute.json` | Administrador de Telegram o propietario responde `/team_pause` a un miembro | Los miembros normales no pueden ejecutarlo; se excluyen objetivos administradores; sin responder no debe restringir al remitente |
| `05-known-link-join-request.json` | La solicitud usa un enlace del catálogo de Combot | Orígenes externos o desconocidos no coinciden; todos los conocidos coinciden salvo selección concreta |
| `06-thumbs-up-reaction.json` | Un usuario añade una reacción y el nuevo estado contiene 👍 | Quitar 👍 no coincide; cambios repetidos pueden volver a enviar |

Son casos de aceptación para tu chat, no una afirmación de que todos se ejecutaron. Las comprobaciones realizadas aparecen después. Revisa ajustes y capacidades de cada ejemplo en tu chat antes de activarlo.

## 16. Fuentes del formato y comprobaciones realizadas

El formato se contrastó con Rails `0d80ce4788ef5adc5c7c1b79e85c6b8be27cc00e` y bot `ddc1a8a6b6ab99bd2517d783870495990c7058e5`. Estas revisiones de la rama principal incluyen las correcciones coordinadas del editor y Automation. Se confirmaron las fusiones de Rails PR #78 y bot PR #56 en Codeberg; no se establecieron de forma independiente las revisiones exactas desplegadas.

Fuentes principales: `trigger_compact_codec_helpers.js`, `trigger_import_export_helpers.js`, `trigger_validation_helpers.js`, registros de eventos y acciones, `user_attribute_model_helpers.js`, `AutomationController`, contrato detallado en `docs/MONGODB.md` y procesamiento de condiciones y acciones en `automation.py`.

Los seis ejemplos originales se comprobaron en memoria con el códec fuente del editor: decodificar, reconstruir, decodificar de nuevo y comprobar estabilidad normalizada. Se conservaron acciones y desactivación. El códec omite algunos valores predeterminados, así que se compararon resultados normalizados, no igualdad byte a byte con la entrada.

El 8 de septiembre se comprobó la desactivación de los seis originales tras importarlos en el editor de producción de combot.org, guardar en servidor y recargar. No sustituye verificar todas las condiciones y acciones en Telegram.

Comando y FAQ se probaron en Telegram: las peticiones que coincidían recibieron respuestas y los controles no. Solo `/course_info` se cambió a un nombre de prueba único permitido por las protecciones del probador; se conservaron los demás ajustes. Esto no demuestra automáticamente otros eventos y acciones.

Para `06-thumbs-up-reaction.json`, añadir 👍 con perfil personal produjo una respuesta esperada y quitarlo no produjo ninguna. Identidad y estados anteriores y nuevos se confirmaron mediante un observador separado de Bot API. No se probaron en esa sesión la bienvenida aleatoria al ingresar, el silencio efectivo ni la aprobación de una solicitud real; importar no demuestra ejecución.

Se eliminaron las reglas de prueba y se comprobó la restauración de la lista original; los mensajes de resultado permanecen en el grupo de prueba. El JSON Schema es documentación adjunta, no está conectado al producto ni se presenta como validador integrado existente.

El 9 de septiembre se revisó la referencia editorial frente a Rails `0d80ce4788ef5adc5c7c1b79e85c6b8be27cc00e` y bot `0a491a6ee50c57e98c1d9de04819253d15214506`. Se aclararon límite del nombre, grupos de administradores, participantes de eventos, destinatarios y enlaces opcionales de listas. Es revisión documental del código, no otra prueba en Telegram. La redacción localizada de los ejemplos no se ha probado en vivo de forma independiente.
