O P
O P

Reputation: 2365

Nodemailer and Amazon SES

My structure:

site
-- node_modules
---- nodemailer
-- webclient
---- js
------- controller.js

site/node_modules/nodemailer
site/webclient/js/controller.js

site/webclient/js/controller.js:

    var nodemailer = require('../../node_modules/nodemailer');

    var transport = nodemailer.createTransport('SES', {
        AWSAccessKeyID: 'xxx', // real one in code
        AWSSecretKey: 'xxx', // real one in code
        ServiceUrl: 'email-smtp.us-west-2.amazonaws.com'
    });

    var message = {
        from: '[email protected]', // verified in Amazon AWS SES
        to: '[email protected]', // verified in Amazon AWS SES
        subject: 'testing',
        text: 'hello',
        html: '<p><b>hello</b></p>' +
              'test'
    };

    transport.sendMail(message, function(error) {
        if (error) {
            console.log(error);
        } else {
            console.log('Message sent: ' + response.message);
        }
    });

This code is part of a controller where all other functions within it work perfectly.

I'm stuck.

Upvotes: 23

Views: 38558

Answers (8)

stanhope
stanhope

Reputation: 336

For those using nodemailer with imports, I needed * as AWS and {SESClient}.

import * as AWS from "@aws-sdk/client-ses";
import nodemailer from "nodemailer";

* as AWS is required for the SES object in createTransport. I also import SESClient because I got Jest errors resolving new AWS.SES(...) as in shown in other solutions.

const client_config = {...};
const ses_client = new SESClient(client_config);
const transporter = nodemailer.createTransport({
    SES: {
        ses: ses_client,
        aws: AWS,
    },
});

Upvotes: 0

Clemens
Clemens

Reputation: 973

TLDR:

import nodemailer from 'nodemailer'
import * as aws from '@aws-sdk/client-ses'

const ses = new aws.SES({ region: 'eu-central-1' })

const transporter = nodemailer.createTransport({
    SES: { ses, aws }
})


More detailed breakdown and explanation of the code above:

  1. Importing Required Modules:
import nodemailer from 'nodemailer';
import * as aws from '@aws-sdk/client-ses';

This part of the code imports the necessary modules. nodemailer is the main module used for sending emails in Node.js applications. @aws-sdk/client-ses is the AWS SDK for JavaScript v3, specifically the SES client. It's a modular version of the AWS SDK, which allows you to only import the specific client you need, in this case, SES for email services.

  1. Configuring AWS SES Client:
const ses = new aws.SES({ region: 'eu-central-1' });

Here, an instance of the SES client is created and configured with the region where you intend to use the SES service. The region 'eu-central-1' refers to the Frankfurt region, but you should replace this with the region that best suits your application's requirements or where your AWS resources are located.

  1. Creating a Nodemailer Transporter with AWS SES:
const transporter = nodemailer.createTransport({
    SES: { ses, aws }
});

In this step, a Nodemailer transporter object is created. This transporter is configured to use AWS SES for sending emails. The SES option within the createTransport method is specifically designed for this purpose. By passing the SES client instance (ses) and the AWS SDK (aws), you're instructing Nodemailer to send emails through AWS SES.

Additional Explanations and Documentation:

  • Nodemailer is a module that allows Node.js applications to easily send emails. It supports various transport options, including SMTP, SES, and more. The official Nodemailer documentation provides a comprehensive guide on its usage: Nodemailer Documentation.

  • AWS SES (Simple Email Service) is a cloud-based email sending service designed to help digital marketers and application developers send marketing, notification, and transactional emails. It's a reliable and cost-effective service for businesses of all sizes. The AWS SDK for JavaScript documentation covers how to use the SES client, among other AWS services: AWS SDK for JavaScript v3 Documentation.

When integrating these services into your application, it's important to ensure that your AWS account and SES service are properly set up and that you have the necessary permissions to send emails. This setup might involve verifying email addresses or domains with SES and ensuring your account is out of the SES sandbox environment, allowing you to send emails to any address, not just verified ones.

Additionally, managing the security of your AWS credentials is crucial. Ensure they are not hardcoded in your application code. Instead, use environment variables or the AWS Secrets Manager to keep them secure.

Upvotes: 0

Lonare
Lonare

Reputation: 4653

With new firebase v9 i used following code and it worked:

exports.sendEmail = functions.https.onRequest(async (req, res) => {
  const params = {
    Destination: {
      ToAddresses: ['[email protected]'], // Add recipient email addresses
    },
    Message: {
      Body: {
        Text: {
          Data: 'Hello, this is the email content!', // Add your email content here
        },
      },
      Subject: {
        Data: 'Firebase Cloud Function Email', // Add your email subject here
      },
    },
    Source: '[email protected]', // Add the sender email address
  };

  try {
    await ses.sendEmail(params).promise();
    res.status(200).send('Email sent successfully');
  } catch (error) {
    console.error('Error sending email:', error);
    res.status(500).send('Error sending email');
  }
});

