Search code examples
pythonoutlookwin32comoffice-automation

Python: Move all outlook emails to different folder


I'm working on a project that involves scraping data from emails that come in.

The part I'm stuck on is, after I bring the messages into local memory, I'm trying to move the emails from the original location to an archive folder because this process will be ran weekly and I want to ensure things aren't getting double counted.

I'm using a pretty standard method to load the emails into memory, with the slight caveat that the emails are coming into a separate email group and not my native email account, which adds a step. It looks like this:

outlook = win32com.client.Dispatch('Outlook.Application').GetNamespace('MAPI')
folder =outlook.Folders.Item('Product Alerts')
tempBox = folder.Folders.Item('Inbox')
inbox = tempBox.Folders.Item('Electronic Product Alert')

archiveFolder = folder.Folders.Item('Product Alert Archive')

messages = inbox.Items

#this is the part that isn't working
for email in inbox.Items:
     email.Move(archiveFolder)

The issue is that the loop that moves the emails to the archive folder doesn't move all the emails in the folder it moves some and leaves others.

I have also tried

for message in messages:
     message.Move(archiveFolder)

and it does the same thing as inbox.Items

I also checked to make sure the messages were loading properly, to make sure there isn't an issue communicating with Outlook, but running

print(len(messages))

gives the correct result for the number of emails in the folder.

Am I missing something obvious that is stopping this loop from moving all of the emails to the archive folder or do I need to use a different method?


Solution

  • First of all, I'd recommend using the GetDefaultFolder method to get the Inbox folder and only then deal with subfolders.

    tempBox = folder.Folders.Item('Inbox')
    

    This call can be replaced because depending on the user's locale the name can be different.

    In the following code you don't take into an account that items are moved and the collection is decreased, so each time by one item less:

    #this is the part that isn't working
    for email in inbox.Items:
         email.Move(archiveFolder)
    

    Instead, you need to use a reverse for loop in the code to move or delete items from the collection:

     For i = Items.Count To 1 Step -1
         Items(i).Move(..)
     Next