Send AWS SES Emails with NodeJS & TypeScript

June 27, 2022

2 min read

Send AWS SES Emails with NodeJS & TypeScript
Watch on YouTube

Here we send a signup confirmation email to a user.

import { getHTMLTemplate, fillHtmlTemplate, sendEmail } from "../email"

export const sendEmailConfirmationLink = async (
  email: string,
  authLink: string
) => {
  const html = await getHTMLTemplate("auth")

  await sendEmail({
    body: fillHtmlTemplate(html, {
      "auth-link": authLink,
    subject: "Log in to Increaser",
    source: `Login <>`,

First, we want to take an HTML template. The function takes the template name and reads it from the file. I make template names the same as HtmlTemplate type.

export const getHTMLTemplate = memoize((template: HtmlTemplate) => {
  return readFile(
    path.resolve(__dirname, `../../templates/${template}.html`),

I don't usually send emails with fancy styling to not appear in recipient spam or promotion tabs.

In the auth-email template, we expect two variables - auth-link and email.

<p>Click the link below to sign in to <b>Increaser</b>.</p>

<p>This link will expire in 20 minutes.</p>

<a href={{auth-link}}>Sign in to Increaser</a>

<p>Confirming this request will securely sign you in using {{email}}.</p>

- Increaser Team

Once we've read the file into a string we'll use the fillHtmlTemplate function to insert variables into an email html.

export const fillHtmlTemplate = (
  html: string,
  variables: Record<string, string>
) => {
  let result = html
  Object.entries(variables).forEach(([key, value]) => {
    result = result.split(`{{${key}}}`).join(value)

  return result

We pass the recipient email, HTML body, subject, and source to the sendEmail function.

I ran my Lambda in the European region, but AWS SES doesn't work there. So I explicitly pass the Virginia region to the SES constructor.

interface SendEmailParameters {
  email: string
  body: string
  subject: string
  source: string

const ses = new aws.SES({ region: "us-east-1" })

export const sendEmail = ({
}: SendEmailParameters) =>
      Destination: {
        ToAddresses: [email],
      Message: {
        Body: {
          Html: {
            Data: body,
        Subject: {
          Data: subject,
      Source: source,

We pass Destination, Message, and Source to the SES method and make it into a promise.