Full tutorial here

Upvotes: 0

Pramod Jaiswal
Pramod Jaiswal

Reputation: 724

Please use aws-sdk directly. It work for me. Hope it will help you.`

let nodemailer = require('nodemailer');
let AWS = require('aws-sdk');

// configure AWS SDK
AWS.config.update({
  accessKeyId: << SES_ACCESS_KEY >>,
  secretAccessKey: << SES_SECRET_KEY >>,
  region: << SES_REGION >>,
});

// create Nodemailer SES transporter
let transporter = nodemailer.createTransport({
SES: new AWS.SES({
  apiVersion: '2010-12-01'
})
});

// send some mail
transporter.sendMail({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Message',
  text: 'I hope this message gets sent!'
}, (err, info) => {
  console.log(info.envelope);
  console.log(info.messageId);
});

Upvotes: 20

user1665355
user1665355

Reputation: 3393

You can do it like this:

let nodemailer = require('nodemailer');
const aws = require('aws-sdk');

export default async function mail({ toAdress, subject, text, html = null }) {
  let transporter = nodemailer.createTransport({
    // Credentials for user with SES access in AWS.
    SES: new aws.SES({
      accessKeyId: process.env.AWS_SES_ACCESS_KEY_ID,
      secretAccessKey: process.env.AWS_SES_SECRET_ACCESS_KEY,
    }),
  });
  try {
    await transporter.sendMail({
      from: '[email protected]',
      to: toAdress,
      subject: subject,
      html: html,
    });
  } catch (error) {
    if (error.response) {
      console.error(error.response.body);
    }
  }
}

Upvotes: -1

Deepak Puthraya
Deepak Puthraya

Reputation: 1435

The below code is what I used and it worked for me. This is for the current NodeMailer. Where the transport module needs to be included separately. In the previous versions the transport modules were built in.

var nodemailer = require('nodemailer');
var sesTransport = require('nodemailer-ses-transport');

var SESCREDENTIALS = {
  accessKeyId: "accesskey",
  secretAccessKey: "secretkey"
};

var transporter = nodemailer.createTransport(sesTransport({
  accessKeyId: SESCREDENTIALS.accessKeyId,
  secretAccessKey: SESCREDENTIALS.secretAccessKey,
  rateLimit: 5
}));

var mailOptions = {
  from: 'FromName <[email protected]>',
  to: '[email protected]', // list of receivers
  subject: 'Amazon SES Template TesT', // Subject line
  html: < p > Mail message < /p> / / html body
};

// send mail with defined transport object
transporter.sendMail(mailOptions, function(error, info) {
  if (error) {
    console.log(error);
  } else {
    console.log('Message sent: ' + info);
  }
});

UPDATE

The nodemailer library has been updated since I last wrote this answer. The correct way to use the library with AWS SES is provided in their docs. The link for a working example

Further Reading

Upvotes: 15

Lahiru Chandima
Lahiru Chandima

Reputation: 24068

Following nodemailer transport configuration worked for me. This doesn't require AWS SDK.

const nodeMailerTransporter = require('nodemailer').createTransport({
    host: '<aws.smpt.host>',
    port: 465,
    auth: {
        user: '<aws_smtp_user>',
        pass: '<aws_smtp_pass>'
    }
});

Where to obtain configurations:

<aws.smpt.host> can be found in Server Name value of SMTP Settings page of AWS SES console.

<aws_smtp_user> and <aws_smtp_pass> are obtained by creating SMTP credentials with Create My SMTP Credentials button in SMTP Settings page of AWS SES console.

Upvotes: 3

Gustavo Decker
Gustavo Decker

Reputation: 91

I use this code in a controller and it worked for me very well. It is using the SMTP auth from AWS SES.

var nodemailer = require('nodemailer');
var dotenv = require('dotenv').config();

var mailOptions = {
  from: '[email protected]',
  to: '[email protected]',
  text: 'This is some text',
  html: '<b>This is some HTML</b>',
};

// Send e-mail using SMTP
mailOptions.subject = 'Nodemailer SMTP transporter';
var smtpTransporter = nodemailer.createTransport({
  port: 465,
  host: process.env.AWS_REGION,
  secure: true,
  auth: {
    user: process.env.AWS_ACCESS_KEY_ID,
    pass: process.env.AWS_SECRET_ACCESS_KEY,
  },
  debug: true
});

smtpTransporter.sendMail(mailOptions, (error, info) => {
  if (error) {
    console.log(error);
    res.status(error.responseCode).send(error.response);
  } else {
    console.log('Message sent: ' + info.response);
    res.status(200).send(info);
  }
});

Upvotes: 9

Related Questions