Ever since Amazon launched their "Simple Email Service" (SES), I've been wanting to try it out. Yesterday, I finally got around to sending my first test message. I used a PHP class created by Dan Myers based on one created by Donovan Schonknecht. But I wasn't quite satisfied with it.

The biggest shortcoming is that it doesn't support the "SendRawEmail" API call, which means that it can't send emails with attachments.

So, being a programmer (one who's worked on an email client and a spam filter in past lives), I went to work and added that feature (plus some little performance optimizations, support for adding arbitrary email headers, features designed to make it more useful with large mailing lists, etc.)

And here it is, free to download: Amazon SES PHP class.

For information about how to use it, first visit Dan's page. Then read on to see the features I added.

How to Use the SendRawEmail Feature

Here's an example of how to send an email with a JPEG image attached:

require_once('ses.php');
$ses = new SimpleEmailService('YourAccessKeyIDGoesHere', 'YourSecretKeyGoesHere');
$m = new SimpleEmailServiceMessage();
$m->setFrom('sender-address@example.com');
$m->addTo('recipient-address@example.com');
$m->setSubject('This is a Test');
$m->addRawMessageFromString('text', 'This is the text message', 'text/plain');
$m->addRawMessageFromString('html', '<b>This <i>is</i> the HTML</b> message', 'text/html');
$m->addRawMessageFromFile('attachment1', 'my-picture.jpeg', 'image/jpeg');
$ses->sendEmail($m);

A few important notes:

  • If you call "addRawMessageFrom*" functions, any messages you added using the old "setMessageFrom*" functions will be ignored. So be sure to add your text and/or HTML messages using the "addRawMessageFrom*" functions.
  • If you want to send the same message to multiple people, and you want each person to see only their own address in the "To" header (ie. you don't want to reveal everyone's email address to everyone else, but you don't want to put them in BCC headers), you can do so by removing any the old recipients, adding any new ones, and sending again. For example:
    require_once('ses.php');
    $ses = new SimpleEmailService('YourAccessKeyIDGoesHere', 'YourSecretKeyGoesHere');
    $m = new SimpleEmailServiceMessage();
    $m->setFrom('sender-address@example.com');
    $m->addTo('recipient-address@example.com');
    $m->setSubject('This is a Test');
    $m->setMessageFromString('This is the message body.');
    $ses->sendEmail($m);
    $m->clearTo();
    $m->addTo('next-recipient-address@example.com');
    $ses->sendEmail($m);
  • Taking it a little further, when using the SendRawEmail method, if the message body includes personalization, you can replace it by calling one of the "addRawMessageFrom*" functions with the same first parameter. (When sending messages with attachments to many recipients, this improves performance because any attachments only have to be processed once to prepare them for transmission.) Here's an example (note that you don't have to remove the old message -- since the first parameter is "text" both times addRawMessageFromString is called, the second one overwrites the first):
    require_once('ses.php');
    $ses = new SimpleEmailService('YourAccessKeyIDGoesHere', 'YourSecretKeyGoesHere');
    $m = new SimpleEmailServiceMessage();
    $m->setFrom('sender-address@example.com');
    $m->addTo('recipient-address@example.com');
    $m->setSubject('This is a Test');
    $m->addRawMessageFromString('text', 'Hey Joe, what do you know?', 'text/plain');
    $m->addRawMessageFromFile('attachment1', 'my-picture.jpeg', 'image/jpeg');
    $ses->sendEmail($m);
    $m->clearTo();
    $m->addTo('next-recipient-address@example.com');
    $m->addRawMessageFromString('text', 'Hey Curly, what up dude?', 'text/plain');
    $ses->sendEmail($m);
  • I came across one surprising limitation imposed the the SES service: you can't attach ZIP files to emails. When the service first launched, amazingly, it didn't support attachments at all. Now it supports a pretty good variety of types (you can find a list here). But ZIP isn't among them. Hopefully Amazon will add support for it later. Note that both the MIME type and the filename of the attachment must match what's shown in the documentation for the file to be accepted.

With this piece in place, I'm ready to start building my own custom mailing list management system that I can add features to to my heart's content.

Reader Comment:
Woodgate said:
Hi, Now Amazon SES supports ZIP files :-) http://docs.aws.amazon.com/ses/latest/DeveloperGuide/mime-types.html
(join the conversation below)

The problem with being a programmer is that you know what's possible, so when you're using a service provider that doesn't do what you want, you're always tempted to sink a bunch of time into rolling your own custom solution.

The good thing about being a programmer is that if you do a good enough job of it, you end up with a product you can sell (which is what happened for me with CaRP Evolution, ExPop, SEO Content Factory...and so on. We'll see whether that's what comes of this effort.