Sending Django Emails via AWS SES

Boto is the de facto standard for working with the AWS API from Python. Unfortunately their SES implementation only sends text or html emails, not both. You need to drop down to their send_raw_email method to send a multi-part email.

Using this Gist as a guideline, here’s an implementation of sending a multi-part email via a library class:

amazonses.py

from email.utils import COMMASPACE
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from boto.ses import SESConnection
from django.conf import settings
class SESMessage(object):
def __init__(self, source, to_addresses, subject, **kw):
self.ses = SESConnection(settings.AWS_ACCESS_KEY, settings.AWS_SECRET_KEY)
self._source = source
self._to_addresses = to_addresses
self._cc_addresses = None
self._bcc_addresses = None
self.subject = subject
self.text = None
self.html = None
self.attachments = []
def send(self):
if not self.ses:
raise Exception, 'No connection found'
if (self.text and not self.html and not self.attachments) or\
(self.html and not self.text and not self.attachments):
return self.ses.send_email(self._source, self.subject,
self.text or self.html,
self._to_addresses, self._cc_addresses,
self._bcc_addresses,
format='text' if self.text else 'html')
else:
if not self.attachments:
message = MIMEMultipart('alternative')
message['Subject'] = self.subject
message['From'] = self._source
if isinstance(self._to_addresses, (list, tuple)):
message['To'] = COMMASPACE.join(self._to_addresses)
else:
message['To'] = self._to_addresses
message.attach(MIMEText(self.text, 'plain'))
message.attach(MIMEText(self.html, 'html'))
else:
raise NotImplementedError, 'Attachments are not currently supported.'
return self.ses.send_raw_email(message.as_string(), source=self._source,
destinations=self._to_addresses)

view raw
amazonses.py
hosted with ❤ by GitHub

You’ll also need to add your AWS access key and secret to your settings file:

settings.py

# Amazon AWS
AWS_ACCESS_KEY = 'AKIA……..'
AWS_SECRET_KEY = 'w71v……..'

view raw
settings.py
hosted with ❤ by GitHub

You can then use the class like this:

from app.lib.amazonses import SESMessage
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
# grab the form data
name = form.cleaned_data['name']
email = form.cleaned_data['email']
subject = form.cleaned_data['subject']
body = form.cleaned_data['body']
recipient = 'recipient@site.com'
# render the template with the submitted data
rendered = render_to_string('email/contact.html', {'name': name, 'email': email, 'subject': subject, 'body': body})
# create the message and send the email
# the from address must be a verified sender in SES
msg = SESMessage('valid_sending_address@site.com', recipient, subject)
msg.text = rendered
msg.html = rendered + ' html'
msg.send()
messages.add_message(request, messages.INFO, 'Your contact enquiry was successfully sent. Thank you!')
return HttpResponseRedirect(reverse('contact'))
else:
form = ContactForm()
return render(request, 'contact.html', {'form': form})

view raw
lib.py
hosted with ❤ by GitHub

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s