Amazon have just released a beta of a new service called Amazon Simple Email Service (SES) that allows you to send out emails with saleability. I’m not here to discuss the service itself, so you can read more information about it here. You can also view more information about the APIs here and sign-up for it here.
Whilst the service is in beta, you can only send emails to the email addresses that you have verified (I’ll discuss how this is done later!) unless you request production access from Amazon.
Note: I created a AWS Console project in Visual Studio which is available to me because I have the AWSSDK.NET installed. During creation this asks for you AWS Keys and places them in the app.config file and is referenced in my code via AppConfig[ ] and
private static readonly NameValueCollection AppConfig = ConfigurationManager.AppSettings;
Listing Verified Email Address
This method will return a String List (List) of each email address that has been verified with Amazon. I’m showing this method first as I use it later when verifying email addresses to prevent re-verifying an already verified email address.
public static void ListVerifiedEmailAddresses() { List<String> verifiedEmailAddresses = GetVerifiedEmailAddresses(); if (verifiedEmailAddresses.Count > 0) { Console.WriteLine("Verfied email addresses: \n"); foreach (String verifiedEmailAddress in verifiedEmailAddresses) { Console.WriteLine("\t" + verifiedEmailAddress); } } else { Console.WriteLine("No email addresses have been verified."); } Console.WriteLine(); } public static List<String> GetVerifiedEmailAddresses() { AmazonSimpleEmailService ses = AWSClientFactory.CreateAmazonSimpleEmailServiceClient(AppConfig["AWSAccessKey"], AppConfig["AWSSecretKey"]); ListVerifiedEmailAddressesRequest request = new ListVerifiedEmailAddressesRequest(); try { ListVerifiedEmailAddressesResponse response = ses.ListVerifiedEmailAddresses(request); ListVerifiedEmailAddressesResult result = response.ListVerifiedEmailAddressesResult; List<String> verifiedEmailAddresses = result.VerifiedEmailAddresses; return verifiedEmailAddresses; } catch (Exception ex) { Console.WriteLine(ex.Message); return new List<String>(); } }
The first method above, ListVerifiedEmailAddresses(), is just to output the results, if any, line by line to the console. The main work is done by the second method, GetVerifiedEmailAddresses() which returns the String List of verified email addresses.
Lines 24 to 26 create my client connection to SES fetching my AWS Keys from the app.config file as mentioned in my note above.
Lines 28/29 create a new ListVerifiedEmailAddressRequest request that we will use when talking to the SES service.
Lines 33/34 passes the request to the SES service and gets the response from the service as a ListVerifiedEmailAddressResponse. This response contains the result that we then get to via lines 36/37 and 39/40 before returning the String List.
These last few lines could be compacted down, but I have left them in this form to show how it all relates together and for tidier code on this blog.
Verify Email Address
Before you can send an email through SES, you must verify the email address the service will send the email from. When you talk to the service to verify an email address it will send an email to the address with a link that the recipient uses to verify the email address. Until this is done, the email address will not show in the Verified Email Address list the code above retrieves.
My method below includes some console output which I won’t discuss in detail.
public static Boolean VerifyEmailAddress(String emailAddress) { List<String> verifiedEmailAddresses = GetVerifiedEmailAddresses(); if (!verifiedEmailAddresses.Contains(emailAddress)) { AmazonSimpleEmailService ses = AWSClientFactory.CreateAmazonSimpleEmailServiceClient(AppConfig["AWSAccessKey"], AppConfig["AWSSecretKey"]); VerifyEmailAddressRequest request = new VerifyEmailAddressRequest(); request.WithEmailAddress(emailAddress); try { VerifyEmailAddressResponse response = ses.VerifyEmailAddress(request); Console.WriteLine("An email has been sent for verification."); Console.WriteLine("Click link in email to verify"); Console.WriteLine(); Console.WriteLine(String.Format("Request ID: {0}", response.ResponseMetadata.RequestId)); return true; } catch (Exception ex) { Console.WriteLine(ex.Message); return false; } } Console.WriteLine("Email address already verified."); return true; }
As I mentioned earlier, I use the GetVerifiedEmailAddresses() method that I discussed in the previous section of this blog to get a list of currently verified email addresses (Lines 3/4). On line 6 I then check to see if the list contains the email address I am trying to verify now. If it does, we don’t need to re-verify it. I haven’t done any checks for case-sensitive email addresses, but I’m sure you could easily add this!
If it’s not in the list of verified email addresses, then I get a connection to the SES service again with lines 8-10. Lines 12-15 build my request to verify an email address. Line 15 being where we actually specify the email address we are verifying in the request.
Lines 19/20 then communicate with the SES service and get back a response. This response only contains a Request ID. If this was successful then an email will have been sent to the email address specified with a link to verify the email address with Amazon.
If the email address was already in the list then we output a relevant message to the console and return from the method.
Once you have clicked this link and the email address has been verified with Amazon, then the address will appear in the List Verified Email Address methods above.
Sending Email
Now that we have a verified email address, we can start to use the service. As I mentioned above, unless you request otherwise, Amazon will only allow you to send emails to the verified email addresses.
public static Boolean SendEmail(String From, String To, String Subject, String Text = null, String HTML = null, String emailReplyTo = null, String returnPath = null) { if (Text != null && HTML != null) { String from = From; List<String> to = To .Replace(", ", ",") .Split(',') .ToList(); Destination destination = new Destination(); destination.WithToAddresses(to); //destination.WithCcAddresses(cc); //destination.WithBccAddresses(bcc); Content subject = new Content(); subject.WithCharset("UTF-8"); subject.WithData(Subject); Content html = new Content(); html.WithCharset("UTF-8"); html.WithData(HTML); Content text = new Content(); text.WithCharset("UTF-8"); text.WithData(Text); Body body = new Body(); body.WithHtml(html); body.WithText(text); Message message = new Message(); message.WithBody(body); message.WithSubject(subject); AmazonSimpleEmailService ses = AWSClientFactory.CreateAmazonSimpleEmailServiceClient(AppConfig["AWSAccessKey"], AppConfig["AWSSecretKey"]); SendEmailRequest request = new SendEmailRequest(); request.WithDestination(destination); request.WithMessage(message); request.WithSource(from); if (emailReplyTo != null) { List<String> replyto = emailReplyTo .Replace(", ", ",") .Split(',') .ToList(); request.WithReplyToAddresses(replyto); } if (returnPath != null) { request.WithReturnPath(returnPath); } try { SendEmailResponse response = ses.SendEmail(request); SendEmailResult result = response.SendEmailResult; Console.WriteLine("Email sent."); Console.WriteLine(String.Format("Message ID: {0}", result.MessageId)); return true; } catch (Exception ex) { Console.WriteLine(ex.Message); return false; } } Console.WriteLine("Specify Text and/or HTML for the email body!"); return false; }
This method is the longest of the lot. Mainly because of the way that the email request is constructed. This method along with the others contains sloppy coding, but is just for example purposes so I’ll let this pass
I’ve included some default values in my method some of which are not required to send an email. HTML & Text are required, but at least only one of them is. This is why I gave them defaults so I can check if either has been specified and give back an error message if they aren’t. This is done on lines 5/6.
For To and ReplyTo I use a input type of String, but in my method I convert them to String Lists separating the email address with at the ‘;’ character. So a list of emails to send to would be passed to the method like “email@domain.com; email2@domain2.co.uk” etc. This is done on lines 9-13 and 48-52.
First we create a Destination giving it the To addresses on lines 15/16. You can also include any CC or BCC addresss here. I have commented out the code on lines 17/18 where this can be done as I am not using them in the example.
Now we need to create Content for the email itself. We create a Content for Subject (lines 20-22), and the two body types (Text and HTML – lines 24-26 and 28-30) specifying a Character Set of UTF-8 for each. We then create a Body and pass in the Text and/or HTML (both in my example) on lines 32-34.
Then we create a Message which we give our Body and subject Content to on lines 36-38.
Now we have constructed out Destination and Message we can communicate with the service to get the email sent.
As before we connect to the service with lines 40-42 and then create a SendEmailRequest request that we provide with our Destination, Message and out From email address, which is all done on lines 44-47.
If we have provided the optional ReplyTo email address (where replies to the email will be delivered) and the ReturnPath email address (where bounce backs will arrive) we also add these to our service request.
We then pass this request to the service and get back its response on line 67.
From this response we get the result (line 69) which contains a Message ID which we output to the console on lines 71-73 along with an email sent message.
If you check your email you should see it has been delivered!
In my next post I will go through examples of:
- Deleting Verified Email Addresses
- Sending Raw Email
Hope this helps people starting to look at this service. If demand is there I can supply the project code. Let me know in comments below!
Neil
UPDATE: Something I forgot to mention during my original post was that the ReplyTo and ReturnPath email addresses need to be verified also.
UPDATE 2: The latest AWS SDK for .NET seems to depricate the method I used to connect to AWS. Change it to:
AmazonSimpleEmailService ses = new AmazonSimpleEmailServiceClient(awsAccessKeyId, awsSecretAccessKey);
Great post! This seems like a cool new service, and in hunting online for more information on how to effectively use it I found this. It’s nice how people like you take the time to share advice with the rest of us.
Thanks Matthew! Glad you found it of use!
Great post will be sure to link to it from The SES Blog 🙂
@thesesblog Thanks, glad you liked it! I’m really impressed with this service.
Looking forward to SendRawEmail example. I cannot get it to work from C#. I get a “Missing final ‘@domain'” exception.
I’ve been a little busy on other projects, but will hopefully have a look tomorrow and have something up ASAP… stay tuned! 😀
I’ve posted my SendRawEmail example here. Hope its useful, if not maybe you could share your code and I can have a look… 🙂
Error 6 ‘Amazon.AWSClientFactory’ does not contain a definition for ‘CreateAmazonSimpleEmailServiceClient’
how to resolve this issue?
thanks.
Change the line for connection to:
AmazonSimpleEmailService ses = new AmazonSimpleEmailServiceClient(awsAccessKeyId, awsSecretAccessKey);
(adjusting for your own names etc…
here is my code :
Destination destination = new Destination();
destination.WithToAddresses(“mahesh.bhat@advali.no”);
Amazon.SimpleEmail.Model.Message message = new Amazon.SimpleEmail.Model.Message();
message.WithBody(new Body(new Content(“this is amazon mail”)));
message.WithSubject(new Content(“Request for activation”));
AmazonSimpleEmailService ses = AWSClientFactory.CreateAmazonSimpleEmailServiceClient(“awsAccessKey”, “awssecretkey”);
VerifyEmailAddressRequest verifyRequest = new VerifyEmailAddressRequest();
verifyRequest.WithEmailAddress(“4100@esri.com”);
VerifyEmailAddressResponse verifyResponse = ses.VerifyEmailAddress(verifyRequest);
SendEmailRequest request = new SendEmailRequest();
request.WithDestination(destination);
request.WithMessage(message);
request.WithSource(“43242@Test.com”);
SendEmailResponse response = ses.SendEmail(request);
SendEmailResult result = response.SendEmailResult;
At the line
SendEmailResponse response = ses.SendEmail(request);
I get error “Email address is not verified.” Can you please help me on it..
As soon as I am back from vacation I will take a look
When I was looking at the service, all email addresses needed to be verified even the from address. Your code doesn’t verify all if them so please check that first. Error says one isn’t verified….
Great post, I’m thinking about using SES to send transactional emails such as PasswordRecovery emails. Any ideas how to override the default behaviour of ASP.NET PasswordRecovery control to stop them being sent to the SMTP server and send them using SES instead?
Hi Nik,
Thanks.
I’m not familiar with the PasswordRecovery controls so I don’t really know. I did a quick search for you and found these two site, which I hope enlighten you towards achieving your aims:
http://goo.gl/ysXA0
http://goo.gl/ccjlN
Let me know if I can be of further assistance!
Neil
Neil,
Thanks for the write up. I am having an issue when the mail is sent, I am receiving duplicate messages. One has the Return-Path with the message ID of the sent message, the one after that has a new ID. Do you know if there are any issues with this C# API provided by Amazon? I have verified that I am only calling the SendEmail method once, in fact I even copied and pasted code from your example here with the same result. Any ideas?
Hi Erick,
I haven’t used it in a while, so I’d need to re-run my code samples.
They’ve likely changed something somewhere, have you had any joy since your comment was posted?
Neil
Hi Neil,
Is there a way we could give a From Name or is it just the From address that will be displayed.
Thanks in advance
Alonso
Hi Alonson,
It should be possible to have a From Name in the email if you pass the email in like so:
‘My Name ‘
If you get it working, please consider adding a sample in a comment! I’ll add it to the original article then too 🙂 Happy Coding!
HI ,
is it posible to get sent and bounce mails details using AWS
if yes ,how can we get that information from AWS
Thanks
Rehan
Hi,
You will get the bounced email in the mailbox of the from email address. It will have a large delimited hex number before the @ sign that is the same value you get back when sending the email (MessageId). The rest of the email address wil be like: @email-bounces.amazonses.com
What are you looking for “sent mail details”?
There is the GetSendStatistics API call that will give you statistics, or you can view this data in the AWS Console.
http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/ManagingActivity.BounceAndComplaintNotifications.html?r=154
Neil
Neil,
In our application we are sending bulk mails.
After sending these bulk mails,we have to store the details of bounce and sent mails in MS Sql Server .
how can we do this.
Is there any method that returns all the details of emails when we send bulk mails?
Because we going to getting some MessageId after sending mails.By using this can we get the details?
As you said the bounce mails will be in mailbox of the from email address.But our requirement is we have to store that information to Database.
You could store the message Id in the table then have done code else where periodically check the mail server for emails with a matching id and then sore the details in the database.
To get unique id for each email I think you’d need to send each email one at a time rather than all together.
Neil
Hi,
may i get some more information about messageId ?
What is the method available that takes messageId as a paramiter to get EmailDetails whether it may be sent or bounce details.
We need both the details (sent and bounce).
The code that I was referring to that uses MessageID would be written by you. There is no method that takes the MessageID as a parameter.
What sent details are you looking for? If it was sent? Well the response gives you that along with a MessageID. To know if the email bounced, you would need to check the mailbox for the FROM email address.
See SES APIs here: http://docs.amazonwebservices.com/ses/latest/APIReference/API_GetSendStatistics.html
What I was suggesting was that you write some code that would check whatever mailserver the FROM address resides on, for emails that match the MessageID. If one exists you know it bounced!
It seems that maybe SES is not really the best choice for you…. maybe you need to look elsewhere!
Hi Neil,
Let me explain our process of sending mail.
1)We are having a news letter
2)Also having some lists, where each list contains group of contacts
3)Now we have to send the news letter to one or more lists
4)After sending this news letter ,we have to store the information of email sent status,like how many of them are bounced and how many are sent successfully.
5)here email sent status means we have get full details,like for bounce status we have to get no.of bounced mails with list of all bounced emailids.similarly for sent,no.of sent mails with list of all sent mailids.
this is overview of our mailing process.
We have to complite all this using AWS.
I am new to AWS.So getting lotof confusion, whats going on after sending a mail in AWS.
Even i am not having idea this entire process can be possible using AWS or not?
I thing you got my point Neil.
As I said in my last comments, if you send an email to each address (rather than as your code posted here yesterday was doing and sending to all at once) then from what I understand you will get a MessageID for each. This can be used to determine if the email was bounced by writing some code to look in the mailbox of the mailserver that the FROM address is hosted (this is not part of SES as SES provides no mailboxes etc).
Each email sent can be added to the database, and assumed sent when you have a MessageID in the response from SES. If the mail is bounced you will get an email in the mailbox of the FROM account with the email address containing the MessageID. You can then set this email in your database to have been bounced and act appropriately.
If you “have to” complete this using AWS then this sounds to me the best flow. SES is just a service for sending emails, it is not a mail system that you can connect say Outlook to or check status of sent emails. For that you’d need something else.
Does this make sense??
Hi,
What is use of returnPath, which you have used as a paramiter in SendEmail() method.
yesterday i have gone through
https://forums.aws.amazon.com/ann.jspa?annID=1367
here is something related to return path.Can you provide me some more information about that.
I mean to say how can we use that returnPath in our coading,and how to get the data which comes through returnpath.
it would be big help to me.
Thank you
Hi,
If you look here: http://docs.amazonwebservices.com/ses/latest/APIReference/API_SendEmail.html
It explains what returnPath is:
So it is only used to specify the email address where the emails that bounce are forwarded to.
Hi Neil,
Thank you for your quick responce.
Can you provide me some sample code to send Raw mail in c#
I’ve already done a blog about this after the original SES one: https://neildeadman.wordpress.com/2011/02/01/amazon-simple-email-service-example-in-c-sendrawemail/
Hai Neil,
We have sent a mail using Amezon SES to three mail ids.The SES has returned these three as bounce mails.But these are working fine.
I don’t know why The Amezon Service displayed these id’s as bounce.
What will be the reason?
And i am 100% sure my email id’s are working fine.
It would be hard for me to know the reason why. Check you can definitely email those addresses. Check Amazon service status. What was rain for bounce if any given?
Hi neil deadman… nice blog.. i want to handle individual email bounce … it means i want a count of bounce and complain emails count … how do i get it.. i get all bounce and email count but not any individual email count….
Great post…..!! Thank You Neil
Hi Neil! Usefiul article) But I can’t understand the Amazon SNS. Can you help me?
Regards, Sergey
Hi Sergey! I no longer handle Amazon Web Services so I haven’t looked at SNS unfortunately. Sure there are good sites out there that do though. Google is your friend here! 🙂
hi Neil Deadman.How can i send bulk mails by using query api (i e., making raw requests to Amazon SES over HTTPS by using the Query API in c#)
Hello Tarun,
You could loop what I have done, but I suspect there is another better method.
Unfortunately, I am not able to help as I am not in the habit of doing work for people. I suggest you look at the API and work it out.
Neil
I posted a new Amazon SES post here.