Search code examples
pythonpython-3.xmacosoutlook

Automate Outlook on Mac with Python


I can automate Outlook on windows with win32/COM, but does anyone know of a pure python way to do the same on mac osx?

A simple use case would be:

  • Open outlook/connect to the active instance
  • Launch a blank new email

I want to create an app to create email templates and attach files, then let the user finish editing the email and send when ready, NOT just send emails.

Is there a python wrapper for applescript that may work? (I don't know anything about applescript, so an example would help).


Solution

  • @ajrwhite adding attachments had one trick, you need to use 'Alias' from mactypes to convert a string/path object to a mactypes path. I'm not sure why but it works.

    here's a working example which creates messages with recipients and can add attachments:

    from appscript import app, k
    from mactypes import Alias
    from pathlib import Path
    
    def create_message_with_attachment():
        subject = 'This is an important email!'
        body = 'Just kidding its not.'
        to_recip = ['[email protected]', '[email protected]']
    
        msg = Message(subject=subject, body=body, to_recip=to_recip)
    
        # attach file
        p = Path('path/to/myfile.pdf')
        msg.add_attachment(p)
    
        msg.show()
    
    class Outlook(object):
        def __init__(self):
        self.client = app('Microsoft Outlook')
    
    class Message(object):
        def __init__(self, parent=None, subject='', body='', to_recip=[], cc_recip=[], show_=True):
    
            if parent is None: parent = Outlook()
            client = parent.client
    
            self.msg = client.make(
                new=k.outgoing_message,
                with_properties={k.subject: subject, k.content: body})
    
            self.add_recipients(emails=to_recip, type_='to')
            self.add_recipients(emails=cc_recip, type_='cc')
    
            if show_: self.show()
    
        def show(self):
            self.msg.open()
            self.msg.activate()
    
        def add_attachment(self, p):
            # p is a Path() obj, could also pass string
    
            p = Alias(str(p)) # convert string/path obj to POSIX/mactypes path
    
            attach = self.msg.make(new=k.attachment, with_properties={k.file: p})
    
        def add_recipients(self, emails, type_='to'):
            if not isinstance(emails, list): emails = [emails]
            for email in emails:
                self.add_recipient(email=email, type_=type_)
    
        def add_recipient(self, email, type_='to'):
            msg = self.msg
    
            if type_ == 'to':
                recipient = k.to_recipient
            elif type_ == 'cc':
                recipient = k.cc_recipient
    
            msg.make(new=recipient, with_properties={k.email_address: {k.address: email}})