> For the complete documentation index, see [llms.txt](https://docs.umbraco.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.umbraco.com/umbraco-automate/18.latest/extending/custom-trigger.md).

# Create a Custom Trigger

A custom trigger lets you start an automation from any event in your project. The most common pattern is reacting to an Umbraco CMS notification.

## Settings Model

A trigger usually has a settings Plain Old CLR Object (POCO) that defines the configuration UI. Each property is decorated with `[Field]`:

{% code title="MyCustomTriggerSettings.cs" %}

```csharp
using Umbraco.Automate.Core.Settings;

namespace MyProject.Automate;

public sealed class MyCustomTriggerSettings
{
    [Field(
        Label = "Filter",
        Description = "Only fire when the entity name matches this prefix.")]
    public string? NamePrefix { get; set; }
}
```

{% endcode %}

## Output Model

The output model describes the data downstream steps can bind to. Property names are exposed to bindings in camelCase, so `EntityKey` becomes `${ trigger.entityKey }`.

{% code title="MyCustomTriggerOutput.cs" %}

```csharp
namespace MyProject.Automate;

public sealed class MyCustomTriggerOutput
{
    public Guid EntityKey { get; init; }
    public string? Name { get; init; }
}
```

{% endcode %}

## Trigger Class

Inherit from `NotificationTriggerBase<TSettings, TOutput, TNotification>` to fire on an Umbraco notification. Override `MapEvent` to convert each notification into one or more `TriggerEvent` items. Override `CanHandle` to filter events using the resolved trigger settings.

{% code title="MyCustomTrigger.cs" %}

```csharp
using Umbraco.Automate.Core.Triggers;
using Umbraco.Cms.Core.Notifications;

namespace MyProject.Automate;

[Trigger("myProject.myCustomTrigger", "My Custom Trigger",
    Description = "Fires when a content item is saved.",
    Group = "My Project",
    Icon = "icon-flash",
    RequiredSections = [Umbraco.Cms.Core.Constants.Applications.Content])]
public sealed class MyCustomTrigger
    : NotificationTriggerBase<MyCustomTriggerSettings, MyCustomTriggerOutput, ContentSavedNotification>
{
    public MyCustomTrigger(TriggerInfrastructure infrastructure)
        : base(infrastructure)
    {
    }

    public override IEnumerable<TriggerEvent> MapEvent(ContentSavedNotification notification)
    {
        foreach (var content in notification.SavedEntities)
        {
            yield return new TriggerEvent<MyCustomTriggerOutput>
            {
                TriggerAlias = Alias,
                InitiatorType = TriggerInitiatorType.System,
                IdempotencyKey = GenerateIdempotencyKey(
                    content.Key, content.VersionId, content.UpdateDate),
                Output = new MyCustomTriggerOutput
                {
                    EntityKey = content.Key,
                    Name = content.Name,
                },
            };
        }
    }

    protected override bool CanHandle(
        MyCustomTriggerOutput output,
        MyCustomTriggerSettings? settings)
    {
        if (string.IsNullOrEmpty(settings?.NamePrefix))
        {
            return true;
        }

        return output.Name is not null
            && output.Name.StartsWith(settings.NamePrefix, StringComparison.OrdinalIgnoreCase);
    }
}
```

{% endcode %}

## Declaring Section Requirements

The `RequiredSections` array on the `[Trigger]` attribute tells Automate which Umbraco backoffice sections the workspace service account must have access to.

Workspaces whose service account is missing any listed section don't see the trigger in the picker. Dispatch silently skips events for already-published automations until the section is restored.

```csharp
RequiredSections = [
    Umbraco.Cms.Core.Constants.Applications.Content,
    Umbraco.Cms.Core.Constants.Applications.Media
]
```

The check is all-of: the service account must have every listed section. Omit the property for triggers that have no CMS data dependency, for example a webhook that receives external input.

See [Service-Account Permissions](/umbraco-automate/18.latest/concepts/workspaces.md#service-account-permissions) for the runtime effects.

## Registration

No manual registration is required. The trigger is discovered at startup by its `[Trigger]` attribute and the base class.

## Verify

Restart your Umbraco site. The new trigger appears in the trigger picker under the **My Project** group. Pick it, configure the filter, and publish the automation.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.umbraco.com/umbraco-automate/18.latest/extending/custom-trigger.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
