googleapis / google-api-nodejs-client

Google's officially supported Node.js client library for accessing Google APIs. Support for authorization and authentication with OAuth 2.0, API Keys and JWT (Service Tokens) is included.
https://googleapis.dev/nodejs/googleapis/latest/
Apache License 2.0
11.42k stars 1.92k forks source link

gmail.users.watch | error sending test message to Cloud PubSub projects/tms-erp-afourtech-assets/topics/gmail-watcher : User not authorized to perform this action. #2843

Open hiteshsalavi opened 3 years ago

hiteshsalavi commented 3 years ago

I want to implement watch for new mails in INBOX for a Google Workspace email ID.

Already Verified Pointers:

  1. I've made sure that client_id from service.json file has domain wide delegated authorisation for the scope being used.
  2. I've also made sure that service account has Publisher access.
  3. I've also made sure that client_email has Publisher access from the Pub/Sub Followed this solution

Still getting

{
      message: 'Error sending test message to Cloud PubSub projects/<PROJECT_ID>/topics/gmail-watcher : User not authorized to perform this action.',
      domain: 'global',
      reason: 'forbidden'
    }

Code:

import { google, Auth } from 'googleapis';
import { resolve } from 'path';

const serviceAccountPath = resolve('./service.json')
const scopes = [
    'https://www.googleapis.com/auth/gmail.metadata'
]
const emailToBeDelegated = 'email.id@domain.com'

class GoogleAuth {
    public auth;
    constructor(serviceAccountPath: string, scopes: string[], emailToBeDelegated: string){
        this.auth = this.getAuth(serviceAccountPath, scopes, emailToBeDelegated);
    }
    public async getAuthorizedJWT () {
        await this.auth.authorize();
        return this.auth;
      };
    private getAuth = (serviceAccountPath: string, scopes: string[], emailToBeDelegated: string): Auth.JWT => {
        return new Auth.JWT({
            keyFile: serviceAccountPath,
          scopes,
          subject: emailToBeDelegated
        });
      };
}

class GMailService extends GoogleAuth {
    constructor(serviceAccountPath: string, scopes: string[], emailToBeDelegated: string){
        super(serviceAccountPath, scopes, emailToBeDelegated);
    }

    watch = async () => {
        const auth = await this.getAuthorizedJWT();
        return google.gmail({ version: 'v1' }).users.watch({auth,
            userId: 'me',
            requestBody: {
                topicName: 'projects/<PROJECT_ID>/topics/gmail-watcher',
                labelIds: ['INBOX']
            }
        })
    }
}

(async () => {
    const gMailService = new GMailService(serviceAccountPath, scopes, emailToBeDelegated);
    console.log(await gMailService.watch());
})();
RevoltEnergy commented 1 year ago

@hiteshsalavi any updates on it?? I have the same issue

henr22 commented 1 year ago

Did you solve this problem?

gelpiu-developers commented 1 year ago

We have the same problem here! All roles and permissions have been added... :-(

BrentFurryBreeze commented 1 year ago

Did anyone figure this out? Same issue here.

Edit Found the solution in this thread. Hidden away in google's documentation is a specific service account that needs publish permissions to the topic. The error message provided from the watch method is a terrible indicator of the actually underlying issue. https://stackoverflow.com/questions/43525182/gmail-users-watch-fails-to-send-test-message-to-pubsub-with-a-dwd-service-accoun/43645610#43645610

chineduukpe commented 4 months ago

Has anyone figured this out? Same issue here in 2024

alexandregv commented 2 weeks ago

@chineduukpe The solution mentioned above worked for me just now.

  1. Go to your topics: https://console.cloud.google.com/cloudpubsub/topic/list (select the right project)
  2. On the right, in Permissions, click Add Principal
  3. Enter gmail-api-push@system.gserviceaccount.com as new principal
  4. Select Pub/Sub > Publisher as role
  5. Validate