5

I'm trying to use gmail smtp with the latest version of nodemailer. I've done the steps that are described here. When sending a mail I still get the following errormessage:

Error: Invalid login: 535-5.7.8 Username and Password not accepted

It's pretty weird since I never try logging in with a password/username, but I use OAuth2 instead:

    transporter = nodemailer.createTransport({
        service: 'gmail',
        auth: {
            type: 'OAuth2',
            user: 'hello@company.com',
            clientId: '<clientId>.apps.googleusercontent.com',
            clientSecret: '<clientSecret>',
            accessToken: '<accessToken>',
            refreshToken: '<refreshToken>',
        }
    });

     transporter.sendMail({
        from: from,
        to: to,
        subject: subject,
        text: message,
        html: htmlMessage
    }, function (err, data) {
            if (err) {
                console.log(err);
                console.log("======");
                console.log(subject);
                console.log(message);
            } else {
                console.log('Email sent:');
                console.log(data);
            }
    });

Does anyone know what I've missed? I tried doing all these steps to generate these tokens 3 times so I'm pretty sure all credentials are filled in correctly.

Thanks in advance

JC97
  • 1,530
  • 2
  • 23
  • 44

4 Answers4

3

Based from this post, try configuring your transporter as shown below:

const transporter = nodemailer.createTransport({
  host: 'smtp.gmail.com',
  port: 465,
  secure: true,
  auth: {
    type: 'OAuth2',
    user: process.env.MAIL_USER,
    clientId: process.env.GOOGLE_CLIENT_ID,
    clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    refreshToken: process.env.GOOGLE_CLIENT_REFRESH_TOKEN
  }
});

If you're unsure how to generate the id, secret and token, follow the steps here https://medium.com/@pandeysoni/nodemailer-service-in-node-js-using-smtp-and-xoauth2-7c638a39a37e

You may also check this link for the possible causes why you're encountering that error.

Community
  • 1
  • 1
abielita
  • 13,147
  • 2
  • 17
  • 59
  • I'm pretty sure the id, secret & token is generated correctly following the official gmail API docs & the authentication there went well. I see no difference with what I've done in your snippet? Except I used accesstoken as well, but even without I get the same error. I followed this guide as well: https://nodemailer.com/smtp/oauth2/ always "username and password not accepted' even if I don't provide one. I'll take a look at the other links you provided so thanks anyways! :) – JC97 Jul 27 '18 at 18:55
  • @JC97 is it resolved yet? Seems to be issue with scopes used when i change scope to use full permission it works else not. – ngLover Nov 27 '18 at 10:26
  • No we just stepped away from using Google & used Mailgun instead :) – JC97 Nov 27 '18 at 12:29
1

In my case, setting the user to only my username seems magically works!

const transport = nodemailer.createTransport({
  service: 'gmail',
  auth: {
    type: 'OAuth2',
    user: 'test', //Excluding the part after '@' Example: test@gmail.com to only 'test'
    clientId: CLIENT_ID,
    clientSecret: CLEINT_SECRET,
    refreshToken: REFRESH_TOKEN,
    accessToken: accessToken,
  },
});
UTSHO
  • 113
  • 2
  • 8
0

Add both the scopes https://mail.google.com/ and http://mail.google.com/ when generating a refresh token. When running a local dev server that isn't using HTTPS, it'll make non-encrypted requests, which it needs additional permissions for.

DutchJelly
  • 116
  • 9
0

So, after a lot of digging through, I found out that nodemailer only works with the https://mail.google.com scope (https://nodemailer.com/smtp/oauth2/#troubleshooting).

It does not work with the https://www.googleapis.com/auth/gmail.send scope. Since the https://mail.google.com scope gives permission to delete all emails in the inbox, nodemailer may not work for your application.

Solution: use the gmail API (https://developers.google.com/gmail/api/guides/sending) or gmail.users.messages.send instead of nodemailer to send emails. Since the API is offered directly by google, it works with the gmail.send scope. Here is some sample code:

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


function makeBody(to, from, subject, message) {
  var str = [
    'Content-Type: text/html; charset="UTF-8"\n',
    "MIME-Version: 1.0\n",
    "Content-Transfer-Encoding: 7bit\n",
    "to: ",
    to,
    "\n",
    "from: ",
    from,
    "\n",
    "subject: ",
    subject,
    "\n\n",
    message,
  ].join("");

  var encodedMail = new Buffer(str)
    .toString("base64")
    .replace(/\+/g, "-")
    .replace(/\//g, "_");
  return encodedMail;
}

export const sendEmail = async () => {
    const gmail = google.gmail({ version: "v1", auth: oauth2Client });
    let raw = makeBody(
      "receiver@gmail.com",
      "sender@gmail.com",
      "my subject",
      "my body"
    );
    const response = await gmail.users.messages.send({
      userId: emailOptions.from,
      resource: { raw },
    });
    console.log("this is the response", response); 
}
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 24 '23 at 20:21