Transactional Emails for Fun and Profit
I love APIs. A well-defined API can make short work of a complex problem. It’s even more fun when you find a cool API with a great wrapper to make it simple to use. That’s what I found when I started playing with Amazon’s Simple Email Service; a tool that was easy to work with, solved a problem I needed solved, and had a simple to use PHP wrapper.
The Problem to Be Solved
I have been running mail servers since the late 90’s. I was always very proud of the fact that I could read and write an exim config file (Exim being my MTA of choice). Recently though, I have come to the conclusion that there are things more interesting in life than tweaking a config file. I’ve handed off most of my mail server responsibilities to services like Gmail and have been happy to do so. There are times, however, when having access to a mail server is a good thing; sending transactional emails from an application is one of those times.
PHP’s built-in mail() function is fine if you have an MTA installed. There are several good and very small ones you can install on Linux to take care of just sending mail, if that’s all you need. However, I am doing my best to get out of that business and let people that know more deal with it. So when Amazon announced they were opening up Simple Email Service (SES), I was intrigued. This seemed to be an excellent solution for allowing web-based applications send emails without having to worry about the details. Recently, I began working on a small e-commerce system to sell one of my books online. I decided this was a great time to put SES to the test.
While Amazon provides a PEAR package that is a wrapper to their entire API library, looking at it, I quickly decided it was over-engineered for what I needed. I wanted something simple. A quick trip to Google showed me that I wasn’t the only one who thought this way, and I came up with a great little library, SES, written by Dan Myers. Installing it is as simple as dropping the file in a directory in PHP’s include_path. Getting going with Amazon’s SES proved to be a little more difficult, but not an insurmountable obstacle.
If you already have an Amazon Web Services (AWS) account, getting SES requires a few steps and Amazon’s explicit approval. Follow the instructions in your AWS Management console to get approval. To be able to do more than just send from and to approved email addresses, you will have to request permission to exit “sandbox” more. Click the button and follow the instructions; it’s not difficult, but it will take several hours or even a day to get approved (in my case, about 4 hours).
While you are waiting for approval, you need to register at least one email address as a “Verified Sender”. This is the email address that your emails will come from. Amazon wants to know that it is real and that you own it. Registering an email address will send you an email with a link to click to prove you own the address.
Once you’ve completed those steps and you’ve been approved, using the API is easy. Using the wrapper discussed above, you simply instantiate the SES object, create a new message, populate the necessary properties and call the sendEmail() method. Here’s an example:
$copy = file_get_contents('email.html');
$ses = new SimpleEmailService($aesKeys['access_key'], $aesKeys['secret_key']);
$message = new SimpleEmailServiceMessage(); $message->addTo($person['emailAddress']); $message->setFrom('email@example.com'); $message->setSubject('Thank you for purchasing Avoiding a Goat Rodeo'); $message->setMessageFromString($copy);
As you can see, it’s not difficult at all. What looks like a normal SMTP transaction is really just a curl call to a URI, wrapped in a pretty OO interface.
This is a question you will have to answer for yourself. For me, I have three reasons for using SES
I like APIs. I can cheaply and easily hand off the bother of sending transactional emails to someone else, and I can concentrate on doing what I do best…whatever that is.
By not relying on an MTA script or service running on my server, I can easily move this application to another server. My application only needs PHP and PHP’s curl.
By not running an MTA on my server, I can close one more hole in my firewall. I am a big fan of “fewer moving parts”. By letting Amazon worry about running and securing the MTA, that’s one less thing I have to worry about.
In researching this article, I was given advice from a few friends about SendGrid. SendGrid was around before Amazon SES and is largely respected as a better solution in many cases. I will admit that I am not trying to build a bulk email system. I would be happy if I could get my little system up to 5 emails a day. I looked at SendGrid and for transactional emails, they did not offer me anything that I couldn’t get from Amazon SES. I am not interested in tracking stats on these emails, just deliverability – which SES gives me. If you are looking to do more than simple transactional emails or if stats are important to you, I recommend you look at SendGrid.
Like all of Amazon’s Web Services, SES seems to be a well thought out solution to a known problem. I used to work for a large datacenter where we had customers that would send thousands of transactional emails weekly. It was always a challenge to keep the mail servers up, keep them from getting blocked, and deal with the inevitable hiccups. Amazon hasn’t really broken new ground here, at its heart, it’s just an MTA. That having been said, because it’s not MY MTA, I don’t have to worry about it. I can just fire off the emails, store the resulting IDs and keep going about my business.