# Webhooks

## Webhooks

Webhooks provide real-time, event-driven communication within Umbraco. Seamlessly integrated, these lightweight, HTTP-based notifications empower you to trigger instant actions and synchronize data. With its different extension points, you can tailor these webhooks to fit a broad range of requirements.

### Getting Started

To work with Webhooks, you need to go to Webhooks within the Settings section:![Webhooks section](https://3872888104-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgEH4FChbCn7eDDqREvdE%2Fuploads%2Fgit-blob-533780ac10147f4cd22f183bfae58882f10b6f10%2Fwebhook-section.png?alt=media)

From here we can create a webhook, by clicking the `Create webhook` button, which will take you to the Create webhook screen:

![Creating a webhook](https://3872888104-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgEH4FChbCn7eDDqREvdE%2Fuploads%2Fgit-blob-cc440dea37ce25e6336b48ba415c77f96b2cd6ca%2Fcreate-webhook.png?alt=media)

### Url

The `Url` should be the endpoint you want the webhook to send a request to, whenever a given `Event` is fired.

### Events

Events are when a given action happens, by default there are 5 events you can choose from.

* Content Published - This event happens whenever some content gets published.
* Content Unpublished - This event happens whenever some content gets unpublished
* Content Deleted - This event happens whenever some content gets deleted.
* Media Deleted - This event happens whenever a media item is deleted.
* Media Saved - This event happens whenever a media item is saved.

### Content type

If you have selected a Content or Media event, you can specify your preferences. You can choose to trigger your webhook only for a given Document or Media type.

For example, if you have selected `Content Published` event. You can then specify that you only want the webhook to fire, when the content is of a given content type.

### Headers

You can specify custom headers, that will be sent with your request.

For example you could specify `Accept: application/json`, security headers, etc.

## Defaults

Umbraco webhooks have been configured with some defaults, such as default headers or some events that send a payload. In this section, we will take a look at those.

### Json payload

For example, the `Content Published` event will also send the given content that triggered the event. The json from is the same as the `Content Delivery Api`, an example of such a json object:

```json
{
  "Name": "Root",
  "CreateDate": "2023-12-11T12:02:38.9979314",
  "UpdateDate": "2023-12-11T12:02:38.9979314",
  "Route": {
    "Path": "/",
    "StartItem": {
      "Id": "c1922956-7855-4fa0-8f2c-7af149a92135",
      "Path": "root"
    }
  },
  "Id": "c1922956-7855-4fa0-8f2c-7af149a92135",
  "ContentType": "root",
  "Properties": {}
}
```

however, the `Content deleted` does not send the entire content as JSON, instead, it sends the `Id` of the content like so:

```json
{
  "Id": "c1922956-7855-4fa0-8f2c-7af149a92135"
}
```

### Headers

By default, webhook requests will include 3 headers

* `user-agent: Umbraco-Cms/{version}`, where version is the current version of Umbraco.
* `umb-webhook-retrycount: {number of retries}`, where number of retries, is the current retry count for a given webhook request.
* `umb-webhook-event: {Umbraco.event}`, where event is the event that triggered the request, for example for Content published: `umb-webhook-event: Umbraco.ContentPublish`

## Configuring Webhooks

### Adding more events

To add more than the default events to Umbraco, you can leverage the provided `IUmbracoBuilder` and `IComposer` interfaces. Below is an example of how you can extend the list of available webhook events using a custom `WebhookComposer`:

```csharp
using Umbraco.Cms.Core.Composing;

public class CustomWebhookComposer : IComposer
{
    public void Compose(IUmbracoBuilder builder)
    {
        builder.WebhookEvents()
            .Clear()
            .AddCms(cmsBuilder =>
            {
                // Add your custom events here
                cmsBuilder
                    .AddDefault()
                    .AddContent()
                    .AddContentType()
                    .AddDataType()
                    .AddDictionary()
                    .AddDomain()
                    .AddFile()
                    .AddHealthCheck()
                    .AddLanguage()
                    .AddMedia()
                    .AddMember()
                    .AddPackage()
                    .AddPublicAccess()
                    .AddRelation()
                    .AddRelationType()
                    .AddUser();
            });
    }
}
```

This is a list of all the current events that are available through Umbraco. If you want them all enabled, you can use the following:

```csharp
builder.WebhookEvents().Clear().AddCms(false);
```

### Replace Webhook Events

Sometimes it is desirable to modify one of the standard Umbraco webhooks, for example, to change the Payload. This can be done by adding a custom implementation, as shown in the code example below:

```csharp
[WebhookEvent("Content Published", Constants.WebhookEvents.Types.Content)]
public class MyCustomContentPublishedWebhookEvent : WebhookEventContentBase<ContentPublishedNotification, IContent>
{
    private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor;
    private readonly IApiContentBuilder _apiContentBuilder;


    public MyCustomContentPublishedWebhookEvent(IWebhookFiringService webhookFiringService, IWebhookService webhookService, IOptionsMonitor<WebhookSettings> webhookSettings, IServerRoleAccessor serverRoleAccessor, IPublishedSnapshotAccessor publishedSnapshotAccessor, IApiContentBuilder apiContentBuilder) : base(webhookFiringService, webhookService, webhookSettings, serverRoleAccessor)
    {
        _publishedSnapshotAccessor = publishedSnapshotAccessor;
        _apiContentBuilder = apiContentBuilder;
    }

    public override string Alias => "Umbraco.ContentPublish";
    protected override IEnumerable<IContent> GetEntitiesFromNotification(ContentPublishedNotification notification) => notification.PublishedEntities;

    protected override object? ConvertEntityToRequestPayload(IContent entity)
    {
        if (_publishedSnapshotAccessor.TryGetPublishedSnapshot(out IPublishedSnapshot? publishedSnapshot) is false || publishedSnapshot!.Content is null)
        {
            return null;
        }

        IPublishedContent? publishedContent = publishedSnapshot.Content.GetById(entity.Key);

        return new
        {
            MyData = "Your data",
            PublishedContent = publishedContent is null ? null : _apiContentBuilder.Build(publishedContent)
        };
    }
}
```

Add the following line in a Composer to replace the standard Umbraco implementation with your custom implementation:

```csharp
public class MyComposer : IComposer
{
    public void Compose(IUmbracoBuilder builder)
    {
        builder.WebhookEvents().Replace<ContentPublishedWebhookEvent, MyCustomContentPublishedWebhookEvent>();
    }
}
```

### Webhook settings

Webhook settings can be configured in your `appsettings.*.json` and is in the `Umbraco::CMS` section, like so:

```json
  "Umbraco": {
    "CMS": {
      "Webhook": {
        "Enabled": true,
        "MaximumRetries": 5,
        "Period": "00:00:10",
        "EnableLoggingCleanup": true,
        "KeepLogsForDays": 30
      }
```

* **Enabled** - Whether or not webhooks are enabled.
* **MaximumRetries** - How many retries a given webhook request will do.
* **Period** - The period to wait between checks of any webhook requests needing to be fired.
* **EnableLoggingCleanup** - Whether of not to enable webhook log cleanup.
* **KeepLogsForDays** - How many days to keep webhook logs for.
