Instantly share code, notes, and snippets.

Embed
What would you like to do?
Extract attachments from emails that Gmail doesn't allow you to download. This is dumb. Please use Python >= 3.4.
#!/usr/bin/env python3
# Get your files that Gmail block. Warning message:
# "Anti-virus warning - 1 attachment contains a virus or blocked file. Downloading this attachment is disabled."
# Based on: https://spapas.github.io/2014/10/23/retrieve-gmail-blocked-attachments/
# Instructions:
# Go to your emails, click the arrow button in the top right, "Show original", then "Download Original".
# Move the files to the same directory as this program, then run it.
import email
import sys
import os
if __name__ == '__main__':
if sys.version_info[0] < 3:
print("Please use Python 3.")
sys.exit()
if len(sys.argv) < 2:
print("Press enter to process all files with .txt extension.")
input()
files = [f for f in os.listdir('.') if os.path.isfile(f) and f.endswith('.txt')]
else:
files = sys.argv[1:]
print("Files: %s" % ', '.join(files))
print()
for f in files:
msg = email.message_from_file(open(f))
print("Processing %s" % f)
print("Subject: %s" % msg['Subject'])
for pl in msg.get_payload():
fn_header = pl.get_filename()
if fn_header:
fn_data = email.header.decode_header(fn_header)
(fn_str, fn_charset) = fn_data[0]
if isinstance(fn_str, str):
fn = fn_str
else:
fn = fn_str.decode(fn_charset)
print("Found %s" % fn)
if os.path.isfile(fn):
print("The file %s already exists! Press enter to overwrite." % fn)
input()
open(fn, 'wb').write(pl.get_payload(decode=True))
print()
@tentenbiz

This comment has been minimized.

tentenbiz commented Mar 17, 2015

Thank you so much, worked perfectly!

@olexandr-maltsev

This comment has been minimized.

olexandr-maltsev commented Apr 5, 2015

Thank you.

@reema123

This comment has been minimized.

reema123 commented Apr 12, 2015

i have done all the process as u told above but after step 32 also my files are not yet extracted and i am not getting what should i do further, so please help me out, in what way i could get my files

@stefansundin

This comment has been minimized.

Owner

stefansundin commented Apr 12, 2015

For those of you who can't get this working, there is an alternative way posted here.

Update, 12 January 2015: Ivana (at the comments section) proposed a different solution that may work for some files: Use a mobile Gmail client (I tested it with Android) and "Save to Drive" your attachment. You’ll then be able to download it from the Google Drive!

@omerbuyuksar

This comment has been minimized.

omerbuyuksar commented May 3, 2015

Thank you

@mohdazlan

This comment has been minimized.

mohdazlan commented May 10, 2015

Many thanks mate

@tymoreau

This comment has been minimized.

tymoreau commented May 21, 2015

Works perfectly with python 2.7, I recover my rar archive. Thanks !

@ntung

This comment has been minimized.

ntung commented Jun 10, 2015

Your code really hepls me a lot. I just download all my documents from Gmail. But I have not seen the instructions for the code. You can see the origin article here:
http://spapas.github.io/2014/10/23/retrieve-gmail-blocked-attachments/

@ssivanatarajan

This comment has been minimized.

ssivanatarajan commented Feb 7, 2016

wow works perfectly recovered my rar file . Thanks

@thiagoh

This comment has been minimized.

thiagoh commented Mar 10, 2016

man!! it works perfectly!! thank u!!

@ethanpayne

This comment has been minimized.

ethanpayne commented Mar 24, 2016

Thanks!
Also you can download the attachment using another client such as Mail.app

@zrod

This comment has been minimized.

zrod commented Mar 24, 2016

Great, worked just fine, thanks!

@huxingyi

This comment has been minimized.

huxingyi commented Apr 13, 2016

Thanks, but I found it failed to extract Chinese name attachments like this Content-Type: application/octet-stream; name="=?GB2312?B?c2RoKDUuMTcuMjMuNDbQ3tX9z9C80rP2wazM9LrzxuTL/M/QvNK15sXG?= =?GB2312?B?tO3O8ykucmFy?=" Content-Disposition: attachment; filename="=?GB2312?B?c2RoKDUuMTcuMjMuNDbQ3tX9z9C80rP2wazM9LrzxuTL/M/QvNK15sXG?= =?GB2312?B?tO3O8ykucmFy?=".

Do the follow changes can fix this.

        try:
            open(fn, 'wb').write(pl.get_payload(decode=True))
        except:
            fn = "test.rar"
            print("Invalid filename, just redirect to write %s" % fn)
            open(fn, 'wb').write(pl.get_payload(decode=True))

Hope this trick can help other guys who encounter the same issue.

@stefansundin

