user-44651
user-44651

Reputation: 4124

Insufficient Permission to modify Gmail labels with via API

I am attempting to modify a GMail inbox via their API.

But I am getting the error:

HttpError 403 when requesting https://www.googleapis.com/gmail/v1/users/me/labels/SOME_MESSAGE_ID returned "Insufficient Permission"

I have used the same OAuth credentials to download my messages. So I know that is working.

I check that the Labels Scope is available.

enter image description here

I can't see anything else that I am doing wrong. The label doc doesn't help.

Can any shed some light?

def archive(msg_id):
    creds = None
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', ArchiveScope)
            creds = flow.run_local_server()
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

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

    msg_labels = {'removeLabelIds': ['INBOX'], 'addLabelIds': ['MyLabel']}

    service.users().labels().update(userId='me', id=msg_id, body=msg_labels).execute()

    print('Message ID: %s' % msg_id)

Upvotes: 1

Views: 1890

Answers (1)

Rafa Guillermo
Rafa Guillermo

Reputation: 15377

There are a few things wrong with your code. Firstly, make sure that ArchiveScope is a list containing the scopes you need for the application. In order to update, create, or delete GMail labels, either https://www.googleapis.com/auth/gmail.readonly or https://www.googleapis.com/auth/gmail.labels will suffice, as documented here.

Your code suggests that you are attempting to delete the ‘INBOX’ label, and add a new label called ‘MyLabel’. The method described by service.users().labels().update() can only be used to change the information of existing labels that are on the GMail account, and not create or delete. On top of this, the ‘Inbox’ label is a reserved label and can not be deleted - when a valid request is made to delete this label, ‘Invalid Delete Request’ is received by the server as shown below.

DELETE https://www.googleapis.com/gmail/v1/users/me/labels/INBOX

{
  "error": {
    "code": 400, 
    "message": "Invalid delete request", 
    "errors": [
      {
        "domain": "global", 
        "message": "Invalid delete request", 
        "reason": "invalidArgument"
      }
    ]
  }
}

Individual mails can however have the ‘Inbox’ tag removed with service.users().messages().modify() and the {'removeLabelIds': ['INBOX'], 'addLabelIds': ['MyLabel']} request body that you used before. This will only remove the label from the specified message however, not delete the label in its entirety.

The full documentation for modifying the contents of an existing label can be found here, but the id parameter should equal the Unique ID of the label you wish to edit, and the body payload should be a dictionary structure containing the new name you would like to change the label to:

lbl_id = "Label_XXXXXXXXXXXXXXX"
    msg_labels = {
      'name' : [‘newLabelName’]
    }
    service.users().labels().update(userId='me', id=lbl_id, body = msg_labels).execute() 
    print('Message ID: %s' % lbl_id)

In order to create a label, you can use the service.users().labels().create(userId=’me’, body={‘name’ : ‘MyLabel’ }).execute() function with the same scopes as update(). As a label has yet to be created, the Label ID is not needed.

Deleting a label is just the same, though service.users().labels().delete(userId=’me’).execute() is used without a body. Unlike create(), the delete service does require the label ID, however this request does not return a response.

Upvotes: 1

Related Questions