Send emails with Amazon SES from inside your app

It’s been almost two years since I decided to move to Amazon SES for sending emails and I couldn’t be happier. Depending on the projects I’m running, there are times I need to send at least 50.000 emails per month. Here’s a starting guide for developers, written in PHP.

Without services like Amazon SES, email infrastructure can be too expensive for many of us to run. And I don’t even want to think about how time consuming maintaining it is. Once you add the deliverability trouble, outsourcing emails to an external service starts looking more attractive. You don’t want your emails landing in SPAM folders or being rejected, do you?

Sure, you can send emails through Gmail if you don’t mind the 500 messages-per-day limit. But there are many services that lift up the burden of running your own infrastructure and can send hundreds of thousands emails in a few minutes. Mandrill (recently acquired by MailChimp), Mailgun, Postmark to name a few.

For the sake of this guide, however, I’ll be picking the most cost-effective and bare-bones of them all. Enter Amazon SES (Simple Email Service).

It’s a service built on top of the same infrastructure that keeps Amazon.com up and running. It has a no commitment pay-as-you-go plan that’s very fitting to small companies, startups, and individual developers (like me!). For comparison, sending 50.000 emails through MailChimp would cost a staggering $500 bill ($0.03 per email). The equivalent with Amazon SES is $5 ($0.0001 per email) .

This guide presumes you have

  • a hosted web server
  • basic knowledge of DNS settings
  • knowledge of PHP
  • a domain name

We will setup an AWS account, authenticate our domain name (SPF, DKIM) and then go through the basics of sending an HTML email message using the PHPMailer class (SMTP also supported)


Step 1 — Create and configure an Amazon Web Services account (AWS)

If you don’t already have an AWS (Amazon Web Services) account, sign up. You should also check out AWS Free Tier that includes a 12-month free EC2 server instance and other services for developers to try out.

Once you have created an AWS account, you need to create your IAM credentials.

Sign in to the Console. Make sure you’re in the correct region (ie. EU Ireland, EU London, US East Ohio etc). Each has its own settings. In this guide, I’ll be using EU Ireland. Make sure you stick to whichever you choose throughout this guide.

Click on Services and choose IAM. You will be transferred onto that service’s control panel.

Screen Shot 2016-12-18 at 04.19.57

From the sidebar choose Users. We’ll need to create a new pair of API keys, so choose Add User.

Choose a username (in this guide we’ll be using ses-test) and enable Programmatic Access under the Access Type section.

 

Screen Shot 2016-12-18 at 04.23.50.png

In the next step (Permissions), we will need to allow this user to access the Simple Email Service as well as the Simple Notification Service.

Through the Attach existing policies directly option, search for sesf and snsf and enable both of them for this user.

Setting permissions on Amazon IAM for new Amazon SES account

After reviewing your settings, complete creating the user. You’ll need to write down the Access Key ID and the Secret Access key. We will be using them later on.

Creating credentials for Amazon SES on IAM service


Step 2 — Setup your domain name and verify it with Amazon

Start by logging into the AWS Console. Enter the SES control panel. On the sidebar, choose under Identity Management the option Domains and then Verify a New Domain.

Type in your domain name and enable Generate DKIM Settings.

Verifying your domain name on Amazon Web Services

This should produce a set of TXT values for your DNS Records. Download them as .CSV. Depending on your DNS control panel, you should set those records according to the values inside the CSV.

For example,

_amazonses.dimis.me

should be a TXT record with a value of

AkgdGIaFswOha+this_isJustanExample/qgqBVk=

That will verify you as the rightful owner of the domain with Amazon.

You will also need to authenticate Amazon to send emails for your behalf for the rest of the world. That’s done through DKIM and SPF.

The SPF record should be easy to do. Just create a TXT record with the value:

v=spf1 include:amazonses.com -all

Some control panels, including CPanel and GoDaddy, might have already created a generic version of SPF for you. Please check with them on how to edit it.

Next up, the DKIM values are generated for you within the domain’s settings in Amazon SES’s control panel. Once you’ve updated your records to reflect them, make sure to enable DKIM. The verification process might take a while.

Amazon SES Configuration DKIM and Authentication

More information at Amazon Documentation webpage.


Step 3 — Using the PHPMailer class with Amazon SES

PHPMailer is a handy class written in PHP that lets you send emails using SMTP or other protocols.

If you’re looking for support in other languages, there are plenty of libraries around. SES also supports SMTP just fine — you just need to create the appropriate credentials in the control panel.

Download the example code from GitHub.

Inside class.amazonses.php I’ve set the region to EU Ireland. You should change that depending on which region you setup your SES account earlier.

The example.php is pretty much self explanatory. Enter the KeyID and Secret Key you generated earlier in Amazon IAM. In setFrom make sure to enter an email address under the domain you’ve verified.

The message is contained in the file index.html. This is loaded as a string and can be any HTML file or text.

// Set mailer to use AmazonSES.
$mail->IsAmazonSES();
//$mail->Debugoutput = 'html';
// Set AWSAccessKeyId and AWSSecretKey provided by amazon.
$mail->AddAmazonSESKey("ENTER YOUR KEY ID", "ENTER YOUR SECRET KEY");
    
$mail->setFrom('FROM@VERIFIEDDOMAINinAMAZON.com', 'Name of the Sender');
$mail->addAddress('RECEIPIENTS EMAIL ADDRESS');
$mail->Subject = 'Set your Subject';
$html_code = file_get_contents('index.html');
    
//echo json_encode($_GET);
$mail->msgHTML($html_code, dirname(__FILE__));
//send the message, check for errors
$mail->send();

Running example.php should now successfully send your message! For more information on PHPMailer, check out the project’s documentation on GitHub .

Newly created Amazon SES accounts have a maximum of 200 emails per day limit. To change that, you should follow the guide in your AWS account and request from Amazon to change your quota to whatever you deem reasonable. You’ll need to explain why you need to send that many emails and provide them with a short case scenario. Be honest and reasonable and don’t ask for more than you’re actually planning on sending. You can increase your quota later on if the need arises.