5

Firstly, I have seen posts related to my below issue but they have not been helpful thus far.

I am currently using Sitecore 8.2 (rev.161221) with Web Forms for Marketers 8.2 (rev.161129). I have this issue on Azure and also on an on-premise deployment. Azure uses azure search and on-premise uses Lucene.

Issue:

When a user submits a WFFM form, I add this person as a contact into a Sitecore list. This part seems to be working since when I open the list, I can see every person who submitted the related form.

My issue is when I open the list, I see the message "Please note that contacts in the list are currently being indexed, so not all contacts are available to view at this time. 100 out of 0 contacts are currently indexed.". It has been this way for days and days now.

When I go back to my lists view, I see 0 under the Recipients column. This value is never updated to the total count of contacts within the list.

I do not see any helpful information within logs.

1: Why is it that List Manager indexing never completes? Is there a patch for the specific version of Sitecore I am using?

2: Is there a way to manually trigger any pipeline that runs and starts updating the recipient count?

Any pointers will be greatly appreciated.

2 Answers 2

2

That's a know issue with Sitecore WFFM action Add Contact to Contact List.

If you use EXM, you can use code below to override the default action. Remember that your contact should have First Name, Surname and Email set.

If you don't use EXM, contact with Sitecore Support. They can provide you a support dll appropriate for your Sitecore and WFFM versions.

using System;
using System.Linq;
using Sitecore.Analytics.Model;
using Sitecore.Analytics.Tracking;
using Sitecore.Data;
using Sitecore.Diagnostics;
using Sitecore.Modules.EmailCampaign;
using Sitecore.SecurityModel;
using Sitecore.WFFM.Abstractions.Actions;
using Sitecore.WFFM.Abstractions.Analytics;
using Sitecore.WFFM.Abstractions.Shared;

namespace WffmCustomization
{
    public class AddContactToContactList : Sitecore.WFFM.Actions.SaveActions.AddContactToContactList
    {
        private const string RootListPath = "/sitecore/system/Modules/E-mail Campaign Manager/System/Root List";
        private const string ManagerRootsFieldName = "Manager Roots";

        private readonly IAnalyticsTracker _analyticsTracker;

        public AddContactToContactList(IAnalyticsTracker analyticsTracker, IContactRepository contactRepository) : base(analyticsTracker, contactRepository)
        {
            _analyticsTracker = analyticsTracker;
        }

