Monitoring an Outlook Inbox with Python

I get a lot of email at work.  Mostly by robots that are triggering on some event or another.  But after a few years of more and more distribution lists having me on it, the amount of email I get in a day is actually unmanageable.  I’m talking thousands.  The vast majority can be safely ignored, such as “Job ABC completely successfully”.

So I’ve gotten pretty aggressive with Outlook rules in order to filter my incoming email into different folders.  But the rules have always felt limited to me.  For example, I cannot say “If the subject contains this or this, do that“.  I’m limited to a logical and.

Looking into whether or not you can use Python in your Outlook rules, I came across an example where you can actively monitor your Inbox and have access to the messages that come in, all from Python.

Subj: Test Email
Body: Hey!


-Matthew Urch | Programmer Extraordinaire

This opens up a whole world of email automation.

The basic script I made that achieves the above is this:

import win32com.client
import pythoncom

class Handler_Class(object):
    def OnNewMailEx(self, receivedItemsIDs):
        for ID in receivedItemsIDs.split(","):
            # Microsoft.Office.Interop.Outlook _MailItem properties:
            mailItem = outlook.Session.GetItemFromID(ID)
            print "Subj: " + mailItem.Subject
            print "Body: " + mailItem.Body.encode( 'ascii', 'ignore' )
            print "========"
outlook = win32com.client.DispatchWithEvents("Outlook.Application", Handler_Class)

And then from here, you can do whatever you like with your email messages that are coming in.

10 thoughts on “Monitoring an Outlook Inbox with Python

  1. Jannis

    Hi Matt,

    I am very interested in this approach of monitoring my inbox.
    Specs: Outlook 2010, Spyder IDE and Python 2.7

    However, I’m a litte puzzled right now: after copying your code from above I expected to see the subject of new incoming mails printed to the console when running the script – isn’t this correct?

    My goal is to identify mails by subject and save the attachment to the machine the script is running on. Therefore this event handling step is the first I’d say 🙂

    Help would be greatly appreciated – further, I’d be happy to share the final code.


    1. Rockford

      Thank you for the useful post! This worked when connected to an Exchange server and only for the default Inbox. I am having trouble coming up with a similar handler class to track items added to a shared inbox using ItemAdd event. Supposedly you can also use ItemAdd in place of OnNewMailEx event for messages to the default inbox, but I cannot figure this out as well. I’m hoping ItemAdd will also only show me e-mails arrivng in my inbox after my inbox rules.

  2. PZaffina

    I cannot say “If the subject contains this or this, do that“.

    I have found the following code can do the if conditionals. (forgive my code because Im new to programming)

    if “blah” or “duh” in mailItem.Subject:
    do something

    do something else

    I’ve also found that sometimes I have to put the mailItem.??? inside a str().

      1. matthewurch Post author

        Yes, in Python, you must have proper indenting. It’s how Python knows where the line belongs. For example if the line belongs in the method, if-statement or somewhere else.

        As for your other question, if I understand it correctly, you can take a look here for one way of how to do that.

        Another way to do it is to simply ask it as two separate questions:

        if ‘blah’ in mailItem.Subject or ‘duh’ in mailItem.Subject:

  3. kokoras

    Hello, Matt, thank for sharing your ideas!
    Some questions though.
    1. How can this be modified for outlook in Mac OSX?
    2. The objective is if a number of messages are x amount of days old, then move them to specific local folders.
    So I can keep only for example the past 3 month’s IMAP server email and the rest to be download.

    Any ideas, much appreciated

  4. Taylor Vickers

    Is there a way to apply this to searching in a subfolder for a specific subject line at a specific time of day, and if said email isn’t available, send an alert e-mail?

  5. Aaron

    I have a question with this line of code

    mailItem = outlook.Session.GetItemFromID(ID)

    Is there a way to treat “outlook” as a local variable inside the “handler” class?
    I mean is it possible that you don’t call this variable from outside?


Leave a Reply to kokoras Cancel reply

Your email address will not be published. Required fields are marked *