Overview
Amazon Simple Email Service provides an API for outbound-only email delivery. It is an excellent API for managing email campaigns, as its API include delivery of bounce and spam ("complaint") notifications to an endpoint.
The qbo.Message.Amazon plugin includes:
SES.cs: a "plain" IMailOutbound wrapper around the SES API; use this for outbound emails when you do not need to programatically track bounce or spam notifications
SESValidator.cs: a "value-added" IMailOutbound wrapper that works with SES to track bounce and spam notifications, and to minimize bounces
Email Campaigns: Handling Bounce and Spam Notifications
Part of the SES terms of service attempt to manage "spammers". Two strong indicators that an entity is a "spammer" is bounce rate and complaint rate. A "bounce" is an attempt to email an address that does not (currently) exist. A complaint is an email that is marked as spam by an end-user, or by an email provider based on a set of rules (e.g. Viagra ads).
qbo.Message.Amazon can assist with managing bounce and spam as follows:
The SESValidator class will check recipients against a list of ContactMethods in a QBO database prior to delivering the email to SES; if a recipient (To, Cc, or Bcc) is part of this list, the recipient will automatically be removed
the list of ContactMethods is delivered by the QBO Message/InvalidRecipientList operation
any removed recipients will be logged to a logging sink under the category "EmailAddressValidation" (configured by Properties.Settings.Default.LogCategoriesAddressValidation)
if the ErrorOnInvalidRecipient message is set to true and a recipient is removed, none of the email will be delivered, and an error will be raised (default value is false)
The SES.ashx handle provide three key pieces of functionality:
SES.ashx/Bounce: parses SES bounce notifications (JSON format) and added any bounce recipients as a ContactMethod using Message/InvalidRecipientAdd
SES.ashx/Spam: parses SES complaint notifications (JSON format) and added any complaint recipients as a ContactMethod using Message/InvalidRecipientAdd
SES.ashx/*: any inbound Amazon SNS topic requiring subscription confirmation will be automatically confirms
From the Amazon SES console, an SNS topic should be create to handle bounces and complaints
add an HTTPS endpoint to both of these topcis; by default, point them to https://{site}/Notification/SES.ashx/Bounce for bounces; SES.ashx/Spam for complaints
note the site's web.config file was modified to allow anonymous access to Notification/SES.ashx; the sns@quandis.net user determine the security context under which this is run
Review SES Best Practices for more context.
Spam Feedback Unit Test
You can unit test the feedback loop with Fiddler as follows:
Open Fiddler's Composer window
POST to https://qrm.quandis.net/Notification/SES.ashx/Spam
Use the JSON below as the Request Body:
{
"Type" : "Notification",
"MessageId" : "8bc02f2f-d890-52dd-80ad-62b3180696a2",
"TopicArn" : "arn:aws:sns:us-east-1:724166662639:Email-Complaint",
"Message" : "{\"notificationType\":\"Complaint\",\"complaint\":{\"complainedRecipients\":[{\"emailAddress\":\"not.eric.patrick@hotmail.com\"}],\"timestamp\":\"2015-04-06T17:11:49.000Z\",\"feedbackId\":\"0000014c8fb7806f-03891f38-dc80-11e4-b188-51db004b08f2-000000\"},\"mail\":{\"timestamp\":\"2015-04-06T17:07:26.000Z\",\"source\":\"\\\"QRM Notification\\\" <no-reply@quandis.net>\",\"messageId\":\"0000014c8fb37c0b-931e62da-507f-4a9b-b9ce-6e3081a83ccd-000000\",\"destination\":[\"bradandresen@hotmail.com\"]}}",
"Timestamp" : "2015-04-06T17:11:50.333Z",
"SignatureVersion" : "1",
"Signature" : "xnwIWPLR2KSrhfoBWpnZDgZxyyRG7ehhbzDZhIZu9Gh6X/y1RhwTq0n5O4tPmIuAFCT43upsF51GV8rB6HL4ZE3zXiZF4JDhlx/TuTCLh5XiRkhf1dRKewd97PYoTE7/lizQyYorZuRzUl71CT8C35xvmnHqYNeZo4a4lrWIN9SC5IJNwvgzUm3NANZwCBi8/sTUtHan5eoSPDpeSLC2PMO7l9vwimyF27kApmIRlE/+plfqEBfVm4iKdWxyjJR/bFZGuJRFU6mIkZnV4OEiwR5EPPxeOR5HclFdHBkH3Bzyw1xgBnW1+iHgzeNCJ6+Ytf9y7n8rleG763VckVI68w==",
"SigningCertURL" : "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-d6d679a1d18e95c2f9ffcf11f4f9e198.pem",
"UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:724166662639:Email-Complaint:3800bc5f-30a1-4d46-9021-802ae23343f3"
}
Bounce Feedback Unit Test
You can unit test the feedback loop with Fiddler as follows:
Open Fiddler's Composer window
POST to https://qrm.quandis.net/Notification/SES.ashx/Bounce
Use the JSON below as the Request Body:
{
"Type" : "Notification",
"MessageId" : "22351349-0958-5d97-bc62-5ed5c9c11128",
"TopicArn" : "arn:aws:sns:us-east-1:724166662639:Email-Bounce",
"Message" : "{\"notificationType\":\"Bounce\",\"bounce\":{\"bounceSubType\":\"General\",\"bounceType\":\"Permanent\",\"reportingMTA\":\"dsn; a8-39.smtp-out.amazonses.com\",\"bouncedRecipients\":[{\"action\":\"failed\",\"emailAddress\":\"not.eric.patrick@yahoo.com\",\"status\":\"5.3.0\",\"diagnosticCode\":\"smtp; 554 delivery error: dd This user doesn't have a yahoo.com account (not.eric.patrick@yahoo.com) [0] -mta1415.mail.gq1.yahoo.com\"}],\"timestamp\":\"2015-04-06T17:11:53.642Z\",\"feedbackId\":\"0000014c8fb78dbf-a7388d60-19fd-41ac-8335-8ad48fece34e-000000\"},\"mail\":{\"timestamp\":\"2015-04-06T17:11:52.000Z\",\"messageId\":\"0000014c8fb7897c-cd0ce951-81be-4b6e-9af5-83b43c012ecc-000000\",\"source\":\"\\\"QRM Notification\\\" <no-reply@quandis.net>\",\"destination\":[\"not.eric.patrick@yahoo.com\"]}}",
"Timestamp" : "2015-04-06T17:11:53.657Z",
"SignatureVersion" : "1",
"Signature" : "oaCax3gYZPx5usDyIKnopdosz0I6x1dce9zDuGMa3oqZhL4nLlfQQ143JgBPf3MyjQ4S2mkmVz1WZ3/PSJ7W6TTiN7Kp6oreTcsqgQvmB841BkxVAvsAT1LCI2tvme0kAvih3iJZHthNkY2n6sLRh+wX2ataALobwJ9qXG+FKMVVD5CY8wdSJ0XQ88USuo44b0b++jcfmUKBde9AGFzHBzLyIThfDneFufiC038JVIOh7VrOPLGA/DIi8Jv1QSwMjjy4FLLOD573BwOHuuMtbFrh7i1PQGfm26Af3bQuDDXKtvy6BBhbnls2QYkBcVUnZzyf2jcC3PccdO2kbjxkLw==",
"SigningCertURL" : "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-d6d679a1d18e95c2f9ffcf11f4f9e198.pem",
"UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:724166662639:Email-Bounce:243310cd-5cbd-4033-b97c-1a798289256c"
}
Data Tier Considerations
Rather than having each QBO client maintain their own bounce / spam list, a common database should be used to maintain the ContactMethods that have been reported as bounces or complaints. For AWS-based QBO installations, the 'master' database for this list should be the QRM database.
Setting up an SES account requires adding one or more domains (quandis.net, mycompany.info, etc.) to route mail from. It is not reasonable to create a dedicated SES account for each Quandis client site; instead all Quandis client sites that use SES will typically route through a single SES account / domain.