Issue
Below is the code to download attachments from a sender with a specific subject. I need to deploy it locally on my computer so that this code keeps monitoring outlook and as soon as the email arrives, it should download the attachment. I have earlier deployed ml models with flask. I need help to deploy this locally. Currently running the .py script in batch mode
import imaplib
import base64
import os
import email
import imap_tools
from imap_tools import MailBox
import win32com.client
import os
from datetime import datetime, timedelta
outlook = win32com.client.Dispatch('outlook.application')
mapi = outlook.GetNamespace("MAPI")
messages = inbox.Items
received_dt = datetime.now() - timedelta(days=7)
received_dt = received_dt.strftime('%m/%d/%Y %H:%M %p')
messages = messages.Restrict("[ReceivedTime] >= '" + received_dt + "'")
messages = messages.Restrict("[SenderEmailAddress] = '[email protected]'")
messages = messages.Restrict("[Subject] = '[EXTERNAL] Fwd: Expense Report'")
outputDir = r"\\BLRESGANALXXXX\XXXXX\attachment_download"
try:
for message in list(messages):
try:
s = message.sender
for attachment in message.Attachments:
attachment.SaveASFile(os.path.join(outputDir,attachment.FileName))
print(f"attachment {attachment.FileName} from {s} saved")
except Exception as e:
print("error when saving the attachment:" + str(e))
except Exception as e:
print("error when processing emails messages:" + str(e))
Solution
One solution is to register to receive certain Events from the Outlook application. This code hooks into the OnItemAdd Event of the Inbox's Items collection.
import win32com.client
import pythoncom
#Class to handle events from an Items collection object
class Items_Handler(object):
def OnItemAdd(self,item): #Handles Items::OnItemAdd event
#Test if it is a MailItem
if item.Class == win32com.client.constants.olMail:
print('New Mail Item!')
print(' From:',item.SenderEmailAddress)
print(' Subject:',item.Subject)
print(' Received at:',item.ReceivedTime)
#Do whatever you want with the message (eg save attachments)
#Create the Outlook application object
outlook = win32com.client.gencache.EnsureDispatch('Outlook.Application')
#Get the Inbox
inBox = outlook.GetNamespace('MAPI').Folders['[email protected]'].Folders['Inbox']
#Get the Items collection for the Inbox
items = inBox.Items
#Tell Outlook you are interested in the events for the Items collection
win32com.client.WithEvents(items,Items_Handler)
print('Listening ...')
#Message loop: will handle incoming events/messages until script killed
pythoncom.PumpMessages()
You can amend the OnItemAdd handler to do whatever you want with the message, eg filter for sender, subject, save attachments etc.
NB. It will only process new messages, so you may still need your original code to sweep up any new messages in your InBox that arrived before this script started.
There is also a caveat in the documentation for ItemAdd that the event might not fire if 'a large number' of items are added to the folder at once.
Answered By - DS_London
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.