Send email using OAuth2, NodeJs the right way
Tags: javascript, tutorial, webdev, node
Published: 2022-08-10 11:14:00

_Hello there, I wrote an article few months ago about how to send email with NodeJs. Check the article [here](https://dev.to/drsimplegraffiti/send-mails-using-nodejs-42ag)._




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](https://console.cloud.google.com/) and create a new project and add a project name and click create
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5qamskcptbpqj3fqb7uv.png)
 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6bzq9sjqlu62nqsosrzu.png)

##### Switch to the project you just created. I named mine `Luther`. 
 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vt9k70ajdpl7kqctvw92.png)


---

#### Creating API credentials, click on the hamburger menu and navigate to `API and Services`
Let's get our credentials

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mne2jacbz9kq46ak9upd.png)

##### Click on credentials
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4118tb144a4wg9h1urux.png)

##### Click on OAuth ClientId
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tkxb8y6r8c406f0g7e4y.png)

##### Click on configure consent screen
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7qmzfo5170519qbg3fiy.png)

##### Click on create
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gcwvph6tx52v9jjnbr7u.png)

##### Configure the screen
Add your app name, email and logo in the highlighted box
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/29i7uz3exycbnpsktix0.png)

##### Click Save and continue
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ms35v56av67nu2xiwuxz.png)

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


##### Click the create credentials icon again
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hstsh3jx4txrvqme67k4.png)

##### Click Oauth CLient Id 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ua80j0hcqvxjchlrd0l.png)
       
 
##### Choose an application type
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/81vhz1hgod7dgcwj8e24.png)

##### Add your redirect and click the create button
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j8hx8ju9t6x3rom2mxg5.png)

You will get your clientID and secret, you can download or copy to somewhere safe
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6q4zfqawu0b785c5a17a.png)
 
---

#### Configure OAuth
Go to this url https://developers.google.com/oauthplayground  and click on the gear icon
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6h2zrcd6mimwj4fhyixv.png)

##### Click use own credentials
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cchxzgau3gh8efabo4so.png)

##### Enter the clientID and the secret key you saved earlier
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/952pca53amazh63ntq8w.png)

Next enter this url: https://mail.google.com/  in highlighted box in orange below
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/57nyw8kni0i7w77xmky1.png)

##### Click on the authorized api button and choose the email you want to authorize **Fig X**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5lffw8lrq98jqys6n0ih.png)
 

---


##### Fixing error -> Sometimes you get authorization error at this point
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lumpceo1qj4fw7isjj2d.png)
 
To fix let's authorize our app, go to dashboard and click the OAuth consent screen 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oepje55svo828yiuuzs4.png)

##### Click on publish
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9x00s13fndmb5bkoxjdy.png)


##### Retry the **Fig X** process and yo get the directed to this page
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zqvu8z22upbpuz1qm8l7.png)

##### Click on the Advanced button, then the unsafe button
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8quqtqbjdfzg8s93ulcm.png)

##### Click on continue
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ehad0qzfigjetore78pd.png)

#### You should get redirected back to the OAuth page
_Click on exchange authorization code for token_ in the Step 2 secttion
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h1djzavwnibj2pxttcpl.png)

This will generate refresh token, access token and Authorization code. Copy and save it somewhere safe.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r9xnxs8v199ylhdld48f.png)


---

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kabwm6g3yxxz6w33ytxj.png)


##### Create a user model
`models/user.model.js`
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vfg3b67ogojn267qijyb.png)


##### Create a user route
`routes/user.route.js`  
```javascript
const router = express.Router();

// signup
router.post('/signup', userSignup);
//...
modeule.exports = router;
```

---

##### Create your nodejs app and create a mail folder inside
```javascript
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;
```

##### Then in your user.controller.js file
```javascript
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' });
  }
};
```
⚠️: Ensure you use your `.env` to store your credentials
  
---
   
##### Testing our API
Let's test our API using postman
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jrfy27q89p2j2zgnggfq.png)


#### Check Integrated terminal for output
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qhc1wa8wmbl0u5pdxs94.png)


---

##### Check email
🕺🏻🕺🏻🕺🏻🕺🏻🕺🏻 It worked
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mu9rf3dsr77h5sarcn8a.png)


---

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

![thanks](https://media.giphy.com/media/EA4ZexjGOnfP2/giphy.gif)