// //========================================================================================== /// <summary> /// process a bounce notification /// </summary> /// <param name="cp"></param> /// <param name="message"></param> private static void processSesBounceNotificationMessage(CPBaseClass cp, AmazonSesBounceNotification message) { if (message.notificationType == "Bounce") { // // -- process bounce messages string bounceMsg = message.bounce.timestamp.ToString() + " AWS email bounce notification, type: " + message.bounce.bounceType; if (!string.IsNullOrEmpty(message.bounce.bounceSubType)) { // // -- append bounce sub type to name bounceMsg += ", " + message.bounce.bounceSubType; } switch (message.bounce.bounceType) { case "Transient": // // -- Remove all recipients that generated a permanent bounce or an unknown bounce. foreach (var recipient in message.bounce.bouncedRecipients) { transientFail(cp, recipient.emailAddress, bounceMsg); } break; default: // // -- Remove all recipients that generated a permanent bounce or an unknown bounce. foreach (var recipient in message.bounce.bouncedRecipients) { permanentFail(cp, recipient.emailAddress, bounceMsg); } break; } } }
private static void ManuallyReviewBounce(AmazonSesBounceNotification bounce) { throw new NotImplementedException(); }
// //========================================================================================== /// <summary> /// addon method /// </summary> /// <param name="cp"></param> /// <returns></returns> public override object Execute(Contensive.BaseClasses.CPBaseClass cp) { try { const string spAwsSecretAccessKey = "AWS Secret Access Key"; const string spAwsAccessKeyId = "AWS Access Key Id"; const string spAwsSQSBounceEmailQueueEndpoint = "AWS SQS Bounce Email Queue Endpoint"; // bool awsAllowBounceProcess = cp.Site.GetBoolean("AWS SES Allow Bounce Process"); if (awsAllowBounceProcess) { // // -- aws keys, use the server config, but allow over-ride by site property string awsAccessKeyId = cp.Site.GetText(spAwsAccessKeyId); if (string.IsNullOrEmpty(awsAccessKeyId)) { awsAccessKeyId = cp.ServerConfig.awsAccessKey; } string awsSecretAccessKey = cp.Site.GetText(spAwsSecretAccessKey); if (string.IsNullOrEmpty(awsSecretAccessKey)) { awsSecretAccessKey = cp.ServerConfig.awsSecretAccessKey; } // // -- settings string awsSQSBounceEmailQueueEndpoint = cp.Site.GetText(spAwsSQSBounceEmailQueueEndpoint); // // -- setup aws client AmazonSQSClient sqsClient = new AmazonSQSClient(awsAccessKeyId, awsSecretAccessKey, Amazon.RegionEndpoint.USEast1); ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest { QueueUrl = awsSQSBounceEmailQueueEndpoint, MaxNumberOfMessages = 10 }; // // -- download a message from queue, process and repeat until no more while (true) { ReceiveMessageResponse receiveMessageResponse = sqsClient.ReceiveMessage(receiveMessageRequest); if (receiveMessageResponse.Messages.Count == 0) { // // -- no message, exit loop break; } foreach (Message msg in receiveMessageResponse.Messages) { // // -- convert the Amazon SNS message into a JSON object. AmazonSqsNotification notification = Newtonsoft.Json.JsonConvert.DeserializeObject <AmazonSqsNotification>(msg.Body); if (notification.type == "Notification") { // // -- process SES bounce notification. AmazonSesBounceNotification message = Newtonsoft.Json.JsonConvert.DeserializeObject <AmazonSesBounceNotification>(notification.message); processSesBounceNotificationMessage(cp, message); } else if (notification.type == null) { // // --unknown type, assume valid message AmazonSesBounceNotification message = Newtonsoft.Json.JsonConvert.DeserializeObject <AmazonSesBounceNotification>(msg.Body); processSesBounceNotificationMessage(cp, message); } // // -- delete the processed message from the SES queue var deleteMessageRequest = new DeleteMessageRequest { QueueUrl = awsSQSBounceEmailQueueEndpoint, ReceiptHandle = msg.ReceiptHandle }; sqsClient.DeleteMessage(deleteMessageRequest); } } // // -- transient bounces beyond the grace period - convert to permanent failures using (CPCSBaseClass cs = cp.CSNew()) { if (cs.Open("email bounce list", "(transient=1)and(transientFixDeadline<" + cp.Db.EncodeSQLDate(DateTime.Now) + ")")) { do { permanentFail(cp, cs.GetText("name"), DateTime.Now.ToString() + " converted from transient to permanent because grace period past with no action, original failure[" + cs.GetText("details") + "]"); cs.GoNext(); } while (cs.OK()); } cs.Close(); } } return(string.Empty); } catch (Exception ex) { cp.Site.ErrorReport(ex); return(string.Empty); } }