How I Automated My Email Welcome Message Using AWS Lambda + SMTP

Sending a welcome email after signup is one of the easiest ways to improve user experience.

Instead of using a third-party automation tool, I built a simple serverless workflow using:

Here’s exactly how I set it up.


Overview

Flow:

  1. User signs up via Cognito
  2. Cognito triggers a Post Confirmation Lambda
  3. Lambda sends a welcome email via SMTP

1. Set Up Cognito Trigger

  1. Go to AWS Cognito
  2. Open your User Pool
  3. Navigate to:
    User Pool → Authentication → Extensions → Add Lambda Trigger
  4. Find Post confirmation trigger
  5. Attach your Lambda function

2️. Create the Lambda Function

Starter code:

export const handler = async (event) => {
  const email = event.request.userAttributes.email;
  const name = event.request.userAttributes.name || "there";

  return event;
};

3️. Install Nodemailer

npm install nodemailer

4️. Configure SMTP Transport

Configure your mail transporter:

import nodemailer from "nodemailer";

const transporter = nodemailer.createTransport({
  host: process.env.SMTP_HOST,
  port: Number(process.env.SMTP_PORT), // usually 587 or 465
  secure: process.env.SMTP_PORT == "465", // true for 465, false for 587
  auth: {
    user: process.env.SMTP_USER,
    pass: process.env.SMTP_PASS,
  },
});

Environment Variables

Set these in Lambda:

SMTP_HOST=smtp.yourprovider.com
SMTP_PORT=587
SMTP_USER=your_user
SMTP_PASS=your_password

5️. Create Email Templates

HTML

const getHtmlTemplate = (name) => `
  <html>
    <body>
      <h1>Welcome, ${name} 🎉</h1>
      <p>We're excited to have you on board.</p>
      <p>Start exploring and let us know if you need anything.</p>
    </body>
  </html>
`;

Plain Text

const getTextTemplate = (name) => `
Welcome, ${name}!

We're excited to have you on board.

Let us know if you need anything.
`;

6️. Send the Email

Full Lambda:

import nodemailer from "nodemailer";

const transporter = nodemailer.createTransport({
  host: process.env.SMTP_HOST,
  port: Number(process.env.SMTP_PORT),
  secure: process.env.SMTP_PORT == "465",
  auth: {
    user: process.env.SMTP_USER,
    pass: process.env.SMTP_PASS,
  },
});

const getHtmlTemplate = (name) => `
  <html>
    <body>
      <h1>Welcome, ${name} 🎉</h1>
      <p>We're excited to have you on board.</p>
    </body>
  </html>
`;

const getTextTemplate = (name) => `
Welcome, ${name}!
We're excited to have you on board.
`;

export const handler = async (event) => {
  const email = event.request.userAttributes.email;
  const name = event.request.userAttributes.name || "there";

  try {
    await transporter.sendMail({
      from: `"Your App" <${process.env.SMTP_USER}>`,
      to: email,
      subject: "Welcome to our platform 🎉",
      text: getTextTemplate(name),
      html: getHtmlTemplate(name),
    });

    console.log("Email sent to:", email);
  } catch (err) {
    console.error("Email error:", err);
  }

  return event;
};

7️. Attach the Trigger

Go back to:

Cognito → User Pool → Authentication → Extensions → Add Lambda Trigger

Attach Lambda to:

Post Confirmation


Test It

  1. Create a new user
  2. Confirm signup
  3. Check inbox

Tips


Improvements


This setup gives you:

If you’re already using Cognito, this is a super easy upgrade.

Happy building 🚀