Automate Emails with Python Featuring a Raspberry Pi

I got a Raspberry Pi and have been wondering what kind of projects I could do with it. Here’s the first one I’ve decided to do. My wife wants me to send her love letters but sometimes I get distracted by too many other things and forget to send her an email or text. I figure I can take human error out of the picture by automating a service to send emails to my wife using a cronjob. For those of you who would rather watch a video about how to do this, I’ve made a YouTube video of it here: https://youtu.be/gQgX3cXwT_4.

The reason I think a Raspberry Pi is an ideal system to deploy this on is because it’s cheap and doesn’t draw much power. For example, the cheapest Pi you can get is the Raspberry Pi Zero and you can find it on Amazon for around $36 for a starter kit. Sending simple emails isn’t really processor intensive so this single board computer is ideal for this use case.

In this tutorial we’re going to use Gmail to send the emails out. If you don’t have a Gmail account, you’ll want to create one. For this project, I created a new email account because this method of sending emails requires you to allow less secure apps through Gmail. To turn this on go to https://myaccount.google.com/lesssecureapps and enable less secure apps. When you’ve done this, we should be able to send emails with Python on your Raspberry Pi or whatever linux device you want to use. The other option is to read Google’s documentation on how to access their API: https://developers.google.com/gmail/api/quickstart/python.

We’re going to import three modules and they’re all in the Python Standard Library so there’s no need to pip install any third party packages. We’ll need to import smtplib, ssl, and random so the first line of our script should look something like this:


import smtplib, ssl, random

Now we’re going to want to use port 465 because we’re using SSL. So we’ll set a variable named port to 465. We’re going to create another variable named smtp_server and we’re going to set this to ‘smtp.gmail.com’. We’ll need a password to log in to the email account. You can store this directly in the file which is what I chose to do but be aware that sensitive information is in the file. This means if you’re going to use version control, consider reading in the password from a text file or using an environment variable to get it. We’re going to set a password variable to a string of whatever password you use for the Gmail account you’ll be using. Then we’ll set a user variable set to the email address you are going to use. We’ll also set up a receiver variable with whatever email address you want to send to. With all that done, your script should look like this:


import smtplib, ssl, random

port = 465

smtp_server = 'smtp.gmail.com'

password = 'Password'

user = 'user@gmail.com'

receiver = 'target@gmail.com'

Now that we have that taken care of, I’m going to build the body of my email message. I have some text files in the same directory where my project lives that have lines of text separated by newline characters (these can be found near the bottom of this post). I am going to read these files into lists so I can randomly choose a line, subject, and term of endearment for my wife. I’m going to initialize four empty lists: subjects, lines, middles, and ends. Then, I’m going to use with open({full filepath}, ‘r’) as rf: to access the text files. I’m going to read rf and split the text on ‘\n’ to create a list of lines from the file. After that I’m going to have a list for terms of endearment called openers. These are going to be pet names for my wife. This portion of the code looks like this:

subjects = []
lines = []
middles = []
ends = []
with open('/home/pi/development/love_letters/lines.txt', 'r') as rf:
  lines = rf.read().split('\n')
with open('/home/pi/development/love_letters/middles.txt', 'r') as rf:
  lines = rf.read().split('\n')
with open('/home/pi/development/love_letters/endings.txt', 'r') as rf:
    ends = rf.read().split('\n')
with open('/home/pi/development/love_letters/subjects.txt', 'r') as rf:
    subjects = rf.read().split('\n')
openers = ['Sweetheart', 'Sugarbuns', 'Sugarbasket', 'Honey', 'Good Looking', 'Pooh Bear']

Now we’re going to create the message to send. In this case it’ll be a plain text email to my wife telling her nice things but you could set this up to be much more complicated with html tags and email attachments if you like. I’m going to randomly choose lines and subjects so that she doesn’t get the same email twice. I’m going to use format to insert the values into the string. I’m going to set Subject: to a random subject. This will be the subject of the email. random.choice will randomly choose the variables from the lists I’ve created. This portion of the code looks like this:

message = """\
Subject: {subject}

{opener},
{line1}
{line2}
{line3}

Love,
    Dmoneyballa
""".format(
    subject=random.choice(subjects),
    opener=random.choice(openers),
    line1=random.choice(lines),
    line2=random.choice(lines),
    line3=random.choice(lines)
)

Now all that’s left to do is create an ssl context, log in, and send the email - so let’s do that now.

We’ll set a variable named context to ssl.create_default_context()

Next, we’ll do a self-closing connection using the with keyword. We’re going to use with smtplib.SMTP_SSL(‘smtp.gmail.com’, port, context=context) as server:. On the next line, we’ll login using server.login(user, password). Then we’ll use server.sendmail(user, receiver, message) to send the message. Here if you wanted to send multiple emails to multiple email addresses, you could set up a for loop to loop over a list of email addresses.

This code portion should look like this:

context = ssl.create_default_context()
with smtplib.SMTP_SSL('smtp.gmail.com', port, context=context) as server:
    server.login(user, password)
    server.sendmail(user, receiver, message)

I’ve got a replit set up so you can look at what the code should look like. You can find that here: https://repl.it/@DrewGillies/Email-Automation
gist for lines.txt: https://gist.github.com/dmoneyballer/ad9f422b117296ebfe2a00ee421cbd93

gist for subjects.txt: https://gist.github.com/dmoneyballer/927c50f954e213ceeefe6b0cef69558b

gist for middles.txt: https://gist.github.com/dmoneyballer/1a7efceb003b962a647a19e3292e920b

gist for endings.txt: https://gist.github.com/dmoneyballer/b01b9d944bb66759f2020da920ab0fab

Once you’ve got your script running, working, and sending emails, you’ll want to set it up on a schedule to send emails. To do this we’ll use cronjobs. We’ll open a terminal. The command we’ll use to get into this is crontab -e. The dash e is for editing. You can do crontab -l to list all the cronjobs on a Linux system. If this is the first time you’ve run this command, it’ll ask you to choose a terminal based text editor. Choose whichever one you’re the most comfortable with. I prefer to use vim so I chose that one. You’ll need to insert a line of text with how often you want the script to run and what commands to run when the time clock reaches the scheduled time.

My cronjob looks like this:

30 20 * * * /usr/bin/python3 /home/pi/development/love_letters/main.py

There are five values at the beginning of this command that specify when to run. The first column is for minutes, the second column is for hours, the third column is for day of month, the fourth column is for month, and the fifth column is for day of week. In this example, the third through fifth columns all display an asterisk which stands for “every.” That means that the asterisks will tell it to run every day of the month, every month, everyday of the week. So essentially this will send an email at 8:30 PM every day when my Raspberry Pi is running.

After specifying when you want your cronjob to run in the first argument, you need to specify what to run. In the above example, I specified that we’re running a Python3 script and then I provided a full path to the script.

Congratulations, now you’ve got a python script scheduled to send emails for you automatically. You’re doing great. I hope you see the utility in automating emails and use this for whatever scenario you dream up. Python is a great language to automate with.

1 Like

That was quite an interesting read. Thanks for sharing this tutorial :slight_smile:

1 Like