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
A few things I learned to keep in mind:
- The reply-to address also has to be verified, just like the sending address.
- As a new account with Production Access, you’ll have a 1,000 message per day quota.
- 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.