AWS SES, SNS, CloudWatch Integration with Node.js
AWS SES, SNS, CloudWatch Integration with Node.js

AWS SES, SNS, CloudWatch Integration with Node.js

Spread the love
AWS SES, SNS, CloudWatch Integration with Node.js
AWS SES+SNS+Cloudwatch In Node.js

AWS SES is a Simple Email Service provided by AWS to send emails from any of the applications. SNS is a Simple Notification Service used to notify the subscribed endpoint user/server & sending Messages to the customer. Cloudwatch monitoring service gives you an insight into all the services/resources used by customers. In today’s post, will learn the SES, SNS & Cloudwatch service of AWS using the simple demo in Node.js. Where you can send email to the customer, notify the server about email delivery/bounce & see the logs of click, spam, bounce, etc of sent email using Cloudwatch. We will also send an SMS using SNS.


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 User
    b. Select AWS access type as“Programmatic access”
    c. Set permissions -> Attach existing policy -> i. AmazonSESFullAccess ii. AmazonSNSFullAccess iii. CloudWatchFullAccess
    d. select the permission Boundry
    e. give the tag
    f. Review & create a user.
    g. download the access key & Id for future use.
AWS IAM user creation
AWS IAM user creation

IAM user creation is required for giving access to your application to perform the action.

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


Step 2. Node.js Setup

  1. Install aws-sdk using npm or bower:
npm i aws-sdk
bower install aws-sdk-js

2. Store AWS access key & secret access to config.js file:

{
"accessKeyId":"AWS_ACCESS_KEY_ID",
"secretAccessKey":"AWS_SECRET_ACCESS_KEY",
"region":"AWS_DEFAULT_REGION"
}

3. Let’s create a ses-helper.js for sending an email

Import AWS module:

const AWS = require('aws-sdk');
const config = require('../config.json');

Initialize SES instance with access info:

const sesConfig = {
 apiVersion: '2010-12-01',
 accessKeyId: config.accessKeyId,
 secretAccessKey: config.secretAccessKey,
 region: config.region,
};
const ses = new AWS.SES(sesConfig);

Create & Export send email module for sending email:

module.exports = {
 /**
  * @param {*} email
  * @param {*} htmlContent
  * @param {*} textContent
  * @param {*} subject
  * @param {*} sourceName
 */
 sendEmail(email, htmlContent, textContent, subject, sourceName, configurationName) {
  const params = {
   Destination: {
    ToAddresses: [email],
   },
   Message: {
    Body: {
     Html: {
      Charset: 'UTF-8',
      Data: htmlContent,
     },
     Text: {
      Charset: 'UTF-8',
      Data: textContent,
     },
    },
    Subject: {
     Charset: 'UTF-8',
     Data: subject,
    },
   },
   ConfigurationSetName: configurationName,
   Source: sourceName,
   ReplyToAddresses: [
    'test@example.com',
   ],
  };
// Create the promise and SES service object
  return ses.sendEmail(params).promise().catch((err) => {
   console.log(`Email Failed to ${email}`)
   console.error(err, err.stack)
  });
 },
}

In the send email function:
1. Destination object contains ToAddresses array which holes array of email id to whom the email will be sent.
2. Message object contains body & 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 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”

Sample SES Configuration setup
Sample SES Configuration setup

Complete ses-helper.js will look like:

const AWS = require('aws-sdk');
const config = require('../config.json');
const sesConfig = {
 apiVersion: '2010-12-01',
 accessKeyId: config.accessKeyId,
 secretAccessKey: config.secretAccessKey,
 region: config.region,
}
const ses = new AWS.SES(sesConfig);
module.exports = {
 /**
  * @param {*} email
  * @param {*} htmlContent
  * @param {*} textContent
  * @param {*} subject
  * @param {*} sourceName
 */
 sendEmail(email, htmlContent, textContent, subject, sourceName, configurationName) {
  const params = {
   Destination: {
    ToAddresses: [email],
   },
   Message: {
    Body: {
     Html: {
      Charset: 'UTF-8',
      Data: htmlContent,
     },
     Text: {
      Charset: 'UTF-8',
      Data: textContent,
     },
    },
    Subject: {
     Charset: 'UTF-8',
     Data: subject,
    },
   },
   ConfigurationSetName: configurationName,
   Source: sourceName,
   ReplyToAddresses: [
    'test@example.com',
   ],
  }
// Create the promise and SES service object
  return ses.sendEmail(params).promise().catch((err) => {
   console.log(`Email Failed to ${email}`)
   console.error(err, err.stack)
  });
 },
}

4. Let’s create an sns-helper.js for sending SMS/handle incoming notification

Import AWS module:

const AWS = require('aws-sdk');
const config = require('../config.json');

Initialize SNS instance with access info:

const snsConfig = {
 apiVersion: '2010-03-31',
 accessKeyId: config.accessKeyId,
 secretAccessKey: config.secretAccessKey,
 region: config.region,
}
const SMS = new AWS.SNS(snsConfig);

Create & Export send SMS module for sending SMS:

module.exports.sendSMS = (msg, phoneNumber) => {
 SMS.publish({
  Message: msg,
  PhoneNumber: phoneNumber,
 }).promise();
}

In Send SMS function:

  1. SNS publish method will send SMS to the given phone no along with the msg.
  2. You can set the default message type to either “Promotional or Transactional”. AWS by default sends the SMS using a numeric sender id generated by AWS. If you want to send SMS using a specific alphanumeric sender id, you have to register your company. You can read more about it here.

Register SNS for email bounce notification:

module.exports.SNSHelper = () => {
 oonst snsTopic = SNS.createTopic({
  Name: 'Email Bounce Notification',
  Attributes: {
   DisplayName: "Bounce Notification",
  },
 }).promise();
 
const subscribePromise = SNS.subscribe({
 Protocol: 'HTTPS',
 TopicArn: snsTopic.TopicArn,
 Endpoint: 'https://yourserve.com/email_bounce_notification'
 }).promise();
}
  1. Create the topic with a name & attribute. Topics in AWS are communication channel which allows us to group multiple endpoints where SNS will notify the specific event action.
  2. Create a subscription to register the server endpoint where we want notification. Topic ARN is a unique id of the topic.
  3. Confirm the subscription & AWS will send a notification to the endpoint.
  4. Now link the Bounce topic to SES Domain -> Notification -> Bounce with original headers.
Link Domain/Email to notification SNS topic
Link Domain/Email to notification SNS topic

5. Let’s create a cloudwatch-helper.js file for monitoring insights of sent email

Import AWS module:

const AWS = require('aws-sdk');
const config = require('../config.json');

Initialize CloudWatch instance with access info:

const cloudconfig = {
 apiVersion: '2010-08-01',
 accessKeyId: config.accessKeyId,
 secretAccessKey: config.secretAccessKey,
 region: config.region,
}

const cloudwatch = new AWS.CloudWatch(cloudconfig);

Create & Export get Metric Data module for statistics:

module.exports = {
 getMetricData() {
  const dateObj = new Date()
  const params = {   StartTime: new Date(new Date().setHours(0, 0, 0, 0)),
   EndTime: dateObj,
   MetricDataQueries: [
    {
     Id: 'm10',
     MetricStat: {
      Metric: {
       Dimensions: [
        {
         Name: 'promotional',
         Value: 'Promotional-Email',
        },
       ],
       MetricName: 'Delivery',
       Namespace: 'AWS/SES',
      },
      Period: 86400,
      Stat: 'Sum',
     },
    },
   ],
  }

  return new Promise((resolve, reject) =>    {cloudwatch.getMetricData(params, (err, data) => {
    if (err) {
     reject(err)
    } // an error occurred
    resolve(data.MetricDataResults)
   })
  });
 },
}

In the getMetricData function:

  1. StartTime contains the start period, from which time you want to see statistics.
  2. EndTime contains the end period, till which time you want to see statistics.
  3. MetricDataQueries contains n number of queries to return the data. The limit of a query is 500 max. Metric stat object contains parameters to the query like:
    – Period shows the number of seconds to show data eg. 86400 means show 1 day of statistics.
    – Stats to show what kind of data you want like the sum of email sent, avg email sent, etc.
    – Metrics contains the namespace which means for which AWS service you want stats like AWS/SES. Metric name contains for which event of AWS service you want stats. Dimensions contain information about what kind of value source you want stats. For eg., We want a total no of promotional emails delivered in the last 1 day.
    – Output result contains “MetricDataResults” along with the id which is used for reference, Timestamps as an array of the interval, and values as array output. You can specify the start date, end date & Interval dynamically.

The below file shows the complete code of cloudwatch-helper.js

Sample cloudwatch-helper.js
Sample cloudwatch-helper.js

6. Create an index.js file & call all these functions

Now let’s create a file & call these functions.

Index.js file
Index.js file

You can unsubscribe the users from your DB if you receive a permanent bounce. Which will help you to reduce the bounce rate. Similarly, you can create a compliant notification to track the email complaint by users.

Email bounce notification
Email bounce notification

Thank you for reading. I hope you have found this useful. You can learn how to handle incoming emails using AWS SES & SNS with node.js here.

One comment

  1. Pingback: Handle Incoming Emails Using AWS SES and SNS | Noob2Geek

Leave a Reply

Your email address will not be published.