Hack This: How to Send an Email from Python
Automating your email doesn't get much easier.
I have five goddamn email accounts: one personal, two school, and two work. There's even a sixth that I sometimes use for sketchy sign-ups. A significant portion of my life consists of quickly assessing and classifying emails, deleting emails, starring emails, and even reading and replying to emails. I'd give you a breakdown of how much time daily is spent on these tasks, but, to be honest, I don't even want to know.
I've joked about hiring an assistant just to manage my email, which makes me wonder what instructions I would give them: If such and such is true about an email, then take this action, or, if this other thing is true, do something different. It would be a set of rules, ultimately, that they would be applying to my email accounts. And when I see the words "set of rules," I immediately think of writing computer programs. Scanning through my emails now, it's clear that I could reasonably implement my assistant in computer code.
To do this, however, I would need some way of connecting my actual email accounts to my email-reading program. This turns out to be fairly simple to do. Email is in real-life just a series of text-based protocols for moving information across networks; it's like the rest of the internet, in other words. Layers of protocols. Everything else is just an interface.
Even if you have no interest in creating an email-sorting bot, handling email as raw data is just an interesting thing to do. We'll do it in Python here mainly because Python is really good at making stuff like this easy and intuitive, even for non-programmers. The instructions below are based in part on the email automation chapter in Al Sweigart's Automate the Boring Stuff with Python, which I highly recommend as both a programming introduction and a cookbook for doing all kinds of fun stuff with automation. It can be accessed for free under a Creative Commons license at automatetheboringstuff.com.
Before starting, you'll need to download Python if you don't have it installed already. You'll also need a basic text editor, which can be anything, but most people are going to tell you to use Sublime Text. I'd agree with them, especially if you're interested in doing more coding. It can be downloaded here. ST is not free, but can be evaluated indefinitely with the occasional nagware message. It's worth the money, however.
Python sort of has two faces. One is the Python interpreter, which allows users to tap lines or snippets of Python code into a command line interface, which will execute those lines as Python commands as they're entered (for example: print("Hello, World!")). The second is Python scripting. This is basically where you take a bunch of Python commands and bundle them together into one or more files that can be invoked all at once from the interpreter. These files essentially act as programs—sometimes they're tiny, simple programs (as below), but they can also wind up being huge projects.
If you've just downloaded Python, you should do two more things first. One: spend 10 minutes doing this "Hello, World" Python for non-programmers tutorial. Two: spend another five minutes doing this tutorial on using Python modules. Python being Python, installing and importing language extensions is criminally easy.
OK! Let's get started.
0) Email protocols 101
There are three main email protocols. The old-school one is called POP (Post Office Protocol). The basic idea with POP is that a software email client (not a browser) connects to a remote server and downloads emails onto the user's actual computer so that they're available locally. This was a good idea when internet connections were more sparse and being offline was a common occurrence, but now it's largely obsolete.
IMAP (Internet Message Access Protocol) is the current Internet standard for accessing email. It's much faster and more in line with how the internet is actually used now, allowing for multiple parties to connect to the same inbox and for those parties to remain connected to the server through their entire email session, start to finish.
Web browsers access email via an extra layer of HTTP, but the underlying protocols are the same.
Crucially, POP (POP3 is the current version) and IMAP both are used for getting emails from a server. To send emails we need a different protocol, called the Simple Mail Transfer Protocol (SMTP), because we can't just send an email to a recipient. We need to send it to some server, from which that other user can download it using IMAP or POP3.
1) Import the Python SMTP module
To get started, we first need to have the right Python module in place. Smtplib comes with Python so we don't need to worry about installing it or anything. So, just tap this into your interpreter.import smtplib
For an overview of the package (and to verify that it's actually imported), try using the help function:help(smtplib)
That will work with any package, btw.
2) Connect to the email server
First thing is to create an smtplib object, which we can view as a sort of portal through which we access our connection and the various capabilities provided by the smtplib package for doing things with that connection. We're basically creating a server.
For our purposes, the function that returns our object needs two parameters or arguments. The first is a domain name, which is usually just your regular email with "smtp" in front of it, as below. The second is a port number, which is where on the email server we'll be connecting to. The port number will almost always be 587, which corresponds to the TLS encryption standard. (Very rarely, a service might use 465, but you almost certainly don't use that service.)
Anyhow, so it will look like this:smtpObj = smtplib.SMTP('smtp.gmail.com', 587)
The object "smtpObj" has the object type "SMTP." You can verify this by entering only the object name smtpObj into the interpreter and hitting enter. You'll get back a memory address and object type, assuming you didn't mess up the above step. The variable name "smtpObj" could be anything of your choosing that's a legit variable name in Python.
3) Start encryption
The next step in establishing a connection is to tell the SMTP object that we need to encrypt our message. So, enter this line into the interpreter (and press enter):smtpObj.starttls()
What we did is send a message to Gmail telling it that that we want our connection to be encrypted using the TLS (Transport Layer Security) protocol, which is the current standard for internet communications. TLS isn't in itself an encryption scheme, but rather it specifies that an acceptable encryption scheme must be used or no deal.
You'll get a confirmation message back:2.0.0 Ready to start TLS
Note what happens when you try and skip this step and just go to the login step below. Errors! Gmail won't let you do it because Gmail uses encryption via the HTTPS protocol. What is the HTTPS protocol? It's simply regular old HTTP but with the addition of the TLS protocol on top.
Not much to it:smtpObj.login('firstname.lastname@example.org','just123kidding')
That is indeed that is your/my email password just floating in the breeze, which is potentially a very bad thing. It's not such an issue here in my Python interpreter on my computer, but if you were actually automating email using a Python script, you should be very careful about where you publish/upload that script.
5) Send a message
Imagine here that I forgot this step and you had to figure out how to actually send the email on your own. You could Google it, of course, but with the Python interpreter or really any other shell-like environment, you could also just ask the interpreter itself. Just enter this in:help(smtpObj)
Not too far down you'll see the method you want, or that you would (correctly) assume that you want.It will even give you an example:
Note that in the above example, the login stuff is absent. This is because the connection was made only to the user's own computer ("localhost") rather than a distant email server. For my connection, let's do this.smtpObj.sendmail("email@example.com","firstname.lastname@example.org","go to bed!")
Did it work? Sure did!
6) Close the connection
Just enter insmtpObj.quit()
and you're golden.
This is obviously just a taste of what you can do with email with Python. This is only sending messages, for one thing. I'd recommend continuing on in Sweigart's book for learning how to deal with an email inbox using IMAP. Spoiler alert: There's still not that much to it. You could be running your whole email show with Python scripts by morning.
You can probably also see how one could be very, very annoying (or worse) when applying automation to email, so let's please avoid the dark side.