Building an automated email system with django and aws
Oct. 8, 2014•0 likes•3,761 views
Download to read offline
Report
Software
This presentation details how to build an automated email system using Amazon Web Services (AWS), Python/Django and CRON. This was originally presented at the Django-NYC meetup on February 26, 2013.
Building an automated email system with django and aws
1. Building an Automated Email System
with Django and AWS
Brett DiDonato
email: brett at brettdidonato dot com
twitter: @brettdidonato
2. Agenda
1. Configure AWS Simple Email Services (SES)
2. Configure AWS Elastic Cloud Compute (EC2)
3. Creating an Email System
a. Sending Emails With Python & Django
b. Tracking Opens & Unsubscribes
c. Open Email In Browser
d. Scheduling With Cron
e. Formatting Emails – Best Practices
f. Personalizing The Experience
4. Case Study: Email Reminder System
3. Configure AWS SES
1. Test Settings – Verify Individual Email Addresses
2. Production Settings – Verify Domain
3. DNS – AWS Route 53
4. Configure AWS EC2
1. Launch an instance
2. Configure Apache, Python, Python Libraries, Django, MongoDB
3. Start Apache & MongoDB
4. Install Python library boto – used for SES and other AWS functions
6. Configure SES With Django
1. Install django-ses
2. Add key, secret and SES reference to settings.py:
aws_access_key_id = your-key-here
aws_secret_access_key = your-secret-here
EMAIL_BACKEND = ‘django_ses.SESBackend’
3. Sending Emails:
from django.core.mail import send_mail
send_mail(
‘Subject’,
‘Body’,
‘from@domain.com’,
[listOfToEmails],
fail_silently=False
)
7. Track Opens
1. Embed image in email body with URL pointing towards Django server address:
<img src=“mywebsite.com/email_img/campaign/identifier” />
2. urls.py: (r'^email_img/(?P<campaign>.*)/(?P<identifier>.*)$', email_img),
3. Log read event and serve image:
from PIL import Image
from datetime import datetime
from pymongo import Connection
connection = Connection()
def email_img(response, campaign, identifier):
myDict = {}
myDict['campaign'] = campaign
myDict['identifier'] = identifier
myDict['read_timestamp'] = datetime.now()
connection.dbName.trackEmails.insert(myDict)
image = Image.open(“/directory/for/my-image.gif")
transparent = image.info["transparency"]
response = HttpResponse(mimetype="image/gif")
image.save(response, "gif", transparency=transparent)
return response
8. Track Unsubscribes
1. Embed link in email body with URL pointing towards Django server address:
<a href=http://mywebsite.com/unsubscribe/userid>Unsubscribe</a>
2. urls.py: (r'^unsubscribe/(?P<campaign>.*)/(?P<userid>.*)$', email_tracking_file),
3. Log unsubscribe event and return confirmation response (probably want to actually confirm it):
from pymongo import Connection
connection = Connection()
def unsubscribe(response, userid):
connection.dbName.userCollection.update({"userid":userid},{"$set":{"unsubscribed":True}})
return HttpResponse("unsubscribed")
9. Open Email in Browser
1. In the email body include a link to view the email in the browser:
<a href=“http://mywebsite.com/campaign/userid”>View This Email In Your
Browser</a>
2. Urls.py: (r'^email_in_browser/(?P<campaign>.*)/(?P<userid>.*)$', email_tracking_file),
3. Log unsubscribe event and return confirmation response (probably want to actually confirm it):
def email_in_browser(response, campaign, userid):
…
return HttpResponse(emailBody)
10. Scheduling with Cron
1. Open cron table:
crontab –e
2. Run job daily at midnight…
0 0 * * * python /directory/for/email_script.py
Log file:
/var/log/cron
Note: consider using a CRON alternative like Celery for more advanced
use cases
11. Formatting Emails – Best Practices
1. No JavaScript
2. GIF or JPG Images
3. HTML Tables
4. Inline CSS
5. Max width ~600px
6. Avoid “spammy” words (in subject especially)
7. Test with major email providers: Gmail, Yahoo!, Outlook,
Hotmail/Outlook.com, AOL
12. Personalizing the Experience
1. Build something that adds value
2. Give the user control
3. Personalized subject & body:
1. Name
2. Age
3. Sex
4. Browsing history
5. Shopping history
6. Location – pygeoip
import pygeoip
ip = response.META['REMOTE_ADDR']
gi = pygeoip.GeoIP('/usr/local/share/GeoIP/GeoIP.dat',
pygeoip.MEMORY_CACHE)
country = gi.country_code_by_name(ip)
13. Case Study: Email Reminder System
1. Users log in to website and configure important life events
2. Event details stored in MongoDB
3. Cron job scheduled once per day against reminder events for current day
4. Database logging and events updated
5. Emails sent with personalized email subject and body
6. Track opens and provide “view in browser” link
7. Try it out at giftivo.com, log in, click red “reminders” button, configure
reminders, click “Get A Gift Now” to view email in browser
14. Building an Automated Email System
with Django and AWS
Thanks!
Brett DiDonato
email: brett at brettdidonato dot com
twitter: @brettdidonato