Guest User

Untitled

a guest
Nov 11th, 2018
622
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.74 KB | None | 0 0
  1. """Send emails via SES."""
  2. import argparse
  3. import email
  4. from email.headerregistry import Address
  5. import json
  6. import mimetypes
  7.  
  8. import boto3
  9.  
  10.  
  11. ses = boto3.client('ses')
  12.  
  13.  
  14. def new_template():
  15. """Create a templated email."""
  16. response = ses.create_template(
  17. Template={
  18. "TemplateName": "TestTemplate",
  19. "SubjectPart": "Hello {{name}}",
  20. "TextPart": "Hello {{name}}! \n\nThis is a test email made by"
  21. "Maxwell Brown using AWS SES's \"Templated Email\" "
  22. "feature.\n\nThis makes it possible to put client "
  23. "names and callsigns into the email!\n\n\n"
  24. "Sincerely,\n\n-Max",
  25. "HtmlPart": "<h1>Hello <b>{{name}}!</b></h1>"
  26. "<p>This is a test email made by Maxwell Brown using "
  27. "AWS SES's \"Templated Email\" feature.</p>"
  28. "<p>This makes it possible to put client names and "
  29. "callsigns into the email!</p>"
  30. "<p><i>Sincerely,</i><br><b>-Maxwell Brown</b></p>",
  31. },
  32. )
  33.  
  34. print(f"Response: {response}")
  35.  
  36.  
  37. def delete_template():
  38. """Create a templated email."""
  39. response = ses.delete_template(TemplateName="TestTemplate")
  40. print(f"Response: {response}")
  41.  
  42.  
  43. def send_templated_email():
  44. """Send a templated email."""
  45. response = ses.send_templated_email(
  46. Source="me@email.com",
  47. Destination={
  48. "ToAddresses": ["me@email.com"],
  49. # "CcAddresses": [],
  50. # "BccAddresses": [],
  51. },
  52. ReplyToAddresses=["me@email.com"],
  53. # ReturnPath is for bounces/complaints
  54. ReturnPath="me@email.com",
  55. Template="TestTemplate",
  56. TemplateData=json.dumps({
  57. "name": "World"
  58. }),
  59. )
  60.  
  61. print(response)
  62.  
  63.  
  64. def send_bulk_templated_email():
  65. """Send a templated email to many recipients."""
  66. response = ses.send_bulk_templated_email(
  67. Source="me@email.com",
  68. Destinations=[
  69. {
  70. "Destination": {"ToAddresses": ["me@email.com"]},
  71. # You MUST include ReplacementTemplateData and at least
  72. # an empty JSON object, or else you'll get InvalidTemplateData
  73. # as an API response
  74. "ReplacementTemplateData": "{}",
  75. },
  76. {
  77. "Destination": {"ToAddresses": ["dad@email.com"]},
  78. "ReplacementTemplateData": json.dumps({"name": "Dad"}),
  79. }
  80. ],
  81. ReplyToAddresses=["me@email.com"],
  82. # ReturnPath is for bounces/complaints
  83. ReturnPath="me@email.com",
  84. Template="TestTemplate",
  85. DefaultTemplateData=json.dumps({"name": "World"}),
  86. )
  87.  
  88. print(response)
  89.  
  90.  
  91. def send_raw_email():
  92. """Send a raw MIME email.
  93.  
  94. Note that this is currently the only way to send emails with attachments.
  95. """
  96. email_parser = email.parser.Parser()
  97. with open("example_email.eml", "r") as email_file:
  98. parsed_email = email_parser.parse(email_file)
  99.  
  100. print("headers")
  101. for key, value in parsed_email.items():
  102. print(f"{key} | {value}")
  103.  
  104. for part in parsed_email.walk():
  105. print(part.get_content_type())
  106.  
  107. # Clear out all of the existing headers in this email
  108. headers = [header for header in parsed_email.keys()]
  109. for header in headers:
  110. # Don't delete these headers, they're complicated
  111. # (also there are probably other headers in other emails)
  112. if header not in ["Mime-version", "Content-type"]:
  113. del parsed_email[header]
  114.  
  115. parsed_email["From"] = "Maxwell Brown <me@email.com>"
  116. parsed_email["Subject"] = "Test Raw Email"
  117.  
  118. response = ses.send_raw_email(
  119. Source='me@email.com',
  120. # NOTE Is Destinations because To:, Cc:, & Bcc: are Headers?
  121. Destinations=['me@email.com'],
  122. RawMessage={'Data': parsed_email.as_bytes()},
  123. )
  124.  
  125. print(response)
  126.  
  127.  
  128. def send_generated_raw_email():
  129. """Send a raw MIME email that was generated procedurally.
  130.  
  131. This is a demonstration on how to do a text + html email
  132. that also has attachments.
  133.  
  134. The outgoing email ends up looking like this:
  135. multipart/mixed
  136. -- multipart/alternative
  137. ---- text/plain
  138. ---- text/html
  139. ---- image/png
  140. -- application/pdf
  141. -- application/x-msexcel
  142. -- application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
  143. """
  144. outgoing_email = email.message.EmailMessage()
  145. outgoing_email.set_content("Hello World\n\nThis is the plain text email.")
  146.  
  147. image_cid = email.utils.make_msgid()
  148. outgoing_email.add_alternative(
  149. "<html>"
  150. "<body>"
  151. "<h1>Hello World</h1>"
  152. "<p>This is the HTML email.</p>"
  153. f'<img src="cid:{image_cid[1:-1]}" />' # need to strip <>
  154. "<p>This should show up after the img</p>"
  155. "</body>"
  156. "</html>",
  157. subtype="html",
  158. )
  159.  
  160. with open("image.jpg", "rb") as image_file:
  161. # Apparently we just have to manually keep track of when we add what
  162. # parts. The text/plain is index 0, our htmls index 1
  163. html_part = outgoing_email.get_payload()[1]
  164. html_part.add_related(
  165. image_file.read(),
  166. "image",
  167. "jpeg",
  168. cid=image_cid,
  169. )
  170.  
  171. attachments = ["sample.pdf", "sample.ods"]
  172. for filename in attachments:
  173. ctype, encoding = mimetypes.guess_type(filename)
  174. if ctype is None or encoding is not None:
  175. ctype = 'application/octet-stream'
  176.  
  177. maintype, subtype = ctype.split("/", 1)
  178. with open(filename, "rb") as attachment_file:
  179. outgoing_email.add_attachment(
  180. attachment_file.read(),
  181. maintype=maintype,
  182. subtype=subtype,
  183. filename=filename,
  184. )
  185.  
  186. outgoing_email["From"] = str(Address("Maxwell Brown", "me", "email.com")) # noqa
  187. outgoing_email["Subject"] = "Test Raw Email"
  188. outgoing_email["To"] = str(Address("Maxwell Brown", "me", "email.com")) # noqa
  189.  
  190. response = ses.send_raw_email(
  191. Source='me@email.com',
  192. Destinations=['me@email.com'],
  193. RawMessage={'Data': outgoing_email.as_bytes()},
  194. )
  195.  
  196. print(response)
  197.  
  198.  
  199. command_map = {
  200. "new": new_template,
  201. "delete": delete_template,
  202. "send": send_templated_email,
  203. "bulk": send_bulk_templated_email,
  204. "raw": send_raw_email,
  205. "generate": send_generated_raw_email,
  206. }
  207.  
  208. parser = argparse.ArgumentParser()
  209. parser.add_argument("command", choices=[k for k in command_map.keys()])
  210.  
  211. if __name__ == '__main__':
  212. kwargs = vars(parser.parse_args())
  213.  
  214. command_fxn = command_map.get(kwargs["command"])
  215. if not command_fxn:
  216. print(f"Command {kwargs['command']!r} not recognized")
  217.  
  218. command_fxn()
Add Comment
Please, Sign In to add comment