Sending Emails Using Node.js, Nodemailer, SMTP, Gmail, and OAuth2 Part 2

Hey Everyone,

In this article, we will learn how to send mail using OAuth credentials in Node.js.

To get the OAuth credentials first follow Part-1.

Execute the following command on the terminal or command prompt to create the node js app:

mkdir Send_mail_Using_oauth2
cd Send_mail_Using_oauth2

To initialize the app as a node project, run npm init.

Next, let’s install the npm packages.

npm i express nodemailer googleapis --save
npm i dotenv --save

Create an index.js file, So go to your app root directory and create it. Now import the below dependencies in the index.js file:

const express = require("express");
const nodemailer = require("nodemailer");
const { google } = require("googleapis");
const OAuth2 = google.auth.OAuth2;
require("dotenv").config();

Now, we have to create environment variables setup

Create a .env file in the root directory of the project and add the following:

EMAIL=YOUR_GOOGLE_EMAIL_HERE
REFRESH_TOKEN=PASTE_REFRESH_TOKEN_HERE
CLIENT_SECRET=PASTE_CLIENT_SECRET_HERE
CLIENT_ID=PASTE_CLIENT_ID_HERE

Now, we need to create an OAuth client with all of our info (client ID, client secret, and the OAuth Playground URL) that we’ve saved earlier. so that the OAuth client will allow us to create an access token from a refresh token.

If you noticed earlier, there was a message indicating the access token would expire after 3582 seconds.

The following code creates the OAuth client and provides it with the refresh token, So copy the below code and paste it into the index.js file:

const oauth2Client = new OAuth2(
    process.env.CLIENT_ID,
    process.env.CLIENT_SECRET,
    "https://developers.google.com/oauthplayground"
);

oauth2Client.setCredentials({
    refresh_token: process.env.REFRESH_TOKEN
});

Now, we can get the access token by calling the getAccessToken method.

const accessToken = oauth2Client.getAccessToken();

We now have to describe how we want to send the email using SMTP and Nodemailer:

const transporter = nodemailer.createTransport({
    service: "gmail",
    auth: {
        type: "OAuth2",
        user: process.env.EMAIL,
        accessToken: accessToken,
        clientId: process.env.CLIENT_ID,
        clientSecret: process.env.CLIENT_SECRET,
        refreshToken: process.env.REFRESH_TOKEN
    }
});

If you receive an “unauthorized client”, try adding the following to the JS object above.

tls: {
  rejectUnauthorized: false
}

After the transporter is created, let’s give our email some content.

const mailOptions = {
    from: process.env.EMAIL,
    to: "put_email_of_the_recipient",
    subject: "Node.js Email with Secure OAuth",
    generateTextFromHTML: true,
    html: "<b>Hello</b>"
};

Now, let’s send our email.

transporter.sendMail(mailOptions, (error, response) => {
    if (error) {
        console.log(error);
    } else {
        console.log(response);
    }
    transporter.close();
});

Here is, Complete code of the index.js file :

const express = require('express');
const port = 3000;
const nodemailer = require("nodemailer");
const { google } = require("googleapis");
const OAuth2 = google.auth.OAuth2;
require("dotenv").config();
const app = express();

const oauth2Client = new OAuth2(
    process.env.CLIENT_ID,
    process.env.CLIENT_SECRET,
    "https://developers.google.com/oauthplayground"
);

oauth2Client.setCredentials({
    refresh_token: process.env.REFRESH_TOKEN
});
const accessToken = oauth2Client.getAccessToken();
const transporter = nodemailer.createTransport({
    service: "gmail",
    auth: {
        type: "OAuth2",
        user: process.env.EMAIL,
        accessToken: accessToken,
        clientId: process.env.CLIENT_ID,
        clientSecret: process.env.CLIENT_SECRET,
        refreshToken: process.env.REFRESH_TOKEN
    }
});

const mailOptions = {
    from: process.env.EMAIL,
    to: "put_email_of_the_recipient",
    subject: "Node.js Email with Secure OAuth",
    generateTextFromHTML: true,
    html: "<b>Hello</b>"
};

transporter.sendMail(mailOptions, (error, response) => {
    if (error) {
        console.log(error);
    } else {
        console.log(response);
    }
    transporter.close();
});

app.listen(port, console.log("Server Start"));

Now let’s run your project using the node index.js command from the terminal and you should get something that looks like this in the terminal.

{
  accepted: [ 'your_gmail' ],
  rejected: [],
  envelopeTime: 744,
  messageTime: 720,
  messageSize: 324,
  response: '250 2.0.0 OK  1657170200 n11-20020a17090a2bcb00b001e85f38bc79sm15740403pje.41 - gsmtp',
  envelope: {
    from: 'your_gmail',
    to: [ 'receiver_gmail' ]
  },
  messageId: '<19ece37a-aa82-522d-99db-e8a3fd0731c6@gmail.com>'
}

Here is the email we sent from the application.

I hope you guys understand how I can do this. If you have any suggestions for improvement or thoughts on better ways of sending a secure email using OAuth please let me know in the comments.

Also check, Node.JS Resize Image Before Upload using Multer Sharp

Submit a Comment

Your email address will not be published. Required fields are marked *

Subscribe

Select Categories