How to get nodemailer to work with 2LO for service accounts?
Asked Answered
O

3

6

I have followed the instructions on the nodemailer site to the letter, but OAuth2 for google service accounts simply does not work for me.

Either I get ECONN timeouts when setting "host" to mail.google.com or some combination of "401, user/pwd not accepted, can not create access token" errors when using smtp.gmail.com as the host.

There seems to be an endless supply of answers for 3LO, but none that I've tried for 2LO that work. Now, having said all that.

var nodemailer = require("nodemailer");
var { google } = require("googleapis");

var accessToken;
var expires;
var key = require(“path/to/secrets.json");
var privateKey = key.private_key;

var jwtClient = new google.auth.JWT(key.client_email, null, key.private_key, ["https://mail.google.com/"], null);

jwtClient.authorize(function(err, tokens) {
    if (err) {
        return;
     } else {
    token = tokens
    accessToken = tokens.access_token //this **IS** a valid token
    expires = tokens.expiry_date
     }

 var transporter = nodemailer.createTransport({
        host: "smtp.gmail.com",
        port: 465,
        secure: true,
        auth: {
            type: "OAuth2",
            user: key.client_email, //I've also used my email here
            serviceClient: key.client_id,
            privateKey: privateKey,
            accessToken: accessToken,
            expires: expires,
        },
    });

var mailOptions = {
    from: “[email protected]”
    to: “[email protected]",
    subject: "Ready",
    text: “Really Ready"
    }

transporter.sendMail(mailOptions, function(error, info) {
    if (error) {
        return;
    }
    console.log("Message %s sent: %s", info.messageId, info.response);
});
});

which generated the error:

535-5.7.8 Username and Password not accepted.

But as I mentioned, I've tried differing configurations and settings and gotten just as many different errors...

SO... Has anyone had success in using service accounts for 2LO using nodemailer?

I'm using node 9.5.0 and nodemailer ^4.6.0

Orb answered 27/2, 2018 at 23:21 Comment(1)
see gypsyshen.com/2018/03/01/… . it works ...Zacharie
P
1

I got it working (2021!), these were the steps:

  1. Log in to console.- https://console.cloud.google.com/
  2. Create a service account under the project.
  3. Click on the new service account, go to permissions and add a member. You will use this member's email address when sending the request.
  4. Create keys for the service account. - keys -> add key. https://console.cloud.google.com/iam-admin/serviceaccounts
  5. Download your key file. You will get something like service-account-name-accountid.json. It will have all the information you need to get the code below running.
  6. Delegate authority to your service account https://developers.google.com/identity/protocols/oauth2/service-account#delegatingauthority. Addhttps://mail.google.com/ as the scope.
  7. Write some code like below:

const nodemailer = require('nodemailer');
const json = require('./service-account-name-accountid.json');

const sendEmail = async (email, subject, text) => {
    try {

        const transporter = nodemailer.createTransport({
            host: 'smtp.gmail.com',
            port: 465,
            secure: true,
            auth: {
                type: 'OAuth2',
                user: email, //your permissioned service account member e-mail address
                serviceClient: json.client_id,
                privateKey: json.private_key
            }
        });

        await transporter.verify();
        
        await transporter.sendMail({
                from: json.service_email,
                to: email, //you can change this to any other e-mail address and it should work!
                subject,
                text
        });
        console.log('success!');
        return {
            status : 200
        }

    } catch (error) {
        console.log(error);
        return {
            status : 500,
            error
        }
    }
}

sendEmail('your_permissioned_service_account_email_address@some_place.com, 'testing 123', 'woohoo!');
Peruse answered 9/6, 2021 at 16:37 Comment(0)
M
0

Why? Because one the default scopes on your credentials for OAuth 2.0 client IDs are these:

  1. email <- Can only view email address
  2. profile
  3. openid

If you want to send email using node mailer it should include this scope:

https://mail.google.com/

and which is a sensitive scope, so google needs to verify it first else you will receive some delegation error messages.

Follow this verification process.

And add scope in the consent page

Or

Make sure you're an admin of the gsuite then give your service account access to sending email or an admin can give your service account access to sending email.

This guide will help. It's in Japanese just translate it to english.

Marcheshvan answered 29/4, 2019 at 19:42 Comment(0)
A
0

Old thread, but I've got this working just now (after a lot of trying) so a few suggestions for anyone interested:

  1. Enable the Gmail API in the Cloud Console
  2. Use your 'normal' email address as the user (not the Service Account email)
  3. Go here https://admin.google.com/ac/owl/domainwidedelegation and add your service client to the list. Here you will have to type in your client_id for the Client Name part and https://mail.google.com/ as the API scope. This last part was hard to find, but made it work for me in the end.

Also, I found this guide very helpful: Here you will have to type in your client_id for the Client Name part and https://mail.google.com/ as the API scope before pressing the Authorise.

Astri answered 1/9, 2020 at 8:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.