DEV Community

Cover image for Send email using OAuth2, NodeJs the right way
Abayomi Ogunnusi
Abayomi Ogunnusi

Posted on

Send email using OAuth2, NodeJs the right way

Hello there, I wrote an article few months ago about how to send email with NodeJs. Check the article here.

While the method described in the blog works well, there are several drawbacks to using it.
Today, I'll walk you through a better way to send email in NodeJs.

Prerequisite

🎯 Install NodeJS
🎯 NodeJS RestAPI fundamentals


Setup

Head on google developer console and create a new project and add a project name and click create
Image description

Image description

Switch to the project you just created. I named mine Luther.

Image description


Creating API credentials, click on the hamburger menu and navigate to API and Services

Let's get our credentials

Image description

Click on credentials

Image description

Click on OAuth ClientId

Image description

Click on configure consent screen

Image description

Click on create

Image description

Configure the screen

Add your app name, email and logo in the highlighted box
Image description

Click Save and continue

Image description

Click on save and continue while leaving all other settings as default

Click the create credentials icon again

Image description

Click Oauth CLient Id

Image description

Choose an application type

Image description

Add your redirect and click the create button

Image description

You will get your clientID and secret, you can download or copy to somewhere safe
Image description


Configure OAuth

Go to this url https://developers.google.com/oauthplayground and click on the gear icon
Image description

Click use own credentials

Image description

Enter the clientID and the secret key you saved earlier

Image description

Next enter this url: https://mail.google.com/ in highlighted box in orange below
Image description

Click on the authorized api button and choose the email you want to authorize Fig X

Image description


Fixing error -> Sometimes you get authorization error at this point

Image description

To fix let's authorize our app, go to dashboard and click the OAuth consent screen
Image description

Click on publish

Image description

Retry the Fig X process and yo get the directed to this page

Image description

Click on the Advanced button, then the unsafe button

Image description

Click on continue

Image description

You should get redirected back to the OAuth page

Click on exchange authorization code for token in the Step 2 secttion
Image description

This will generate refresh token, access token and Authorization code. Copy and save it somewhere safe.
Image description


Now that we have gotten api google console credentials, let's create our NodeJS app using ExpressJS

Intialize a NodeJs app

npm init -y

Install Development Dependencies

npm i express nodemailer googleapis

Create a NodeJS Server

index.js
Image description

Create a user model

models/user.model.js
Image description

Create a user route

routes/user.route.js

const router = express.Router();

// signup
router.post('/signup', userSignup);
//...
modeule.exports = router;
Enter fullscreen mode Exit fullscreen mode

Create your nodejs app and create a mail folder inside
const nodemailer = require('nodemailer');
const { google } = require('googleapis');
const OAuth2 = google.auth.OAuth2;

const oauth2Client = new OAuth2(
  'put client id here',
  'put client secret here', // Client Secret
  'https://developers.google.com/oauthplayground' // Redirect URL
);

oauth2Client.setCredentials({
  refresh_token:
    ' add your refresh token here',
});
const accessToken = oauth2Client.getAccessToken();

const sendEmail = async (options) => {
  const transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
      type: 'OAuth2',
      user: 'put your email here',
      clientId:
        'put your client id here',
      clientSecret: 'put your client secret here',
      refreshToken:
        'put your refresh token here',
      accessToken: accessToken,
    },
    tls: {
      rejectUnauthorized: false,
    },
  });
  try {
    const message = {
      from: "put your email here",
      to: options.email,
      subject: options.subject,
      text: options.message,
      html: options.message,
    };

    const m = await transporter.sendMail(message);
    console.log(m);
  } catch (error) {
    console.log(error);
    return error;
  }
};

module.exports = sendEmail;
Enter fullscreen mode Exit fullscreen mode
Then in your user.controller.js file
const User = require('../models/user.model');
const House = require('../models/house.model');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const sendEmail = require('../mail/email-sender');

exports.userSignup = async (req, res) => {
  const { password, email, name } = req.body;
  try {
    //  hash password
    const salt = await bcrypt.genSalt(10);
    const hashedPassword = await bcrypt.hash(password, salt);
    const user = await User.create({
      name,
      email,
      password: hashedPassword,
    });
    await sendEmail({
      email: user.email,
      subject: `${user.name} Registered Successfully`,
      message: `<div>
          <h1>HELLO ${user.name}</h1>
          <h2>You just registered successfully</h2>
      </div>`,
    });
    return res
      .status(201)
      .json({ message: 'User created successfully', userId: user._id });
  } catch (error) {
    console.log(error);
    if (error.message.includes('duplicate key error')) {
      return res
        .status(200)
        .json({ message: `${error.message.split('{')[1]} already exist` });
    }
    return res
      .status(500)
      .json({ error: error.message, message: 'internal server error' });
  }
};
Enter fullscreen mode Exit fullscreen mode

⚠️: Ensure you use your .env to store your credentials


Testing our API

Let's test our API using postman
Image description

Check Integrated terminal for output

Image description


Check email

πŸ•ΊπŸ»πŸ•ΊπŸ»πŸ•ΊπŸ»πŸ•ΊπŸ»πŸ•ΊπŸ» It worked
Image description


Conclusion

I hope this post was helpful in sending email using NodeJS.
Thanks for reading

thanks

Oldest comments (0)