pythongmail-api

Error when trying add filter to Gmail using python script


I am trying to create a simple Python app that would be able to delete and add filters to Gmail. Using different SCOPES I can easily list labels, filters, and so on but when trying to add a new filter I am getting an error.

The code below is a simplification of my actual code (that is broken into set of functions) but basically, it does exactly the same as my full code.

import os.path
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build

def main():
    scope = ['https://www.googleapis.com/auth/gmail.settings.basic']
    credentials_file = 'credentials.json'
    token_file = f'token_test.json'

    credentials = None
    if os.path.exists(token_file):
        credentials = Credentials.from_authorized_user_file(token_file, scope)
    if not credentials or not credentials.valid:
        if credentials and credentials.expired and credentials.refresh_token:
            credentials.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(credentials_file, scope)
            credentials = flow.run_local_server(port=0)
        with open(token_file, 'w') as token:
            token.write(credentials.to_json())

    service = build('gmail', 'v1', credentials=credentials)
    filter_body = {'criteria': {'from': 'example@example.com'}, 'action': {'removeLabelsIds': ['SPAM']}}
    result = (
        service.users()
        .settings()
        .filters()
        .create(userId='me', body=filter_body)
        .execute())

    return result

if __name__ == '__main__':
    main()

I am getting this error

Traceback (most recent call last):
  File "C:\DATA\WORK\Assets\Development\Python\GmailManager\src\temp.py", line 36, in <module>
    main()
  File "C:\DATA\WORK\Assets\Development\Python\GmailManager\src\temp.py", line 31, in main
    .execute())
     ^^^^^^^^^
  File "C:\DATA\WORK\Assets\Development\Python\GmailManager\.venv\Lib\site-packages\googleapiclient\_helpers.py", line 130, in positional_wrapper
    return wrapped(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\DATA\WORK\Assets\Development\Python\GmailManager\.venv\Lib\site-packages\googleapiclient\http.py", line 938, in execute
    raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 400 when requesting https://gmail.googleapis.com/gmail/v1/users/me/settings/filters?alt=json returned "Filter doesn't have any actions". Details: "[{'message': "Filter doesn't have any actions", 'domain': 'global', 'reason': 'invalidArgument'}]">

The info under link https://gmail.googleapis.com/gmail/v1/users/me/settings/filters?alt=json is this

{
    "error": {
        "code": 401,
        "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
        "errors": [
            {
                "message": "Login Required.",
                "domain": "global",
                "reason": "required",
                "location": "Authorization",
                "locationType": "header"
            }
        ],
        "status": "UNAUTHENTICATED",
        "details": [
            {
                "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                "reason": "CREDENTIALS_MISSING",
                "domain": "googleapis.com",
                "metadata": {
                    "method": "caribou.api.proto.MailboxService.ListFilters",
                    "service": "gmail.googleapis.com"
                }
            }
        ]
    }
}

which is quite strange because right now I do not know if the error stems from content of the filter or from authentication error.


Solution

  • Please modify your script as follows.

    From:

    filter_body = {'criteria': {'from': 'example@example.com'}, 'action': {'removeLabelsIds': ['SPAM']}}
    

    To:

    filter_body = {'criteria': {'from': 'example@example.com'}, 'action': {'removeLabelIds': ['SPAM']}}
    

    Reference: