If you’re developing an email send action, or using the default send-email action in WFFM, you probably want to test it out before you send it to the world. If you’re working locally, then a great idea is to use SMTP4Dev to test things out. This allows you to see the email in context by listening for emails to come across a certain port (default is 25).
What if you want to do this on a remote server? You won’t likely be logged in, so you can’t actually see what the email is looking like. But, there is a way! Out of the box, WFFM uses a pipeline for sending emails. These pipelines do a couple things: Expand the Tokens, set attachments, Expand Links, and a few others. This all occurs in the processMessage pipeline below:
<processMessage patch:source="Sitecore.Forms.config"> <processor type="Sitecore.Forms.Core.Pipelines.ProcessMessage, Sitecore.Forms.Core" method="ExpandLinks"/> <processor type="Sitecore.Forms.Core.Pipelines.ProcessMessage, Sitecore.Forms.Core" method="ExpandTokens"> <ItemRepository ref="/sitecore/wffm/itemRepository"/> <FieldProvider ref="/sitecore/wffm/fieldProvider"/> </processor> <processor type="Sitecore.Forms.Core.Pipelines.ProcessMessage, Sitecore.Forms.Core" method="AddHostToItemLink"/> <processor type="Sitecore.Forms.Core.Pipelines.ProcessMessage, Sitecore.Forms.Core" method="AddHostToMediaItem"/> <processor type="Sitecore.Forms.Core.Pipelines.ProcessMessage, Sitecore.Forms.Core" method="AddAttachments"> <ItemRepository ref="/sitecore/wffm/itemRepository"/> </processor> <processor type="Sitecore.Forms.Core.Pipelines.ProcessMessage, Sitecore.Forms.Core" method="BuildToFromRecipient"/> <processor type="Sitecore.Forms.Core.Pipelines.ProcessMessage, Sitecore.Forms.Core" method="SendEmail"/> </processMessage>
Looking at the highlighted line above, you can see the final step in the process is to send the email. What if we replaced that with a debug processor? I like XML for this, since it can organize data into a way that is easy to visually diagnose. Check out this processor:
using System;
using System.IO;
using System.Text;
using System.Xml;
using Sitecore.WFFM.Abstractions.Mail;
namespace Client.Framework.Forms.Pipelines
{
public class DebugSendEmail
{
public void LogEmail(ProcessMessageArgs args)
{
var tempFolder = Path.Combine(Sitecore.Configuration.Settings.TempFolderPath, "MailLog");
if (!Directory.Exists(tempFolder))
Directory.CreateDirectory(tempFolder);
var fullPath = Path.Combine(tempFolder, DateTime.Now.ToFileTimeUtc() + ".xml");
using (var writer = XmlWriter.Create(fullPath))
{
writer.WriteStartDocument();
writer.WriteStartElement("MailMessage");
writer.WriteAttributeString("IsBodyHtml", args.IsBodyHtml.ToString());
writer.WriteAttributeString("Host", args.Host);
writer.WriteAttributeString("Port", args.Port.ToString());
// From
writer.WriteStartElement("From");
writer.WriteRaw(args.From);
writer.WriteEndElement();
// To
writer.WriteStartElement("To");
writer.WriteRaw(args.To.ToString());
writer.WriteEndElement();
// CC
if (args.CC != null && args.CC.Length > 0)
{
writer.WriteStartElement("CC");
writer.WriteCData(args.CC.ToString());
writer.WriteEndElement();
}
// Bcc
if (args.BCC != null && args.BCC.Length > 0)
{
writer.WriteStartElement("Bcc");
writer.WriteCData(args.BCC.ToString());
writer.WriteEndElement();
}
// Subject
writer.WriteStartElement("Subject");
writer.WriteCData(args.Subject.ToString());
writer.WriteEndElement();
// Body
writer.WriteStartElement("Body");
writer.WriteCData(args.Mail.ToString());
writer.WriteEndElement();
writer.WriteEndElement(); //MailMessage
writer.WriteEndDocument();
}
}
}
}
That looks like a bunch of code, doesn’t it? It’s not too bad. First we’re going to snag the Temp Folder from Sitecore. Then we’ll drop in a MailLog folder to organize things. After that, we just write the attributes of the email to the XML and we’re done. We patch this in via a simple config below:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<processMessage>
<processor type="Client.Framework.Forms.Pipelines.DebugSendEmail, Client.Framework" method="SendEmail" patch:instead="processor[@type='Sitecore.Forms.Core.Pipelines.ProcessMessage, Sitecore.Forms.Core' and @method='SendEmail']" />
</processMessage>
</pipelines>
</sitecore>
</configuration>
Btw, I gave myself a gold start for the boolean expression in the patch:instead. I’d not had to do that before and wasn’t 100% sure it would work. It did though!
If you have any issues with this code, let me know in the comments below.