0

does anyone know how to load EmailAddressList facet? I have created a custom rule for EXM in order to identify contacts I need to access EmailAddressList facet but when I execute this code it only loads PersonalInformation facet. I know that for marketing automation I have to change the configuration and add a facet key but in this case, it did not work. Thank you in advance!

private IEnumerable<Contact> GetContactsFromList()
{
    Guid contactListId = Guid.Parse({2986A090-9C58-48B7-C6A2-C2F88FA5B2C8});

    ContactExpandOptions expandOptions = new ContactExpandOptions(CollectionModel.FacetKeys.PersonalInformation);

    ISegmentationEngine segmentationEngine = (ISegmentationEngine)ServiceLocator.ServiceProvider.GetService(typeof(ISegmentationEngine));

    ListSubscriptionMatches listSubscriptionConditions = new ListSubscriptionMatches()
    {
        ListId = contactListId
    };

    IEntityBatchEnumerator<Contact> contacts = segmentationEngine.FindContacts(listSubscriptionConditions, 200, expandOptions);

    if (contacts != null)
    {
        while (contacts.MoveNext())
        {
            foreach (var contact in contacts?.Current ?? Enumerable.Empty<Contact>())
            {
                yield return contact;
            }
        }
    }
}

protected override bool Execute(T ruleContext)
{

    Assert.IsNotNull(Tracker.Current, "Tracker.Current is not initialized");
    Assert.IsNotNull(Tracker.Current.Contact, "Tracker.Current.Contact is not initialized");

    var oper = GetCurrentOperator();

    using (var client = XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
    {

        var contacts = GetContactsFromList();

        foreach (var c in contacts)
        {
            var info = c.GetFacet<EmailAddressList>(EmailAddressList.DefaultFacetKey);

            var existingContact = client.Get(new IdentifiedContactReference("quiz", info.PreferredEmail.SmtpAddress), new ContactExpandOptions(new string[] { QuizInfo.DefaultFacetKey }));

            if (existingContact == null)
            {

                return false;
            }
            else
            {
                var quizzesInfoFacet = existingContact.GetFacet<QuizInfo>(QuizInfo.DefaultFacetKey);

                var score = quizzesInfoFacet.MaxScore;

                return oper.Evaluate(score, Int32.Parse(stringValuee));
            }
        }
        return false;
    }
}
0

Try to change

ContactExpandOptions expandOptions = new ContactExpandOptions(CollectionModel.FacetKeys.PersonalInformation);

to

ContactExpandOptions expandOptions = new ContactExpandOptions(CollectionModel.FacetKeys.PersonalInformation,CollectionModel.FacetKeys.EmailAddressList);

This could solve your problem.

0

I believe you are looking to create a segment that you can use in EXM? In that case you don't need to use xConnect query, you just need to make a CreateContactSearchQuery predicate that will run against xConnect, in the list manager.

Below is my code and this is the doco we used for it. https://doc.sitecore.com/developers/91/sitecore-experience-platform/en/create-a-custom-predicate.html

First I use a extension to to get the Facet, this makes the code much easy in the predicate. The extension MUST be called Emails, which is the default facet key (EmailAddressList.DefaultFacetKey).

namespace Sitecore.Foundation.XdbModels.Extensions
{
    using Sitecore.XConnect.Collection.Model;
    using Sitecore.Foundation.XdbModels.Facets;

    public static class ContactExtensions
    {
        public static EmailAddressList Emails(this Sitecore.XConnect.Contact c)
        {
            return c?.GetFacet<EmailAddressList>(EmailAddressList.DefaultFacetKey) ?? new EmailAddressList();
        }
    }
}

Then you rule would look like this

namespace Sitecore.Project.Website.Segmentation.Predicates.Contacts
{
    using System;
    using System.Linq.Expressions;
    using Sitecore.Framework.Rules;
    using Sitecore.XConnect;
    using Sitecore.XConnect.Segmentation.Predicates;
    using Sitecore.Foundation.XdbModels.Extensions;

    public class ContactMemberAgeGroupMatches : ICondition, IMappableRuleEntity, IContactSearchQueryFactory
    {
        public string EmailAddress { get; set; }
        public StringOperationType Comparison { get; set; }

        public bool Evaluate(IRuleExecutionContext context)
        {            
            return this.Comparison.Evaluate(context.Fact<Contact>().Emails()?.PreferredEmail.SmtpAddress, this.EmailAddress);
        }

        public Expression<Func<Contact, bool>> CreateContactSearchQuery(IContactSearchQueryContext context)
        {

            return (Expression<Func<Contact, bool>>)(contact => this.Comparison.Evaluate(contact.Emails().PreferredEmail.SmtpAddress, this.EmailAddress));
        }
    }
}
0

Facets are represented by the Sitecore.Analytics.Tracker.Current.Contact.Facets dictionary in the tracker and are loaded from xConnect into shared the session state at the start of a session. The default list of facets that are loaded into the session are:

  • Classification
  • EngagementMeasures
  • ContactBehaviorProfile
  • Personal
  • KeyBehaviorCache
  • ListSubscriptions

which can be found at App_Config\Sitecore\Marketing.Tracking\Sitecore.Analytics.Tracking.config file

<dataAdapterManager defaultProvider="xconnect">
        <providers>
            <clear/>
            <add name="xconnect" type="Sitecore.Analytics.XConnect.DataAccess.XConnectDataAdapterProvider, Sitecore.Analytics.XConnect">
                <facets hint="raw:AddFacet">
                    <!-- Removing some of the default facets (Classification, EngagementMeasures, etc.) can cause issues, because there is code depending on them. -->
                    <facet facetKey="Classification"/>
                    <facet facetKey="EngagementMeasures"/>
                    <facet facetKey="ContactBehaviorProfile"/>
                    <facet facetKey="Personal"/>
                    <facet facetKey="KeyBehaviorCache"/>
                    <facet facetKey="ListSubscriptions"/>
                </facets>
                <GetOperationTimeout>0.00:00:05</GetOperationTimeout>
            </add>
        </providers>
    </dataAdapterManager>

As you noticed, you were able to access the PersonalInformation facet but not the EmailAddressList because the PersonalInformation facet is defined as part of the default facets list.

To load custom facets or other OOTB facets in the session, we need to register the facets key in the App_Config\Sitecore\Marketing.Tracking\Sitecore.Analytics.Tracking.config file by creating a patch of it:

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
    <dataAdapterManager defaultProvider="xconnect">
        <providers>
            <add name="xconnect" type="Sitecore.Analytics.XConnect.DataAccess.XConnectDataAdapterProvider, Sitecore.Analytics.XConnect">
               <facets hint="raw:AddFacet">
                    <facet facetKey="Emails"/> <!-- NOTE: Taken from EmailAddressList.DefaultFacetKey -->
                </facets>
           </add>
        </providers>
    </dataAdapterManager>
</sitecore>
</configuration>

I've blogged down all the steps required to create a custom personalization rule for EXM here: https://sitecorewithraman.wordpress.com/2021/05/02/custom-rules-for-sitecore-email-personalization/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.