Search code examples
gmail-api

gmail api watch : Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested


I am trying to call User: watch from a python google cloud function.

I'm testing the script on my laptop.

Setup that I did:

  1. enable gmail API on the project
  2. create service account with json credential file
  3. put the client ID of the service account into Manage API client access with the following API scopes ['https://mail.google.com/','https://www.googleapis.com/auth/admin.directory.user']
  4. verified that G Suite Domain-wide Delegation is enabled

The error I keep getting is: err=('unauthorized_client: Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested.', '{\n "error": "unauthorized_client",\n "error_description": "Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested."\n}')

I've tried passing the service credential accounts and setting userId = TARGET_INBOX and that just comes back with a bad request. I've tried looking at the other SO posts associated with this errors and I don't see anything that I've done wrong.

Pipfile:

[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]
pytest = "*"

[packages]
flask = "*"
google-cloud-pubsub = "*"
google-api-python-client = "*"
google-auth = "*"

[requires]
python_version = "3.7"

watch_inboxes.py

import os

import google.auth
from google.auth import impersonated_credentials
from google.auth.exceptions import RefreshError
from googleapiclient.discovery import build
import json

from googleapiclient.errors import HttpError

SCOPES = ['https://mail.google.com/', 'https://www.googleapis.com/auth/admin.directory.user']

TARGET_INBOX = '***TARGET_EMAIL_ADDRESS****'


def watch_inboxes(request):
    
    if not os.environ['GOOGLE_APPLICATION_CREDENTIALS']:
        exit(-1)

    creds, proj = google.auth.default()
    
    request = {
        'labelIds': ['INBOX'],
        'topicName': 'projects/***PROJECTNAME***/topics/***TOPICNAME****'
    }

    delegated_credentials = creds.with_subject(TARGET_INBOX)

    org_service = build('gmail', 'v1', credentials=delegated_credentials)
    org_rval = None

    try:
        org_rval = org_service.users().watch(userId='me', body=request).execute()
    except HttpError as err:
        print("err={}, context={}".format(err, err.content))
    except RefreshError as err:
        print("err={}".format(err))

    print("org_rval={}".format(org_rval))

    return org_rval

Solution

  • Reading your code it seems you forgot to add scopes to your google.auth.default()-function.

    So the end product would look like this google.auth.default(scopes)