I want to change my current text email format to HTML format, so that I can send an email in nicely formatted way with headers, font values etc as shown in the screenshot below. Image showing email body with header font size etc
Currently I have text format for sending email using AWS.ses
exports.sendEmail = function(email, token, event, context) {
var ses = new AWS.SES({
region: process.env.SES_REGION
});
var eParams = {
Destination: {
ToAddresses: [email]
},
Message: {
Body: {
Text: {
//template or environment variable
Data: `Hello ${event.request.userAttributes.given_name},\n\nYour Device Validation Token is ${token}\nSimply copy this token and paste it into the device validation input field.`
}
},
Subject: {
//template or environment variable
Data: "CWDS - CARES Device Validation Token"
}
},
//environment variable
Source: process.env.SOURCE_EMAIL
};
/* eslint-disable no-unused-vars */
ses.sendEmail(eParams, function(err, data){
if(err) {
logWrapper.logExceptOnTest("FAILURE SENDING EMAIL - Device Verify OTP");
logWrapper.logExceptOnTest(event);
logWrapper.logExceptOnTest(context);
context.fail(err);
}
else {
logWrapper.logExceptOnTest("Device Verify OTP sent");
context.succeed(event);
}
});
/* eslint-enable no-unused-vars */
}
It's fairly straight forward, just add the Html section of the Body node, i.e.:
var eParams = {
Destination: {
ToAddresses: [email]
},
Message: {
Body: {
Text: {
Data: `Hello ${event.request.userAttributes.given_name},\n\nYour Device Validation Token is ${token}\nSimply copy this token and paste it into the device validation input field.`
},
Html: {
Data: `<html><head><title>Your Token</title><style>h1{color:#f00;}</style></head><body><h1>Hello ${event.request.userAttributes.given_name},</h1><div>Your Device Validation Token is ${token}<br/>Simply copy this token and paste it into the device validation input field.</div></body></html>`
}
},
Subject: {
//template or environment variable
Data: "CWDS - CARES Device Validation Token"
}
},
//environment variable
Source: process.env.SOURCE_EMAIL
};
However... I generally split out the email template into html and text files, and use handlebars to inject data items. Here is an extract of one of my working solutions:
contact/contact.js
var AWS = require('aws-sdk');
var ses = new AWS.SES();
var fs = require('fs');
var Handlebars = require('handlebars');
module.exports.sendemail = (event, context, callback) =>
var eventData = JSON.parse(event.body);
fs.readFile("./contact/emailtemplate.html", function (err, emailHtmlTemplate) {
if (err) {
console.log("Unable to load HTML Template");
throw err;
}
fs.readFile("./contact/emailtemplate.txt", function (err, emailTextTemplate) {
if (err) {
console.log("Unable to load TEXT Template");
throw err;
}
// Prepare data for template placeholders
var emailData = {
"given_name": event.request.userAttributes.given_name,
"token": token
};
// Inject data into templates
var templateTitle = Handlebars.compile(process.env.EMAIL_TITLE);
var titleText = templateTitle(emailData);
console.log(titleText);
emailData.title = titleText;
var templateText = Handlebars.compile(emailTextTemplate.toString());
var bodyText = templateText(emailData);
console.log(bodyText);
var templateHtml = Handlebars.compile(emailHtmlTemplate.toString());
var bodyHtml = templateHtml(emailData);
console.log(bodyHtml);
// Prepare SES params
var params = {
Destination: {
ToAddresses: [
process.env.EMAIL_TO
]
},
Message: {
Body: {
Text: {
Data: bodyText,
Charset: 'UTF-8'
},
Html: {
Data: bodyHtml
},
},
Subject: {
Data: titleText,
Charset: 'UTF-8'
}
},
Source: process.env.EMAIL_FROM
}
console.log(JSON.stringify(params,null,4));
// Send Email
ses.sendEmail(params, function(err,data){
if(err) {
console.log(err,err.stack); // error
var response = {
statusCode: 500,
headers: {
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Credentials" : true
},
body: JSON.stringify({"message":"Error: Unable to Send Message"})
}
callback(null, response);
}
else {
console.log(data); // success
var response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Credentials" : true
},
body: JSON.stringify({"message":"Message Sent"})
}
callback(null, response);
}
});
}); //end of load text template
}); //end of load html template
};
contact/emailtemplate.html
<!DOCTYPE html>
<html>
<head>
<title>Your New Token</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>
h1 { color:#f00; }
</style>
</head>
<body>
<div class="emailwrapper">
<div class="main">
<div class="content">
<h1>Hi {{given_name}}</h1>
<div style="padding:20px;">
<div>your new token is {{token}}.</div>
</div>
</div>
</div>
</div>
</body>
</html>
contact/emailtemplate.txt
Hi {{given_name}}
your new token is {{token}}.
Here is the ES6 version using the newer AWS SDK, and some other optimisations:
import { SESClient, SendEmailCommand } from '@aws-sdk/client-ses';
import fs from 'fs/promises';
import Handlebars from 'handlebars';
import util from 'util';
const ses = new SESClient({ region: 'your-aws-region' }); // Replace 'your-aws-region' with the appropriate AWS region
const readFileAsync = util.promisify(fs.readFile);
export const sendemail = async (event, context, callback) => {
try {
const eventData = JSON.parse(event.body);
const [emailHtmlTemplate, emailTextTemplate] = await Promise.all([
readFileAsync("./contact/emailtemplate.html"),
readFileAsync("./contact/emailtemplate.txt")
]);
// Prepare data for template placeholders
const emailData = {
"given_name": event.request.userAttributes.given_name,
"token": token // Where does 'token' come from? You need to define it.
};
// Inject data into templates
const templateTitle = Handlebars.compile(process.env.EMAIL_TITLE);
const titleText = templateTitle(emailData);
console.log(titleText);
emailData.title = titleText;
const templateText = Handlebars.compile(emailTextTemplate.toString());
const bodyText = templateText(emailData);
console.log(bodyText);
const templateHtml = Handlebars.compile(emailHtmlTemplate.toString());
const bodyHtml = templateHtml(emailData);
console.log(bodyHtml);
// Prepare SES params
const params = {
Destination: {
ToAddresses: [process.env.EMAIL_TO]
},
Message: {
Body: {
Text: {
Data: bodyText,
Charset: 'UTF-8'
},
Html: {
Data: bodyHtml
},
},
Subject: {
Data: titleText,
Charset: 'UTF-8'
}
},
Source: process.env.EMAIL_FROM
};
console.log(JSON.stringify(params, null, 4));
// Send Email
const sendEmailCommand = new SendEmailCommand(params);
await ses.send(sendEmailCommand);
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": true
},
body: JSON.stringify({ "message": "Message Sent" })
};
callback(null, response);
} catch (error) {
console.log(error, error.stack); // error
const response = {
statusCode: 500,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": true
},
body: JSON.stringify({ "message": "Error: Unable to Send Message" })
};
callback(null, response);
}
};