Create a custom condition and segmentation query

Abstract

How to create a custom condition and segmentation query that are used by the List Manager and Marketing Automation Engine.

You can create a custom condition and segmentation query to identify contacts and enroll them into a marketing automation plan. In the following example, Sitecore:

  • Segments customers by preferred cinema in order to send them the most relevant promotions each week. For example, customers who visit the Sitecore City cinema can get 3-for-2 on tickets for the upcoming Classic Films Festival.

  • Changes the path a customer takes through automation plans based on their preferred cinema. For example, customers who are enrolled in the Free Popcorn plan will receive a coupon for a bar of chocolate if East Sitecore is their preferred cinema. The East Sitecore cinema accidentally ordered 20,000 bars of chocolate instead of 2000.

In this example, you create a single class, sometimes referred to as a predicate, that implements the following interfaces:

  • The ICondition implementation is used by the Marketing Automation Engine.

  • The IContactSearchQueryContext implementation is used by the List Manager to create a segmented list.

Note

In most cases it makes sense to create both a condition and a segmentation query. However, if you are targeting data that is specific to a contact - such as a membership ID - it does not make sense to create a segmentation query. In this case, do not implement IContactSearchQueryContext.

This example demonstrates how to create a custom condition and segmentation query class that returns true if the following conditions are met:

  • The contact has at least one interaction.

  • The supplied cinema name matches the contact’s preferred cinema.

Note

The Sitecore personalization engine uses a different implementation of condition.

You must create a custom facet, for example the CinemaDetails facet, and deploy it for use in the condition class.

To create and deploy the CinemaDetails facet:

  1. Create a class that inherits Sitecore.XConnect.Facet.

    using System;
    using System.Linq.Expressions;
    using Sitecore.Framework.Rules;
    using Sitecore.XConnect;
    using Sitecore.XConnect.Segmentation.Predicates;
    
    namespace Documentation.Examples
    {
        // Contact facet that stores contact's preferred cinema name
        [Serializable]
        public class CinemaDetails : Facet
        {
            public const string DefaultFacetKey = "CinemaDetails";
            public string PreferredCinema { get; set; }
        }
    }
    
  2. Implement and register a collection model.

  3. Deploy the collection model.

Now that you have created the CinemaDetails facet, you need to create a condition class with the condition logic that uses the custom facet.

To create a condition class:

  • Create a class that inherits ICondition and IContactSearchQueryFactory as shown in the following code sample:

Important

You must use the InteractionsCache facet rather than the contact.Interactions property because joins are not supported by all search providers.

using System;
using System.Linq.Expressions;
using Sitecore.Framework.Rules;
using Sitecore.XConnect;
using Sitecore.XConnect.Segmentation.Predicates;
using Sitecore.XConnect.Collection.Model;
using System.Linq;

namespace Documentation.Examples
{
    public class PreferredCinemaMatches : ICondition, IContactSearchQueryFactory
    {
        public string PreferredCinema { get; set; }

       // TIP: There are other operation types in theSitecore.XConnect.Segmentation.Predicates namespace
        public StringOperationType Comparison { get; set; }

        // Evaluates condition for single contact
        public bool Evaluate(IRuleExecutionContext context)
        {
            var contact = context.Fact<Contact>();

            return Comparison.Evaluate(contact.GetFacet<CinemaDetails>(CinemaDetails.DefaultFacetKey)?.PreferredCinema, PreferredCinema)
                && contact.Interactions.Any();
        }

        // Evaluates contact in a search context
        // IMPORTANT: Use InteractionsCache() facet rather than contact.Interactions as some search providers do not provide joins.
        public Expression<Func<Contact, bool>> CreateContactSearchQuery(IContactSearchQueryContext context)
        {
            return contact => Comparison.Evaluate(contact.GetFacet<CinemaDetails>(CinemaDetails.DefaultFacetKey).PreferredCinema, PreferredCinema)
            && contact.InteractionsCache().InteractionCaches.Any();
        }
    }
}

The condition descriptor defines the condition type and associated text. Sitecore users can then search for the condition text in the List Manager and Marketing Automation user interfaces.

To create a condition descriptor:

  1. Deploy the custom condition and segmentation query DLL to all core roles - Content Management, Content Delivery, xDB Processing, and xDB Reporting.

  2. Choose a location for your condition under /sitecore/system/Settings/Rules/Definitions/Elements - for example, /sitecore/system/Settings/Rules/Definitions/Elements/XConnect - Contact Personal Details.

    Note

    The location of your condition determines which user interfaces the condition is available in.

  3. Create a condition using the following template /sitecore/Templates/System/Rules/Condition template:

    xConnect conditions shown in the Content Editor
  4. Specify the Type and Text fields as shown in the following example. In this example, we are using a string comparison:

    Type and Text fields defined for the preferred cinema condition

To make it easier to find custom rules when creating a segment, you can create a section for them that is displayed in the Create rule dialog box.

Custom section in the Create rule dialog box.

To create a section in the List Manager for custom segmentation rules:

  1. Go to the /sitecore/System/Settings/Rules/Definitions item in your Master database.

  2. Right-click the Element folder and then click Insert, Element Folder.

  3. In the Message dialog box, enter a name for the folder and click OK.

  4. Expand the newly created Element folder and go to the Tags/Default item.

  5. Select the Default item then on the Content tab, in the Taxonomy section, in the Tags field, double-click the xConnect – Search Query tag to move it to the Selected list.

  6. Save your changes.

Note

The custom section is only displayed when it contains at least one rule.

The Marketing Automation Engine requires a copy of the condition and segmentation query DLL in order to evaluate contacts against your custom condition.

Note

In the context of the Marketing Automation Engine, the combination of a condition and segmentation query is referred to as a predicate in configuration.

To configure the Marketing Automation Engine:

  1. Deploy your condition and segmentation query DLL to the Marketing Automation engine and the Marketing Automation Operations service.

  2. Create a configuration file with the following XML and add it to C:\path\to\xconnect\App_Data\Config\sitecore\Segmentation and to C:\path\to\xconnect\App_data\jobs\continuous\AutomationEngine\App_Data\Config\sitecore\Segmentation. The id node must match the ID of the condition item in Sitecore.

    <Settings>
        <Sitecore>
            <XConnect>
            <Services>
                <DescriptorLocator>
                <Options>
                    <PredicateDescriptors>
                        <PreferredCinemaMatches>
                            <id>{E9046292-BF68-4733-9FD4-10A74FB45E50}</id>
                            <type>Documentation.Examples.PreferredCinemaMatches, Documentation.Examples</type>
                        </PreferredCinemaMatches>
                    </PredicateDescriptors>
                </Options>
                </DescriptorLocator>
            </Services>
            </XConnect>
        </Sitecore>
    </Settings>
            

Note

Default predicates are defined in the sc.XConnect.Segmentation.Predicates.Model.xml configuration file.