title: Google Suite - Google API access - Client is unauthorized to retrieve access tokens using this method
body: <p>I am struggling for days with the set up in trying to access GMail Google API from a node.js script using googleapis lib. I succeeded once but I cannot remember how I did it , I tried to reset a project, service-account and G-Suite Domain wide delegation following the Google doc .. </p>
  
  <p>Here is what I did :</p>
  
  <p>In my GCP Console console, 
  1. Existing organisation : lechorodescharentes.org
  2. In this organisation , I created a project : choro-dev
  3. In this project I created a service account : choro-dev-postoffice
      with choro-dev-postoffice with role TokenGenerator
      and enabled the Google Apps Domain-wid Delegation
      downloaded the new private key ( JSON file )
  4.  I enabled the GMail API ( from Libray menu)</p>
  
  <p>In my G-Suite domain's admin console, 
  5. I added the following copes for this service account's ClientID
       "<a href="https://www.googleapis.com/auth/admin.directory.user" rel="nofollow noreferrer">https://www.googleapis.com/auth/admin.directory.user</a>",
       "<a href="https://www.googleapis.com/auth/admin.directory.group" rel="nofollow noreferrer">https://www.googleapis.com/auth/admin.directory.group</a>"</p>
  
  <ol start="6">
  <li><p>Node.js client
  I am trying to access the GMail API with the following Firebase function code using the node.js googleapis library
  with server -server authentication using service account
  see node.js client code
  In this code, I have 2 authentication functions
   connect() : to a JSON Web Token
   authorize() : to request an access token from the Google OAuth 2.0 Authorization Server</p></li>
  <li><p>Deployed the Firebase function</p></li>
  <li>Run the function</li>
  <li>Got the JWT client displayed</li>
  <li>Function ended with error :
  {"infos":"unauthorized_client: Client is unauthorized to retrieve access tokens using this method."}</li>
  </ol>
  
  <p><strong>node.js client code</strong></p>
  
  <pre><code>const functions = require('firebase-functions');
  const admin = require('firebase-admin');
  admin.initializeApp();
  
  const {google} = require('googleapis');
  const nodemailer = require('nodemailer')
  const _ = require('lodash');
  
  const KEY = require('./service-key.json');
  
   function connect () {
    return new Promise((resolve, reject) =&gt; {
      const jwtClient = new google.auth.JWT(
        KEY.client_email,
        null,
        KEY.private_key,
        _.values(KEY.scopes), // scopes as authorized in G-Suite admin
        KEY.admin_email . // impersonated user
      );
      jwtClient.authorize((err) =&gt; {
        if(err) {
          reject(err);
        } else {
          resolve(jwtClient); // returns client
        }
      });
    });
  }
  
  // Send  a message to the contact user 
  function sendMessage (client, sender, msg) {
    return new Promise((resolve, reject) =&gt; {
      var transporter = nodemailer.createTransport({
        host: 'smtp.gmail.com',
        port: 465,
        secure: true,
        auth: {
          type: 'OAuth2',
          user: KEY.admin_email,
          serviceClient: KEY.client_id,
          privateKey: KEY.private_key,
          accessToken: client.access_token,
          refreshToken: client.refresh_token,
          expires: client.expiry_date
        }
      });
  
      const mailOptions = {
        from: 'SITE CONTACT&lt;' + sender + '&gt;',
        to: KEY.contact_email,
        subject: 'Message',
        text: 'From: ' + sender + '\n\n' + msg,
        html: '&lt;h1&gt;Message&lt;/h1&gt;&lt;p&gt;From: ' + sender + '&lt;/p&gt;&lt;p&gt;' + msg + '&lt;/p&gt;'
      };
  
      transporter.sendMail(mailOptions, (err, response) =&gt; {
        if (err) {
          reject(err);
          return;
        }
        resolve(response);
      });
  
    });
  }
  
  function newContactMessage (from, msg) {
    return connect()
      .then(client =&gt; {
        return sendMessage(client, from, msg);
      });
  }
  
  exports.sendContactMessage = functions.https.onRequest((req, res) =&gt; {
    const sender_email = 'dufourisabelle@orange.fr';
    const sender_msg = 'just a test message to contact the site owner.'
    newContactMessage(sender_email, sender_msg).then(() =&gt; {
      return {status: 200};
    }, error =&gt; {
      return {status: error.status, infos: error.message};
    }).then(response =&gt; {
      return res.send(response);
    }).catch(console.error);
  });
  </code></pre>
  
  <p>What could I add to it ? I'll try to re-initiate the all process and pray ... ??</p>