Search code examples
node.jsgmail-apigoogle-api-clientgoogle-api-nodejs-client

How to use Service Account to access GMAIL API for a GSuite email account


I want my service account to impersonate one of the users in the GSuite. I have

  • created a project via GCP
  • enabled GMail API in the project
  • added a service account to that project
  • enabled the domain-wide delegation in the service account settings on the GCP
  • added an API Client with service account id in advanced settings via Google Admin panel for the GSuite

While going through docs (java), I saw this

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN))
    .createDelegated("user@example.com");

Here they are specifying which user the service account should impersonate. This code is in java. I need to accomplish the same thing in nodejs.

While going through documentation of nodejs-client for googleapis, I found this:

const {google} = require('googleapis');

const auth = new google.auth.GoogleAuth({
  keyFile: '/path/to/your-secret-key.json',
  scopes: ['https://www.googleapis.com/auth/cloud-platform'],
});

and

const {google} = require('googleapis');

const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// set auth as a global default
google.options({
  auth: oauth2Client
});

What is the difference between GoogleAuth and OAuth2 here?

How do I set everything up so that my node.js application can access user@abc.xyz mail via the service account?

How do I specify the email I want to access via service account?


Solution

  • The documentation specifies:

    Rather than manually creating an OAuth2 client, JWT client, or Compute client, the auth library can create the correct credential type for you, depending upon the environment your code is running under.

    In other words:

    • google.auth.GoogleAuth is a library tool that creates dynamically the correct credentials for you if you do not know which credentials you need
    • google.auth.OAuth2 always creates specifically OAuth2 credentials
    • For most applications where you authenticate as yourself OAth2 is what you need
    • However for using a service account you need to create a JSON Web Token a specified here
    • Double-check that you created service account crendetials, preferably as a json file, enabled domain-wide delegation and provided the service account with the necessary scopes in the admin console.
    • To implement impersonation into your code, add the line subject: USER_EMAIL when creating the JWT client.

    Sample

    const {JWT} = require('google-auth-library');
    //THE PATH TO YOUR SERVICE ACCOUNT CRENDETIALS JSON FILE
    const keys = require('./jwt.keys.json');
    
    async function main() {
      const client = new JWT({
        email: keys.client_email,
        key: keys.private_key,
        scopes: ['YOUR SCOPES HERE'],
        subject: USER_EMAIL
      });
      const url = `https://dns.googleapis.com/dns/v1/projects/${keys.project_id}`;
      const res = await client.request({url});
      console.log(res.data);
    }
    
    main().catch(console.error);