Create a gist now

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.

Show comment
Hide comment
@tentenbiz

tentenbiz Mar 17, 2015

Thank you so much, worked perfectly!

Thank you so much, worked perfectly!

@olexandr-maltsev

This comment has been minimized.

Show comment
Hide comment

Thank you.

@reema123

This comment has been minimized.

Show comment
Hide comment
@reema123

reema123 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

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.

Show comment
Hide comment
@stefansundin

stefansundin 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!

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.

Show comment
Hide comment

Thank you

@mohdazlan

This comment has been minimized.

Show comment
Hide comment
@mohdazlan

mohdazlan May 10, 2015

Many thanks mate

Many thanks mate

@tymoreau

This comment has been minimized.

Show comment
Hide comment
@tymoreau

tymoreau May 21, 2015

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

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

@ntung

This comment has been minimized.

Show comment
Hide comment
@ntung

ntung 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/

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.

Show comment
Hide comment
@ssivanatarajan

ssivanatarajan Feb 7, 2016

wow works perfectly recovered my rar file . Thanks

wow works perfectly recovered my rar file . Thanks

@thiagoh

This comment has been minimized.

Show comment
Hide comment
@thiagoh

thiagoh Mar 10, 2016

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

thiagoh commented Mar 10, 2016

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

@ethanpayne

This comment has been minimized.

Show comment
Hide comment
@ethanpayne

ethanpayne Mar 24, 2016

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

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

@zrod

This comment has been minimized.

Show comment
Hide comment
@zrod

zrod Mar 24, 2016

Great, worked just fine, thanks!

zrod commented Mar 24, 2016

Great, worked just fine, thanks!

@huxingyi

This comment has been minimized.

Show comment
Hide comment
@huxingyi

huxingyi 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.

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.

Show comment
Hide comment
@stefansundin

stefansundin Apr 13, 2016

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

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.

Show comment
Hide comment
@nielsaust

nielsaust Apr 26, 2016

This is so awesome. I thank you!

This is so awesome. I thank you!

@jeanadam

This comment has been minimized.

Show comment
Hide comment
@jeanadam

jeanadam Nov 10, 2016

Still working great! thanks!

Still working great! thanks!

@kavunshiva

This comment has been minimized.

Show comment
Hide comment
@kavunshiva

kavunshiva Feb 13, 2017

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

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

@UdayKanike

This comment has been minimized.

Show comment
Hide comment
@UdayKanike

UdayKanike 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

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.

Show comment
Hide comment
@stefansundin

stefansundin 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
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.

Show comment
Hide comment
@devlifealways

devlifealways Apr 20, 2017

Worked perfectly, thanks (y)

Worked perfectly, thanks (y)

@me-suzy

This comment has been minimized.

Show comment
Hide comment
@me-suzy

me-suzy May 17, 2017

EOF problem on notepad, see this print screen:

https://snag.gy/GFLYU6.jpg

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.

Show comment
Hide comment
@stefansundin

stefansundin May 17, 2017

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

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.

Show comment
Hide comment
@tejasshah93

tejasshah93 Jul 27, 2017

Works perfectly! Thanks 👍

Works perfectly! Thanks 👍

@NadeemBaloch

This comment has been minimized.

Show comment
Hide comment
@NadeemBaloch

NadeemBaloch Aug 12, 2017

Where should i place that particular file ?

Where should i place that particular file ?

@stefansundin

This comment has been minimized.

Show comment
Hide comment
@stefansundin

stefansundin Aug 12, 2017

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

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.

Show comment
Hide comment
@woodenleaves

woodenleaves Sep 20, 2017

Thanks a lot! It works like a charm!

Thanks a lot! It works like a charm!

@guimeira

This comment has been minimized.

Show comment
Hide comment
@guimeira

guimeira Sep 25, 2017

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

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

@tolew1

This comment has been minimized.

Show comment
Hide comment
@tolew1

tolew1 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.

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.

Show comment
Hide comment
@riavalon

riavalon 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

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.

Show comment
Hide comment
@Alinaki

Alinaki Dec 9, 2017

Works like a charm. Thank you!

Alinaki commented Dec 9, 2017

Works like a charm. Thank you!

@TonyStark

This comment has been minimized.

Show comment
Hide comment
@TonyStark

TonyStark Dec 23, 2017

no words man
very very thank you :)

no words man
very very thank you :)

@wonkknows

This comment has been minimized.

Show comment
Hide comment
@wonkknows

wonkknows Feb 20, 2018

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

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

@dan400man

This comment has been minimized.

Show comment
Hide comment
@dan400man

dan400man 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.

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.

Show comment
Hide comment
@heiniovason

heiniovason Jul 4, 2018

This script saved my ass. Thanks a bunch!

This script saved my ass. Thanks a bunch!

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