I am trying to fetch all the unread messages from a gmail account using below code
msgs = service.users().messages().list(userId='me',q='in:inbox is:unread').execute()
flag=1
while flag==1:
for i in range(0,len(msgs['messages'])):
message = service.users().messages().get(userId='me', id=msgs['messages'][i]['id']).execute()
print(message['snippet'])
if 'nextPageToken' in msgs.keys():
msgs = service.users().messages().list(userId='me',pageToken= msgs['nextPageToken']).execute()
else:
flag=0
The logic for above code
The API returns 100 message IDs and an ID for next page called nextPageToken
. We use this token to fetch next 100 message IDs and so forth so on. If there is no next page, it won't have the token and hence my last 4 line of code checks for it's existence. If it doesn't exists, it sets the flag to 0 and the while loop completes.
Problem
The above code fetches ALL the messages (READ and UNREAD)
Other methods tried
msgs = service.users().messages().list(userId='me',labelIds=['UNREAD']).execute()
and
msgs = service.users().messages().list(userId='me',q='in:inbox is:unread').execute()
Possible Root Cause
I've noticed that if the unread messages are <100 then it fetches them correctly. However, if the unread messages are >100 then it pulls all the messages (READ+UNREAD)
I have looked into this stackoverflow answer, but it didn't help either.
The thing that bothers me about your code is that you only filter your messages in the first API call.
So without filtering the messages make sense that you are getting all the messages (READ or UNREAD). Except for the first call (the only you are filtering).
msgs = service.users().messages().list(userId='me',q='in:inbox is:unread').execute()
flag=1
while flag==1:
for i in range(0,len(msgs['messages'])):
message = service.users().messages().get(userId='me', id=msgs['messages'][i]['id']).execute()
print(message['snippet'])
if 'nextPageToken' in msgs.keys():
msgs = service.users().messages().list(userId='me',
q='in:inbox is:unread', # Add this to subsequent calls
pageToken= msgs['nextPageToken']
).execute()
else:
flag=0
Take a look at the examples of pagination in the official documentation. There you can see how the query is passed for every call (not just the first one).
try:
response = service.users().messages().list(userId=user_id,
q=query).execute()
messages = []
if 'messages' in response:
messages.extend(response['messages'])
while 'nextPageToken' in response:
page_token = response['nextPageToken']
response = service.users().messages().list(userId=user_id, q=query,
pageToken=page_token).execute()
messages.extend(response['messages'])
return messages
except errors.HttpError, error:
print 'An error occurred: %s' % error