¿Cómo revisar todos los correos electrónicos que llegaron dentro de un período de tiempo?

Tengo el siguiente método get_email() que, básicamente, cada 20 segundos, recibe el último correo electrónico y realiza una serie de otros métodos en él.

 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.') 

Mi pregunta principal es:

  • ¿Hay alguna manera de que pueda recorrer cada correo electrónico utilizando la función GetNext() per se cada hora en lugar de obtener el último cada 20 segundos (lo que definitivamente no es tan eficiente como buscar en todos los correos electrónicos)?

Dado que hay dos funciones: GetFirst() y GetNext() ¿cómo puedo hacer que guarde la última GetFirst() comprobada y luego revisar todas las funciones que aún no se han verificado?


¿Crees que sería más fácil configurar una carpeta diferente en Outlook donde puedo enviar todos estos informes y luego iterarlos en una base de tiempo? El único problema aquí es si un informe entrante se genera automáticamente y el intervalo de tiempo entre el correo electrónico es inferior a 20 segundos, o incluso 1 segundo.


¡Cualquier ayuda en absoluto es apreciada!

Puede usar la función Restringir para restringir la variable de sus mensajes a los correos electrónicos enviados en la última hora e iterar sobre cada uno de ellos. Restrict toma la lista completa de elementos de su bandeja de entrada y le proporciona una lista de los que cumplen con criterios específicos, como haber sido recibidos en un rango de tiempo específico. (La documentación de MSDN vinculada anteriormente enumera algunas otras propiedades potenciales que podría restringir por).

Si ejecuta esto cada hora, puede restringir su bandeja de entrada a los mensajes que recibió en la última hora (que, presumiblemente, son los que aún deben buscarse) e iterarlos.

Aquí hay un ejemplo de restricción a los correos electrónicos recibidos en la última hora (o minuto):

 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 hour ago lastHourDateTime = dt.datetime.now() - dt.timedelta(hours = 1) #This is set to one minute ago; you can change timedelta's argument to whatever you want it to be lastMinuteDateTime = dt.datetime.now() - dt.timedelta(minutes = 1) 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 messages.Sort("[ReceivedTime]", True) # restrict to messages from the past hour based on ReceivedTime using the dates defined above. # lastHourMessages will contain only emails with a ReceivedTime later than an hour ago # The way the datetime is formatted DOES matter; You can't add seconds here. lastHourMessages = messages.Restrict("[ReceivedTime] >= '" +lastHourDateTime.strftime('%m/%d/%Y %H:%M %p')+"'") lastMinuteMessages = messages.Restrict("[ReceivedTime] >= '" +lastMinuteDateTime.strftime('%m/%d/%Y %H:%M %p')+"'") print "Current time: "+date_time.strftime('%m/%d/%Y %H:%M %p') print "Messages from the past hour:" for message in lastHourMessages: print message.subject print message.ReceivedTime print "Messages from the past minute:" for message in lastMinuteMessages: print message.subject print message.ReceivedTime # GetFirst/GetNext will also work, since the restricted message list is just a shortened version of your full inbox. print "Using GetFirst/GetNext" message = lastHourMessages.GetFirst() while message: print message.subject print message.ReceivedTime message = lastHourMessages.GetNext() 

Parece que se ejecuta cada 20 segundos, por lo que probablemente podría ejecutarlo en un intervalo diferente. Si no puede ejecutarlo de manera confiable en un intervalo regular (que luego se especificaría en el timedelta, por ejemplo, horas = 1), podría guardar el Tiempo de recepción del correo electrónico más reciente verificado y usarlo para restringir su búsqueda. (En ese caso, el ReceivedTime guardado reemplazaría a lastHourDateTime, y Restrict recuperaría todos los correos electrónicos enviados después de que se verificara el último).

¡Espero que esto ayude!

Tuve una pregunta similar y trabajé a través de la solución anterior. Incluyendo otro ejemplo de uso general en caso de que otras personas lo encuentren más fácil:

 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... 

Usando la fecha y hora de importación, esto es lo que se me ocurrió:

 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