{"section":"tutorials","requestedLocale":"es","requestedSlug":"creando-automaciones","locale":"es","slug":"creando-automaciones","path":"docs/es/tutorials/storefront/agentic-cx/creando-automaciones.md","branch":"main","content":"## Información general\n\nLas automatizaciones se diseñan para actuar de forma proactiva con base en reglas y condiciones predefinidas. A diferencia de los agentes pasivos, que solo reaccionan a las interacciones de los usuarios, las automatizaciones pueden iniciar acciones o comunicaciones cuando se cumplen determinados criterios, muchas veces a partir de cambios en los datos o eventos del sistema. El comando para hacer el deploy de una automatización es: `weni project push agent_definition.yaml`.\n\n## Conceptos básicos y estructura YAML\n\nUna automatización se define en un archivo `agent_definition.yaml`. Los campos principales son:\n\n- **agents.<id_do_agente>**: identifica al agente.\n- **name**: nombre para mostrar del agente, con un límite de 55 caracteres.\n- **description**: descripción del propósito y las capacidades del agente.\n- **rules**: diccionario de las reglas que disparan las acciones del agente.\n- Dentro de **rules.<id_da_regra>**:\n  - **display_name**: nombre legible de la regla.\n  - **template**: plantilla de mensaje HSM que será utilizado.\n  - **start_condition**: descripción de la condición que debe cumplirse para activar la regla.\n  - **source**: define el código que se ejecutará cuando se dispare la regla, con `entrypoint` apuntando a la clase/método y `path` al directorio donde está el código.\n- **pre_processing**: define una etapa de preprocesamiento para preparar datos antes de evaluar las reglas, con `source` especificando el código y `result_examples_file` apuntando a un JSON con ejemplos de salida.\n\nEl archivo `result_example.json` debe ser un arreglo de objetos. Cada objeto contiene:\n\n- `urn`: identificador único del contacto (por ejemplo, número de teléfono o ID de usuario).\n- `data`: un diccionario con los datos relevantes para la regla. La estructura de ese diccionario depende de la información que tu agente necesita procesar.\n\n## Estructura del proyecto\n\nUna automatización sigue una estructura de carpetas organizada.\n\n```\nyour-project-name/\n├── rules/\n│   ├── status_aprobado/\n│   │   ├── main.py\n│   │   └── requirements.txt\n│   └── status_invoiced/\n│       ├── main.py\n│       └── requirements.txt\n├── pre_processors/\n│   └── processor/\n│       ├── processing.py\n│       └── requirements.txt\n├── agent_definition.yaml\n└── result_example.json\n```\n\nEsta estructura ayuda a organizar los diferentes componentes del agente. En la carpeta `rules/` se encuentran las reglas separadas por status, cada una con su propio archivo `main.py` y `requirements.txt`. La carpeta `pre_processors/processor` contiene el código de preprocesamiento y su `requirements.txt`, mientras que los archivos `agent_definition.yaml` y `result_example.json` se encuentran en la raíz.\n\n## Ejemplo de definición YAML\n\nA continuación se muestra un ejemplo de `agent_definition.yaml` con un agente llamado `active_order_status` que gestiona el status de pedidos:\n\n```yaml\nagents:\n  active_order_status:\n    name: \"Active Order Status\"\n    description: \"Agente responsable de activar plantillas de status de pedido en función del status recibido de VTEX - Order Status\"\n    language: \"es_MX\"\n    rules:\n      PaymentApproved:\n        display_name: \"Payment Approved\"\n        template: \"payment_confirmation_2\"\n        start_condition: \"When the status is Payment Approved\"\n        source:\n          entrypoint: \"main.PaymentApproved\"\n          path: \"rules/status_payment_approved\"\n      OrderInvoiced:\n        display_name: \"Order Invoiced\"\n        template: \"order_update_no_cta_1\"\n        start_condition: \"When the status is Invoiced\"\n        source:\n          entrypoint: \"main.StatusInvoiced\"\n          path: \"rules/status_invoiced\"\n      OrderCanceled:\n        display_name: \"Order Canceled\"\n        template: \"order_canceled_3\"\n        start_condition: \"When the status is Canceled\"\n        source:\n          entrypoint: \"main.Canceled\"\n          path: \"rules/status_canceled\"\n      OrderCreated:\n        display_name: \"Order Created\"\n        template: \"order_management_no_cta_5\"\n        start_condition: \"When the status is Order Created\"\n        source:\n          entrypoint: \"main.OrderCreated\"\n          path: \"rules/status_order_created\"\n    pre_processing:\n      source:\n        entrypoint: \"processing.PreProcessor\"\n        path: \"pre_processors/processor\"\n      result_examples_file: \"result_example.json\"\n```\n\nEste archivo define cuatro reglas vinculadas a los diferentes status del pedido. Para cada regla se configuran el nombre para mostrar, la plantilla HSM asociada, la condición de inicio y la ruta al código de Python que se ejecutará. El bloque `pre_processing` indica la clase y el directorio que se utilizarán para preparar los datos antes de evaluar las reglas.\n\n## Preprocesamiento\n\nLa etapa de preprocesamiento se encarga de recopilar todos los datos necesarios que usarán las reglas. Solo en esta etapa se permite realizar solicitudes HTTP u otras llamadas externas; por eso, existe un único `requirements.txt` dentro de `pre_processors`. El objeto `PreProcessorContext` contiene el payload del webhook y la información del proyecto. Se accede a los datos del webhook mediante `context.payload.get(\\\"campo\\\")`. Por ejemplo, para recuperar el `orderId` en un payload como el que se muestra a continuación, se utiliza `context.payload.get(\"orderId\")`.\n\n```json\n{\n    \"recorder\": {\n        \"_record\": {\n            \"x-vtex-meta\": {},\n            \"x-vtex-meta-bucket\": {}\n        }\n    },\n    \"domain\": \"Marketplace\",\n    \"orderId\": \"1544102600592-01\",\n    \"currentState\": \"payment-approved\",\n    \"lastState\": \"canceled\",\n    \"currentChangeDate\": \"2025-02-07T13:54:54.7438532Z\",\n    \"lastChangeDate\": \"2025-02-07T13:54:54.6657558Z\",\n    \"vtexAccount\": \"leoamaral\"\n}\n```\n\nAdemás de acceder a campos del payload, puedes recuperar información del proyecto, como el identificador (`uuid`) y la cuenta de VTEX, mediante `context.project.get(\"uuid\")` y `context.project.get(\"vtex_account\")`. El método `process` del preprocesador debe devolver un objeto `ProcessedData`, compuesto por una `urn` (identificador del contacto) y un diccionario con los datos que se transferirán a las reglas. La `urn` debe seguir el formato `whatsapp:5582900000000`.\n\nA continuación se muestra un ejemplo simplificado de preprocesador:\n\n```python\nfrom weni.context.preprocessor_context import PreProcessorContext\nfrom weni.preprocessor import PreProcessor as BasePreProcessor, ProcessedData\n\nclass PreProcessor(BasePreProcessor):\n    def process(self, context: PreProcessorContext) -> ProcessedData:\n        # Obtener datos del webhook\n        order_id = context.payload.get(\"orderId\", \"\")\n        phone_number = context.payload.get(\"phone_number\", \"\")\n        state = context.payload.get(\"currentState\", \"\")\n\n        # Obtener datos del proyecto\n        project_id = context.project.get(\"uuid\")\n        vtex_account = context.project.get(\"vtex_account\")\n\n        # Procesamiento específico del negocio (aquí se pueden realizar llamadas externas)\n        # ...\n\n        # Devolver el contacto y los datos para las reglas\n        urn = f\"whatsapp:{phone_number}\"\n        return ProcessedData(urn, {\"orderId\": order_id, \"status\": state})\n```\n\n## Implementación de regla: PaymentApproved\n\nCada regla del agente se implementa como una clase que hereda de `Rule`. La función `execute` verifica si se cumple la condición y devuelve `True` en caso de que deba enviarse el mensaje. La función `get_template_variables` construye un diccionario con las variables de la plantilla. A continuación se muestra la implementación de la regla **PaymentApproved**:\n\n```python\nfrom weni.preprocessor import ProcessedData\nfrom weni.rules import Rule\n\nclass PaymentApproved(Rule):\n    def execute(self, data: ProcessedData) -> bool:\n        status = data.data.get(\"status\")\n        # Verifica si el status recibido en el preprocesamiento es 'payment-approved'\n        return status == \"payment-approved\"\n\n    def get_template_variables(self, data: ProcessedData) -> dict:\n        name = data.data.get(\"name\")\n        price = int(data.data.get(\"price\", 0))\n        order_id = data.data.get(\"orderId\")\n        # Devuelve las variables en el orden de la plantilla HSM\n        return {\"1\": f\"R$ {price / 100}\", \"2\": order_id}\n```\n\n## Uso de plantillas (HSM)\n\nLas plantillas de mensaje (HSM) registradas en WhatsApp Business pueden contener marcadores como `{{1}}`, `{{2}}`, etc. Cuando `execute` devuelve `True`, VTEX CX Platform (Weni) CLI llama a `get_template_variables` para llenar esas variables. Por ejemplo, considerando una plantilla `Olá {{1}}, seu pedido {{2}} está em fase de {{3}}`, la función debe devolver:\n\n```json\n{\"1\": \"Leonardo\", \"2\": \"12345\", \"3\": \"Entrega\"}\n```\n\n## Lógica de ejecución de reglas y casos de uso\n\nDespués del preprocesamiento, el agente sigue las reglas definidas en el YAML en orden. La primera regla cuyo método `execute` devuelva `True` se ejecutará y las demás se ignorarán. Por lo tanto, es importante organizar las reglas de forma jerárquica y asegurarte de que el preprocesamiento devuelva datos suficientes para las condiciones de cada regla. Los casos de uso comunes incluyen notificaciones de pedidos (aprobados, facturados, cancelados, creados), pero puedes crear reglas para cualquier evento relevante dentro de VTEX o de tu flujo de negocio.\n\n## Conclusión\n\nLas automatizaciones permiten automatizar notificaciones e interacciones con tus clientes con base en eventos de VTEX. Al estructurar tu proyecto según esta guía (definiendo claramente el YAML, el preprocesamiento y las reglas), garantizas una integración segura y escalable para informar a tus clientes en el momento adecuado.\n\n> [Aquí](https://github.com/weni-ai/weni-example-agents) encontrarás un ejemplo de código de automatización."}