Tutorial: Send Emails Using AWS SES & Lambda Functions

Tutorial: Send Emails Using AWS SES & Lambda Functions

If you’re a good developer, you may have nightmares about difficult 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 FunctionsFigure 1. Domain 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

Figure 2. 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. 

Interested in hiring talented Latin American developers to add capacity to your team? Contact Jobsity: the nearshore staff augmentation choice for U.S. companies.

Sep 28, 2021
Mauricio Lopez
Mauricio Lopez

Mauricio has been at the forefront of technology for 12 years. He is constantly integrating new technologies including frameworks, CMS, and standard industry models. He is a pragmatic problem-solver and customizes solutions based on the best schema/language/application for each project. As head of technology at Jobsity, he ensures that his team is always up to date with the latest advances in software development by researching the software ecosystem, implementing several professional development initiatives, and coordinating with new and existing clients about their needs.
He holds a BA in Business and Marketing from UTEG Ecuador

Subscribe for the updates

 

Better hires, more work, less stress. Join the Jobsity Community. Contact Us