# Automation Action Create

> Implements a custom automation process action in Xperience by Kentico. Reviews project conventions and the action API, confirms the action's behavior and properties with the user, then emits the action class, the optional properties class with form-component annotations, and the assembly-level RegisterAutomationAction registration.

- **Type:** Skill
- **Install:** `agentstack add skill-kentico-xperience-by-kentico-kenticopilot-automation-action-create`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [Kentico](https://agentstack.voostack.com/s/kentico)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [Kentico](https://github.com/Kentico)
- **Source:** https://github.com/Kentico/xperience-by-kentico-kenticopilot/tree/main/plugins/kentico-digital-experience/skills/automation-action-create

## Install

```sh
agentstack add skill-kentico-xperience-by-kentico-kenticopilot-automation-action-create
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

You implement a custom **automation process action** in an Xperience by Kentico project — a step type that appears in the Automation Builder and runs `Execute` for every contact (or other processed object) that reaches it.

## What you must produce

1. A class extending **`CMS.Automation.AutomationAction`** (no properties) or **`CMS.Automation.AutomationAction`** (with properties).
2. An assembly-level **`[assembly: RegisterAutomationAction(identifier, displayName, IconName = ..., Description = ...)]`**.
3. If properties: a **`TProperties`** class implementing `CMS.Automation.IAutomationActionProperties` with form-component-annotated public read/write properties, in **its own file** (`Properties.cs`) — not co-located in the action's file.
4. If the action shares cross-step state: an **`IAutomationProcessData`** implementation with a unique `static abstract string Identifier`.
5. If the project uses `.resx` localization in `Register*` attributes (look for `"{$...$}"` strings): the new display name, description, and labels in the existing `.resx`, referenced via the `{$...$}` syntax.

## Steps

### 1. Read context

- Read **`references/guardrails.md`** — code quality guardrails beyond the API spec.
- Study **`references/example-actions.md`** — canonical action samples covering distinct patterns (service injection, typed `HttpClient`, cross-step process data, no-properties actions). Mirror their structure and conventions, including one class per file.
- Fetch the action API contract from the live documentation via the **Kentico Docs MCP** — the **Custom automation steps** page listed in **`references/docs.md`** is authoritative for the base classes, the `RegisterAutomationAction` attribute and its parameters (`identifier`, `displayName`, optional `IconName`, `Description`), identifier constraints, the `AutomationProcessContext` (processed contact via `GetProcessedObject`, process name, trigger data, cross-step `GetProcessData` / `SetProcessData`), and `IAutomationProcessData`. Do not rely on memorized API shapes — confirm against the page.
- Fetch the supplementary docs listed in **`references/docs.md`** via the Kentico Docs MCP as needed (form-component reference, visibility conditions, validation rules — see `references/docs.md` for the catalog of pages worth fetching on demand).

### 2. Discover the project and the surrounding APIs

- Search for `AutomationAction`, `INotificationEmailMessageProvider`) before calling its methods — check the actual method signatures, return types, and whether they are sync or async. Do not assume.
- **If the action integrates with an external service** (Twilio, Slack, HubSpot, Salesforce, a webhook, an SDK, etc.) — briefly research that service's documentation and request shape (via Kentico Docs MCP for Kentico-side concerns, and via WebSearch/WebFetch for the third-party API). Enough to make the SDK call or HTTP payload look realistic, including: the canonical SDK entry point or HTTP endpoint, required authentication shape, the request body, and how the provider signals errors / duplicates. Capture credentials in a typed `*Options` class bound to `appsettings.json` — never on `TProperties`.

### 3. Confirm the design

Walk through **`assets/ACTION_TEMPLATE.md`** with the user in chat — identifier, display name, icon, tooltip, base class, properties (name, type, form component, default, validation rules, visibility conditions), runtime behavior (inputs, side effects, failure handling), injected dependencies, and any `IAutomationProcessData` types the action reads or writes. **Do not save the template to disk** — it is an in-chat scaffold, not an artifact.

Ask only what you cannot reasonably infer. Propose defaults the user can override.

### 4. Implement

Write the files following these rules (full detail in `guardrails.md`):

- One class per file: the action, its `TProperties`, each `IAutomationProcessData`, and any typed `*Options` each go in their own file named after the class.
- Constructor injection for dependencies; verify every injected service is registered with the DI container.
- Use `ILogger` for logging — not `IEventLogService`.
- Never `.Result`/`.Wait()`; no static mutable state; no per-execution state in instance fields.
- Retrieve the processed contact with `ContactInfo contact = await context.GetProcessedObject(cancellationToken);` (extension method in `CMS.ContactManagement`) — see the canonical pattern in `guardrails.md`. Do not read `context.ProcessedObject` directly; it is not part of the public API.
- External calls keyed by a stable identifier on the cast contact (typically `ContactInfo.ContactID`; prefer `ContactInfo.ContactGUID` when the external system needs a globally stable key) for idempotency.
- No secrets in `TProperties` — read them from `IConfiguration` / `IOptions`.
- Outbound HTTP uses typed `HttpClient` registered with `services.AddHttpClient()`.
- Prefer declarative validation attributes (`RequiredValidationRule`, `MaxLengthValidationRule`, `MinimumIntegerValueValidationRule`, `MaximumIntegerValueValidationRule`, `MinimumDecimalValueValidationRule`, ...) on `TProperties` instead of hand-rolled checks in `Execute`. Reserve `Execute` validation for cross-property or runtime conditions only.
- Form-component attributes and validation rules come from `Kentico.Xperience.Admin.Base.FormAnnotations` (plus `Kentico.Xperience.Admin.Content.FormAnnotations` and `Kentico.Xperience.Admin.DigitalMarketing.FormAnnotations` for content- and marketing-specific selectors). Do **not** import `Kentico.Forms.Web.Mvc` — that namespace contains obsolete classes with matching names (`ValidationRule`, `RegisterFormValidationRule`, ...) for the live-site Form Builder, which is the wrong API surface here.

### 5. Verify

- Run `dotnet build` on the web project.
- Confirm the identifier is unique in the solution (grep the identifier string).
- If you added `.resx` strings, confirm the `.resx` and its registration class compile.

Report what you produced and the manual steps (if any) the user still owes — typically registering a new dependency in DI or adding a configuration value to `appsettings.json`.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [Kentico](https://github.com/Kentico)
- **Source:** [Kentico/xperience-by-kentico-kenticopilot](https://github.com/Kentico/xperience-by-kentico-kenticopilot)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-kentico-xperience-by-kentico-kenticopilot-automation-action-create
- Seller: https://agentstack.voostack.com/s/kentico
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
