Tutorial: Send Emails Using AWS SES & Lambda Functions

Written by Andres Garzon
Management

If you’re a good developer, you will be getting nightmares when it comes to interactions with third-party services. Be it calling third-party APIs or sending emails to a large number of people.

If the API is slow to respond, this might affect your system performance because of things outside your control. No one wants calls in the middle of the night because of third-party breakdown and the cussing that follows. So, we will introduce a new technique here to offload such independent pieces of work in separate lambda functions that run outside the scope of your app process and provide a layer of insulation to your app and also to your good night’s sleep.

Today's post will cover AWS SES & lambda function for sending an email to the customer using a small demo.

AWS SES is a managed service that is used to send and receive emails.
AWS Lambda is also a managed service that can spin up very temporary servers to compute small pieces of work.

Cloud-native features like AWS lambda are not unique to AWS, they are also present in other cloud providers. It’s called cloud functions in GCP for instance. For this post, we will focus on AWS Offering.

There are 5 main steps to be followed here,

1. Create an AWS account
2. Verify domain to send emails
3. Make a lambda function with the right roles to send emails
4. Make an SQS queue and add the lambda function as a consumer
5. Enqueue the payload to process which triggers the lambda function

Without wasting much time let’s begin.

Step 1. AWS Setup

1. Create an AWS account here https://portal.aws.amazon.com/billing/signup#/start

2. Now go to IAM(Identity and Access Management)

a. Add new Role
b. Select AWS service
c. Choose Use case -> Lambda -> i. AmazonSESFullAccess, ii. AmazonSQSFullAccess
d. select the permission Boundary
e. give the tag
f. Review and create a role.

IAM role creation is required to give access to your lambda function to perform the send email action and invoke the lambda function on your behalf.

Step 2: Domain setup

Now Go to SES and register the email address/domain to send the email from your account.

Optional Steps(Only Domain registration):

Tutorial: Send Emails Using AWS SES & Lambda FunctionsDomain Setup in AWS SES

As soon as a new domain is added for verification DKIM record sets, TXT records, and MX(for receive) records are displayed, which must be added to the domain’s DNS settings.

  • TXT record is used to verify domain ownership and ensure email security.
  • MX record specifies the mail server responsible for accepting email messages on behalf of a domain name.
  • DKIM records are an email authentication method designed to detect forged sender addresses in email, a technique often used in phishing and email spam.

Every email that you sent has the possibility of bounce or complaint. SES can send you detailed notifications about your bounces, complaints, and deliveries. You can configure this under the notifications tab.

Tutorial: Send Emails Using AWS SES & Lambda Functions

You can send emails through Amazon SES by using applications or programming languages that use the SMTP protocol. We will, however, be using the AWS JS SDK in this example.

Tutorial: Send Emails Using AWS SES & Lambda Functions

Step 3: Lambda Setup

1. Go to AWS Lambda > Functions.

AWS Lambda is a serverless compute service that runs your code in response to events and automatically manages the underlying compute resources for you. You can use AWS Lambda to extend other AWS services with custom logic or create your own back-end services that operate at AWS scale, performance, and security.

2. Choose to create a function -> Choose Author from scratch.

The code you run on AWS Lambda is called a “Lambda function.” After you create your Lambda function it is always ready to run as soon as it is triggered, similar to a formula in a spreadsheet.

Each function includes your code as well as some associated configuration information, including the function name and resource requirements. Lambda functions are “stateless,” with no affinity to the underlying infrastructure, so that Lambda can rapidly launch as many copies of the function as needed to scale to the rate of incoming events.

3. Give the function a name. Choose runtime as Node.js 14x, select the permission as “Existing role”, and select the role that we have created earlier.

4. Once the lambda function is created. Go to Code, copy-paste the following code, and click deploy. Whenever changes are made to the code, always deploy the updated code.

Tutorial: Send Emails Using AWS SES & Lambda Functions

AWS Lambda dashboard

const AWS = require('aws-sdk')
const sesConfig = {
apiVersion: '2010-12-01',
region: 'selected_region',
}
const ses = new AWS.SES(sesConfig)
exports.handler =  async (event, context, callback) => {
 const incomingMsg = JSON.parse(event.Records[0].body)
  const params = {
    Destination: {
     ToAddresses: [incomingMsg.toEmail],
    },
    Message: {
     Body: {
      Html: {
       Charset: 'UTF-8',
       Data: incomingMsg.htmlContent,
      },
      Text: {
       Charset: 'UTF-8',
       Data: incomingMsg.textContent,
      },
     },
     Subject: {
      Charset: 'UTF-8',
      Data:incomingMsg.subject,
     },
    },
    ConfigurationSetName: configurationName,
    Source: incomingMsg.source,
    ReplyToAddresses: [
     'email@domain.com',
    ],
   }
await ses.sendEmail(params).promise().then((data) => {
   console.log(data)
   const response = {
        "statusCode": 200,
        "body": JSON.stringify(data),
        "isBase64Encoded": false
    };
    callback(null, response);
 }).catch((err) => {
   console.error(err)
  	const response = {
        "statusCode": 501,
        "body": JSON.stringify(err),
        "isBase64Encoded": false
    };
    callback(err,response);

 });
}

In the send email function:

1. Destination object contains ToAddresses array which holds an array of email id to whom the email will be sent.
2. Message object contains body and subject which is also an object that specifies email subject and body content of the email. You can send either HTML content or text content inside the message body.
3. Source contains “from email address” which is used to send an email.
4. ReplyToAddresses contains an array of email addresses to whom the email receiver can reply.
5. ConfigurationSetName is a “set name” which is used to track email activity like transactional email/ promotional email.

You can set the configuration set name inside “SES -> Email Sending -> Configuration Sets -> setName(PromotionalEmail) -> Add destination as “CloudWatch” and select all the event types ->select Message tag for value source & set dimensions”

Tutorial: Send Emails Using AWS SES & Lambda Functions

Step 4: Configure the SQS Queue

1. Go to AWS SQS > Create Queue.

Amazon SQS is a message queue service used to exchange messages through a polling model and can be used to decouple sending and receiving components.

2. Choose the queueing system bases on the requirement, for now, let’s choose the standard type.

3. Once the queue is created, go to lambda triggers and configure the lambda function that we have created.

Tutorial: Send Emails Using AWS SES & Lambda Functions

4. Copy the URL of the queue for later use.

Step 5: Enqueue the message to SQS

Once the SQS is set up, now we have to enqueue a message to the queue. We are going to use Node.js for this.

const emailToSend = {
email: “testUser@domain.com”,
htmlContent: ‘<p>Hello World</p>’,
textContent: ‘Hello World’
}

return new Promise((resolve, reject) => {
SQS.sendMessage({
MessageBody: JSON.stringify(emailToSend),
QueueUrl: “SQS_URL", //Copied from step 4
}, (err, data) => {
if (err) {
console.log(`Queueing email Failed`)
reject(err)
} else {
console.log(`Queueing email SQS message id ${data.MessageId}`)
resolve(data)
}

})}).catch((ignore) => console.log(ignore))

Once you run the above code, it will send the message to SQS, triggering the lambda function internally.


This post is just an example of de-coupling external services to lambda. This technique is applied to any long-running tasks or interactions with external services. You can also use DLQs for adding some fault tolerance in the lambda execution.

--

If you want to stay up to date with all the new content we publish on our blog, share your email and hit the subscribe button.

Also, feel free to browse through the other sections of the blog where you can find many other amazing articles on: Programming, IT, Outsourcing, and even Management.

Share
linkedIn icon
Written by Andres Garzon
LinkedIn

Andres was born in Quito, Ecuador, where he was raised with an appreciation for cultural exchange. After graduating from Universidad San Francisco de Quito, he worked for a number of companies in the US, before earning his MBA from Fordham University in New York City. While a student, he noticed there was a shortage of good programmers in the United States and an abundance of talented programmers in South America. So he bet everything on South American talent and founded Jobsity -- an innovative company that helps US companies hire and retain Latin American programmers.