Thursday, 8 February 2018

AWS: Fetching messages from AWS queue and then sending emails with attachments using AWS SES.

This code sample is to fetch messages from AWS queue and then send emails with attachments using AWS SES service. To achieve this I have used some AWS's sdks. Please add following nuget packages in your project before starting:

Nuget Packages to install:
1. AWSSDK.SimpleEmail
2. AWSSDK.SQS
3. MimeKit

Step 1: Add following code in cs file:

using Amazon;
using Amazon.Runtime;
using Amazon.SimpleEmail;
using Amazon.SimpleEmail.Model;
using Amazon.SQS;
using Amazon.SQS.Model;
using MimeKit;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Net;

namespace JsonToHtml.Models

{
    public class EmailUtils
    {
        public static void ProcessSQSMessages()
        {
            var credentials = new BasicAWSCredentials(ConfigurationManager.AppSettings["AWSAccessKey"], ConfigurationManager.AppSettings["AWSSecretKey"]);
            var regEndPoint = RegionEndpoint.USEast1;
            using (var client = new AmazonSQSClient(credentials, RegionEndpoint.USEast1))
            {
                var receiveMessageRequest = new ReceiveMessageRequest();
                receiveMessageRequest.QueueUrl = ConfigurationManager.AppSettings["AWSQueueUrl"];
                ReceiveMessageResponse result = client.ReceiveMessage(receiveMessageRequest);

                if (result.Messages.Count != 0)

                {
                    for (int i = 0; i < result.Messages.Count; i++)
                    {
                        var emailData = JsonConvert.DeserializeObject<EmailModel>(result.Messages[i].Body);
                        emailData.ReceiptHandle = result.Messages[i].ReceiptHandle;
                        var emailResponse = SendEmail(emailData, credentials, regEndPoint);
                        //To-Do: Use email message response here
                    }
                }
            }
        }

        public static EmailResponse SendEmail(EmailModel emailData, BasicAWSCredentials credentials, RegionEndpoint regEndPoint)

        {
            EmailResponse emailResponse = null;
            try
            {
                using (var client = new AmazonSimpleEmailServiceClient(credentials, regEndPoint))
                {

                    var sendRequest = new SendRawEmailRequest { RawMessage = new RawMessage(GenerateMailMessage(emailData)) };


                    var response = client.SendRawEmail(sendRequest);

                    emailResponse = new EmailResponse { StatusCode = (int)response.HttpStatusCode };

                    if (response.HttpStatusCode == HttpStatusCode.OK)

                    {
                        emailResponse.MessageId = response.MessageId;
                        emailResponse.DeleteMessageResponse = DeleteAWSQueueMessage(credentials, emailData.ReceiptHandle, regEndPoint);
                    }
                    else
                    {
                        emailResponse.Message = "Message couldn't send";
                    }
                }
            }
            catch (Exception ex)
            {
                emailResponse = new EmailResponse { StatusCode = (int)HttpStatusCode.BadRequest, Message = ex.Message };
            }

            return emailResponse;

        }

        private static MemoryStream GenerateMailMessage(EmailModel emailData)

        {
            var message = new MimeMessage
            {
                Subject = emailData.Subject,
                Body = GenerateBody(emailData.Body, emailData.Attachments).ToMessageBody()
            };

            message.From.Add(new MailboxAddress(emailData.Sender));

            message.To.Add(new MailboxAddress(emailData.Recipient));
            message.ReplyTo.Add(new MailboxAddress(emailData.ReplyTo));

            using (var stream = new MemoryStream())

            {
                message.WriteTo(stream);
                return stream;
            }
        }

        private static BodyBuilder GenerateBody(string emailBody, IList<string> attachments)

        {
            var body = new BodyBuilder() { HtmlBody = emailBody };
            int count = 1;

            foreach (var attachment in attachments)

            {
                if (!string.IsNullOrWhiteSpace(attachment))
                {
                    string[] fileData = attachment.Split(',');
                    string fileExtension = fileData[0].Split(';')[0];

                    fileExtension = fileExtension.Substring(fileExtension.IndexOf(':') + 1).Split('/')[1];


                    string base64String = fileData[1];

                    string attachmentName = $"Attachment{count}.{fileExtension}";
                    int mod4 = base64String.Length % 4;

                    if (mod4 > 0)

                    {
                        base64String += new string('=', 4 - mod4);
                    }

                    body.Attachments.Add(attachmentName, Convert.FromBase64String(base64String));

                    count++;
                }
            }

            return body;

        }

        private static DeleteMessageResponse DeleteAWSQueueMessage(BasicAWSCredentials credentials, string receiptHandler, RegionEndpoint regEndPoint)

        {
            DeleteMessageResponse response = null;
            try
            {
                using (var client = new AmazonSQSClient(credentials, regEndPoint))
                {
                    var delRequest = new DeleteMessageRequest
                    {
                        QueueUrl = ConfigurationManager.AppSettings["AWSQueueUrl"],
                        ReceiptHandle = receiptHandler
                    };

                    var msgResponse = client.DeleteMessage(delRequest);

                    response = new DeleteMessageResponse { StatusCode = (int)msgResponse.HttpStatusCode, Message = msgResponse.HttpStatusCode == HttpStatusCode.OK ? "Success" : "Couldn't delete message" };
                }
            }
            catch (Exception ex)
            {
                response = new DeleteMessageResponse { StatusCode = (int)HttpStatusCode.BadRequest, Message = ex.Message };
            }

            return response;

        }
    }
}

Note: In the above code sample you need to add "AWSAccessKey, AWSSecretKey, AWSQueueUrl" keys in your web.config's <appSettings> tag.

2 comments: