Sending Emails from Umbraco

Email is a core part of many websites — whether it's for contact forms, signup confirmations, receipts or newsletter integrations. In this blog post we'll explore different ways to send emails from Umbraco CMS. This article was written for Umbraco 15, but the concepts has been around for a while and evolved over time, so parts of the examples might not work in older versions of Umbraco.

The built in way

Umbraco ships with some simple abstractions for sending emails. Under the hood it uses the well-known MailKit library. To avoid tightly coupling the CMS to MailKit, Umbraco has a number of abstractions that we need to work with.

  • EmailMessage is Umbraco's representation of an email to avoid using the MimeMessage type from MailKit directly in the core CMS code.
  • IEmailSender provides the SendAsync() method that can send a EmailMessage.
  • IEmailSenderClient used by IEmailSender to perform the actual sending. The BasicSmtpEmailSenderClient in Umbraco.Cms.Infrastructure implements this interface using Mailkit but this could be swopped if needed.

Configuration

Before we can send any emails, we need to ensure that our settings are correctly configured in appsettings.json.

{
  "Umbraco": {
    "CMS": {
      "Global": {
        "Smtp": {
          "Host": "smtp.something.com",
          "From": "website@your-domain.com",
          "Username": "****",
          "Password": "****",
        }
      }
    }
  }
}

During development, I like to use either the fake SMTP server Papercut or configure a pickup directory in appsettings.json.

{
    "Smtp": {
      "From": "website@your-domain.com",
      "DeliveryMethod": "SpecifiedPickupDirectory",
      "PickupDirectoryLocation": "c:\\temp\\smtp"
    }
}

Sending the email

Now, to send emails, we need to use Umbraco's IEmailSender to send our EmailMessage. Here's a simple example of a class that handles lead form submissions.

public class LeadFormHandler
{
    private readonly IEmailSender _emailSender;

    public LeadFormHandler(IEmailSender emailSender)
    {
        _emailSender = emailSender;
    }

    public async Task<bool> SendEmail(LeadFormModel model)
    {
        var senderEmail = "website@your-domain.com";
        var recipientEmail = "sales@your-domain.com";
        var subject = "New lead from website";
        var body = $"""
                   <h1>New lead from website</h1>
                   <p><strong>Name:</strong> {model.Name}</p>
                   <p><strong>Email:</strong> {model.Email}</p>
                   <p><strong>Message:</strong><br/> {model.Message}</p>
                   """;
        
        // Create the EmailMessage to send
        var message = new EmailMessage(
            senderEmail, 
            [recipientEmail], 
            null, // cc
            null,  // bcc
            [model.Email], 
            subject, body, 
            true,
            null // attachments
        );

        // Send using IEmailSender
        await _emailSender.SendAsync(message,"lead",true);

        return true;

    }
}

You might wonder about the "lead" and true parameters in the call to SendAsync. We'll examine that later. If we run the code above, we'd get an email that looks something like this in Papercut:

Send Email Notification

Umbraco has a very flexible notification system that allow us to hook into and react to events in the application.

When calling SendEmailAsync(), the "lead" and true values sets the "emailType" and the enableNotification parameters, this will trigger a SendEmailNotification. The "emailType" is simply a custom string that's only used for the notification - you could leave this blank if you're not using the SendEmailNotification.

Here's a simple example of a INotificationHandler that handles this notification and logs any leads:

public class EmailSendingHandler : INotificationHandler<SendEmailNotification>
{
    private readonly ILogger<EmailSendingHandler> _logger;

    public EmailSendingHandler(ILogger<EmailSendingHandler> logger)
    {
        _logger = logger;
    }

    public void Handle(SendEmailNotification notification)
    {
        if (!notification.EmailType.Equals("lead"))
            return;

        _logger.LogInformation("Lead email was sent. Content: {@Message}", notification.Message);

        // could use notification to send email in
        // another way OR abort by calling HandleEmail()
        //notification.HandleEmail();

    }
}

 

Newsletter Studio Transactional Emails

An alternative approach to sending email from Umbraco is to use Newsletter Studio. Our built in email editor to send transactional emails gives your editors a seamless editing experience with our drag-and-drop editor. We'll even provide a dropdown with all the relevant merge fields based on the model defined for the email.

It also provide configurable, automatic logging and the ability to save the email content that was sent. The Transactional log gives a great overview:

And it allows editors to drill into the details of the email, see when it was opened, and whether any links were clicked.

If allowed by the configuration, editors can also see the content of the actual email and resend it to the recipient if needed.

Check out our transactional email documentation for more details, and of course, you are always welcome to reach out to us if you have any questions.

 

More from the blog