0

So I am successful in getting the date for the last email received from the contact in the code below.

Now I am trying to get the date for the last email sent to the contact. As a beginner to the coding/python, I am not able to get it right. I tried to change 'From' to 'To' but it wasn't giving me the right date.

Any idea how should I proceed with this? I have tried looking around and didn't find a solution.

import email
from imapclient import IMAPClient
from datetime import timedelta, date, datetime


HOST = 'imap.gmail.com'
USERNAME = 'username'
PASSWORD = 'password'
ssl = True

## Connect, login and select the INBOX
server = IMAPClient(HOST, use_uid=True, ssl=ssl)
server.login(USERNAME, PASSWORD)
select_info = server.select_folder('INBOX') 

since_date = date(2016, 1, 1)    

##Search Inbox
messages = server.search(['FROM', 'email_i_want_to_search@gmail.com', 'Since', since_date])
response = server.fetch(messages, ['RFC822'])
last_msg_id = list(response.keys())[-1] 
data = response[last_msg_id]
msg_string = data[b'RFC822']
msg = email.message_from_string(msg_string.decode())
print('ID %d: From: %s Date: %s' % (last_msg_id , msg['From'], msg['date']))

2 Answers2

0

The reason you are not getting the right date is because the list is unordered. In order to guarantee that you are getting the right one, you need to first sort it.

Try this quick step-by-step solution coded in a friendly style for newbies:

# Getting your response keys
response_keys='cabd' 

# Your response keys converted into list
msg_ids = list(response_keys) 
print(msg_ids) # result: ['c', 'a', 'b', 'd']

# Here your are sorting the list in place using built-in sort function
# The syntax is: list.sort(reverse=True|False) and the default is True
msg_ids.sort() 
print(msg_ids) # result: ['a', 'b', 'c', 'd']

# Finally, grab the last item in the list
last_msg_id = msg_ids[-1] 
print(last_msg_id ) # result: d
Jeffrey Kilelo
  • 4,444
  • 1
  • 9
  • 6
  • Hi Jeffrey, thank you so much for the answer. I tried sorting the list way you have described, however, it's still showing me a date for the last email sent to contact 1-2 months prior (something like second-to-last or third-to-last email). Whereas I had sent the mail to one person last night itself. I feel it has something to do with the syntax with which we can obtain the appropriate date. Please do let me know what are your thoughts. – Sourav Chatterjee Mar 11 '20 at 03:07
  • Hi Sourav, the sorting could be affected by the date format you are using. You might first need to convert the date-strings data type in your msg_ids into date data type, then sort accordingly. To be able to determine best solution, could you post here the results of list(response.keys())? – Jeffrey Kilelo Mar 11 '20 at 12:41
  • So this is the output that I get when I set it 'To' `ID 16390: To: "souravchatterjee00" Date: 20 Nov 2019 12:49:29 -0000` and this is the output when I set it 'From' `ID 17155: From: Sourav Chatterjee Date: Fri, 7 Feb 2020 20:14:38 +0530 ` – Sourav Chatterjee Mar 11 '20 at 13:57
0

How about this method? Is not very simple but it does the job.

  • Make a List of the messages sent to a certain user
  • Get the items from it (the first one is the most recent message sent)
  • Use the id of the first message to do a Get, using metadata and date as parameters for format and metadataHeaders

  • Get the value of the first item of the headers returned

    service = build('gmail', 'v1', credentials=creds)


    messages = service.users().messages().list(userId='me', q='to:user@email.com').execute()

    items = messages.items()[1][1]

    lastmess = service.users().messages().get(userId='me', id=items[0]['id'], format='metadata', metadataHeaders='Date').execute()
    print (lastmess['payload']['headers'][0]['value'])

Result:

Wed, 11 Mar 2020 16:10:32 +0100

Jescanellas
  • 2,555
  • 2
  • 9
  • 20
  • Hi, I am getting an error `NameError: name 'build' is not defined`. Do I need to import some modules to proceed? – Sourav Chatterjee Mar 11 '20 at 16:16
  • Yes, you need to add the imports and authorization code from the [Quickstart](https://developers.google.com/gmail/api/quickstart/python#step_3_set_up_the_sample) (from the first line to `service = build('gmail', 'v1', credentials=creds)`) – Jescanellas Mar 11 '20 at 16:19
  • Ok the code is working now. But it's not printing out anything. – Sourav Chatterjee Mar 11 '20 at 16:45
  • Can you edit your question with the new code? Also, make sure you get results when searching `to:user@email.com` in your search bar of the Gmail interface. – Jescanellas Mar 11 '20 at 16:52
  • Well, the code is getting executed. But it's not giving any results. – Sourav Chatterjee Mar 11 '20 at 16:58
  • Did you add `if __name__ == '__main__': main()` at the end of the code? If you have `def main()` but you don't call it, the code won't run. Copy it from the Quickstart link, not from this comment. Otherwise the indentation will break it for python. – Jescanellas Mar 12 '20 at 10:19