According to the documentation referenced below a Message should contain a MessagePart which in turn should contain a MessagePartBody.
https://developers.google.com/gmail/api/reference/rest/v1/users.messages#Message
When I run the code below (it's just a modified version of the sample script found here with messages substituted for labels)
from __future__ import print_function
import pickle
import os.path
import openpyxl
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://mail.google.com/']
def main():
"""Shows basic usage of the Gmail API.
Lists the user's Gmail labels.
"""
creds = None
# The file token.pickle stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
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', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('gmail', 'v1', credentials=creds)
# Call the Gmail API
results = service.users().messages().list(userId='me').execute()
messages = results.get('messages', [])
if not messages:
print('No messages found.')
else:
print('Messages:')
for message in messages:
print(message)
if __name__ == '__main__':
main()
I get only Messageids and Threadsids eg:
Messages:
{'id': '177045ba844e1991', 'threadId': '177045ba844e1991'}
{'id': '1770415ccdd222d7', 'threadId': '1770415ccdd222d7'}
{'id': '17703970573550eb', 'threadId': '17703970573550eb'}
{'id': '177031073928a223', 'threadId': '177031073928a223'}
{'id': '17702de505951773', 'threadId': '17702de505951773'}
{'id': '17702a3e6d1893de', 'threadId': '17702a3e6d1893de'}
How can I get the actual body of a message using this API?
As stated in the documentation of users.messages.list
:
Note that each message resource contains only an
id
and athreadId
. Additional message details can be fetched using the messages.get method.
So basically it is a two step process:
list
to get the emails in the inbox.get
to read information about them.Which it looks something like:
results = service.users().messages().list(userId='me').execute()
messages = results.get('messages', [])
messages = [service.users().messages().get(userId='me', id=msg['id']).execute() for msg in messages]
Now, if you do that, you will run into problems as this makes the requests 1 by 1. The way of getting multiple messages with one request is using a batch request:
results = service.users().messages().list(userId='me').execute()
message_ids = results.get('messages', [])
messages = []
def add(id, msg, err):
# id is given because this will not be called in the same order
if err:
print(err)
else:
messages.append(msg)
batch = service.new_batch_http_request()
for msg in message_ids:
batch.add(service.users().messages().get(userId='me', id=msg['id']), add)
batch.execute()
One important note about batch requests is that the order in which the callback is called can be different from the order that you started with.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With