
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
- Create an AWS account here https://portal.aws.amazon.com/billing/signup#/start
- 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.

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
- 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”

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:
- SNS publish method will send SMS to the given phone no along with the msg.
- 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();
}
- 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.
- Create a subscription to register the server endpoint where we want notification. Topic ARN is a unique id of the topic.
- Confirm the subscription & AWS will send a notification to the endpoint.
- Now link the Bounce topic to SES Domain -> Notification -> Bounce with original headers.

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:
- StartTime contains the start period, from which time you want to see statistics.
- EndTime contains the end period, till which time you want to see statistics.
- 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

6. Create an index.js file & call all these functions
Now let’s create a file & call these functions.

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.

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.
Hello noob2geek.in admin, Your posts are always well-written and easy to understand.
To the noob2geek.in administrator, Your posts are always well-supported by research and data.
Hi noob2geek.in owner, Your posts are always well-referenced and credible.
Hello noob2geek.in webmaster, Your posts are always well structured and easy to follow.
Hello noob2geek.in webmaster, Thanks for the valuable information!
I have read your article carefully and I agree with you very much. So, do you allow me to do this? I want to share your article link to my website: Cryptocurrency Prices
I have read your article carefully and I agree with you very much. So, do you allow me to do this? I want to share your article link to my website: gateio
Hello noob2geek.in webmaster, Your posts are always well researched.
Dear noob2geek.in administrator, Thanks for the well-researched and well-written post!
Hi noob2geek.in owner, You always provide great insights.
Dear noob2geek.in webmaster, You always provide great examples and real-world applications.
Hello noob2geek.in owner, Thanks for the well-researched and well-written post!
Hi noob2geek.in administrator, You always provide key takeaways and summaries.
To the noob2geek.in administrator, Your posts are always a great source of knowledge.
Dear noob2geek.in administrator, Thanks for the well-structured and well-presented post!
To the noob2geek.in admin, Your posts are always well structured and easy to follow.
Hi noob2geek.in admin, Your posts are always well-received by the community.
Dear noob2geek.in admin, Thanks for the well-organized post!
Dear noob2geek.in owner, Thanks for the detailed post!
Hello noob2geek.in owner, Your posts are always well-structured and logical.
Hi noob2geek.in webmaster, You always provide valuable information.
Pingback: Handle Incoming Emails Using AWS SES and SNS | Noob2Geek