Thursday, June 14, 2018

Enrolling a contact list to a Marketing Automation plan

The new Marketing Automation in Sitecore 9 has a lot of built in options to automatically enroll contacts as they trigger goals or events, or satisfy custom conditions. However this is largely focused around user actions and not marketings desire to enroll a group of contacts into a plan.

I was posed with a problem where I needed to enroll contacts that had already ended their interaction. For this I made a simple service that would enroll all contacts from a given Sitecore List Manager list into my Marketing Automation plan.

Making this was surprisingly easy by combining the enrolling a contact in a single plan and the list manager api guides from Sitecores' documentation.



The resulting code looks like this:

using Microsoft.Extensions.DependencyInjection;
using Sitecore.DependencyInjection;
using Sitecore.Diagnostics;
using Sitecore.ListManagement;
using Sitecore.ListManagement.XConnect;
using Sitecore.Xdb.MarketingAutomation.Core.Requests;
using Sitecore.Xdb.MarketingAutomation.Core.Results;
using Sitecore.Xdb.MarketingAutomation.OperationsClient;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;

namespace WorldCup.Services
{
    public class XConnectService
    {
        private IContactListProvider _contactListProvider;
        private IContactProvider _contactProvider;
        private IAutomationOperationsClient _automationOperationsClient;
        private int _batchSize = 100;

        public XConnectService()
        {
            _contactListProvider = ServiceLocator.ServiceProvider.GetService<IContactListProvider>();
            _contactProvider = ServiceLocator.ServiceProvider.GetService<IContactProvider>();
            _automationOperationsClient = ServiceLocator.ServiceProvider.GetService<IAutomationOperationsClient>();
        }

        public void EnrollListToMarketingAutomation(Guid contactListId, CultureInfo cultureInfo, Guid automationPlanId)
        {
            try
            {
                var contactList = _contactListProvider.Get(contactListId, cultureInfo);
                var contactBatchEnumerator = _contactProvider.GetContactBatchEnumerator(
                    contactList,
                    _batchSize,
                    new string[0]);

                var results = new List<Task<BatchEnrollmentRequestResult>>();

                while (contactBatchEnumerator.MoveNext())
                {
                    var contacts = contactBatchEnumerator.Current;
                    var enrollmentRequests = contacts.Where(c => c.Id.HasValue).Select(c => new EnrollmentRequest(c.Id.Value, automationPlanId)).ToArray();
                    results.Add(_automationOperationsClient.EnrollInPlanDirectAsync(enrollmentRequests));
                }

                Task.WaitAll(results.ToArray());
            }
            catch (Exception ex)
            {
                Log.Error($"Error while enrolling list: {contactListId} to plan: {automationPlanId}", ex, this);
                throw;
            }
        }
    }
}


See my WorldCup post for an example of usage of the API.

To finish this up nicely, we need a proper button in the Marketing Automation interface. I haven't gotten that far yet, but will update if/when I get the time for it.

Update:
After looking at creating the button I found that it wasn't as easy, as unfortunately the new Marketing Automation interface is a precompiled Angular plugin. That being said, I learned through slack that the new Sitecore 9.0 update 2 has something along these lines built in, and that Sitecore 9.1 will have this exact functionality. So I'll wrap it up for now.
If anyone really wants a button for this now, it could be made in either the Marketing Automation list overview or inside the List Manager application.