Reputation: 11706
The Amazon SES documentation is not clear for me. So if you can help me with an example tot send raw text e-mails including a PDF attachment, this will help me a lot. I use Python 2.5 and Google App engine. I have to use "raw", because that is the only SES option if I include attachments.
My problems at the moment :
Upvotes: 6
Views: 7156
Reputation: 11706
Example code here to send SES raw e-mail using a multipart body (plain / html / attachment) :
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from google.appengine.api import urlfetch
from google.appengine.runtime import DeadlineExceededError
import urllib
import hmac
import base64
import hashlib
from datetime import datetime
import logging
def ses_multi_part(msg_subject, msg_to, msg_body='', msg_cc=None, msg_bcc=None, file_name=None, file_reader=None,
msg_type='plain', msg_from='noreply@....', msg_reply_to='contact@....'):
""" send an html or plain e-mail. Use file_name and file_reader to pass an attachment
inspiration: https://codeadict.wordpress.com/2010/02/11/send-e-mails-with-attachment-in-python/
"""
msg = MIMEMultipart()
msg.set_charset("utf-8")
msg['Subject'] = msg_subject
msg['From'] = msg_from
msg['Reply-to'] = msg_reply_to
msg['To'] = msg_to
if msg_cc:
msg['Cc'] = msg_cc
if msg_bcc:
msg['Bcc'] = msg_bcc
logging.debug(msg)
msg.preamble = 'Multipart massage.\n'
part = MIMEText(msg_body, msg_type, "utf-8")
msg.attach(part)
if file_name:
part = MIMEApplication(file_reader.read())
part.add_header('Content-Disposition', 'attachment', filename=file_name)
msg.attach(part)
return msg.as_string()
class SES(object):
""" SES send RAW e-mail
inspiration: https://github.com/richieforeman/python-amazon-ses-api/blob/master/amazon_ses.py
"""
def __init__(self, accessKeyID, secretAccessKey, return_path='contact@....'):
self._accessKeyID = accessKeyID
self._secretAccessKey = secretAccessKey
self.ses_return_path = return_path
def _getSignature(self, dateValue):
h = hmac.new(key=self._secretAccessKey, msg=dateValue, digestmod=hashlib.sha256)
return base64.b64encode(h.digest()).decode()
def _getHeaders(self):
headers = {'Content-type': 'application/x-www-form-urlencoded', 'Return-Path': self.ses_return_path}
d = datetime.utcnow()
dateValue = d.strftime('%a, %d %b %Y %H:%M:%S GMT')
headers['Date'] = dateValue
signature = self._getSignature(dateValue)
headers['X-Amzn-Authorization'] = 'AWS3-HTTPS AWSAccessKeyId=%s, Algorithm=HMACSHA256, Signature=%s' % (self._accessKeyID, signature)
return headers
def _performAction(self, actionName, params=None):
if not params:
params = {}
params['Action'] = actionName
response = None
#https://email.us-east-1.amazonaws.com/
retry = 0 # download error retry
while retry <= 1: # dan een eenmalige retry
try:
url = 'https://email.us-east-1.amazonaws.com'
response = urlfetch.fetch(url=url, payload=urllib.urlencode(params), method=urlfetch.POST, headers=self._getHeaders())
break
except (urlfetch.DownloadError, DeadlineExceededError), e:
logging.debug('Amazon SES download or deadline error : %d' % (retry + 1))
if retry == 0:
retry += 1
continue # retry
else:
logging.warning('fetcherror' + str(e))
raise # bij een dubbele fout stoppen
if response.status_code != 200:
logging.warning(response.headers)
logging.warning(response.content)
raise ValueError('status_code : %s' % (str(response.status_code)))
logging.debug(response.content)
return response.content
def sendRawEmail(self, raw_msg_data):
return self._performAction("SendRawEmail", params={"RawMessage.Data": base64.b64encode(raw_msg_data)})
Example usage:
ses = SES(settings.AMAZON_ACCESS_KEY_ID, settings.AMAZON_SECRET_ACCESS_KEY, settings.SES_RETURN_PATH[country])
raw_msg_data = ses_multi_part(msg_subject=subject.encode('utf-8'), msg_to=mail_to, msg_body=body_text.encode('utf-8'),
msg_bcc=settings.MAIL_BCC, msg_reply_to=reply_to, msg_from=sender, msg_type=msg_type)
ses.sendRawEmail(raw_msg_data)
Upvotes: 5
Reputation: 2648
Why use raw with their API when you can send attachments and everything via their standard SMTP interface? Besides, last time I checked raw does not support BCC.
SMTP Interface: http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/SMTP.html
List of approved MIME types (otherwise SES gets angry): http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/MIMETypes.html
Upvotes: 0