macosapplescriptmimeapple-mail

AppleScript - extract an email message as a MIME object


I have an AppleScript I wrote to do some parsing on Mail.app messages, however it seems I will need more powerful processing (specifically - separate a replied message from the original message it quotes) than what is provided by AppleScript (say, using Python's email package). Is it possible to get an email message as a MIME string?


Solution

  • I'm not sure if this is what you meant, but here is how you can get the raw message text from a selection you've made in Mail.app which can than be processed with MIME tools to extract all the parts.

    tell application "Mail"
        set msgs to selection
        if length of msgs is not 0 then
            repeat with msg in msgs
    
                set messageSource to source of msg
    
                set textFile to "/Users/harley/Desktop/foo.txt"
    
                set myFile to open for access textFile with write permission
                write messageSource to myFile
                close access myFile
    
            end repeat
        end if
    end tell
    

    And then here's a Python email example script that unpacks the message and writes out each MIME part to a separate file in a directory

    https://docs.python.org/3.4/library/email-examples.html

    #!/usr/bin/env python3
    
    """Unpack a MIME message into a directory of files."""
    
    import os
    import sys
    import email
    import errno
    import mimetypes
    
    from argparse import ArgumentParser
    
    
    def main():
        parser = ArgumentParser(description="""\
    Unpack a MIME message into a directory of files.
    """)
        parser.add_argument('-d', '--directory', required=True,
                            help="""Unpack the MIME message into the named
                            directory, which will be created if it doesn't already
                            exist.""")
        parser.add_argument('msgfile')
        args = parser.parse_args()
    
        with open(args.msgfile) as fp:
            msg = email.message_from_file(fp)
    
        try:
            os.mkdir(args.directory)
        except FileExistsError:
            pass
    
        counter = 1
        for part in msg.walk():
            # multipart/* are just containers
            if part.get_content_maintype() == 'multipart':
                continue
            # Applications should really sanitize the given filename so that an
            # email message can't be used to overwrite important files
            filename = part.get_filename()
            if not filename:
                ext = mimetypes.guess_extension(part.get_content_type())
                if not ext:
                    # Use a generic bag-of-bits extension
                    ext = '.bin'
                filename = 'part-%03d%s' % (counter, ext)
            counter += 1
            with open(os.path.join(args.directory, filename), 'wb') as fp:
                fp.write(part.get_payload(decode=True))
    
    
    if __name__ == '__main__':
        main()
    

    So then if the unpack.py script is run on the AppleScript output...

    python unpack.py -d OUTPUT ./foo.txt 
    

    You get a directory with the MIME parts separated. When I run this on a message which quotes an original message then the original message shows up in a separate part.