Photo by Stephen Phillips - Hostreviews.co.uk on Unsplash
Send files with Gmail using a python script
Sending an email with this Python 3 script is very easy, but you can also send attachments with Python and Gmail. Follow this guide and have it in minutes.
Now as I do not like doing stuff twice I wanted to have a script that would send files from a folder as separate emails.
And that is exactly what this python script does. It takes a folder and for every file a mail with that file is created and send to a email address.
So I have a subscription on this online Receipt scanner service where I can scan receipts with my mobile camera and it will get processed by this service.
Now as this service is very good I also receive a lot of invoices and receipts by mail or I have to download them manually. As the service has a send to email option, sending hundreds of invoices manually to this email address is not really an option for me…. it doing something very simple more then twice! And if I have to do it twice I AUOTMATE it!
Gmail app Password
Now if you are like me and want to use the Gmail service for this and you have 2-way authentication (which you REALLY shoud have!) you cannot simple start using Gmail to send these emails as Gmail wants to authenticate in a 2-way!
So when you have signed up for 2-Step Verification, Gmaikl normally sends you verification codes. However, these codes do not work with some apps and devices, like Outlook or my Python script. Instead, you’ll need to authorize the app or device the first time you use it to sign in to your Google Account by generating and entering an App password.
Creating a Google App Password is very easy.
- Go to your Google Account.
- On the left navigation panel, click Security.
On the Signing in to Google panel, click App passwords. Note: If you can’t get to the page, 2-Step Verification is:
Not set up for your account
Set up for security keys only
At the bottom, click Select app and choose the app you’re using.
- Click Select device and choose the device you’re using.
- Click Generate.
- Copy the the 16 character code in the yellow bar you will need it for this script.
- Click Done.
Once you are finished, you won’t see that App password code again. However, you will see a list of apps and devices you’ve created App passwords for.
Mail file folders
To use this script save it somewhere on your pc or Mac, name it “send_files_by_gmail.py” and create a folder named “mail_files” and within this folder, and within this new “mail_files” folder create a folder named “done” and “new”.
Your folder will look like this
- send_files_by_gmail.py
- mail_files
- done
- new
You can place all the attachments within the “new” folder.
When the script is ready all attachments send will be in the “done” folder.
If the script crashes, you can rerun the script as it will start where it stopped as it only puts files in the “done” folder when the mail is send out.
How the python script works
Well, very simple! You do not need to install anything. You have to use python 3 (it will not work with python 2)
You only have to fill in 3 items in the python script
your gmail email address your gmail app password and the email address your want to send it to!
if __name__ == '__main__':
from_addr = "some@gmail.com" # your gmail account email address
pass_wd = "yourpasswors" # your pwd (see discription above)
to_addr = "to@emailaddress.com" # where the attachment should go to
m = MailFiles(from_addr, pass_wd, to_addr)
That’s it! Have Fun!
"""
author: Theo van der Sluijs
url: https://itheo.tech
copyright: CC BY-NC 4.0
creation date: 02-01-2019
Small script to send mails with attachment from folder with Gmail
Uses nothing but python 3 modules.
Create a folder named mail_files and within this folder done and new.
You can place all the attachments within the new folder.
When the script is ready all attachments send will be in the Done folder.
If the script crashes, you can rerun the script as it will start
where it stopped.
You need an gmail app password for this to work
https://support.google.com/accounts/answer/185833?hl=en
"""
import os
import time
import smtplib
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email import encoders
class MailFiles:
def __init__(self, from_addr=None, pass_wd=None, to_addr=None):
"""
init function for this to work
:param from_addr: your gmail account email address
:param pass_wd: your gmail app pwd (see discription above)
:param to_addr: here the attachment should go to
"""
self.from_addr = from_addr
self.pass_wd = pass_wd
self.to_addr = to_addr
dir_path = os.path.dirname(os.path.realpath(__file__))
self.start_dir = os.path.join(dir_path, "mail_files/new")
self.done_dir = os.path.join(dir_path, "mail_files/done")
self.process_files()
def process_files(self):
"""
This will loop thru the files in the New folder and calls the
mail_file function. It has a sleep function so Gmail will not
be flooded.
"""
i = 1
for filename in os.listdir(self.start_dir):
file = os.path.join(self.start_dir, filename)
if self.mail_file(file, filename): # Mailing retuns True or False
backup_file = os.path.join(self.done_dir, filename)
os.rename(file, backup_file) # move done file to done folder
print("Document {} send!".format(filename))
i += 1
time.sleep(5) # Sleep for 5 seconds to not overrun Gmail
def mail_file(self, file=None, filename=None):
"""
This function will mail the file to the email address as an attachment
:param file: path with filename
:param filename: filename online
:return: true or false
"""
try:
msg = MIMEMultipart()
['From'] = self.from_addr
['To'] = self.to_addr
['Subject'] = "Sending file {}".format(filename)
body = "Sending File {} to you".format(filename)
msg.attach(MIMEText(body, 'plain'))
attachment = open(file, "rb")
part = MIMEBase('application', 'octet-stream')
part.set_payload(attachment.read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', "attachment; filename= %s" % filename)
msg.attach(part)
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(self.from_addr, self.pass_wd)
text = msg.as_string()
server.sendmail(self.from_addr, self.to_addr, text)
server.quit()
return True
except smtplib.SMTPException as e:
print(e)
return False
except:
return False
if __name__ == '__main__':
from_addr = "some@gmail.com" # your gmail account email address
pass_wd = "yourpasswors" # your pwd (see discription above)
to_addr = "to@emailaddress.com" # where the attachment should go to
m = MailFiles(from_addr, pass_wd, to_addr)