Search code examples
pythongoogle-apigmail-apigoogle-api-python-client

Gmail api: How do I get the recipient's email using the ID?


I'm trying to get the recipient's email using the ID that I have retrieved. Below is the code.

messages = service.users().threads().list(userId='me', q='to:').execute().get('threads', [])
    for message in messages:
        #print(message)
        # print(dir(message))
        # print(message.get())
        if search in message['snippet']:
            #print(message['id'])
            message_id = message['id']
            # print(message_id)
            full_message = service.users().messages().get(userId='me', id=message_id, format="raw").execute()
            #print(full_message)
            msg_headers = full_message['payload']['headers']
            #print(msg_headers)
            msg_str = base64.urlsafe_b64decode(full_message['raw'].encode('ASCII'))
            mime_msg = email.message_from_bytes(msg_str)

            #print(mime_msg)

            x = re.findall('id=(\w+)\'', str(mime_msg))
            print(x)
            if len(x)> 0:
                return x[0]
                if msg_headers[x]['name'] == "To":
                    return msg_headers[x[0]]['value']
            else:
                return None

I get the error below. How do I resolve this?

Traceback (most recent call last):
  File "C:\test\test2.py", line 102, in <module>
    test = get_email_with("Test string")
  File "C:\test\test2.py", line 55, in get_email_with
    msg_headers = full_message['payload']['headers']
KeyError: 'payload'

Solution

  • Issue:

    When the format is set to RAW, the field payload is not populated in the response.

    From the API official docs:

    RAW: Returns the full email message data with body content in the raw field as a base64url encoded string; the payload field is not used.

    Solution:

    Use either FULL or METADATA as format when calling messages().get, instead of RAW (format is an option parameter, and if it is not specified, FULL is used as default).

    So you should change this:

    full_message = service.users().messages().get(userId='me', id=message_id, format="raw").execute()
    

    To this:

    full_message = service.users().messages().get(userId='me', id=message_id).execute()
    

    Or, alternatively, use format="raw" anyway and decode the base-64 encoded string full_message["raw"]. Edit: In this case, though, you'd have to remove this line: msg_headers = full_message['payload']['headers'].

    Edit:

    So, if you want to retrieve the recipient, you can do the following:

    full_message = service.users().messages().get(userId='me', id=message_id).execute()
    msg_headers = full_message['payload']['headers']
    for header in msg_headers:
        if header["name"] == "To":
            return header["value"]
    

    Reference: