Search code examples
sitecoresitecore8sitecore-ecmsitecore-exm

Sitecore 8 EXM add a contact to list from listmanager


I'm using Sitecore 8 and the new Email Experience Manager module. I have configured a newsletter email message with an empty list from the listmanager as recipients.

When subscribing for the newsletter via a selfmade form, I receive an email address and a name. Now I want to make a new contact with this mail and name and add it to the list in my listmanager via code.

Is there any way to call this list via the api and add a contact to it?


Solution

  • I have had the exact same issue, i.e. the list manager reports 0 contacts after adding the contact to the recipient list.

    I have investigated the issue closer and found that adding a contact to a recipient list actually just sets a field on the contact in the "sitecore_analytics_index" index (assuming you use Mongo/XDB as the underlying storage). Specifically, Sitecore should update the "contact.tags" field on the contact document with the value "ContactLists:{recipientListGuid}". I tried opening the index with Luke to verify that this field was indeed not being set in the index. The index is located in C:\inetpub\wwwroot[Sitename]\Data\indexes\sitecore_analytics_index.

    This led me to the conclusion, that you have to save the contact after adding him to the recipient list.

    Summing up, the following code works for me:

    var ecm = EcmFactory.GetDefaultFactory();
    XdbContactId contactId = /* some valid contact id */;
    LeaseOwner leaseOwner = new LeaseOwner("UpdateContact-" + Guid.NewGuid().ToString(), LeaseOwnerType.OutOfRequestWorker);
    Sitecore.Analytics.Tracking.Contact contact;
    string webClusterName;
    var status = ecm.Gateways.AnalyticsGateway.TryGetContactForUpdate(contactId.Value,
        leaseOwner,
        TimeSpan.FromSeconds(5),
         TimeSpan.FromSeconds(5),
         out contact, out webClusterName);
    
    var recipientList = ecm.Bl.RecipientCollectionRepository.GetEditableRecipientCollection(recipientListId);
      if (recipientList != null)
      {
        if (!recipientList.Contains(contactId, true).Value)
        {
          recipientList.AddRecipient(contactId);
        }
      }
    
    contact.ContactSaveMode = ContactSaveMode.AlwaysSave;
    var contactRepository = new ContactRepository();
    var success = contactRepository.SaveContact(contact, new ContactSaveOptions(true, leaseOwner));
    

    Note, the above code is used in an update-scenario. In your case, I guess you just have to move this code:

    contactRepository.SaveContact(contact, new ContactSaveOptions(true, null));
    

    After this:

    var recipientList = EcmFactory.GetDefaultFactory().Bl.RecipientCollectionRepository.GetEditableRecipientCollection(recipientListId);
      if (recipientList != null)
      {
        var xdbContact = new XdbContactId(contactId);
        if (!recipientList.Contains(xdbContact, true).Value)
        {
          recipientList.AddRecipient(xdbContact);
        }
      }
    

    UPDATE: Actually the above only works if the contact saved is the contact currently tracked by Sitecore Analytics.