Search code examples
pythongmail

What is causing my Python script to throw a KeyError when accessing the subject line of Gmail messages?


I am attempting to automatically download attachments from a work gmail account into an s3 bucket. As part of my research, I am just attempting to verify that I can access the messages in the inbox. I have developed some code that looks like it should work, but it keeps coming back with an error. I just need someone to tell me where I might be going wrong here.

# Import the necessary modules
import googleapiclient.discovery
import os.path
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow

SCOPES = ['https://mail.google.com/']

def get_credentials():
    if os.path.exists('/home/matillion/gmail_token.json'):
        creds = Credentials.from_authorized_user_file('/home/matillion/gmail_token.json', SCOPES)
    return creds

# Create a service object
service = googleapiclient.discovery.build('gmail', 'v1', credentials=get_credentials())

# Get the user's inbox
inbox = service.users().messages().list(userId='me', maxResults=100).execute()

# Loop through the messages in the inbox
for message in inbox['messages']:
    # Get the subject line of the message
    subject = message['subject']

    # If the subject line contains the word "Zillion", print the message
    if 'Zillion' in subject:
        print(message)

The error that I am getting is:

Traceback (most recent call last): File "/tmp/interpreter-input-5955b24e-bd35-463a-909e-6ca5f0e592a4.tmp", line 28, in subject = message['subject'] KeyError: 'subject' Script failed with status: 1


Solution

  • service.users().messages().list(userId='me', maxResults=100).execute() only gives you a list of message IDs.

    if we want the message details (including headers such as Subject) we have to use service.users().messages().get()

    import googleapiclient.discovery
    import os.path
    from google.auth.transport.requests import Request
    from google.oauth2.credentials import Credentials
    from google_auth_oauthlib.flow import InstalledAppFlow
    
    SCOPES = ['https://mail.google.com/']
    
    def get_credentials():
        if os.path.exists('/home/matillion/gmail_token.json'):
            creds = Credentials.from_authorized_user_file('/home/matillion/gmail_token.json', SCOPES)
        return creds
    
    service = googleapiclient.discovery.build('gmail', 'v1', credentials=get_credentials())
    
    inbox = service.users().messages().list(userId='me', maxResults=100).execute()
    
    for message in inbox['messages']:
        msg = service.users().messages().get(userId='me', id=message['id']).execute()
        payload = msg['payload']
        headers = payload['headers']
    
        for d in headers:
            if d['name'] == 'Subject':
                subject = d['value']
    
        if 'Zillion' in subject:
            print(msg)