Cloud to Cloud: Using AWS Simple Email Service from Force.com

Amazon released a really interesting service not too long ago called Simple Email Service (SES). It allows you to send individual or bulk emails without having to rely on your own mail servers. This is important because sending (legitimate) mass emails while staying off spam blacklists like Spamhaus is no simple task, and you don’t want all of your company emails to start being blocked by ISPs that subscribe to those blacklists. If you have all of your customer data in Salesforce.com, you’ll be able to email some of them with Salesforce’s standard email capabilities, but they have pretty strict governor limits (1,000 emails per SFDC License) when it comes to sending external emails, so mass emailing is often not a possibility without a third-party provider.

Reasons why you may want to consider using SES

  1. Ever receive an email from Amazon.com? Yeah, so has everybody else. They know a thing or two about sending out mass emails.
  2. Their pricing is ridiculously competitive. Other mass email services start out around $15 per thousand emails. Amazon charges $0.10 per thousand. Of course, other services offer more in the way of campaign management, point-and-click setup, and analytics, but if you’re just sending emails, it’s hard to beat the price.
  3. It’s relatively easy to use. Emails are sent through simple RESTful API calls.

Getting set up

So assuming you’re already an AWS member, first off you have to sign up for SES. That will get you set up with a developer account relatively quickly, and you can test sending emails to a few email addresses with the ses-send-email.pl script that comes with the AWS SES Developer Tools. If you want to actually start sending out mass emails, you have to then request production access from Amazon.

Sending emails from Force.com

First off, get the Apex code here.

Then, take a look through the files:

AWS.cls

This is a top-level abstract class that has a few methods in it that you’ll need for any AWS functions. This includes the code to generate a signature from the current Date/Time and your AWS Secret Key:

public string signature(String awsNow, String secret) {

     system.assert( secret != null ,‘ missing S3.secret key’);

     Blob bsig = Crypto.generateMac(‘HmacSHA256′, Blob.valueOf(awsNow), Blob.valueOf(secret));          

     return EncodingUtil.base64Encode(bsig); 

And the code to generate the authorization header using that signature:

public string headerForAmazonAuthorization(String accessKey, String signature)

{

return ‘AWS3-HTTPS AWSAccessKeyId=’+accessKey+’, Algorithm=HmacSHA256, Signature=’+signature;

}

SES.cls

Being an abstract class, AWS.cls is then subclassed by SES.cls. This includes the method to actually send an email by setting the HTTP headers and body, and sending the request to the SES endpoint. To use this, you just need to send in a List of recipient addresses, your from: address, a subject, and a body for the email. The response from AWS is then written to the debug log, so you can see any error messages sent back by Amazon.

SESEmail.cls

The SESEmail class defines a single SES Email message with multiple recipients, a sender, a subject, and a body, and it takes care of URL Encoding all of that and setting up the Body of the request to Amazon.

AWSKeys.cls 

So this one I didn’t actually write. I got it from the Force.com AWS Toolkit. Mostly it just reads your AWS Access Key and Secret Key from a custom object. The authentication code in that toolkit is a bit out of date for the current version of the AWS API, and I did modify this class to be a singleton so a DML statement doesn’t get kicked off every time you query for your AWS Keys. If you’re using this, you’ll probably also want to make the AWSKey__c SObject private so your entire org doesn’t have access to your AWS keys, but I’ll leave that as an exercise for the reader.

SESController.cls

Last, and I’ll be honest, least, is a dummy VF Page and controller that connects the dots and sends off emails using SES. The page is a pretty simple page that calls the controller:

And sends an email to a List of recipients:

AWSKeys awsKey = AWSKeys.getInstance(AWSCredentialName);
SES sesEmail = new SES(awsKey.key,awsKey.secret);
List recipients = new List();
recipients.add(‘nobody@modelmetrics.com’); 
String sender = ‘nobody@modelmetrics.com';
String subject = ‘Test message';
String body = ‘This is the body of the message';
sesEmail.sendEmail(recipients,sender,subject,body);

That’s it. Relatively easy. Adding test classes is left as an exercise for the reader ;-).

tomgersic Avatar

tomgersic

Tom Gersic is a respected industry leader who is responsible for strategic work with many of the worlds largest and most well-known enterprise companies.

Website