Making item-based webhook events work on Sitecore 10.3

A great new feature on Sitecore XM Cloud and also XM/XP 10.3+ is the possibility to set up Webhooks for a variety of events eg. item_saved, item_created etc. There is a limitation though if you’re on Platform DXP (10.3+):

Let’s say we set up a webhook which informs the product owner whenever an author modifies the home item:

Setup of the example webhook within Sitecore Content Editor

When modifying the home item, this is what is posted to the URL:

POST https://myendpoint.mydomain.com/notifyProductOwner
{
  "EventName": "item:saved",
  "Item": {
    "Language": "en",
    "Version": 1,
    "Id": "110d559f-dea5-42ea-9c1c-8a5df7e70ef9",
    "Name": "Home",
    "ParentId": "0de95ae4-41ab-4d01-9eb0-67441b7c2450",
    "TemplateId": "76036f5e-cbce-46d1-af0a-4143f9b557aa",
    "MasterId": "00000000-0000-0000-0000-000000000000",
    "SharedFields": [
       ... omitted
    ],
    "UnversionedFields": [
       ... omitted
    ],
    "VersionedFields": [
       ... omitted
    ],
  },
  "Changes": {
    "FieldChanges": [
      ... partially omitted
      {
        "FieldId": "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a",
        "Value": "sitecore\\SomeNewbieAuthor",
        "OriginalValue": "sitecore\\TheWebsiteAdmin"
      },
      {
        "FieldId": "75577384-3c97-45da-a847-81b00500e250",
        "Value": "So I changed the home item. Let's see what happens.",
        "OriginalValue": "Welcome to our Website!"
      }
    ],
    "PropertyChanges": [],
    "IsUnversionedFieldChanged": false,
    "IsSharedFieldChanged": false
  },
  "WebhookItemId": "a4a7d9f4-88ce-4070-81a5-1b0814efa6c9",
  "WebhookItemName": "Save Test"
}

So far so good. Our webhook endpoint can now send a notification to the product owner.

Email notification in the inbox

The Problem

The problem arises as soon as someone publishes the modified item. The webhook will be called again because publishing will trigger an item:saved event for every publish target (typically the web database).

POST https://myendpoint.mydomain.com/notifySuperAdmin
{
  "EventName": "item:saved",
  "Item": {
    "Language": "en",
    "Version": 1,
    "Id": "110d559f-dea5-42ea-9c1c-8a5df7e70ef9",
    "Name": "Home",
    "ParentId": "0de95ae4-41ab-4d01-9eb0-67441b7c2450",
    "TemplateId": "76036f5e-cbce-46d1-af0a-4143f9b557aa",
    "MasterId": "00000000-0000-0000-0000-000000000000",
    "SharedFields": [
...

Notice how the database name is not provided in the item data? This leaves us no way of knowing if this was an author saving the item or if the event was triggered through a publish. Our product owner would be notified about the modification multiple times.

Two emails in the inbox with the same content

Side-Note: This feature was likely implemented with XM Cloud in mind where the database name becomes irrelevant because there is only one content database: master. The publishing target on XM Cloud is Experience Edge which triggers different webhook events.

The workaround

A nice feature would be to have a condition on our webhook item that limits triggers to a specific database. There is no such condition out of the box but it is easy to implement it ourself:

1. Create a C# Class in a .NET Framework 4.8 project:

public class DatabaseNameCondition<T> : StringOperatorCondition<T> where T : RuleContext
{
    public string Value
    {
        get;
        set;
    }
    protected override bool Execute(T ruleContext)
    {
        Assert.ArgumentNotNull(ruleContext, "ruleContext");
        Item item = ruleContext.Item;
        if (item == null)
        {
            return false;
        }
        string value = Value ?? "master";
        return Compare(item.Database.Name, value);
    }
}

2. Create a new Condition item

Pathmaster:/sitecore/system/Settings/Rules/Definitions/Elements/Item Information/Database Name
Textwhere the database name [operatorid,StringOperator,,compares to] [value,,,value]
TypeMyNamespace.DatabaseNameCondition,MyAssembly
Screenshot showing the configuration of the "database name" condition

3. Add the condition to the Webhook rule definition

Setup of the example webhook including the newly created condition

And it works! Now, this webhook endpoint will only be triggered for modifications in the master database.

Is this an issue on XM Cloud?

No, this shouldn’t be an issue. As mentioned above the item_ events are only triggered once for the master database as the new publishing target is Experience Edge. You won’t be able to differ item_saved events between the core and the master database though but I couldn’t think of a use case where you’d need to do that. (And there would be workarounds using the “where the item is the … Item” condition)

Status

I was in contact with Sitecore Support about this issue and they’ve registered two feature requests:

  1. Include the database name with the other item data in the webhook payload (#612983)
  2. Add a condition like the one above (#612984)

Hopefully this makes it into the product in a future release. For the time being we can easily implement the condition ourselves.


Leave a Reply

Your email address will not be published. Required fields are marked *