In a previous article, I explored the benefits of using Kentico EMS in a headless architecture. It’s a great choice for organizations that have well-established applications and integration, because it allows adopting the features of Kentico EMS without a major rebuild. Additionally, it provides the strategic benefits of a headless architecture, including reusing content in multiple marketing channels (e.g. web, email, apps, etc.). These are the reasons one of our enterprise customers chose this approach. Naturally, this brings up the question, if they wanted a headless architecture, why not use an entirely headless platform, like Kentico Kontent? In this instance, this customer recognized the value of the integrated online marketing solution provided by Kentico EMS, which includes customer insights powered by the website to personalize and target email campaigns.
Kentico’s email marketing feature is one of its most powerful online marketing capabilities. However, out-of-the-box the email marketing feature depends on having a website served by Kentico, something not provided in a headless architecture. This is because Kentico uses the website to provide subscribe, unsubscribe, and confirm pages, as well as image hosting and email tracking endpoints. These endpoints support tracking viewed emails and clicked email links. Additionally, Kentico provides a similar endpoint for supporting an email’s view-in-browser link. In this article, I’ll share how to build a headless architecture that supports Kentico’s email tracking endpoints.
If you examine the source of a Kentico marketing email, you’ll discover that it uses the following three handlers that are normally provided by a Kentico website. To support email marketing in a headless architecture, each of these handler endpoints must instead be provided in the headless website:
- Viewed Email Tracking: This Kentico handler returns a pixel added to emails and records each email view.
- Email Link Tracking: This handler records when a user clicks an email link, and then redirects the request to the destination URL.
- View-in-browser Handler: Kentico emails provide the ability to view the email in a browser. To support this, the view-in-browser handler returns the email content.
There are two main options for providing these endpoints in a headless architecture. The first method is to use a gateway to route requests to Kentico instead of the website. The headless architecture already includes a Kentico application to provide the headless API, which automatically includes the email tracking endpoints. These endpoints can be provided by configuring a network gateway to split requests for the required routes to the headless API – the custom web application that already includes the required handlers using Kentico’s Kentico.Web.Mvc package.
This is the option we initially pitched to our customer. However, because they were already splitting traffic between their e-commerce application and a legacy CMS, they wanted to move away from this approach. They preferred to add the needed endpoints directly to their custom website.
Adding the endpoints
To support the email-tracking endpoints without splitting the network traffic, handlers had to be added to the headless website using the same URLs and parameters used by Kentico’s built-in handlers. Additionally, because the website did not include Kentico components, endpoints had to be added to the headless content service, so that the handler requests could be passed on to Kentico. Since all the work was done in the headless API endpoints, the custom handlers added to the website were essentially just a facade that received parameters from the email requests and then passed them to the endpoints added to the API.
Below, I've listed each of the replicated email-tracking handlers, including their parameters and functionality to show how simple the implementation of each handler is. As I will describe later, the work of taking the parameters, validating the hash, and using the Kentico API all happens within the endpoints provided in the headless API.
Handler: Viewed Email Tracking
- Name: issueguid
Description: Issue GUID provided by the Kentico email IMG link identifying the specific email issue within a newsletter or campaign.
- Name: recipient
Description: email address provided by the Kentico email IMG link.
- Name: hash
Description: Hash parameter provided by the Kentico email IMG link, used to authenticate the email and recipient.
Functionality: Call the headless API endpoint with the provided parameters and return a transparent pixel. This pixel is included in an email as an IMG tag.
Handler: Email Link Tracking
- Name: linkguid
Description: Link GUID provided by the Kentico email link identifying the specific link within a specific email.
- Name: email
Description: Recipient email address provided by the Kentico email link.
- Name: hash
Description: Hash parameter provided by the Kentico email link, used to authenticate the email and recipient.
Functionality: Call the headless API endpoint with the provided parameters. The endpoint will return the URL that the user wants to navigate to. Provide a redirect response to the returned URL.
Example: /CMSModules/Newsletters/CMSPages/Redirect.ashx?linkguid=c9fe0cee-7066-4017-b31c-6e98c0cf4bb3& email=johndoe%40gmail.com& hash=3fc7dabbd8d9661150224ad265079615c7cfe2449d74ae448d60adcdeac03bae
Handler: View-in-browser Handler
- Name: issueguid
Description: Issue GUID provided by the Kentico view-in-browser link identifying the specific issue within a campaign.
- Name: email
Description: Recipient email address provided by the Kentico link.
- Name: hash
Description: Hash parameter provided by the Kentico link, used to authenticate the email and recipient.
Functionality: Call the headless API endpoint with the provided parameters. The endpoint will return the HTML content for the email. Return the provided HTML content to the user as a response.
Example: /CMSPages/Newsletters/GetEmailBrowserContent.ashx?issueGuid=1eb1cb43-8820-4eda-866b-140c62ed7f69& recipientEmail=johndoe%40gmail.com& hash=03999eec54105079eae2cca32d85e1e40c6f7f2ea30a25aae7bd033d37c3f9c7
Web API endpoints
To provide the needed endpoints in the headless API, we implemented Web API actions for the following routes, using REST naming best practices:
- /v1/emails/opens (Track.ashx)
- /v1/emails/clicks (Redirect.ashx)
- /v1/emails/browserviews (GetEmailBrowserContent.ashx)
The first task of each of these endpoints is to validate the hash parameter. The hash parameter authenticates that the request is coming from the user identified by the email parameter, and from a message identified by the issueguid or linkguid parameter. Fortunately, Kentico provides a robust API designed to support deep customizations. Kentico is excellent in its ability to support this headless architecture. As an example, it provides the EmailHashService class for validating the hash parameter. This allows validation of the email and hash parameters in a few lines of code, like this:
var service = new EmailHashService();
var response = service.ValidateEmailHash(hash, email);
After validating the email hash, the opens endpoint, which supports the website’s Track.ashx handler, looks up the newsletter issue, and records that the newsletter was viewed. It looks up the issue using the IssueInfoProvider’s GetIssueInfo method, increments the view count of the email using the IssueInfoProvider’s AddOpenedEmails method, and logs that a specific subscriber opened the email using the OpenedEmailInfoProvider’s LogOpenedEmail method.
var issueInfo = IssueInfoProvider.GetIssueInfo(issueGuid, siteID);
After validating the email hash, the clicks endpoint records the link click, and returns the target URL to support the Redirect.ashx handler. Unlike the opens endpoint, it receives a Guid for a specific link, looks it up with the LinkInfoProvider’s GetLinkInfo method, and then looks up the IssueInfo. Next, it logs the click, so that marketers know the subscriber clicked the link, and finally, it looks up the URL associated to the link and returns it to the headless website. Here’s some simplified sample code, with error checking and structure removed:
var linkInfo = LinkInfoProvider.GetLinkInfo(linkGuid);
var issueInfo = IssueInfoProvider.GetIssueInfo(linkInfo.LinkIssueID);
var newsletterInfo = NewsletterInfoProvider.GetNewsletterInfo(issueInfo.IssueNewsletterID);
var linkTarget = linkInfo.LinkTarget;
var subscriberInfo = SubscriberInfoProvider.GetSubscriberByEmail(email, issueInfo.IssueSiteID);
return new EmailContentMacroResolver(new EmailContentMacroResolverSettings
Subscriber = subscriberInfo,
Newsletter = newsletterInfo,
Issue = issueInfo,
Site = SiteContext.CurrentSiteName
The browserviews endpoint is very similar to the others. It validates the email hash, and looks up the IssueInfo, NewsletterInfo, and SubscriberInfo. Then it uses Kentico’s EmailViewer class to create the email body and return it to the headless website.
var emailBody = EmailViewer(issueInfo, newsletterInfo, subscriberInfo, false).GetBody();
Supporting the email tracking links in a headless architecture is a very straight forward process, thanks to Kentico’s well-structured API. This is another example of how Kentico shines in a headless architecture. Without Kentico’s robust API and extensibility, a quality in which other platforms fall short, the headless architecture would not be possible. This makes all the difference for our enterprise customer to be able to adopt and leverage Kentico EMS for its content management and online marketing capabilities.