- Python Automation Cookbook
- Jaime Buelta
- 46字
- 2021-06-30 14:52:52
Sending email notifications
Email has become an inescapable tool for everyday use. It's arguably the best place to send a notification if an automated task has detected something. On the other hand, email inboxes are already too full up with spam messages, so be careful.
Spam filters are also a reality. Be careful with whom to send emails to and the number of emails to be sent. An email server or address can be labeled as a spam source
, and all emails may be quietly dropped by the internet.
This recipe will show you how to send a single email using an existing email account.
This approach is viable for spare emails sent to a couple of people, as a result of an automated task, but no more than that. Refer to Chapter 9, Dealing with Communication Channels, for more ideas on how to send emails, including groups.
Getting ready
For this recipe, we require a valid email account set up, which includes the following:
- A valid email server using SMTP; SMTP is the standard email protocol
- A port to connect to
- An address
- A password
These four elements should be enough to be able to send an email.
Some email services, for example, Gmail, will encourage you to set up 2FA, meaning that a password is not enough to send an email. Typically, they'll allow you to create a specific password for apps to use, bypassing the 2FA request. Check your email provider's information for options.
The email service you use should indicate what the SMTP server is and what port to use in their documentation. This can be retrieved from email clients as well, as they are the same parameters. Check your provider documentation. In the following example, we will use a Gmail account.
How to do it...
- Create the
email_task.py
file, as follows:import argparse import configparser import smtplib from email.message import EmailMessage def main(to_email, server, port, from_email, password): print(f'With love, from {from_email} to {to_email}') # Create the message subject = 'With love, from ME to YOU' text = '''This is an example test''' msg = EmailMessage() msg.set_content(text) msg['Subject'] = subject msg['From'] = from_email msg['To'] = to_email # Open communication and send server = smtplib.SMTP_SSL(server, port) server.login(from_email, password) server.send_message(msg) server.quit() if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('email', type=str, help='destination email') parser.add_argument('-c', dest='config', type=argparse.FileType('r'), help='config file', default=None) args = parser.parse_args() if not args.config: print('Error, a config file is required') parser.print_help() exit(1) config = configparser.ConfigParser() config.read_file(args.config) main(args.email, server=config['DEFAULT']['server'], port=config['DEFAULT']['port'], from_email=config['DEFAULT']['email'], password=config['DEFAULT']['password'])
- Create a configuration file called
email_conf.ini
with the specifics of your email account. For example, for a Gmail account, fill in the following template. The template is available in GitHub at https://github.com/PacktPublishing/Python-Automation-Cookbook-Second-Edition/blob/master/Chapter02/email_conf.ini but be sure to fill it in with your data:[DEFAULT] email = EMAIL@gmail.com server = smtp.gmail.com port = 465 password = PASSWORD
- Ensure that the file cannot be read or written by other users on the system, setting the permissions of the file to allow only our user.
600
permissions mean read and write access for the file owner, and no access to anyone else:$ chmod 600 email_conf.ini
- Run the script to send a test email:
$ python3 email_task.py -c email_conf.ini destination_email@server.com
- Check the inbox of the destination email; an email should be received with the subject
With love, from ME to YOU.
How it works...
There are two key steps in the preceding scripts—the generation of the message and the sending.
The message needs to contain mainly the To
and From
email addresses, as well as the Subject
. If the content is pure text, as in this case, calling .set_content()
is enough. The whole message can then be sent.
It is technically possible to send an email that is tagged as coming from a different email address than the one you used to send it. This is discouraged, though, as it can be considered by your email provider as trying to impersonate a different email. You can use the reply-to header to allow answering to a different account.
Sending the email requires you to connect to the specified server and start an SMTP connection. SMTP is the standard for email communication.
The steps are quite straightforward—configure the server, log into it, send the prepared message, and quit.
If you need to send more than one message, you can log in, send multiple emails, and then quit, instead of connecting each time.
There's more...
If the objective is a bigger operation, such as a marketing campaign, or even production emails, such as confirming a user's email, please refer to Chapter 9, Dealing with Communication Channels.
The email message content used in this recipe is very simple, but emails can be much more complicated than that.
The To
field can contain multiple recipients. Separate them with commas, like this:
message['To'] = ','.join(recipients)
Emails can be defined in HTML, with an alternative plain text, and have attachments. The basic operation is to set up a MIMEMultipart
and then attach each of the MIME
parts that compose the email:
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
message = MIMEMultipart()
part1 = MIMEText('some text', 'plain')
message.attach(part1)
with open('path/image', 'rb') as image:
part2 = MIMEImage(image.read())
message.attach(part2)
The most common SMTP connection is SMTP_SSL
, which is more secure, as all communication with the server is encrypted and always requires a login and password. However, plain, unauthenticated SMTP exists—check your email provider documentation.
Remember that this recipe is aimed toward simple notifications. Emails can grow quite complex if attaching different information. If your objective is an email for customers or any general group, try to use the ideas in Chapter 9, Dealing with Communication Channels.
See also
- The Adding command-line options recipe in Chapter 1, Let's Begin Our Automation Journey, to understand the basic concepts of command-line options.
- The Preparing a task recipe, covered earlier in this chapter, to learn about the strategy to follow when designing an automated task.