contact@skillcore.net

Sitecore - proper way of adding contacts to contact lists

Posted 13 November 2017 by Marek Musielak

sitecore list manager

Not that long ago I was asked to write a code which will allow to subcribe users to Sitecore Contact List. Task was really simple - let's create a form with few fields and after user submits the form, we should update properties of the current Sitecore contact and subscribe to the selected list. I never worked with Contact Lists before, so I started to google and found many different ways how to achieve what I needed. I tried few of them and nothing worked for me. Some of them added the contact to the list, but the recipients number of the list was not updated, others caused that list was locked forever and never indexed properly.

It took me some time before I learned that despite the fact that contact lists are there when you install vanilla Sitecore instance, you do need Email Experience Manager module before you can add contacts to Sitecore Contact List programatically. After you install EXM, make sure that your project references Sitecore.EmailCampaign.dll and use Sitecore.Modules.EmailCampaign.ClientApi.UpdateSubscriptions method. It sounds simple, but there were few more things I learned that day:

  1. FirstName and Surname of the contact have to be populated. If not, contact will not be subscribed to the list.
  2. If you're in a POST call from MVC form, remember to check if Tracker.IsActive and Tracker.StartTracking() if needed.
  3. managerRootId parameter is the id of one of EXM Root Managers. In 99.9% of the cases it will be id of the /sitecore/content/Email Campaign item. You can find all the EXM Root Managers in the Manager Roots field of the /sitecore/system/Modules/E-mail Campaign Manager/System/Root List item.

To summarize, here is the code which can be used to add contact to a Sitecore contact list:

public void AddContactToContactList(string contactListId, string firstName, string surname, string emailAddress)
{
  Item managerRoot = Sitecore.Data.Database.GetDatabase("master").GetItem("/sitecore/content/Email Campaign");

  if (managerRoot == null)
  {
    throw new Exception("No root manager found at '/sitecore/content/Email Campaign'. Have you installed EXM?");
  }

  string managerRootId = managerRoot.ID.ToString();

  if (!Sitecore.Analytics.Tracker.IsActive)
    Sitecore.Analytics.Tracker.StartTracking();

  var currentContact = Sitecore.Analytics.Tracker.Current.Contact;

  var personal = currentContact.GetFacet<Sitecore.Analytics.Model.Entities.IContactPersonalInfo>("Personal");

  personal.FirstName = firstName;
  personal.Surname = surname;

  var emailAddresses = currentContact.GetFacet<Sitecore.Analytics.Model.Entities.IContactEmailAddresses>("Emails");
  if (!emailAddresses.Entries.Contains("Email"))
  {
    emailAddresses.Entries.Create("Email");
  }

  var email = emailAddresses.Entries["Email"];
  email.SmtpAddress = emailAddress;
  emailAddresses.Preferred = "Email";

  var recipientId = new Sitecore.Modules.EmailCampaign.Xdb.XdbContactId(currentContact.ContactId);

  Sitecore.Modules.EmailCampaign.ClientApi.UpdateSubscriptions
    (recipientId, new[] { contactListId }, new string[] { }, managerRootId, false);
}

When you look at the code now, it is really simple. But I spent some time on the task which I could avoid if I knew the right way when I started my work. So if I can save you some troubles, I'm more than happy.

And if you want to learn more, read The Email Experience Manager Client API documentation.