        public override void Execute(ID formId, AdaptedResultList adaptedFields, ActionCallContext actionCallContext = null, params object[] data)
        {
            Assert.ArgumentNotNull(adaptedFields, "adaptedFields");
            Assert.IsNotNullOrEmpty(ContactsLists, "Empty contact list.");
            Assert.IsNotNull(_analyticsTracker.CurrentContact, "Tracker.Current.Contact");

            if (!adaptedFields.IsTrueStatement(ExecuteWhen))
                return;

            var lists = ContactsLists.Split(',').Select(x => ID.Parse(x).ToString()).ToArray();

            using (new SecurityDisabler())
            {
                Contact currentContact = _analyticsTracker.CurrentContact;

                if (currentContact.Identifiers.IdentificationLevel != ContactIdentificationLevel.Known)
                {
                    var emailAddresses = currentContact.GetFacet<Sitecore.Analytics.Model.Entities.IContactEmailAddresses>("Emails");
                    if (emailAddresses.Entries.Contains("Preferred"))
                    {
                        var email = emailAddresses.Entries["Preferred"];
                        _analyticsTracker.Current.Session.Identify(email.SmtpAddress);
                    }
                }

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

                var rootList = (Sitecore.Context.ContentDatabase ?? Sitecore.Context.Database).GetItem(RootListPath);

                Assert.IsNotNull(rootList, "Empty root list.");

                var managerRootId = (rootList[ManagerRootsFieldName] ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();

                Assert.IsNotNullOrEmpty(managerRootId, "Empty manager root id.");

                Log.Info($"AddContactToContactList [{currentContact.ContactId}, {ContactsLists}, {managerRootId}]", this);

                ClientApi.UpdateSubscriptions(recipientId, lists, new string[] { }, managerRootId, false);
            }
        }
    }
}
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/">
  <sitecore>
    <wffm>
      <actions>
        <addContactToContactList  type="Sitecore.WFFM.Actions.SaveActions.AddContactToContactList, Sitecore.WFFM.Actions" >
          <patch:attribute name="type">WffmCustomization.AddContactToContactList, WffmCustomization</patch:attribute>
        </addContactToContactList>
      </actions>
    </wffm>
  </sitecore>
</configuration>

EDIT

Below is the code I receive from Sitecore Support for fixing the number of recipients of all the contact lists in Sitecore. I received it for another Sitecore version but it should do the trick in your case as well:

ListManager<ContactList, ContactData> listManager = Factory.CreateObject("contactListManager", false) as ListManager<ContactList, ContactData>;
using (new SecurityDisabler())
{
  using (IEnumerator<ContactList> enumerator = ((IEnumerable<ContactList>) listManager.GetAll((string) null, true)).GetEnumerator())
  {
    while (((IEnumerator) enumerator).MoveNext())
    {
      ContactList current = enumerator.Current;
      Item obj = Factory.GetDatabase(ListManagementSettings.get_Database()).GetItem(current.get_Id());
      this.Response.Write("List: " + current.get_DisplayName() + ", list id: (" + current.get_Id() + "), contacts in index: " + (object) listManager.GetContacts(current).Count<ContactData>() + ", contacts in field: " + ((BaseItem) obj).get_Item("Recipients"));
      if (obj != null && listManager.GetContacts(current).Count<ContactData>() > int.Parse(((BaseItem) obj).get_Item("Recipients")))
      {
        obj.get_Editing().BeginEdit();
        ((BaseItem) obj).set_Item("Recipients", listManager.GetContacts(current).Count<ContactData>().ToString());
        obj.get_Editing().EndEdit();
        this.Response.Write("</br>List field was updated");
      }
      this.Response.Write("</br></br>");
    }
  }
}
3
  • Thank you Marek. That definitely solved 80% of the issue. Now when we add contact to contact list via WFFM, the recipient count gets updated properly. Only issue thats left is the count of contacts that were there previously do not get updated. E.g. lets say the list previously had 10 contacts and was showing recipients 0, after adding contact to contact list via WFFM, now it shows recipients 1 instead of 11. Any idea how to factor in the existing list contacts when updating the recipient count? Nov 20, 2017 at 21:14
  • @NavneetPisharodi Code updated
    – Marek Musielak
    Nov 21, 2017 at 6:56
  • Marek, Updated based on your response. Thanks again. Nov 21, 2017 at 17:50
0

Edited

@Marek Musielak Thanks a lot. Your answer worked like a charm. I am sure your suggestions in this post will be extremely useful for the Sitecore community.

I had to make some minor changes to your code (as posted below) for it to work for my version. Also, noticed that for EXM, after you update the recipient count, the contact still needs to have an identifier in MongoDb for the email to be sent.

Code block:

<%@ Import Namespace="Sitecore.SecurityModel" %>
<%@ Import Namespace="Sitecore.Configuration" %>
<%@ Import Namespace="Sitecore.Data" %>
<%@ Import Namespace="Sitecore.Data.Items" %>
<%@ Import Namespace="Sitecore.ListManagement" %>
<%@ Import Namespace="Sitecore.ListManagement.ContentSearch" %>
<%@ Import Namespace="Sitecore.ListManagement.ContentSearch.Model" %>
<%@ Import Namespace="Sitecore.WFFM.Abstractions.Actions" %>
<%@ Import Namespace="Sitecore.WFFM.Abstractions.Shared" %>
<%@ Import Namespace="System.Collections" %>
<%@ Import Namespace="System.Collections.Generic" %>
<%@ Import Namespace="System.Linq" %>

ListManager<ContactList, ContactData> listManager = Factory.CreateObject("contactListManager", false) as ListManager<ContactList, ContactData>;
            using (new SecurityDisabler())
            {
                using (IEnumerator<ContactList> enumerator = ((IEnumerable<ContactList>)listManager.GetAll((string)null, true)).GetEnumerator())
                {
                    while (((IEnumerator)enumerator).MoveNext())
                    {
                        ContactList current = enumerator.Current;
                                                                                                output.AppendLine(current.Id.ToString());
                        Item obj = Factory.GetDatabase("master").GetItem(current.Id);
                        //this.Response.Write("List: " + current.get_DisplayName() + ", list id: (" + current.get_Id() + "), contacts in index: " + (object)listManager.GetContacts(current).Count<ContactData>() + ", contacts in field: " + ((BaseItem)obj).get_Item("Recipients"));
                        if (obj != null && listManager.GetContacts(current).Count<ContactData>() > int.Parse(((BaseItem)obj).Fields["Recipients"].ToString()))
                        {
                            obj.Editing.BeginEdit();
                                                                                                                output.AppendLine(listManager.GetContacts(current).Count<ContactData>().ToString());
                            ((BaseItem)obj).Fields["Recipients"].Value = listManager.GetContacts(current).Count<ContactData>().ToString();
                            obj.Editing.EndEdit();
                            //this.Response.Write("</br>List field was updated");
                        }
                        //this.Response.Write("</br></br>");
                    }
                }
            }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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