AlbinoRhino
AlbinoRhino

Reputation: 497

How can I get the date recieved / sent from email in python

I have a program that needs to read in emails and validate if they are from this month, before continuing.

I obtain the email info via the following code

import email
import smtplib
import imaplib
mail = imaplib.IMAP4_SSL('redacted', 993)
mail.login(username, bytes(password).decode('utf-8')) #password is bytes that have been decrypted
msg_data2 = [] #My template allows for multiple email data to be appended
mailbox_data = mail.list()
mail.select('INBOX', readonly=True)
result, msg_ids = mail.search(None, f'(SEARCH CRITERIA REDACTED)')
lister = msg_ids[0].split()
most_recent = lister[-1]
result2, msg_data = mail.fetch(most_recent, '(RFC822)')
msg_data2.append(msg_data)
raw = email.message_from_bytes(msg_data[0][1])

from here I'm able to get attachments from my emails matching the search criteria, and previously, vendors would name the files properly with the month their jobs ran. Now some are not, so I'm attempting to just check the date the email was sent or received.

Upvotes: 5

Views: 10176

Answers (2)

Robert
Robert

Reputation: 8571

The Date: header is inserted by the sender, and may or may not be accurate. For example, when I write an email and place it in the outbox, it gets the date and time of me placing it in the outbox in the Date: header. The header remains the same even if I only send the email hours (or possibly days) later.

This still doesn't say anything on when it was received. It may be stuck in transit for days. For that it depends on your mail client. For example, Claws inserts a X-Received header when it fetches mail, and that will have the timestamp when Claws downloaded the email from the server to your local machine. This may be minutes or even days after it arrived in your inbox.

To check when the email actually was received by your email provider, look at the Received: headers. The top header is from your (provider's) mail server. It should end in a time stamp, with a semicolon separating the time stamp from the rest of the header.

All RFC 5322 time stamps can be parsed with email.utils.parsedate.

So the code would be something along those lines:

from email import utils

mail = "..."

sent = mail['date']
print(f"Date header: {sent}")

received = mail['Received'][0]
received = received.split(";")[-1]
print(f"Received: {received}")

sent_ts = utils.parsedate(sent_date)
received_ts = utils.parsedate(received_ts)

time_in_transit = received_ts = sent_ts
print(f"Sent {sent_ts}, received {received_ts}, took {time_in_transit}")

Upvotes: 1

snakecharmerb
snakecharmerb

Reputation: 55629

You can get the sending date from the email's 'date' header.

from email import utils

...
raw = email.message_from_bytes(msg_data[0][1])

datestring = raw['date']
print(datestring)
# Convert to datetime object
datetime_obj = utils.parsedate_to_datetime(datestring)
print(repr(datetime_obj))

Upvotes: 4

Related Questions