DEV Community

9

Node.js Send Email using Google OAuth2

One common requirement of back-end application development is sending a message via email. This feature can support business processes such as verifying user data, notifications, account security, marketing, and many other use cases.

Then, how can we send an email message in a Node.js application?

One of the libraries that are widely used in sending emails is Nodemailer. There is the easiest way of implementation which using the Google App Password service. However, this method has been labelled by Google as less secure because the result of generated password is easy to memorize and less complex, so the security level is lower.

Alternatively, there is a way in sending an email using the Google OAuth2 method. OAuth2 (Open Authorization 2.0) is an authentication and authorization protocol used to allow third parties to access protected resources. This method has a high level of security and has been used as a security standard in the technology industry.

Ok, shall we begin :)

The first thing to do is to create a project in the Google Developer Console (make sure you have a Google account) :D

Create project in google developer console (1)
Create project in google developer console (2)

After the project is successfully created, go to the left tab in the section API & Services > OAuth Consent Screen then select External configuration. Next, fill in the app name data, user support email, and developer contact information, then follow the next instructions and save. To activate the OAuth Consent Screen configuration, do Publish App and confirm.

OAuth consent screen configuration (1)
OAuth consent screen configuration (2)

Great, it's time to configure the OAuth Client ID. On the tab API & Service, select the menu Credential > Create Credentials > OAuth Client ID. After that, fill the application type with a web application, a name with the application name (feel free to naming), and add the URI https://developers.google.com/oauthplayground in the Authorized redirect URIs section. Creating an OAuth Client ID generates credentials in the form of an ID and a secret (keep it safe, you can download it in JSON format).

OAuth Client ID configuration (1)
OAuth Client ID configuration (2)
OAuth Client ID configuration (3)

Nice, the next step is to test OAuth Client ID and get the refresh token. Visit Google Developer OAuth Playground, set OAuth Client ID and secret configuration using your credentials, then select http://mail.google.com/. Next, you will be redirected to the Google Authentication pages, choose the same account used to create OAuth Client ID. If you are facing a page that is not safe, open the menu Advanced Options and click Continue (not safe) (this is happen because we are not submitting the verification app to Google, but you can ignore it for a moment). The result is an authentication code, refresh token, and access token (once more, keep it safe).

OAuth test and getting refresh token (1)
OAuth test and getting refresh token (2)
OAuth test and getting refresh token (3)

Wow, the configuration is quite long, whereas we are not yet writing a single piece of code. But now, let's write some code. Start with creating an empty folder then initialize the project (fill it according to the project initialization instructions).



npm init


Enter fullscreen mode Exit fullscreen mode

We will code using Typescript, if you are more prefer using Javascript just install the 3 dependencies needed (however you will need some adjustments from Typescript to Javascript).



npm i --save-dev typescript ts-node @types/node


Enter fullscreen mode Exit fullscreen mode


npm i dotenv nodemailer googleapis


Enter fullscreen mode Exit fullscreen mode

Great, now create a file with an .env extension to store the credentials locally.



OAUTH_EMAIL=
OAUTH_CLIENT_ID=
OAUTH_CLIENT_SECRET=
OAUTH_REFRESH_TOKEN=


Enter fullscreen mode Exit fullscreen mode

Nice, now create an index.ts file. The first thing to do is import the required dependencies and get the value of our environment variables.

// import required dependencies
import dotenv from 'dotenv';
import nodemailer from 'nodemailer';
import { google } from 'googleapis';
const OAuth2 = google.auth.OAuth2;
// init dotenv
dotenv.config();
// get environment variables
const OAUTH_EMAIL = process.env.OAUTH_EMAIL || '' as string;
const OAUTH_CLIENT_ID = process.env.OAUTH_CLIENT_ID || '' as string;
const OAUTH_CLIENT_SECRET = process.env.OAUTH_CLIENT_SECRET || '' as string;
const OAUTH_REFRESH_TOKEN = process.env.OAUTH_REFRESH_TOKEN || '' as string;

Next, create an OAuth2 Client object and make a getAccessToken request. This function returns a value in the form of an accessToken code which is used as the authorization when sending emails.

// create OAuth2 client
const oauth2Client = new OAuth2(
OAUTH_CLIENT_ID,
OAUTH_CLIENT_SECRET,
'https://developers.google.com/oauthplayground'
);
// set refresh token
oauth2Client.setCredentials({
refresh_token: OAUTH_REFRESH_TOKEN
});
// get access token using promise
const accessToken = oauth2Client.getAccessToken()

Lastly, create a transporter configuration with SMTP and set the mailOptions as the email sending object.

// create reusable transporter object using the default SMTP transport
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
type: 'OAuth2',
user: OAUTH_EMAIL,
clientId: OAUTH_CLIENT_ID,
clientSecret: OAUTH_CLIENT_SECRET,
refreshToken: OAUTH_REFRESH_TOKEN,
accessToken: accessToken.toString()
}
});
// create mail options
const mailOptions = {
from: OAUTH_EMAIL,
to: 'someone@example.com',
subject: 'Hello ✔',
text: 'Hello world?',
};
// send mail
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log(error);
}
console.log('Message sent: %s', info.messageId);
});

Congratulations! Email sending using the OAuth2 method was successful. With the steps that have been followed, the email sent will be guaranteed to be secure and properly authenticated.

Conclusion

Using the OAuth2 method to send email via Nodemailer has several advantages, including: increasing security by avoiding using usernames and passwords, enabling good integration with third-party email services and can increase application scalability.

If you want to get this source code, feel free to take a look at this GitHub repo.

Thank you for reading this article, hope it's useful 📖. Don't forget to follow the account to get the latest information🌟. See you in the next article🙌.

Image of Datadog

The Essential Toolkit for Front-end Developers

Take a user-centric approach to front-end monitoring that evolves alongside increasingly complex frameworks and single-page applications.

Get The Kit

Top comments (2)

Collapse
 
alonmiz profile image
Alon Mizrahi • Edited

thanks for that article, but that is a particular use case, where you as an admin can send emails from your backend.
But, a more real-world use case is one where you as an application allow users to send emails using their Gmail, not just one specific email.
what about when you only have an accessToken to an authenticated user and want to send an email on his behalf?
thanks

Collapse
 
tommie_lee profile image
Alali Ogoli

hi, thank you for this article, i have followed every step but i get this
Error No refresh token or refresh handler callback is set.

Cloudinary image

Optimize, customize, deliver, manage and analyze your images.

Remove background in all your web images at the same time, use outpainting to expand images with matching content, remove objects via open-set object detection and fill, recolor, crop, resize... Discover these and hundreds more ways to manage your web images and videos on a scale.

Learn more

AWS GenAI LIVE!

GenAI LIVE! is a dynamic live-streamed show exploring how AWS and our partners are helping organizations unlock real value with generative AI.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️