0

I would like to manage my filters with the Gmail API through a service account. I have my domain registered in GSuite and manage all the faily accounts there.

I wrote some code which allows me to access the calendars - it works fine across all calendars of my users.

After creating a credentials JSON file from the console (giving it ownership for the project), I replicated this working code for the gmail case:

import googleapiclient.discovery from google.oauth2 import service_account as google_oauth2_service_account secrets = { "type": "service_account", "project_id": "setfilter", "private_key_id": "3xxxb", "private_key": "-----BEGIN PRIVATE KEY-----xxxDpLU\n-----END PRIVATE KEY-----\n", "client_email": "[email protected]", "client_id": "1xxx2", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/setfilter%40setfilter.iam.gserviceaccount.com" } credentials = google_oauth2_service_account.Credentials.from_service_account_info(secrets, scopes=['https://mail.google.com/'], subject='MyAccountToAdministerTheConsole@mydomain') service = googleapiclient.discovery.build('gmail', 'v1', credentials=credentials) results = service.users().labels().list(userId='me').execute() print(results) 

Running this code yields the dreaded

Traceback (most recent call last): File "D:/Nextcloud/dev-perso/setfilter/setfilter.py", line 25, in <module> results = service.users().labels().list(userId='me').execute() File "C:\Python38\lib\site-packages\googleapiclient\_helpers.py", line 134, in positional_wrapper return wrapped(*args, **kwargs) File "C:\Python38\lib\site-packages\googleapiclient\http.py", line 892, in execute resp, content = _retry_request( File "C:\Python38\lib\site-packages\googleapiclient\http.py", line 177, in _retry_request resp, content = http.request(uri, method, *args, **kwargs) File "C:\Python38\lib\site-packages\google_auth_httplib2.py", line 189, in request self.credentials.before_request( File "C:\Python38\lib\site-packages\google\auth\credentials.py", line 133, in before_request self.refresh(request) File "C:\Python38\lib\site-packages\google\oauth2\service_account.py", line 359, in refresh access_token, expiry, _ = _client.jwt_grant(request, self._token_uri, assertion) File "C:\Python38\lib\site-packages\google\oauth2\_client.py", line 153, in jwt_grant response_data = _token_endpoint_request(request, token_uri, body) File "C:\Python38\lib\site-packages\google\oauth2\_client.py", line 124, in _token_endpoint_request _handle_error_response(response_body) File "C:\Python38\lib\site-packages\google\oauth2\_client.py", line 60, in _handle_error_response raise exceptions.RefreshError(error_details, response_body) google.auth.exceptions.RefreshError: ('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}') 

Is this the correct approach? If so - which special scopes are required for Gmail? (and where to set them?)

1 Answer 1

1

Missing domain-wide access to scopes:

You should set the appropriate scopes that the service account should have domain-wide access to in order to call Users.labels: list on behalf of other users: when you delegate domain-wide authority to a service account, you have to define which scopes the service account should have domain-wide access to.

This is done on the Admin console, while managing domain-wide delegation. Follow the steps specified here and, when you get to the domain-wide delegation panel, add one or more of these scopes:

https://mail.google.com/ https://www.googleapis.com/auth/gmail.modify https://www.googleapis.com/auth/gmail.readonly https://www.googleapis.com/auth/gmail.labels https://www.googleapis.com/auth/gmail.metadata 

Note:

  • I assume that you have already granted domain-wide authority to the service account, since you are able to access other users' calendars, so you had already provided Calendar scopes but not the appropriate Gmail ones (please grant domain-wide authority if you haven't done so, following these steps).
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you - this was it. I managed somehow to make it work previously for the calendar access (it was a year ago so i forgot how) - the documentation is quite confusing to be honest

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.