Saturday, 10 May 2014

"Send Email Message" Bug in Sitecore DMS Engagement Plans

Sitecore engagement plans contain an action for sending an email. In the action's settings there's an option to send the email to the "Current Visitors Email Address", but unfortunately this has a bug.


Background
The term Visitior in Sitecore refers to a client which is tracked by means of a cookie containing a unique ID. This is in contrast to the term User, which is a client that has authenticated to the site somehow and has an associated username and profile. You can read more about this distinction on John West's article on the topic.

The Bug

Sitecore is usually very careful with its use of the of the word Visitor, so you might reasonably assume that "Current Visitors Email Address" means it will somehow try to find an email address using their visitor cookie. But that's not quite what happens. Sitecore only attempts to send an email if the visitor is linked to a known user account, in which case it gets the address from their profile.

I always thought this was a bit odd, but I just thought it was probably poor labelling - maybe it should read "Current User's Email Address". However, after reading Brian Pedersen's blog post Programming for Sitecore DMS Engagement Plans, I decided do a bit of investigation.

Looking around the decompiled code, I found that Sitecore hands the job obtaining the email address over to a pipeline named findVisitorEmailAddress. The pipeline runs through each processor until one of them successfully finds an email address. By default, there are 2 processors. The first employs the method I described above, looking up the email address in the user profile if it's available. The second looks to see if there is a Visitor Tag with the key "email".

So it seems Sitecore has been designed to find email addresses in a flexible and extensible way. I was pleased with my discovery and promptly put my theory to the test. I removed the existing processors from the pipeline and replaced them with a new one I'd created that simply returns my own email address every time. The result - nothing! The email still wasn't being sent.

I'd been convinced this would work, so I was very confused. I spent some more time examining the surrounding code, and eventually arrived at the root of the problem. Although the pipeline itself is free to get the email address by whatever means it likes, the code that sets the pipeline running only does so if the visitor is associated with a user account. Here's a snippet:
if (automationStatesRow.IsUserNameNull()) // The culprit
    return string.Empty;

FindVisitorEmailAddressArgs emailAddressArgs =  
    new FindVisitorEmailAddressArgs(automationStatesRow.UserName, (object) 
        this.GetAutomationVisitor(automationStatesRow));

// you can't get here unless the visitor record is associated with a username.
CorePipeline.Run("findVisitorEmailAddress", (PipelineArgs) emailAddressArgs);

The Solution
I raised the issue with Sitecore support. After acknowledging that this was indeed a bug, they quickly put together this patch file to fix it, and provided the following instructions:
  1. Put the assembly in to the /bin folder of your site.
  2. Navigate to the following item:
    /Sitecore/system/Settings/Analytics/Engagement Automation/Predefined items/Actions/Send E-Mail Message  
  3. Set the Type field to:
    Sitecore.Support.Automation.MarketingAutomation.AutomationActions.SendEmailMessageAction,Sitecore.Support.387406
  4. Update any existing engagement plans which use the "Send Email Message" action.
The fix will presumably be in future releases, but until then this should do the trick. Thanks Sitecore support!