Skip to content

Instantly share code, notes, and snippets.

@shreydesai
Created January 6, 2017 19:53
Show Gist options
  • Save shreydesai/552a820ade2afe5980b85cbfb27dc6a0 to your computer and use it in GitHub Desktop.
Save shreydesai/552a820ade2afe5980b85cbfb27dc6a0 to your computer and use it in GitHub Desktop.
Mass personalized email script
"""Mass personalized email script"""
import sys
import smtplib
import argparse
from email import encoders
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
HOST = 'smtp.gmail.com'
PORT = 587
RATE_LIMIT = 10 - 1
def smtp_login(username, password):
server = smtplib.SMTP(HOST, PORT)
server.starttls()
try:
server.login(username, password)
except:
sys.stderr.write('Error: SMTP connection failed\n')
exit(1)
return server
def is_text_file(name):
if '.txt' in name:
return True
return False
def read_body(path):
try:
with open(path) as f:
body = f.read().strip()
return body
f.close()
except:
sys.stderr.write('Error: Metadata file doesn\'t exist\n')
exit(1)
def read_receivers(path):
receivers = []
try:
with open(path) as f:
lines = f.read().split('\n')
for line in lines:
tags = line.split(',')
if len(tags) == 2:
receivers.append((tags[0],tags[1]))
f.close()
except:
sys.stderr.write('Error: Receivers file doesn\'t exist\n')
exit(1)
return receivers
def read_attachment(path):
try:
with open(path) as f:
pass
except:
sys.stderr.write('Error: Attachment file doesn\'t exist\n')
exit(1)
def create_email(subject, body, sender, receiver, attachment):
outer = MIMEMultipart()
name, email = receiver
outer['Subject'] = subject
outer['To'] = email
outer['From'] = sender
message_text = body.replace('<>', name)
outer.attach(MIMEText(message_text, 'plain'))
attachment_file = open(attachment, 'rb')
part = MIMEBase('application', 'octet-stream')
part.set_payload((attachment_file).read())
encoders.encode_base64(part)
part.add_header(
'Content-Disposition',
'attachment',
filename=attachment
)
outer.attach(part)
return outer
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="""
Send mass personalized emails to a collection of receivers. This script
only supports one PDF attachment and placeholder value reserved for the
name of the receiver.
Usage example:
python3 mass_email.py -u username -p password -s 'Summer Internship' -b body.txt -r receivers.txt -a Resume.pdf
""")
parser.add_argument('-u', '--username', required=True,
help="""Gmail username used to authenticate
the SMTP sever""")
parser.add_argument('-p', '--password', required=True,
help="""Gmail password used to authenciate
the SMTP server""")
parser.add_argument('-s', '--subject', required=True,
help="""Subject of email""")
parser.add_argument('-b', '--body', required=True,
help="""Name of text file containing email body.
Body should include <> whenever a placeholder
value needs to be used.
""")
parser.add_argument('-r', '--receivers', required=True,
help="""Name of text file containing email receivers.
Must include receiver name and address in this form:
<name 1>,<address 1>
<name 2>,<address 2>
...
""")
parser.add_argument('-a', '--attachment', required=True,
help="""Name of PDF attachment""")
args = parser.parse_args()
if not is_text_file(args.body) or not is_text_file(args.receivers):
sys.stderr.write('Error: Incorrect metadata or receiver file types\n')
exit(1)
subject = args.subject
body = read_body(args.body)
sys.stdout.write('Body file parsing successful\n')
receivers = read_receivers(args.receivers)
sys.stdout.write('Receivers file parsing successful\n')
attachment = read_attachment(args.attachment)
sys.stdout.write('Attachment file parsing successful\n')
username, password = args.username, args.password
server = smtp_login(username, password)
sys.stdout.write('SMTP server authentication successful\n\n')
for i in range(len(receivers)):
if i == RATE_LIMIT:
sys.stdout.write('\nGoogle SMTP rate limit exceeded. Please try ' +
'sending the rest of these emails tomorrow.\n')
sys.stdout.write('You left off at {}.\n'.format(receivers[i]))
exit(1)
email = create_email(
subject=subject,
body=body,
sender=username,
receiver=receivers[i],
attachment=args.attachment
)
text = email.as_string()
server.sendmail(username, receivers[i][1], text)
print('({index}/{total}) Email sent to {email}'.format(
index=(i + 1),
total=len(receivers),
email=receivers[i]
))
server.quit()
exit(0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment