Custom Email provider example

Customizing the email provider allows you to:

  • Execute custom actions when sending emails (for example logging the sent emails for auditing purposes)
  • Use third‑party components for sending emails

Once you create and register your custom email provider, it is used to process all emails sent out by Xperience.

The following example demonstrates how to define a custom email provider. This sample provider supports all of the default email functionality, but additionally creates an entry in the Event log whenever the system sends an email.

Writing the custom email provider

Start by preparing a separate project for custom classes in your Xperience solution:

  1. Open your solution in Visual Studio.
  2. Add a custom assembly (Class Library project) with class discovery enabled to the solution, or re-use an existing assembly.
  3. Reference the project from both your live site project and the Xperience administration project (CMSApp).

Continue by implementing the custom provider class:

  1. Add a new class under the custom project. For example, name the class CustomEmailProvider.cs

  2. Modify the class’s declaration so that it inherits from the CMS.EmailEngine.EmailProvider class.

    Custom email providers must always inherit from the default EmailProvider class. This allows you to call the base methods before adding your own custom functionality.

  3. Register the custom provider by adding the RegisterCustomProvider assembly attribute above the class declaration (requires a using statement for the CMS namespace). The attribute’s parameter specifies the type of the custom provider class as a System.Type object.

  4. Override the following methods in the class:

    
    
    
     using System.ComponentModel;
     using System.Net.Mail;
    
     using CMS;
     using CMS.Core;
     using CMS.EmailEngine;
    
     // Registers the custom EmailProvider
     [assembly: RegisterCustomProvider(typeof(CustomEmailProvider))]
    
     public class CustomEmailProvider : EmailProvider
     {
         private readonly IEventLogService eventLog;
    
         public CustomEmailProvider()
         {
             eventLog = Service.Resolve<IEventLogService>();
         }
    
         /// <summary>
         /// Synchronously sends an email through the SMTP server.
         /// </summary>
         /// <param name="siteName">Site name</param>
         /// <param name="message">Email message</param>
         /// <param name="smtpServer">SMTP server</param>
         protected override void SendEmailInternal(string siteName, MailMessage message, SMTPServerInfo smtpServer)
         {
             base.SendEmailInternal(siteName, message, smtpServer);
    
             string detail = string.Format("Email from {0} was sent via {1} (synchronously)", message.From.Address, smtpServer.ServerName);
             eventLog.LogInformation("CMSCustom", "EMAIL SENDOUT", detail);
         }
    
         /// <summary>
         /// Asynchronously sends an email through the SMTP server.
         /// </summary>
         /// <param name="siteName">Site name</param>
         /// <param name="message">Email message</param>
         /// <param name="smtpServer">SMTP server</param>
         /// <param name="emailToken">Email token that represents the message being sent</param>   
         protected override void SendEmailAsyncInternal(string siteName, MailMessage message, SMTPServerInfo smtpServer, EmailToken emailToken)
         {
             base.SendEmailAsyncInternal(siteName, message, smtpServer, emailToken);
    
             string detail = string.Format("Email from {0} was dispatched via {1} (asynchronously)", message.From.Address, smtpServer.ServerName);
             eventLog.LogInformation("CMSCustom", "EMAIL SENDOUT", detail);
         }
    
         /// <summary>
         /// Raises the SendCompleted event after the send is completed.
         /// </summary>
         /// <param name="e">Provides data for the async SendCompleted event</param>
         protected override void OnSendCompleted(AsyncCompletedEventArgs e)
         {
             base.OnSendCompleted(e);
             string detail = "Received callback from asynchronous dispatch";
             eventLog.LogInformation("CMSCustom", "SEND COMPLETE", detail);
         }
     }
    
    
     
  5. Save all changes and Rebuild the solution.

Customizing live site projects

Remember to deploy the assembly containing your custom provider to the live site (MVC) application. This ensures that the customization applies if the system (or your custom code) sends emails through the Xperience API on the live site. For example, notification emails are sent from the live site application when a customer completes an order on an e-commerce site.

The provider uses the customized methods to send out emails. Each method calls the base from the parent provider class and then logs an information event into the system’s event log. You can use the same approach to add any type of custom functionality.

Result

The system now uses the custom email provider (defined in the CustomEmailProvider class) when sending emails.

To try out the functionality:

  1. Send some emails using Xperience.
    • For example, you can use the System -> Email interface to send a test email (synchronously).
  2. Check the log in the Event log application.

The event log displays an entry for every successfully sent email, identified by the CMSCustom Source value (two entries for emails sent asynchronously).