Created
July 27, 2018 18:18
-
-
Save ideabrian/8a76d78a12aec79e5311c3bfc4e97586 to your computer and use it in GitHub Desktop.
Python script to send HTML email from command line
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- | |
This is a sample email taken from https://developers.google.com/gmail/schemas/apps-script-tutorial | |
and used to test the GMail actions support. | |
--> | |
<html> | |
<head> | |
<script type="application/ld+json"> | |
{ | |
"@context": "http://schema.org", | |
"@type": "EmailMessage", | |
"description": "Check this out", | |
"action": { | |
"@type": "ViewAction", | |
"url": "https://www.youtube.com/watch?v=eH8KwfdkSqU" | |
} | |
} | |
</script> | |
</head> | |
<body> | |
<p> | |
This a test for a Go-To action in Gmail. | |
</p> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Simple script used to send an HTML file as an HTML formatted email, | |
# using Gmail's SMTP service. Used for testing HTML emails. | |
# The core message-sending code is taken from the docs: | |
# http://docs.python.org/2/library/email-examples.html | |
# The code for correctly authenticating against Gmail comes from: | |
# http://kutuma.blogspot.co.uk/2007/08/sending-emails-via-gmail-with-python.html | |
import smtplib | |
import argparse | |
from getpass import getpass | |
from email.mime.multipart import MIMEMultipart | |
from email.mime.text import MIMEText | |
def parse_args(): | |
""" | |
Parse script input arguments. | |
Returns the parsed args, having validated that the input | |
file can be read, and that there is a valid Username. | |
""" | |
parser = get_parser() | |
args = parser.parse_args() | |
# artificially adding this to args, so that | |
# it can be passed around easily | |
args.html = open(args.html_filename).read() | |
# we have to have a valid Gmail account in order to access the SMTP service | |
if args.username is None: | |
args.username = raw_input('Gmail username: ') | |
print_args(args) | |
return args | |
def get_parser(): | |
""" Return the parser used to interpret the script arguments.""" | |
usage = ( | |
"Script to send an HTML file as an HTML email, using Google's SMTP server." | |
"\nExamples:" | |
"\n1. Send the contents of test_file.html to fred" | |
"\n$ send_html_email.py [email protected] test_file.html" | |
"\n" | |
"\n2. Send the mail to both fred and bob" | |
"\n$ send_html_email.py [email protected] [email protected] test_file.html" | |
"\n" | |
"\n3. Use [email protected] as the Gmail authenticating account" | |
"\n$ send_html_email.py [email protected] test_file.html -u [email protected]" | |
"\n" | |
"\n4. Override the default test mail subject line" | |
"\n$ send_html_email.py [email protected] test_file.html -t 'Test email'" | |
"\n" | |
"\n5. Turn on SMTP debugging" | |
"\n$ send_html_email.py [email protected] test_file.html -d" | |
) | |
epilog = "NB This script requires a Gmail account." | |
parser = argparse.ArgumentParser(description=usage, epilog=epilog, | |
# maintains raw formatting, instead of wrapping lines automatically | |
formatter_class=argparse.RawDescriptionHelpFormatter | |
) | |
parser.add_argument('recipients', help='The recipient email addresses (space delimited)', nargs='+') | |
parser.add_argument('html_filename', help='The HTML file to use as the email body content') | |
parser.add_argument('-s', '--sender', | |
help='The sender email address (defaults to <[email protected]>)', | |
default='[email protected]' | |
) | |
parser.add_argument('-u', '--username', | |
help=('A valid Gmail user account (used to authenticate against Google\'s SMTP service). ' | |
'If this argument is not supplied, the user will be prompted to type it in.') | |
) | |
parser.add_argument('-t', '--title', | |
help='The test email subject line (defaults to "Test email")', | |
default="Test email" | |
) | |
parser.add_argument('-p', '--plain', | |
help=('The test email plain text content. This script is designed primarily for the ' | |
'testing of HTML emails, so this text is really just a placeholder, for completeness. ' | |
'The default is "This is a test email (plain text)."'), | |
default="This is a test email (plain text)" | |
) | |
parser.add_argument('-d', '--debug', action='store_true', | |
help=('Use this option to turn on DEBUG for the SMTP server interaction.') | |
) | |
return parser | |
def print_args(args): | |
"""Print out the input arguments.""" | |
print 'Sending test email to: %s' % args.recipients | |
print 'Sending test email from: %s' % args.sender | |
print 'Using Gmail account: %s' % args.username | |
def create_message(args): | |
""" Create the email message container from the input args.""" | |
# Create message container - the correct MIME type is multipart/alternative. | |
msg = MIMEMultipart('alternative') | |
msg['Subject'] = args.title | |
msg['From'] = args.sender | |
msg['To'] = ','.join(args.recipients) | |
# Record the MIME types of both parts - text/plain and text/html. | |
part1 = MIMEText(args.plain, 'plain') | |
part2 = MIMEText(args.html, 'html') | |
# Attach parts into message container. | |
# According to RFC 2046, the last part of a multipart message, in this case | |
# the HTML message, is best and preferred. | |
msg.attach(part1) | |
msg.attach(part2) | |
return msg | |
def main(): | |
args = parse_args() | |
msg = create_message(args) | |
try: | |
smtpserver = smtplib.SMTP("smtp.gmail.com", 587) | |
smtpserver.set_debuglevel(args.debug) | |
smtpserver.ehlo() | |
smtpserver.starttls() | |
smtpserver.ehlo | |
# getpass() prompts the user for their password (so it never appears in plain text) | |
smtpserver.login(args.username, getpass()) | |
# sendmail function takes 3 arguments: sender's address, recipient's address | |
# and message to send - here it is sent as one string. | |
smtpserver.sendmail(args.sender, args.recipients, msg.as_string()) | |
print "Message sent to '%s'." % args.recipients | |
smtpserver.quit() | |
except smtplib.SMTPAuthenticationError as e: | |
print "Unable to send message: %s" % e | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment