Sending an email with Python isn't all that difficult. But most tutorials leave out the most important bits! Namely:
- How to get Gmail to work with Python
- How to properly manage secrets (passwords)
- How to schedule message delivery
In this tutorial you're going to learn how to do it all and how do it properly!
Configuring Gmail
First things first, you have to configure Gmail to work with Python...
Sign into your Google Account and go to: https://myaccount.google.com/
Find and click on Security in the sidebar on the left:
Scroll down and click on "Turn on access" in the "Less secure app access" panel:
Flip the toggle:
Google will probably send you a menacing email about a "Critical security alert"... don't worry, you're about to deal with this...
Managing Secrets
Google's freaking out right now because they know you're about to give Python your email and password. And if you copy-and-pasted your credentials as plaintext into a Python script they would have cause for concern! But you're not going to do that... you're going to manage your secrets the right way.
Create a new directory and cd
into it:
mkdir email-tut
cd email-tut
Open text editor and save a .env
file to the directory you just created with your email and password:
GMAIL_USER=replace_me@gmail.com
GMAIL_PASSWORD=Sup3r$ecretP@assW0rd!
Because you saved your credentials outside of Python you can .gitignore
this .env
file so that if/when you upload the repo to Github you won't expose your password!
Now you can create a Python script called emailbot.py
inside the email-tut
directory (right beside your .env
) and fill it with:
import os
from dotenv import load_dotenv
load_dotenv(".env")
SENDER = os.environ.get("GMAIL_USER")
PASSWORD = os.environ.get("GMAIL_PASSWORD")
The load_dotenv
function from the python-dotenv package will allow you to safely import your secrets.
Sending an email with the Standard Library requires the following imports and convenience function:
from email.message import EmailMessage
import smtplib
def send_email(recipient, subject, body):
msg = EmailMessage()
msg.set_content(body)
msg["Subject"] = subject
msg["From"] = SENDER
msg["To"] = recipient
server = smtplib.SMTP_SSL("smtp.gmail.com", 465)
server.login(SENDER, PASSWORD)
server.send_message(msg)
server.quit()
Calling the function should fire off an email:
send_email("replace_me@hey.com", subject="test", body="test")
Save the entire python script:
from email.message import EmailMessage
import smtplib
import os
from dotenv import load_dotenv
load_dotenv(".env")
SENDER = os.environ.get("GMAIL_USER")
PASSWORD = os.environ.get("GMAIL_PASSWORD")
def send_email(recipient, subject, body):
msg = EmailMessage()
msg.set_content(body)
msg["Subject"] = subject
msg["From"] = SENDER
msg["To"] = recipient
server = smtplib.SMTP_SSL("smtp.gmail.com", 465)
server.login(SENDER, PASSWORD)
server.send_message(msg)
server.quit()
send_email("replace_me@hey.com", subject="test", body="test")
And test it at the command line to make sure that it works:
python emailbot.py
Sending just "test" is a little pedestrian, spice up your script with some inspirational quotes:
from quote import quote
import random
quotes = quote("William Shakespeare", limit=50)
body = random.sample(quotes, k=1)[0]['quote']
send_email("replace_me@hey.com", subject="Quote of the Day", body=body)
Save the script and call it from the command line again to make sure you didn't screw anything up 😉
Scheduling Delivery
Hopefully you've got a cute little Shakespearean Email Bot working and now you're itching to schedule this bot to send you a quote every day at 9:00am. To accomplish this install hickory:
pip install hickory
Call hickory schedule
at the command line with emailbot.py
as the script argument:
hickory schedule emailbot.py --every=day@9:00am
And that's literally it!
If you want to check the status of the schedule you can with:
hickory status
# ID FILE STATE RUNS
# ea6b74 emailbot.py waiting 0
And to kill the schedule:
hickory kill emailbot.py
Happy emailing!
TL;DR: The entire script:
from email.message import EmailMessage
import smtplib
import os
import random
from dotenv import load_dotenv
from quote import quote
load_dotenv(".env")
SENDER = os.environ.get("GMAIL_USER")
PASSWORD = os.environ.get("GMAIL_PASSWORD")
def send_email(recipient, subject, body):
msg = EmailMessage()
msg.set_content(body)
msg["Subject"] = subject
msg["From"] = SENDER
msg["To"] = recipient
server = smtplib.SMTP_SSL("smtp.gmail.com", 465)
server.login(SENDER, PASSWORD)
server.send_message(msg)
server.quit()
quotes = quote("William Shakespeare", limit=50)
body = random.sample(quotes, k=1)[0]['quote']
send_email("replace_me@hey.com", subject="Quote of the Day", body=body)
Top comments (2)
hickory status doesnt work with linux?
hickory command is not found
I am getting this error