1

I am currently working on automation solution with Python to read an incoming Outlook emails and download any attachments. I am using exchangelib library to achieve this. I am able to the read email body and able to save file attachments (.pdf, .jpg, .xlsx), but facing issue on how to download Outlook items (.msg attachments. ex: someone provided an email approval or attached email has additional info etc..,). I read through exchangelib documentation, but it doesn't have any info on how to save an outlook attachment.

I have tried various ways by changing various modes 'w', 'wb' ..but no luck.

My code

# Read & Save Attachments code
  for item in emails.all().order_by('-datetime_received')[:1]:  
     for attachment in item.attachments:
         print('Number of Attachment found:', len(item.attachments))

       if isinstance(attachment, FileAttachment):
           local_path=os.path.join('C:/Attachments', attachment.name)
           with open(local_path, 'wb') as f, attachment.fp as fp:
                buffer = fp.read(1024)
                while buffer:
                   f.write(buffer)
                   buffer = fp.read(1024)
                   print('Saved attachment to', local_path)

       elif isinstance(attachment, ItemAttachment):
            name = str(attachment.name)+'.msg'
            local_path=os.path.join('C:/Attachments/', name)
            with open(local_path, 'w') as f:
                 f.write(attachment.item.body)
                 print('Saved attachment to', local_path)

Exchangelib Sample example

for item in a.inbox.all():
    for attachment in item.attachments:
        if isinstance(attachment, FileAttachment):
            local_path = os.path.join('/tmp', attachment.name)
            with open(local_path, 'wb') as f:
                f.write(attachment.content)
            print('Saved attachment to', local_path)
        elif isinstance(attachment, ItemAttachment):
            if isinstance(attachment.item, Message):
                print(attachment.item.subject, attachment.item.body)

With above code, all i see is a file that is created with subject name, but 0 kb (with no content) and without extension (.msg) which is why i was concatenating the 'name' above.

Erik Cederstrand
  • 9,643
  • 8
  • 39
  • 63
Sumanth C
  • 25
  • 5
  • I think there's a difference between a .msg attachment as a file, and an ItemAttachment. Does your code print the `Saved attachment to...` line? If not, then this is still a FileAttachment, not an ItemAttachment. – Erik Cederstrand Sep 05 '19 at 06:36
  • Hello Erik, Thanks for responding. The code prints "Saved attachment to.." (elif block). But the folder contains a file that is 0kb in size and without any extension. (.msg). The FileAttachment block works perfectly without any issues. – Sumanth C Sep 05 '19 at 14:36
  • The print statement tells you in both cases which file was written to. If it prints the path with the `.msg` and you still see the file without the suffix, then it's either a stale file from a previous attempt or because your Windows hides the file suffix in the explorer window. – Erik Cederstrand Sep 06 '19 at 04:32
  • I humbly disagree with you. Let's say it's a stale file because it is not giving you .msg extension, but why the content is NOT exported just like FileAttachment and it remains with 0kb always? May i know if exchangelib supports to export "ItemAttachment" as filehandling logic of Python as your documentation also do not have the info except Print statement of "attachment.item.subject", "attachment.item.body" which works? – Sumanth C Sep 06 '19 at 13:09
  • For item attachments, you have to decide yourself which parts of the item you want to write to the file. But in any case, the `open()` method in Python doesn’t magically write to a different file than the path you specify. – Erik Cederstrand Sep 06 '19 at 22:11

0 Answers0