nico
nico

Reputation: 189

Outlook using python win32com to iterate subfolders

I have the following code which gets me the inbox of my shared folder, and all of the emails inside. This code works great and will print the subject of the last email.

outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
recip = outlook.CreateRecipient("[email protected]")
inbox = outlook.GetSharedDefaultFolder(recip, 6)
messages = inbox.Items
message = messages.GetLast()
print (message.Subject)

I can access other parent folders in [email protected]'s mailbox (like Sent), but I can't get any subfolders of a folder within the inbox, or deeper than that. So if I want inbox\subfolder1, how do I access that? Using Outlook 2013 if that matters. My main goal is to do:

message.Move(inbox\subfolder1)

Upvotes: 14

Views: 45725

Answers (8)

Igor
Igor

Reputation: 1292

This is the way I did it. Have to add "Folders" attribute to each level down.

import win32com.client as client

outlook = client.Dispatch('Outlook.Application')
namespace = outlook.GetNameSpace('MAPI')
inbox = namespace.GetDefaultFolder(6)

for i in inbox.Folders:
    print('Top Folder is:', i)
    for folder in inbox.Folders[str(i)].Folders:
        print('2nd tier folder is:', folder)
        for nfolder in inbox.Folders[str(i)].Folders[str(folder)].Folders:
            print('3nd tier folder is:', nfolder)

Upvotes: 1

Dmitry Streblechenko
Dmitry Streblechenko

Reputation: 66235

Can't do that - Outlook caches shared default folders in the main OST file The subfolders are not cached. If the mailbox in question is added as a delegate store, you should be able to parse to the folder in question using Namespace.Folders or Namespace.Stores.

Otherwise you can use Redemption (I am its author) and its RDOSession.GetSharedDefaultFolder - the folder will be opened in the online mode with all of its subfolders (RDOFolder.Folders).

Upvotes: 3

Gerry
Gerry

Reputation: 21

def processfolder(folder):

    ignoredfolders = []
    
    if not folder.Name in ignoredfolders:
        print("processing", folder.Name)
        count=0
        for mail in folder.Items:
               savemsg(mail)
               count += 1

        print(count, "Mails in folder")
        for fld in folder.Folders:
            processfolder(fld)

Upvotes: 2

Ding Ming
Ding Ming

Reputation: 1

import win32com.client as win32

# new outlook object
outlook = win32.Dispatch("Outlook.Application")

# get user namespace *Important when reading email*
namespace = outlook.GetNamespace("MAPI")

# Default inbox folder either Folders.Item(1/2)
root_folder = namespace.Folders.Item(2)

# Use this function to display subfolders inside the current folder

def menu(outlookFolderItem):
    for i in range(0,20):
        try:
            print(i,outlookFolderItem.Folders(i).Name)
        except:
            pass

# example
menu(root_folder)

# navigate into the subfile by

sub_folder = root_folder.Folders(2).Folders(14)

Upvotes: 0

Ozzius
Ozzius

Reputation: 139

Sir Tesla. Actually, I followed up your code pattern & change it as per my current project. Please find the below specimen code.

import win32com.client
outlook = win32com.client.Dispatch("Outlook.application")
mapi = outlook.GetNamespace("MAPI")
FirstFMB = mapi.Folders['FirstFMB'].Folders['Inbox']
SecondFMB = mapi.Folders['SecondFMB'].Folders['Another_folder']

<Hence other loops & operations as per requirement>

Here I got to know, one thing. When we need to perform with some kind Function Mail Boxes then we just need to put the name under mapi.Folder[] then just go with the flow.

Sir Tesla your code pattern was helpful for me instead of using Folder number.

On another side, this technique helps me to append mail reading & taking action within a certain time frame.

Upvotes: 0

Sir Tesla
Sir Tesla

Reputation: 328

Yeah its better to write it as the name of the folder instead of writing the folder numbers

Like my folder hierarchy is : Outlook_Mails > Inbox > Important

outlook = win32.com.client.Dispatch("Outlook.Application")
mapi = outlook.GetNamespace("MAPI")

your_folder = mapi.Folders['Outlook_Mails'].Folders['Inbox'].Folders['Important']
for message in your_folder.Items:
    print(message.Subject)

Upvotes: 23

cole
cole

Reputation: 125

I took Jared Goguen's answer and modified it.

outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6)
root_folder = inbox.Folders(6)
messages = root_folder.Items

Where inbox.Folders(6) uses the index of my subfolder of interest to identify it. I was able to successfully iterate through the messages in the subfolder using this message.

Upvotes: -1

Jared Goguen
Jared Goguen

Reputation: 9010

This is the code I'm using to do a similar task.

outlook = win32com.client.Dispatch("Outlook.Application")
namespace = outlook.GetNamespace("MAPI")
root_folder = namespace.Folders.Item(1)
subfolder = root_folder.Folders['All'].Folders['Main Folder'].Folders['Subfolder']
messages = subfolder.Items

This finds the messages in the folder "All/Main Folder/Subfolder".

Upvotes: 7

Related Questions