Dynamic Email Recipients with Umbraco Formulate

Dynamic Email Recipients with Umbraco Formulate

For most forms, emailing a single person or group of people is all you need. However, there are sometimes occasions to change the email recipients depending on some factor, such as the field input values or the page that a form appears on.

Luckily, Formulate offers a number of options to facilitate this; I’ll explain a few of them.

Option 1: Different Email Per Drop Down Value

Here’s the form we’ll use as an example:

An example Formulate form.

An example Formulate form.

Create this form in Formulate using the usual approach: http://www.formulate.rocks/simple-form

Once it’s been created, you’ll need to create a “Pair List” data value with the values set to email addresses (remember to select this data value on the drop down):

A “Pair List” data value, with the value of each being an email address.

Next, create an “Email” handler, making sure to select the “Offices” drop down as the field containing the email address to send the email to:

The “Recipient Email Fields” has the “Office” field selected.

The “Recipient Email Fields” has the “Office” field selected.

Now, when the form is submitted, an email will be sent to the email address indicated by the drop down selection.

Option 2: Different Email Per Page

Suppose you have a business with multiple offices, and for each office, you have a “Location” page. You might display a form on those pages, but the recipient should change depending on which page the form appears on.

The manual way of implementing that would be to create a new form for each and every location page. That would take quite a bit of time. There’s a better way.

Create a field on your “Location” document type called “Email Recipient”. A content editor will type in the email addresses on each location page. Then you create a form like normal and have it display on your location pages.

Field with Custom Category

You’ll need to customize the form a bit. Edit the “~/config/formulate/fieldCategories.config” to add a new category called “Dynamic Email Recipient”:

<?xml version="1.0" encoding="utf-8" ?>
<fieldCategories>
    <fieldCategory kind="Dynamic Email Recipient" group="Email" />
</fieldCategories>

View Gist

Create a “Text Constant” field named “Automatic Recipient” with the “Dynamic Email Recipient” category selected.

Add an “Email” handler to your form. Ensure your “Automatic Recipient” field is chosen as one of the recipient email fields. Now you just need to write some code to populate that field value when the form is submitted.

Populate Automatic Email Recipient Field

In order for your field to be populated, you’ll need to create a function like this that will extract the email address from the current page and set the field value in the form submission:

/// <summary>
/// Sets the "Dynamic Email Recipient" field based on the current page.
/// </summary>
/// <param name="context">
/// The form submission context.
/// </param>
private static void SetEmailByPage(FormSubmissionContext context)
{

    // Find the "Dynamic Email Recipient" field (exit early if not found).
    var field = context.Form.Fields
        .Where(x => x.Category == "Dynamic Email Recipient")
        .FirstOrDefault();
    if (field == null)
    {
        return;
    }

    // Get the recipient email address from the current page.
    var recipient = context.CurrentPage.GetPropertyValue<string>("emailRecipient");

    // Copy the field data into a new list.
    var newData = new List<FieldSubmission>(context.Data);

    // Set field data to the email address.
    MergeFieldData(newData, field, recipient);

    // Ensure the modified field data gets used.
    context.Data = newData;

}

View Gist

You’ll also need this utility function to merge that field data in with the rest of the field data for a form submission:

/// <summary>
/// Merges the specified field value into the collection of field submissions.
/// </summary>
/// <param name="data">
/// The collection to merge the field value into.
/// </param>
/// <param name="field">
/// The field to merge.
/// </param>
/// <param name="fieldValue">
/// The value to merge in for the field.
/// </param>
private static void MergeFieldData(List<FieldSubmission> data, IFormField field, string fieldValue)
{
    var fieldData = data.FirstOrDefault(x => x.FieldId == field.Id);
    if (fieldData == null)
    {
        fieldData = new FieldSubmission()
        {
            FieldId = field.Id
        };
        data.Add(fieldData);
    }
    fieldData.FieldValues = new List<string>() { fieldValue };
}

View Gist

Finally, you’ll need to actually call your function when a form is submitted. You can do that by configuring the event handling when your app starts:

/// <summary>
/// Handles application startup.
/// </summary>
public class AppStart : ApplicationEventHandler
{
    protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication,
        ApplicationContext applicationContext)
    {

        // Initialize Formulate events.
        formulate.api.Submissions.Submitting += SetEmailByPage;

        // Boilerplate.
        base.ApplicationStarting(umbracoApplication, applicationContext);

    }
}

View Gist

That’s all there is to it. Your form submissions will now be emailed to whatever email address you specify on the content node the form was submitted from.

You can customize that logic to suit your needs. For example, the email address may depend on some other factor, such as a location page’s state. And there’s no reason that email address needs to be stored in Umbraco; it could be stored in some external database or be acquired via a web service.

Formulate allows you to customize to your exact needs.