Skip to content

Instantly share code, notes, and snippets.

@styrmis
Created March 19, 2014 08:55
Show Gist options
  • Save styrmis/9637945 to your computer and use it in GitHub Desktop.
Save styrmis/9637945 to your computer and use it in GitHub Desktop.
Download all attachments from Gmail from a specific sender
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import email, getpass, imaplib, os, sys
# The following script will download all attachments from a given sender
# that you specify. Little to no error handling, use at your own risk!
#
# IMPORTANT: If you first used Gmail in the UK then you need to select
# a different mailbox (please see below and uncomment the appropriate line).
#
# Adapted from http://stackoverflow.com/questions/10182499/how-do-i-download-only-unread-attachments-from-a-specific-gmail-label
# Directory where to save attachments ('.' = current directory)
detach_dir = '.'
user = raw_input("Gmail username: ")
pwd = getpass.getpass("Password: ")
sender_email = raw_input("Enter the sender's email (to filter by): ")
# Connecting to the gmail imap server
m = imaplib.IMAP4_SSL("imap.gmail.com")
m.login(user,pwd)
# Select the mailbox
m.select("[Gmail]/All Mail")
# If you get an error "command SEARCH illegal in state AUTH, only allowed in states SELECTED"
# then it is likely that the mailbox you have tried to select doesn't exist.
# If you were originally a Google Mail user (i.e. a user in the UK) then you should uncomment
# the line below.
# m.select("[Google Mail]/All Mail") # here you a can choose a mail box like INBOX instead
# Alternatively you can search for emails in the inbox only
# m.select("INBOX")
# Use m.list() to get all the mailboxes
resp, items = m.search(None, 'FROM', '"%s"' % sender_email)
items = items[0].split()
for emailid in items:
resp, data = m.fetch(emailid, "(RFC822)")
email_body = data[0][1]
mail = email.message_from_string(email_body)
if mail.get_content_maintype() != 'multipart':
continue
subject = ""
if mail["subject"] is not None:
subject = mail["subject"]
print "["+mail["From"]+"] :" + subject
for part in mail.walk():
if part.get_content_maintype() == 'multipart':
continue
if part.get('Content-Disposition') is None:
continue
filename = part.get_filename()
counter = 1
if not filename:
filename = 'part-%03d%s' % (counter, 'bin')
counter += 1
att_path = os.path.join(detach_dir, filename)
if not os.path.isfile(att_path) :
fp = open(att_path, 'wb')
fp.write(part.get_payload(decode=True))
fp.close()
@ntyagi-dev
Copy link

ntyagi-dev commented Apr 19, 2022

SOLVED IT 💯

                                                            mail = email.message_from_string(email_body)

The above line in the code must be replaced with the following line and it works perfectly

                                                            mail = email.message_from_bytes(email_body)

in short: "email.message_from_string" must be replaced with "email.message_from_bytes". Because the data is present in bytes not in the string format.

Thanks for that @RahulSapparapu !
In addition to that, I had to make the following minor changes to make it python3 compatible

  1. Use input in place of raw_input
  2. Use additional single quote at

('"[Gmail]/All Mail"')

  1. Use parentheses at

print("["+mail["From"]+"] :" + subject)

Finally, added the following to filename as my attachments were of the same name and were getting overwritten:

datestring = mail['date']
datestring2 = utils.parsedate_to_datetime(datestring).strftime("%Y_%m_%d")
filename = datestring2 + '_' + part.get_filename()

Thank you @styrmis for sharing this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment