Search code examples
python-3.xgoogle-apigmail-apigoogle-api-python-clientservice-accounts

Make use of the gmail api through a service account from the server side avoiding the OAUTH2 GUI


I have an application developed in python that uses the SMPT service to connect to a gmail account. This type of connection is typified as an "Access of insecure applications" lesssecureapps.

To remedy this I have set myself the task of updating my app, using the gmail api and for authentication to use a private key generated from a service account (without using G-Suit).

I have created a first proof of concept and it seems that it connects and authenticates correctly, but when trying to get the labels of the gmail account I get the following message:

<HttpError 400 when requesting https://gmail.googleapis.com/gmail/v1/users/me/labels?alt=json returned "Precondition check failed.">

I recap the steps I have followed to configure my google account:

  1. I access Google Api Console and enable the use of the gmail api through the button that appears at the top: Enable apis and services
  2. I access the credentials section, click on the top button: "create credentials" and select Service account
  3. I create a service account and then generate a private key in json format

I add a small code snippet with my proof of concept and it that returns the error that I comment on the top:

    from google.oauth2 import service_account
    from googleapiclient.discovery import build

    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','https://www.googleapis.com/auth/gmail.addons.current.message.metadata','https://www.googleapis.com/auth/gmail.addons.current.message.readonly']
    SERVICE_ACCOUNT_FILE = '/home/user/keys/privatekey_from_service_account.json'

    credentials = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)

    service = build('gmail', 'v1', credentials=credentials)

    # Call the Gmail API
    results = service.users().labels().list(userId='me').execute()
    labels = results.get('labels', [])

    if not labels:
        print('No tienes labels.')
    else:
        print('Labels:')
        for label in labels:
            print(label['name'])

How can I solve my problem without using g-suite?


Solution

  • "Precondition check failed."

    Means that you are not allowed to do what you are trying to do.

    use a private key generated from a service account (without using G-Suit).

    The Gmail api does not support service accounts for non gsuite domains. You can only use a service account with a Gsuite domain account and gsuite domain emails.

    Services account wont work with normal google gmail accounts.