Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Download attachment from mail using python

I have multiple emails that contain an attachment. I would like to download the attachment for unread emails and with a specific subject line.

for example, I got an email that has a subject "EXAMPLE" and contains an attachment. So how it would be Below code, I tried but it is not working" it's a Python code

#Subject line can be "EXAMPLE" 
      for subject_line in lst_subject_line:    
             # typ, msgs = conn.search(None,'(UNSEEN SUBJECT "' + subject_line + '")')
             typ, msgs = conn.search(None,'("UNSEEN")')
             msgs = msgs[0].split()
             print(msgs)
             outputdir = "C:/Private/Python/Python/Source/Mail Reader"
             for email_id in msgs:
                    download_attachments_in_email(conn, email_id, outputdir)

Thank You

like image 942
Karthik S Avatar asked Apr 22 '20 13:04

Karthik S


People also ask

How do I download an email attachment in Python?

First, we import the required modules to connect to Gmail account. Next, we save Gmail username and password. We also store the path to directory where we need to download & store attachment. Next, we create a folder DataFiles where we will be downloading the attachments to, if it doesn't exist.

How do I read email attachments in python?

We explicitly tell to use new EmailMessage class in our byte read method through _class=EmailMessage parameter. You can read your email message (aka envelope) from sources such as bytes-like object, binary file object or string thanks to built-in methods in message. Parser API.


2 Answers

Most answers I could find were outdated.
Here's a python (>=3.6) script to download attachments from a Gmail account.
Make sure to check the filter options at the bottom and enable less secure apps on your google account.

import os
from imbox import Imbox # pip install imbox
import traceback

# enable less secure apps on your google account
# https://myaccount.google.com/lesssecureapps

host = "imap.gmail.com"
username = "username"
password = 'password'
download_folder = "/path/to/download/folder"

if not os.path.isdir(download_folder):
    os.makedirs(download_folder, exist_ok=True)
    
mail = Imbox(host, username=username, password=password, ssl=True, ssl_context=None, starttls=False)
messages = mail.messages() # defaults to inbox

for (uid, message) in messages:
    mail.mark_seen(uid) # optional, mark message as read

    for idx, attachment in enumerate(message.attachments):
        try:
            att_fn = attachment.get('filename')
            download_path = f"{download_folder}/{att_fn}"
            print(download_path)
            with open(download_path, "wb") as fp:
                fp.write(attachment.get('content').read())
        except:
            print(traceback.print_exc())

mail.logout()


"""
Available Message filters: 

# Gets all messages from the inbox
messages = mail.messages()

# Unread messages
messages = mail.messages(unread=True)

# Flagged messages
messages = mail.messages(flagged=True)

# Un-flagged messages
messages = mail.messages(unflagged=True)

# Messages sent FROM
messages = mail.messages(sent_from='[email protected]')

# Messages sent TO
messages = mail.messages(sent_to='[email protected]')

# Messages received before specific date
messages = mail.messages(date__lt=datetime.date(2018, 7, 31))

# Messages received after specific date
messages = mail.messages(date__gt=datetime.date(2018, 7, 30))

# Messages received on a specific date
messages = mail.messages(date__on=datetime.date(2018, 7, 30))

# Messages whose subjects contain a string
messages = mail.messages(subject='Christmas')

# Messages from a specific folder
messages = mail.messages(folder='Social')
"""

For Self Sign Certificates use:

...
import ssl
    
context = ssl._create_unverified_context()
mail = Imbox(host, username=username, password=password, ssl=True, ssl_context=context, starttls=False)
...
like image 129
Pedro Lobito Avatar answered Sep 26 '22 22:09

Pedro Lobito


I found this most effective in my case. Just keep your outlook open while running the program and it will extract unread messages with specific subject line.

import datetime
import os
import win32com.client


path = os.path.expanduser("~/Documents/xyz/folder_to_be_saved")  #location o file today = datetime.date.today()  # current date if you want current

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


def saveattachemnts(subject):
    for message in messages:
        if message.Subject == subject and message.Unread:
        #if message.Unread:  #I usually use this because the subject line contains time and it varies over time. So I just use unread

            # body_content = message.body
            attachments = message.Attachments
            attachment = attachments.Item(1)
            for attachment in message.Attachments:
                attachment.SaveAsFile(os.path.join(path, str(attachment)))
                if message.Subject == subject and message.Unread:
                    message.Unread = False
                break                
                
saveattachemnts('EXAMPLE 1')
saveattachemnts('EXAMPLE 2')
like image 30
Aps Avatar answered Sep 23 '22 22:09

Aps