This comment has been minimized.

Owner

stefansundin commented Apr 13, 2016

@huxingyi I updated the code so it should decode filenames properly now. Give it a try.

@nielsaust

This comment has been minimized.

nielsaust commented Apr 26, 2016

This is so awesome. I thank you!

@jeanadam

This comment has been minimized.

jeanadam commented Nov 10, 2016

Still working great! thanks!

@kavunshiva

This comment has been minimized.

kavunshiva commented Feb 13, 2017

Dope! This worked like a charm. Yayyy, Python modules for everything, and thanks @stefansundin

@UdayKanike

This comment has been minimized.

UdayKanike commented Mar 7, 2017

Hi,

I am getting following error, can you please help me

udays-MacBook-Pro:mystuff udaykumarkanike$ python extract-attachments.py 0.txt
Files: 0.txt
()
Processing 0.txt
Subject: None
Traceback (most recent call last):
  File "extract-attachments.py", line 27, in <module>
    fn_header = pl.get_filename()
AttributeError: 'str' object has no attribute 'get_filename'
udays-MacBook-Pro:mystuff udaykumarkanike$ 

Thanks
Uday

@stefansundin

This comment has been minimized.

Owner

stefansundin commented Mar 8, 2017

Hi @UdayKanike. I suspect your email is formatted in a way I have not encountered before. msg.get_payload() seems to have returned a string.

Try adding this (use the first line to see where to put it):

    for pl in msg.get_payload():
      if not isinstance(pl, email.message.Message):
        print("Unexpected payload")
        continue
@devlifealways

This comment has been minimized.

devlifealways commented Apr 20, 2017

Worked perfectly, thanks (y)

@me-suzy

This comment has been minimized.

me-suzy commented May 17, 2017

EOF problem on notepad, see this print screen:

https://snag.gy/GFLYU6.jpg

@stefansundin

This comment has been minimized.

Owner

stefansundin commented May 17, 2017

@me-suzy it appears you are using Python 2.7. Please run this script with Python 3.

@tejasshah93

This comment has been minimized.

tejasshah93 commented Jul 27, 2017

Works perfectly! Thanks 👍

@NadeemBaloch

This comment has been minimized.

NadeemBaloch commented Aug 12, 2017

Where should i place that particular file ?

@stefansundin

This comment has been minimized.

Owner

stefansundin commented Aug 12, 2017

@NadeemBaloch Place the .py file and your emails (.txt files) in the same directory. Then run the python script.

@woodenleaves

This comment has been minimized.

woodenleaves commented Sep 20, 2017

Thanks a lot! It works like a charm!

@guimeira

This comment has been minimized.

guimeira commented Sep 25, 2017

For all the python noobs like me out there: do not save the script as email.py.

@tolew1

This comment has been minimized.

tolew1 commented Oct 8, 2017

Genius, this is great and works perfectly. Google and their omnipotence blocks common extensions like JS in zip files now and don't provide an override option. time to for another email.

@riavalon

This comment has been minimized.

riavalon commented Nov 21, 2017

Really terrific, thanks for this! Had some files from old personal website I saved in my email a loooong time ago and couldn't download them cause of this "antivirus" thing. This script worked perfectly, though

@Alinaki

This comment has been minimized.

Alinaki commented Dec 9, 2017

Works like a charm. Thank you!

@TonyStark

This comment has been minimized.

TonyStark commented Dec 23, 2017

no words man
very very thank you :)

@wonkknows

This comment has been minimized.

wonkknows commented Feb 20, 2018

this worked awesome -- thank you -- I'm currently studying Python so am super happy with this.

@dan400man

This comment has been minimized.

dan400man commented Mar 20, 2018

I was finally able to retrieve my 3-year old attachment by using Gmail's "Save to Drive", as mentioned above. Interestingly, I couldn't download it from the Drive page (it just opened a blank page with a cryptic URL) in Firefox. I tried "sharing" it, sending a link to the file to my work Outlook email. Outlook opens IE here at work to navigate to the link and, after the obligatory advice to move to Chrome, I was able to download the file, an encrypted .7z file. It was all source code. At first, I couldn't figure out why I chose to encrypt the archive, since it was just source code. But then I saw that some of the file extensions were .CMD, which I seem to recall Gmail screaming about and not allowing.

7zip allows the file names to be encrypted, so that's how I got around that. Apparently, Google has decided that any archive whose file names are encrypted must be malware designed by Russian, Chinese, or North Korean hackers.

@heiniovason

This comment has been minimized.

heiniovason commented Jul 4, 2018

This script saved my ass. Thanks a bunch!

@akhileshdarjee

This comment has been minimized.

akhileshdarjee commented Sep 27, 2018

Awesome, it works :)

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