3
votes

i am trying to run the gmail API to get email from a specif user. However i always receive the following error: googleapiclient.errors.HttpError: https://www.googleapis.com/gmail/v1/users/me/settings/filters?alt=json returned "Insufficient Permission">

I have tried all the different options suggested from changing the scope to enabling the less secure applications in the gmail setting. The last thing is that my code could be wrong:

from __future__ import print_function
from googleapiclient import discovery
from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools

# Setup the Gmail API
SCOPES = 'https://mail.google.com/'
store = file.Storage('credentials.json')
creds = store.get()
if not creds or creds.invalid:
    flow = client.flow_from_clientsecrets('client_secret.json', SCOPES)
    creds = tools.run_flow(flow, store)
service = build('gmail', 'v1', http=creds.authorize(Http()))

# Call the Gmail API
    # results = service.users().labels().list(userId='me').execute()
    # labels = results.get('labels', [])
    # if not labels:
    #     print('No labels found.')
    # else:
    #     print('Labels:')
    #     for label in labels:
    #         print(label['name'])
label_id = 'mine' # ID of user label to add
filter = {
    'criteria': {
        'from': '[email protected]'
    }#,
    #'action': {
        #'addLabelIds': [label_id],
        #'removeLabelIds': ['INBOX']
    #}
}
result = service.users().settings().filters().create(userId='me', body=filter).execute()
print ('Created filter: %s' % result.get('id'))

Could please help me?

Thanks

3

3 Answers

5
votes

Just remove credentials.json file from the folder where you run this script from and rerun your script with the final desired list of scopes such as SCOPES = ['https://www.googleapis.com/auth/gmail.send', 'https://www.googleapis.com/auth/gmail.labels']. Authorize, at the resulting pop up browser window, the list of scopes for the desired gmail account. Then you should be all set.

Background story: It is likely you had authorized less permissive scopes (such as readonly) via the browser screen that popped up when your run_flow() ran first time. This would have created a file called credentials.json in the folder where you ran the script. This credentials.json is not again regenerated per your script above. It is just frozen with the first time scope. Just for curiosity, you can open and read the credentials.json and look for the key 'scopes'. Of course, you cannot add more scopes in this file manually and expect newer scopes to work. This has to be regenerated for different set of scopes if any.

Unrelated cautionary note: Avoid the too permissive scope https://mail.google.com/ if at all possible:)

2
votes

None of the above fixed my problem with moving emails from the inbox into another "box/label". I am not sure if things changed with the gmail api, but what I found I had to do was to change the SCOPES line to the desired level i.e. SCOPES= ['https://www.googleapis.com/auth/gmail.modify'], then delete the token.pickle file (in that order). Following those two changes I reran the python script. Those two steps caused the authorization web page to appear reflecting the new permissions being granted and thus after me giving the OK, recreating a new token.pickle file. Everything ran as desired after that. No more 403 errors and the emails moved to the target box/label. I found the credentials.json file just allowed the script to access the emails but did not have any impact on the actions taken on the emails themselves.

I found the article on Medium titled "A Beginner’s Guide to the Gmail API and Its Documentation" by Anton Odman to be the best overall guide to python and the gmail api.

BTW, The other "gotcha" is the label created is not necessarily the label id. I recommend running code as mentioned at https://stackoverflow.com/a/55713119/4495318 to make sure you get the right label ID, it seems the label IDs and the label names are not the same except for the system generated labels.

0
votes

Simply deleting the JSON file created using file.Storage('credentials.json') after you change or add SCOPES will help you and run the program once again.