Skip to content

Instantly share code, notes, and snippets.

@jcausey-astate
Last active April 3, 2023 06:06
Show Gist options
  • Save jcausey-astate/91412607172f870f770413e3523044d3 to your computer and use it in GitHub Desktop.
Save jcausey-astate/91412607172f870f770413e3523044d3 to your computer and use it in GitHub Desktop.
Send email using Python without requiring an MTA or installing sendmail. Adapted from https://moythreads.com/wordpress/2015/07/09/sending-email-with-python-without-an-mta/
#!/usr/bin/env python2.7
#
# Send email without requiring account credentials to be stored on the
# Docker instance.
#
# Adapted from:
# https://moythreads.com/wordpress/2015/07/09/sending-email-with-python-without-an-mta/
#
# Dependencies:
# `smtplib` (pip install smtplib to install)
#
# Usage:
# sendemail.py [--from=FROM-ADDRESS] TO-ADDRESS MESSAGE-BODY
#----------------------------------------------------------------------------------------
import sys, argparse, re
import smtplib
import dns.resolver, socket
# Try to create a reasonable default. Note the check here doesn't work for the newer
# 4+ letter TLDs, nor does it actually verify TLD.
default_from = socket.getfqdn()
if re.match(r".*\.local$", default_from) or not re.match(r".+\.[a-z]{2,3}$", default_from):
default_from = socket.gethostbyname(socket.gethostname())
default_from = 'noreply@' + default_from
parser = argparse.ArgumentParser(description='Send simple email.')
parser.add_argument('to_address', type=str,
help='email address of the recipient')
parser.add_argument('message', type=str, nargs='+',
help='body of the message')
parser.add_argument('--from', dest='from_address', type=str, default=default_from,
help='custom address for "from" field')
parser.add_argument('--verbose', action='store_true',
help='give more verbose output')
parser.set_defaults(verbose=False, use_patient_id=False)
args = parser.parse_args()
if not re.match(r"[^@]+@[^@]+\.[^@]+", args.to_address):
sys.stderr.write('Destination address does not appear to be a valid email address: ' + args.to_address)
parser.print_help()
sys.exit(1)
if not len(args.message) >= 1:
sys.stderr.write('A message body is required.')
parser.print_help()
sys.exit(2)
dest_server = args.to_address.split('@')[1]
dest_addrs = dns.resolver.query(dest_server, 'MX')
if len(dest_addrs) <= 0:
sys.stderr.write('No mail servers found for destination\n')
sys.exit(3)
# Just pick the first destination address
server = str(dest_addrs[0].exchange)
# Add the From: and To: headers
fromaddr = args.from_address
toaddr = args.to_address
body = ' '.join(args.message)
msg = "From: {}\r\nTo: {}\r\n\r\n{}".format(fromaddr, toaddr, body)
server = smtplib.SMTP(server)
if(args.verbose):
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddr, msg)
server.quit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment