1

I have a script that moves/saves/categorizes emails in a shared mail. And I'm encountering errors when sometimes mail folders are not found. I'm using below function to retrieve mail folders. And sometimes it works and othertimes it doesn't. I usually have to restart outlook to make it work once the error has been thrown. It sometimes fails to find the subfolders within the Inbox and it returns that it is empty.

Is there anyway to ensure that the subfolders are always found?

OUTLOOK = win32com.client.GetActiveObject('Outlook.Application') #This is how I dispatch outlook
Mapi - folders
['x', 'y', 'z',]

x - folders
['PersonMetadata', 'Yammer Root', 'Tasks', 'Sent Items', 'Outbox', 'Notes', 'Junk Email', 'Journal', 'Inbox', 'Files', 'ExternalContacts', 'Drafts', 'Deleted Items', 'Conversation History', 'Conversation Action Settings', 'Contacts', 'Calendar', 'Archive']

Inbox - folders
['a', 'b', 'c'] #THIS IS SOMETIMES EMPTY

FOLDERS = {"example": ["x", "Inbox", "a"]}

def get_folder(outlook_instance, *folders):
    target_folder = outlook_instance
    try:
        for folder in folders:
            print(folder_path)
            print([f.Name for f in target_folder.Folders])
            target_folder = target_folder.Folders[str(folder)]
    except Exception:
        raise ValueError("".join(f".Folders[{folder}]" for folder in folders))
    return target_folder 

def get_outlook_folder(folder, outlook):
    mapi = outlook.GetNamespace("MAPI")
    return get_folder(mapi, *FOLDERS.get(folder))

I found this on an other post that I think relates to my issue, but I don't really understand what it is saying stackoverflow.com/a/40853098/10833061

MisterButter
  • 749
  • 1
  • 10
  • 27

1 Answers1

0

Is Outlook always running on the system when your code is executed?

Otherwise, you need to create a new Outlook Application instance and logon to the profile to be able to access folders. I am not a python developer, so here is a C# sample code which illustrates the required workflow for you:

 Outlook.Application GetApplicationObject()
        {

            Outlook.Application application = null;

            // Check whether there is an Outlook process running.
            if (Process.GetProcessesByName("OUTLOOK").Count() > 0)
            {

                // If so, use the GetActiveObject method to obtain the process and cast it to an Application object.
                application = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
            }
            else
            {

                // If not, create a new instance of Outlook and sign in to the default profile.
                application = new Outlook.Application();
                Outlook.NameSpace nameSpace = application.GetNamespace("MAPI");
                nameSpace.Logon("", "", Missing.Value, Missing.Value);
                nameSpace = null;
            }

            // Return the Outlook Application object.
            return application;
        }

The Outlook object model is common for all programming languages, so I hope there you won't find any difficulties in understanding the required approach. Read more about that in the Get and sign in to an instance of Outlook article in MSDN.

Finally, it is not clear what comes from where - I'd recommend clarifying all bits in the sample code posted, so we could suggest anything else.

Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
  • Outlook is always running, my dispatch function is like the sample code you provided, but since I always have outlook running it's always that I dispatch an active instance. I can always find the top level folders e.g., my own mail and the shared mail and it's inbox. But when I try to go deeper it sometimes fails to find those subfolder. – MisterButter Dec 08 '21 at 07:34
  • I found this on an other post that I think relates to my issue, but I don't really understand what it is saying https://stackoverflow.com/a/40853098/10833061 – MisterButter Dec 08 '21 at 07:38