Exploring Email Tracking with Amazon SES and CloudWatch


Every WordPress site sends emails (like notifications for comments, updates, and new users), but there’s no tracking for them. This makes it hard to know if your emails are getting opened or clicked, or if they are just sitting unread in someone’s spam folder.

This may not be a problem for a quiet site that sends out a rare password reset or comment notification, but busy sites that send out hundreds or even thousands of emails a day need a way to track them in order to see if the emails are effective and being read.

For this week’s article I take a look at email tracking with Amazon SES and CloudWatch, and find out if it’s a good solution in conjunction with our newly-acquired (and free) WP SES plugin.

How Email Tracking Works

First, let’s take a look at how email tracking works. When you send a regular email, through WordPress or otherwise, there’s no way to tell if it was opened or clicked – the email protocols simply don’t have that capability. Luckily, there are a few workarounds that will get the job done.

On the most basic level, tracking email opens works by inserting an image that is stored on a server (in this case, Amazon) into the email. When the email is opened, the image loads from the server and the server logs the email as being opened. Usually, the image loaded is a discreet 1-pixel transparent image (also known as a tracking pixel), so that it doesn’t interfere with the layout of the email.

This won’t work if the recipient has images disabled in emails or if emails are sent as plain text, so the technique isn’t 100% foolproof. However, this remains the most common and effective way to track email opens.

Tracking link clicks works in a similar way – links are generated in such a way that they first go to a server that logs the link as clicked, and then redirects to the actual URL requested. Often URL shorteners are used, so that smaller and tidier links can be used while tracking clicks at the same time.

Email Tracking with Amazon SES

Amazon SES recently started offering email tracking, which integrates with Amazon CloudWatch and/or Amazon Simple Notification Service (SNS). I thought it’d be a perfect compliment to our WP SES plugin, so I dove right in.

To enable the open/click tracking, you need to create a configuration set in your AWS SES console so that SES knows to track the open/click events and publish them to your provided destination.

To set this up I created a configuration set called “Engagement” and added CloudWatch as a destination:

Adding a CloudWatch destination

For the event types, I selected “Send”, “Click”, and “Open”, as these were the metrics I was interested in having graphed. For the sake of simplicity I opted to use Amazon’s domain for the open and click tracking, but it’s nice to know that you have the option of using your own domain as well.

Then I ran into my first hurdle. It was asking for a “Dimension Name” and “Default Value”, and I had no idea what those were. After reading and rereading the docs on the subject, I realized that I should be specifying the use of a configuration set as the Dimension Name and its name as the Default Value.

After figuring that out, I realized that the WP SES plugin doesn’t support setting custom headers, which are needed to specify the SES configuration set created earlier. To get around this I edited the WP SES plugin to support custom headers, which was surprisingly easy and may be released in a future update once properly tested.

I was then able to add the necessary email headers to let SES know that the emails being sent out should be tracked:

function ses_wp_mail_headers( $mail ) {
    $mail['headers'] = "X-SES-CONFIGURATION-SET: Engagement";
    return $mail;
add_filter( 'wp_mail', 'ses_wp_mail_headers' );

With that in place, Amazon started inserting the tracking pixel and converting links to trackable URLs, with one exception: WordPress notification emails weren’t being tracked. After further investigation I realized that this was happening because WordPress doesn’t send out emails as HTML, and sends them out as plain text by default. It is possible to override the content-type that WordPress uses, but this has the unfortunate side effect of breaking the formatting of WordPress notification emails since they aren’t coded to use HTML:

Broken WordPress site email

This means that you’d either need to customize the notification emails yourself or use another plugin to customize them for you. I tested out the well-reviewed WP HTML Mail plugin, and it seems to be just the tool for the job. The notification email templates provided by the plugin look great, and it even sets the correct content type for you.

After installing that, emails were finally being tracked by Amazon! I logged into CloudWatch and created a custom dashboard to view the events. To do this, I created a “Line Graph” widget so I could see a graph of the send, open, and click rates over time. Then I selected the Engagement metrics that I had set up earlier and marveled at my handiwork:

SES engagement graph in CloudWatch


Despite managing to get it set up, I can’t say I recommend using Amazon’s tracking in conjunction with WordPress and WP SES. It’s a lot of work to set up, doesn’t work with the default WordPress site notifications, and you don’t get a very detailed graph unless you add a lot of custom metrics – driving up the price of CloudWatch. Perhaps the most frustrating aspect of this was Amazon’s documentation, which I found to be vague and lacking specific examples. This led to a lot of trial and error, and I was constantly questioning myself if there was a better way to set things up.

The good news is that our up-and-coming revamp of WP SES, WP Offload SES, will handle click and open tracking out-of-the-box, so you won’t have to set anything up or pour through pages of Amazon’s technical documentation. It will also allow you to view the open/click rate by subject line, and eventually support viewing stats for specific emails or email addresses.

Are you tracking your site emails already? How have you set it up? Have you ever tried to do it with SES? Let us know in the comments.

About the Author

Matt Shaw

Matt is a WordPress plugin developer located near Philadelphia, PA. He loves to create awesome new tools with PHP, Javascript, and whatever else he happens to get his hands on.