1

my goal is to use a python script to trigger an event handler whenever I open up an email on Outlook, from there I should be able to get the data of the email that was opened, then do something with the data. There is a similar thread on how to do it via VBA (here), but I can't figure out how to translate that to python using win32com.

I have looked through the microsoft docs but can't figure out how to trigger events on MailItem objects. https://learn.microsoft.com/en-us/office/vba/api/outlook.mailitem

The closest I had come to doing something close was by doing something like the below, which is probably not the solution as item in this case(as the doc states) does not contain the data.

import win32com.client
import pythoncom
import re

class Handler_Class(object):
  def OnItemLoad(self, item):
       print(item.Class)
 
outlook = win32com.client.DispatchWithEvents("Outlook.Application",Handler_Class)

Any ideas/suggestions appreciated! Thanks in advance!

Bolo
  • 93
  • 1
  • 9

1 Answers1

2

Here's something that worked for me as proof-of-concept, from an amalgam of SO posts including this one: How to pass arguments to win32com event handler. It prints out the Subject line and Body of a MailItem when Read.

The extra step from the OP's code is to handle the Application.ItemLoad event, and with the information passed go on to separately set a handler for the Item. Also, since your MailItem handler doesn't receive the this or self pointer in the event handler call (ie the IDispatch interface to the MailItem) you have to save it away yourself for later.

import win32com.client
import pythoncom

#Handler for Application Object
class Application_Handler(object):
    def OnItemLoad(self, item):
        print('Application::OnItemLoad')

        #Only want to work with MailItems 
        if( item.Class == win32com.client.constants.olMail ): 
            #Get a Dispatch interface to the item
            cli = win32com.client.Dispatch(item)
            #Set up a handler
            handler = win32com.client.WithEvents(cli,MailItem_Handler)
            #Store the MailItem's Dispatch interface for use later
            handler.setDisp(cli)
 
#Handler for MailItem object
class MailItem_Handler(object):
    def setDisp(self,disp):
        self._disp = disp

    def OnOpen(self,bCancel):
        print('MailItem::OnOpen')
    
    def OnRead(self):
        print('MailItem::OnRead')
        subj = self._disp.Subject
        print('Subject:',subj)
        body = self._disp.Body
        print('Body:',body)

outlook = win32com.client.DispatchWithEvents("Outlook.Application", Application_Handler)
#Message loop
pythoncom.PumpMessages()
DS_London
  • 3,644
  • 1
  • 7
  • 24