Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """Send emails via SES."""
- import argparse
- import email
- from email.headerregistry import Address
- import json
- import mimetypes
- import boto3
- ses = boto3.client('ses')
- def new_template():
- """Create a templated email."""
- response = ses.create_template(
- Template={
- "TemplateName": "TestTemplate",
- "SubjectPart": "Hello {{name}}",
- "TextPart": "Hello {{name}}! \n\nThis is a test email made by"
- "Maxwell Brown using AWS SES's \"Templated Email\" "
- "feature.\n\nThis makes it possible to put client "
- "names and callsigns into the email!\n\n\n"
- "Sincerely,\n\n-Max",
- "HtmlPart": "<h1>Hello <b>{{name}}!</b></h1>"
- "<p>This is a test email made by Maxwell Brown using "
- "AWS SES's \"Templated Email\" feature.</p>"
- "<p>This makes it possible to put client names and "
- "callsigns into the email!</p>"
- "<p><i>Sincerely,</i><br><b>-Maxwell Brown</b></p>",
- },
- )
- print(f"Response: {response}")
- def delete_template():
- """Create a templated email."""
- response = ses.delete_template(TemplateName="TestTemplate")
- print(f"Response: {response}")
- def send_templated_email():
- """Send a templated email."""
- response = ses.send_templated_email(
- Source="me@email.com",
- Destination={
- "ToAddresses": ["me@email.com"],
- # "CcAddresses": [],
- # "BccAddresses": [],
- },
- ReplyToAddresses=["me@email.com"],
- # ReturnPath is for bounces/complaints
- ReturnPath="me@email.com",
- Template="TestTemplate",
- TemplateData=json.dumps({
- "name": "World"
- }),
- )
- print(response)
- def send_bulk_templated_email():
- """Send a templated email to many recipients."""
- response = ses.send_bulk_templated_email(
- Source="me@email.com",
- Destinations=[
- {
- "Destination": {"ToAddresses": ["me@email.com"]},
- # You MUST include ReplacementTemplateData and at least
- # an empty JSON object, or else you'll get InvalidTemplateData
- # as an API response
- "ReplacementTemplateData": "{}",
- },
- {
- "Destination": {"ToAddresses": ["dad@email.com"]},
- "ReplacementTemplateData": json.dumps({"name": "Dad"}),
- }
- ],
- ReplyToAddresses=["me@email.com"],
- # ReturnPath is for bounces/complaints
- ReturnPath="me@email.com",
- Template="TestTemplate",
- DefaultTemplateData=json.dumps({"name": "World"}),
- )
- print(response)
- def send_raw_email():
- """Send a raw MIME email.
- Note that this is currently the only way to send emails with attachments.
- """
- email_parser = email.parser.Parser()
- with open("example_email.eml", "r") as email_file:
- parsed_email = email_parser.parse(email_file)
- print("headers")
- for key, value in parsed_email.items():
- print(f"{key} | {value}")
- for part in parsed_email.walk():
- print(part.get_content_type())
- # Clear out all of the existing headers in this email
- headers = [header for header in parsed_email.keys()]
- for header in headers:
- # Don't delete these headers, they're complicated
- # (also there are probably other headers in other emails)
- if header not in ["Mime-version", "Content-type"]:
- del parsed_email[header]
- parsed_email["From"] = "Maxwell Brown <me@email.com>"
- parsed_email["Subject"] = "Test Raw Email"
- response = ses.send_raw_email(
- Source='me@email.com',
- # NOTE Is Destinations because To:, Cc:, & Bcc: are Headers?
- Destinations=['me@email.com'],
- RawMessage={'Data': parsed_email.as_bytes()},
- )
- print(response)
- def send_generated_raw_email():
- """Send a raw MIME email that was generated procedurally.
- This is a demonstration on how to do a text + html email
- that also has attachments.
- The outgoing email ends up looking like this:
- multipart/mixed
- -- multipart/alternative
- ---- text/plain
- ---- text/html
- ---- image/png
- -- application/pdf
- -- application/x-msexcel
- -- application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
- """
- outgoing_email = email.message.EmailMessage()
- outgoing_email.set_content("Hello World\n\nThis is the plain text email.")
- image_cid = email.utils.make_msgid()
- outgoing_email.add_alternative(
- "<html>"
- "<body>"
- "<h1>Hello World</h1>"
- "<p>This is the HTML email.</p>"
- f'<img src="cid:{image_cid[1:-1]}" />' # need to strip <>
- "<p>This should show up after the img</p>"
- "</body>"
- "</html>",
- subtype="html",
- )
- with open("image.jpg", "rb") as image_file:
- # Apparently we just have to manually keep track of when we add what
- # parts. The text/plain is index 0, our htmls index 1
- html_part = outgoing_email.get_payload()[1]
- html_part.add_related(
- image_file.read(),
- "image",
- "jpeg",
- cid=image_cid,
- )
- attachments = ["sample.pdf", "sample.ods"]
- for filename in attachments:
- ctype, encoding = mimetypes.guess_type(filename)
- if ctype is None or encoding is not None:
- ctype = 'application/octet-stream'
- maintype, subtype = ctype.split("/", 1)
- with open(filename, "rb") as attachment_file:
- outgoing_email.add_attachment(
- attachment_file.read(),
- maintype=maintype,
- subtype=subtype,
- filename=filename,
- )
- outgoing_email["From"] = str(Address("Maxwell Brown", "me", "email.com")) # noqa
- outgoing_email["Subject"] = "Test Raw Email"
- outgoing_email["To"] = str(Address("Maxwell Brown", "me", "email.com")) # noqa
- response = ses.send_raw_email(
- Source='me@email.com',
- Destinations=['me@email.com'],
- RawMessage={'Data': outgoing_email.as_bytes()},
- )
- print(response)
- command_map = {
- "new": new_template,
- "delete": delete_template,
- "send": send_templated_email,
- "bulk": send_bulk_templated_email,
- "raw": send_raw_email,
- "generate": send_generated_raw_email,
- }
- parser = argparse.ArgumentParser()
- parser.add_argument("command", choices=[k for k in command_map.keys()])
- if __name__ == '__main__':
- kwargs = vars(parser.parse_args())
- command_fxn = command_map.get(kwargs["command"])
- if not command_fxn:
- print(f"Command {kwargs['command']!r} not recognized")
- command_fxn()
Add Comment
Please, Sign In to add comment