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.