How to check all emails that came in within a time period?

Viewed 13539

I have the following method get_email() that basically every 20 seconds, gets the latest email and performs a series of other methods on it.

def get_email():
    import win32com.client
    import os
    import time
    import datetime as dt

    date_time = time.strftime('%m-%d-%Y')

    outlook = win32com.client.Dispatch("Outlook.Application").GetNameSpace("MAPI")
    inbox = outlook.GetDefaultFolder(6)

    messages = inbox.Items
    message = messages.GetFirst()  # any time calling GetFirst(), you can get GetNext()....
    email_subject = message.subject
    email_sender = message.SenderEmailAddress
    attachments = message.Attachments
    body_content = message.body

    print ('From: ' + email_sender)
    print ('Subject: ' + email_subject)

    if attachments.Count > 0:
        print (str(attachments.Count) + ' attachments found.')
        for i in range(attachments.Count):
                email_attachment = attachments.Item(i+1)
                report_name = date_time + '_' + email_attachment.FileName
                print('Pushing attachment - ' + report_name + ' - to check_correct_email() function.')

                if check_correct_email(email_attachment, email_subject, report_name) == True:
                    save_incoming_report(email_attachment, report_name, get_report_directory(email_subject))
                else:
                    print('Not the attachment we are looking for.')
                    # add error logging here
                    break

    else: #***********add error logging here**************
        print('No attachment found.')

My main question is:

  • Is there a way I can iterate over every email using the GetNext() function per se every hour instead of getting the latest one every 20 seconds (which is definitely not as efficient as searching through all emails)?

Given that there are two functions: GetFirst() and GetNext() how would I properly have it save the latest checked, and then go through all the ones that have yet to be checked?


Do you think it would be easier to potentially set up a different folder in Outlook where I can push all of these reports to, and then iterate through them on a time basis? The only problem here is, if an incoming report is auto-generated and the time interval between the email is less than 20 seconds, or even 1 second.


Any help at all is appreciated!

4 Answers

I had a similar question and worked through the above solution. Including another general use example in case other folks find it easier:

import win32com.client
import os
import datetime as dt

outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")

# setup range for outlook to search emails (so we don't go through the entire inbox)
lastWeekDateTime = dt.datetime.now() - dt.timedelta(days = 7)
lastWeekDateTime = lastWeekDateTime.strftime('%m/%d/%Y %H:%M %p')  #<-- This format compatible with "Restrict"

# Select main Inbox
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items

# Only search emails in the last week:
messages = messages.Restrict("[ReceivedTime] >= '" + lastWeekDateTime +"'")

print(message.subject)
# Rest of code...

Using import datetime, this is what I came up with:

count = 0    
msg = messages[len(messages) - count - 1]
while msg.SentOn.strftime("%d-%m-%y") == datetime.datetime.today().strftime("%d-%m-%y"):
        msg = messages[len(messages) - count - 1]
        count += 1
        # Rest of the code

The below solution gives past 30 minutes unread folder mails from outlook and the count of the mails within the past 30 minutes

import win32com.client
import os
import time
import datetime as dt
# this is set to the current time
date_time = dt.datetime.now()

#This is set to one minute ago; you can change timedelta's argument to whatever you want it to be
last30MinuteDateTime = dt.datetime.now() - dt.timedelta(minutes = 30 )

outlook = win32com.client.Dispatch("Outlook.Application").GetNameSpace("MAPI")
inbox = outlook.GetDefaultFolder(6)

# retrieve all emails in the inbox, then sort them from most recently received to oldest (False will give you the reverse). Not strictly necessary, but good to know if order matters for your search
messages = inbox.Items.Restrict("[Unread]=true")
messages.Sort("[ReceivedTime]", True)




last30MinuteMessages = messages.Restrict("[ReceivedTime] >= '" +last30MinuteDateTime.strftime('%m/%d/%Y %H:%M %p')+"'")

print "Current time: "+date_time.strftime('%m/%d/%Y %H:%M %p')

print "Messages from the past 30 minute:"
c=0
for message in last30MinuteMessages:
    print message.subject
    print message.ReceivedTime
    c=c+1;

print "The count of meesgaes unread from past 30 minutes ==",c
Related