Integrating with Amazon Simple Email Service (SES)

Amazon recently announced the release of their Simple Email Service for use by developers.  In doing so, Amazon opens up a pay-as-you-go email sending mechanism that is tailored for application developers.

Sending system generated email messages has always proven to be a challenge for developers.  It’s not for lack of means to do so, it’s dealing with a multitude of anti-spam safeguards imposed by ISPs and hosting providers.  Some block outbound sending altogether, and many throttle the number of messages that can be send per day/hour/minute.

Amazon’s SES provides a great deal of infrastructure, and uses a variety of proven methods to help ensure deliverability of your message.  Their quota system is dynamic, so the more you prove your messages are legitimate, the more you can send.

Setting up your SES account.

If you already have an Amazon Web Services account, adding on the Simple Email Service is pretty straightforward.  You’ll get a confirmation email from Amazon to click through and activate the service.  Initially, you’ll be set up in a Sandbox, and there is a process for requesting Production Access.

Getting your Access Keys

After you have enabled the service, you’ll need a set of credentials to use it.  Again, if you already have an AWS account, you’ve probably got your Access Keys set up already.  Like any credentials, keep them safe and secure.  If someone were to gain access to your AWS keys, they could send email through SES without your knowledge.

Verifying an email address.

Before you can send outbound messages through SES, you have to verify the source email address.  Amazon provides a small collection of scripts used to communicate via command line to the SES services.  Follow the Getting Started guide’s instruction to prepare a file containing your AWS Access Keys and verify a sending address.  SES will generate a response email to the address you are verifying, within which is a link you’ll have to click in order to complete the verification.

Downloading the Amazon Web Services API.

Amazon offers a couple of methods for leveraging the SES API.  You can use the scripts downloaded to verify your source address to also send messages.  I chose, however, to use their packaged .NET SDK library.  It contains wrappers for all of Amazon’s Web Services, including the SES.

After downloading and unpacking the SDK, you can add a reference to the AWSSDK.dll assembly to your project.

Using the SES API methods.

Creating and sending email via the SDK then becomes a matter of setting up the outbound SES message object and sending it through the API.  The following method takes a standard .NET MailMessage object and translates it to a SES message, then sends it along.

Public Function SendMessage(ByVal message As System.Net.Mail.MailMessage) As String Implements Core.DataInterfaces.IMailServer.SendMessage

            If String.IsNullOrEmpty(_accessKey) Or String.IsNullOrEmpty(_secretKey) Then Throw New Exception("API Credentials are required to use this provider.")

            Dim ses As New AmazonSimpleEmailServiceClient(_accessKey, _secretKey)

            Dim messageToSend As New Amazon.SimpleEmail.Model.SendEmailRequest

            'set up addresses
            messageToSend.Destination = New Amazon.SimpleEmail.Model.Destination

            For Each toAddress In message.To
                messageToSend.Destination.ToAddresses.Add(toAddress.Address)
            Next

            For Each ccAddress In message.CC
                messageToSend.Destination.CcAddresses.Add(ccAddress.Address)
            Next

            For Each bcAddress In message.Bcc
                messageToSend.Destination.BccAddresses.Add(bcAddress.Address)
            Next

            'set reply to
            If message.ReplyTo IsNot Nothing Then
                messageToSend.ReplyToAddresses.Add(message.ReplyTo.Address)
            End If

            'set subject line
            messageToSend.Message = New Amazon.SimpleEmail.Model.Message
            messageToSend.Message.Subject = New Amazon.SimpleEmail.Model.Content().WithData(message.Subject)

            'set message body
            If message.AlternateViews.Count > 0 Then
                Dim messageBody As New Amazon.SimpleEmail.Model.Body()

                For Each view In message.AlternateViews
                    Dim viewStream = view.ContentStream
                    Dim viewData(viewStream.Length) As Byte
                    Dim viewContent As String = System.Text.Encoding.ASCII.GetString(viewData, 0, viewStream.Read(viewData, 0, viewData.Length))

                    If view.ContentType.MediaType.Equals("text/html") Then
                        messageBody.Html = New Amazon.SimpleEmail.Model.Content(viewContent)
                    Else
                        messageBody.Text = New Amazon.SimpleEmail.Model.Content(viewContent)

                    End If
                Next

                messageToSend.Message.Body = messageBody
            Else
                messageToSend.Message.Body = New Amazon.SimpleEmail.Model.Body(New Amazon.SimpleEmail.Model.Content(message.Body))
            End If

            'set from address
            messageToSend.Source = message.From.Address.ToString

            'send message
            Dim sendResponse As Amazon.SimpleEmail.Model.SendEmailResponse

            sendResponse = ses.SendEmail(messageToSend)

            Return sendResponse.SendEmailResult.MessageId

        End Function
    End Class

Lessons Learned

A few things I learned to keep in mind:

  1. The reply-to address also has to be verified, just like the sending address.
  2. As a new account with Production Access, you’ll have a 1,000 message per day quota.
  3. There is a Send Rate limiter for the number of messages per second.  You’ll have to account for this limit in your code to ensure that it doesn’t fail mid-way through your batch of messages.

Amazon’s service is easy to use, economical, and capable.  I probably won’t replace every outbound message instance with SES, but definitely for cases where I need to generate larger batches (such as monthly newletters or maintenance reminders) I will leverage SES.

About the author

derek Derek Smith is a software developer with 20 years of history developing on the Microsoft platform. He is the founder of HomeSpot HQ, and is the Director for Microsoft SharePoint Professional Services at rmsource, inc. in Raleigh, NC. Derek is on Twitter, , and Linked In

1 comment for “Integrating with Amazon Simple Email Service (SES)

  1. Hemlata Mehta
    April 14, 2011 at 1:32 am

    Sir,

    Can you give a suggestion how i add header and attachment with sendRawEmail code.

    When I was trying to attach then it give illegal header error.

    Thank You.

Leave a Reply