Can't send nodemailer using Oauth2 by Google cloud (responseCode: 530)

Viewed 176

I've already configured two GMAIL accounts to integrate nodemailer with Oauth2 from Google cloud, the first time I've done it I could successfully send GMAIL's email from my nodejs application. However, today I've made the same steps I've already done before and It's throwing an error when I try to send an e-mail.

Error: Mail command failed: 530-5.7.0 Authentication Required

Some answers on internet says I need to activate less secure app on google, but since May,2022 this option was deactivate by google, so I can't do it.

All the steps I made to set up the Oauth2 on Google cloud (summary):

  1. Create a new project

  2. Eneabled services and API's

  3. Created a new Oauth2 on OAuth consent screen

  4. Created new credential, web application, with redirecting: https://developers.google.com/oauthplayground

  5. Added test users on OAuth consent screen

  6. On oauthplayground selected 'https://mail.google.com' service and added CLIENT_ID and CLIENT_SECRET, then click on Exchange authorization code for tokens

This is the same set up I always do when I need to configure nodejs with GMAIL, I should work, then I copy all necessary values to node.js CLIENT_ID , CLIENT_SECRET, refresh_tokens ...


Now I would like to share to important .js files related with nodemailer and GoogleApis, respectively:

const nodemailer = require('nodemailer');
const urlUtil = require('../utils/urlUtil');
const config = require(urlUtil.getPath('../config.min.js'));
const googleApiUtil = require(urlUtil.getPath('../utils/googleApiUtil.min.js'));

/**
 * Send generic email
 * @param {*} destination to
 * @param {*} subject title of the email
 * @param {*} html html content for email template
 * @returns promise
 */
function sendEmail(destination, subject, html) {

    return new Promise((resolve) => {
        googleApiUtil.getCredentials().then((credentials) => {
            try {
                let transporter = nodemailer.createTransport({
                    service: config.mail.service,
                    auth: {
                        type: 'OAuth2',
                        user: config.mail.user,
                        clientId: credentials.client_id,
                        clientSecret: credentials.client_secret,
                        refreshToken: credentials.refresh_token,
                        accessToken: credentials.accessToken
                    }, tls: {
                        rejectUnauthorized: false
                    }

                });
                let mailOptions = {};

                mailOptions = {
                    from: `IARA <${config.mail.user}>`,
                    to: destination,
                    subject: subject,
                    html: html,
                    attachments: null

                };

                transporter.sendMail(mailOptions, resolve);
            } catch (error) {
                console.log(error);
            }
        });

    });
}

//This should send an email to destinantion
sendEmail('adriel.kirch.1@gmail.com','teste','testando').then(r=> {
    console.log(r)
})

/**
 * Exports
 */
module.exports = {
    sendEmail
};

const {google} = require('googleapis');
const urlUtil = require('../utils/urlUtil');
const config = require(urlUtil.getPath('../config.min.js'));
const fsUtil = require(urlUtil.getPath('../utils/fsUtil.min.js'));
//Basic credentials
const CLIENT_ID = '4123123..';
const CLIENT_SECRET = 'GO...';

//https://developers.google.com/oauthplayground
const REDIRECT_URI = 'https://developers.google.com/oauthplayground';
let refresh_token = '';
let accessToken = '';

if (!config.mail.refresh_token) {
    refresh_token = '1//...';
} else {
    refresh_token = config.mail.refresh_token;
}

const oAuth2Client = new google.auth.OAuth2(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI);


oAuth2Client.setCredentials({
    refresh_token: refresh_token,
});

oAuth2Client.refreshAccessToken((err, tokens) => {
    console.log(tokens)
    accessToken = tokens['access_token'];
    refresh_token = tokens['refresh_token'];
    //Set Config
    if (err) {
        console.log(err);
    }
    config.mail.accessToken = accessToken;
    config.mail.refresh_token = refresh_token;
    fsUtil.updateCredentials(config);
});

/**
 * @returns Get credentials
 */
async function getCredentials() {
    return {
        redirect_uri: REDIRECT_URI,
        refresh_token: refresh_token,
        client_id: CLIENT_ID,
        client_secret: CLIENT_SECRET,
        accessToken: accessToken
    };
}


module.exports = {
    getCredentials
};

Conclusion:

I not even know if my mistake is on Oauth2 configuration or in Nodejs, I belive it's on Google cloud, but I'm not really sure, If anyone more experienced know how I can solve it let me know, Thanks a lott

Fullstack trace:

Error: Mail command failed: 530-5.7.0 Authentication Required. Learn more at 530 5.7.0 https://support.google.com/mail/?p=WantAuthError dy43-20020a056870c7ab00b00101cdb417f1sm5627633oab.22 - gsmtp at SMTPConnection._formatError (c:\Javascript Projects\IARA-backend\node_modules\nodemailer\lib\smtp-connection\index.js:784:19) at SMTPConnection._actionMAIL (c:\Javascript Projects\IARA-backend\node_modules\nodemailer\lib\smtp-connection\index.js:1566:34) at SMTPConnection. (c:\Javascript Projects\IARA-backend\node_modules\nodemailer\lib\smtp-connection\index.js:1041:18) at SMTPConnection._processResponse (c:\Javascript Projects\IARA-backend\node_modules\nodemailer\lib\smtp-connection\index.js:947:20) at SMTPConnection._onData (c:\Javascript Projects\IARA-backend\node_modules\nodemailer\lib\smtp-connection\index.js:749:14)
at TLSSocket.SMTPConnection._onSocketData (c:\Javascript Projects\IARA-backend\node_modules\nodemailer\lib\smtp-connection\index.js:189:44) at TLSSocket.emit (events.js:315:20) at addChunk (internal/streams/readable.js:309:12) at readableAddChunk (internal/streams/readable.js:284:9) at TLSSocket.Readable.push (internal/streams/readable.js:223:10) { code: 'EENVELOPE', response: '530-5.7.0 Authentication Required. Learn more at\n' + '530 5.7.0 https://support.google.com/mail/?p=WantAuthError dy43-20020a056870c7ab00b00101cdb417f1sm5627633oab.22 - gsmtp',
responseCode: 530, command: 'MAIL FROM' }

1 Answers

I've just solved the issue, the best solution I got, whenever I call the oAuth2Client.refreshAccessToken() function I save all returned credentials such as refresh_token, access_token on a config file (.json), so when I call to send e-mail I got those credentials updated from config file. It's was quite easy actually, sorry for open a silly question here on Stackoverflow.

Related