1

I think the answer is that using a gcloud service account with GmailAPI requires domain wide delegation, but I haven't been able to find a definitive answer.

Basic code setup within node, called from my express server.

const { google } = require('googleapis');
const gmail = google.gmail('v1');
const GMAIL_SCOPE_SEND = 'https://www.googleapis.com/auth/gmail.send';

const setAuth = async (scopes) => {
  const auth = new google.auth.GoogleAuth({
    // Uses default credientials from the env variable GOOGLE_APPLICATION_CREDENTIALS
    // Scopes can be specified either as an array or as a single, space-delimited string.
    scopes: scopes,
  });
  const authClient = await auth.getClient();
  google.options({ auth: authClient });
  return authClient;
};

const sendEmail = async (address, code) => {
  console.log('sendEmail', address, code);

  const subject = "Hello";
  const utf8Subject = `=?utf-8?B?${Buffer.from(subject).toString('base64')}?=`;
  const messageParts = [
    'From: ${SERVICE_ACCOUNT_EMAIL}',
    `To: ${address}`,
    'Content-Type: text/html; charset=utf-8',
    'MIME-Version: 1.0',
    `Subject: ${utf8Subject}`,
    '',
    'Test',
  ];
  const message = messageParts.join('\n');

  // The body needs to be base64url encoded.
  const encodedMessage = Buffer.from(message)
    .toString('base64')
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '');

  const res = await gmail.users.messages.send({
    userId: 'me',
    requestBody: {
      raw: encodedMessage,
    },
  });
  console.log(res.data);
  return res.data;
};

const init = () => {
  setAuth([GMAIL_SCOPE_SEND]);
};
init();

module.exports = { sendEmail };

This results in the error:

code: 400,
errors: [
 {
   message: 'Precondition check failed.',
   domain: 'global',
   reason: 'failedPrecondition'
 }
]

Is there a way to make this work? What does this error mean?

Ohhh
  • 460
  • 5
  • 8
  • There is an excellent post about how to send emails using a service account in node.js [here](https://stackoverflow.com/questions/37243862/send-mail-via-google-apps-gmail-using-service-account-domain-wide-delegation-in). But in a nutshell, you need to create your credentials using a token and the ```google.auth.JWT()``` method. – Oriol Castander Jan 04 '22 at 09:10

0 Answers0