Friday, May 20, 2016

WFFM SendMail message routing

Sitecore WFFM SendMail SaveAction

People who have been working with Sitecore WebForms for Marketers probably all know the SendMail save action to send an email after submitting the form. The mail can contain data entered in the mail and can be send to a fixed address or an address provided in the form. But.. sometimes you do want/need your form to send this email to a different email address based on the value chosen in a dropdown list (e.g. the department the visitor wants to contact).

Custom routing

The code I will share here will demonstrate this routing scenario, where the administrators could define in the list of departments the corresponding email address(es). It can be used as a base for similar situations as well. [We are using Sitecore 8.1 update 1]

The implementation

Our implementation works on a value entered in the "To" field of the mail template. If that value contains a fixed string and a guid pointing towards the dropdown field to identify the recipient we check if we can find the value of that field in a defined folder. The found item will give us the recipients' email-address(es) in one of the fields.

The code

Lets have a look at the code (stripped a bit, I removed the logging to just keep the main points here):

public void Process(ProcessMessageArgs args)
{
 if (args == null || args.To == null) { return; }

 var toEmail = args.To.ToString();
 if (!toEmail.Contains(EmailKey)) { return; }

 var fieldIdValue = toEmail.Replace(EmailKey, string.Empty);
 Guid fieldId;
 if (!Guid.TryParse(fieldIdValue, out fieldId)) { return; }

 var field = args.Fields.GetEntryByID(new ID(fieldId));
 if (field == null) { return; }

 var formDataItem = settingsRepository.GetSettingItem("Forms.FormDataRoot");
 if (formDataItem == null) { return; }

 var result = Sitecore.Context.Database.SelectSingleItem(string.Format(CultureInfo.InvariantCulture, "fast:{0}//*[@@name='{1}']", formDataItem.Paths.FullPath, field.Value));
 if (result == null) { return; }

 var toAddress = result["To"];
 if (string.IsNullOrEmpty(toAddress)) { return; }

 args.To.Clear();
 args.To.Append(toAddress);
}

The steps we perform in this function are:

  1. Check the arguments, especially the "To" value as that is our target
  2. We check if the "To" value contains a constant value EmailKey (if not, we skip)
  3. We check if the remainder of the "To" field is a Guid (if not, we skip)
  4. We try to find a field in the form with this Guid as ID
  5. We (try to) get the root of the values (using our SettingsRepository which is a custom piece of code - it just comes down to fetching an item from Sitecore)
  6. We do a fast query in that root to get the item that corresponds with the selected item (value) in the defined field (if not found, we skip)
  7. We get the value of the "To" field in the found item and use this as the new recipient for the mail by clearing and assigning the "To" field of the arguments. 

The config


<pipelines>
  <processMessage>
    <processor patch:before="processor[@method='SendEmail']" type="xx.Wffm.Pipelines.RouteMessage, xx.Wffm" />
  </processMessage>
</pipelines>

We add our class to the processMessage pipeline just before the mail is send.
And that's it. Nothing more to it.

No comments:

Post a Comment