django-ses
A Django email backend for Amazon's Simple Email Service (SES)
Rank: #3812Downloads: 1,266,967 (30 days)Stars: 1,074Forks: 242
Description
==========
Django-SES
==========
:Info: A Django email backend for Amazon's Simple Email Service
:Author: Harry Marr (http://github.com/hmarr, http://twitter.com/harrymarr)
:Collaborators: Paul Craciunoiu (http://github.com/pcraciunoiu, http://twitter.com/embrangler)
|pypi| |pypi-downloads| |build| |python| |django|
A bird's eye view
=================
Django-SES is a drop-in mail backend for Django_. Instead of sending emails
through a traditional SMTP mail server, Django-SES routes email through
Amazon Web Services' excellent Simple Email Service (SES_).
Django-SES can also receive emails using `SES Email receiving`_
.. _SES: http://aws.amazon.com/ses/
.. _Django: http://djangoproject.com
.. _SES Email receiving: https://docs.aws.amazon.com/ses/latest/dg/receiving-email.html
Please Contribute!
==================
This project is maintained, but not actively used by the maintainer. Interested
in helping maintain this project? Reach out via GitHub Issues if you're actively
using `django-ses` and would be interested in contributing to it.
Changelog
=========
For details about each release, see the GitHub releases page: https://github.com/django-ses/django-ses/releases or CHANGES.md.
Using Django directly
=====================
Amazon SES allows you to also setup usernames and passwords. If you do configure
things that way, you do not need this package. The Django default email backend
is capable of authenticating with Amazon SES and correctly sending email.
Using django-ses gives you additional features like deliverability reports that
can be hard and/or cumbersome to obtain when using the SMTP interface.
Why SES instead of SMTP?
========================
Configuring, maintaining, and dealing with some complicated edge cases can be
time-consuming. Sending emails with Django-SES might be attractive to you if:
* You don't want to maintain mail servers.
* You are already deployed on EC2 (In-bound traffic to SES is free from EC2
instances).
* You need to send a high volume of email.
* You don't want to have to worry about PTR records, Reverse DNS, email
whitelist/blacklist services.
* You want to improve delivery rate and inbox cosmetics by DKIM signing
your messages using SES's Easy DKIM feature.
* Django-SES is a truly drop-in replacement for the default mail backend.
Your code should require no changes.
Why SES instead of IMAP/POP?
============================
Configuring, maintaining, and dealing with some complicated edge cases can be
time-consuming. Receiving emails with Django-SES might be attractive to you if:
* You don't want to maintain mail servers.
* You want programmatic access to received emails.
* You want to react to received emails as soon as they are received.
Getting going
=============
Assuming you've got Django_ installed, you'll just need to install django-ses::
pip install django-ses
To receive bounces or webhook events install the events "extra"::
pip install django-ses[events]
Add the following to your settings.py::
EMAIL_BACKEND = 'django_ses.SESBackend'
# These are optional if you are using AWS IAM Roles https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html
AWS_ACCESS_KEY_ID = 'YOUR-ACCESS-KEY-ID'
AWS_SECRET_ACCESS_KEY = 'YOUR-SECRET-ACCESS-KEY'
# https://docs.aws.amazon.com/cli/v1/userguide/cli-configure-files.html
AWS_SESSION_PROFILE = 'YOUR-PROFILE-NAME'
# Additionally, if you are not using the default AWS region of us-east-1,
# you need to specify a region, like so:
AWS_SES_REGION_NAME = 'us-west-2'
AWS_SES_REGION_ENDPOINT = 'email.us-west-2.amazonaws.com'
# If you want to use the SESv2 client
USE_SES_V2 = True
# If you want to use SES Global Endpoint (Multi-Region Endpoint) for high availability
AWS_SES_GLOBAL_ENDPOINT_ID = 'abcdef12.g3h' # Your global endpoint ID
USE_SES_V2 = True # Required for global endpoints
Alternatively, instead of `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`, you
can include the following two settings values. This is useful in situations
where you would like to use a separate access key to send emails via SES than
you would to upload files via S3::
AWS_SES_ACCESS_KEY_ID = 'YOUR-ACCESS-KEY-ID'
AWS_SES_SECRET_ACCESS_KEY = 'YOUR-SECRET-ACCESS-KEY'
Now, when you use ``django.core.mail.send_mail``, Simple Email Service will
send the messages by default.
Since SES imposes a rate limit and will reject emails after the limit has been
reached, django-ses will attempt to conform to the rate limit by querying the
API for your current limit and then sending no more than that number of
messages in a two-second period (which is half of the rate limit, just to
be sure to stay clear of the limit). This is controlled by the following setting:
AWS_SES_AUTO_THROTTLE = 0.5 # (default; safety factor applied to rate limit)
To turn off automatic throttling, set this to None.
Check out the ``example`` directory for more information.
Monitoring email status using Amazon Simple Notification Service (Amazon SNS)
=============================================================================
To set this up, install `django-ses` with the `events` extra::
pip install django-ses[events]
Then add a event URL handler in your `urls.py`::
from django.urls import re_path
from django_ses.views import SESEventWebhookView
from django.views.decorators.csrf import csrf_exempt
urlpatterns = [ ...
re_path(r'^ses/event-webhook/$', SESEventWebhookView.as_view(), name='handle-event-webhook'),
...
]
SESEventWebhookView handles bounce, complaint, send, delivery, open and click events.
It is also capable of auto confirming subscriptions, it handles `SubscriptionConfirmation` notification.
On AWS
-------
1. Add an SNS topic.
2. In SES setup an SNS destination in "Configuration Sets". Use this
configuration set by setting ``AWS_SES_CONFIGURATION_SET``. Set the topic
to what you created in 1.
3. Add an https subscriber to the topic. (e.g., https://www.yourdomain.com/ses/event-webhook/)
Do not check "Enable raw message delivery".
Bounces
-------
Using signal 'bounce_received' for manager bounce email. For example::
from django_ses.signals import bounce_received
from django.dispatch import receiver
@receiver(bounce_received)
def bounce_handler(sender, mail_obj, bounce_obj, raw_message, *args, **kwargs):
# you can then use the message ID and/or recipient_list(email address) to identify any problematic email messages that you have sent
message_id = mail_obj['messageId']
recipient_list = mail_obj['destination']
...
print("This is bounce email object")
print(mail_obj)
The most common use case for irrecoverable bounces (status ``5xx``) is to add the
email(s) that caused the bounce to a blacklist in order to avoid sending more
emails and triggering more bounces. ``django-ses`` provides a built-in blacklist
that does this. Check ``AWS_SES_ADD_BOUNCE_TO_BLACKLIST`` and ``AWS_SES_USE_BLACKLIST``.
Complaint
---------
Using signal 'complaint_received' for manager complaint email. For example::
from django_ses.signals import complaint_received
from django.dispatch import receiver
@receiver(complaint_received)
def complaint_handler(sender, mail_obj, complaint_obj, raw_message, *args, **kwargs):
...
The most common use case for complaints is to add the email(s) that caused the
complaint to a blacklist in order to avoid sending more emails and triggering
more complaints. ``django-ses`` provides a built-in blacklist that does this.
Check ``AWS_SES_ADD_COMPLAINT_TO_BLACKLIST`` and ``AWS_SES_USE_BLACKLIST``.
Message sent
------------
Use this event to know when an email was sent. Keep in mind that the
``extra_headers`` field of the message will contain the ``message_id`` that AWS
SES assigned to the email, which means you could use this event to store emails
and cross-reference them later if/when you receive a bounce/complaint. For
example::
from django_ses.signals import message_sent
from django.dispatch import receiver
@receiver(message_sent)
def sent_handler(sender, message, *args, **kwargs):
...
Send
----
Using signal 'send_received' for manager send email. For example::
from django_ses.signals import send_received
from django.dispatch import receiver
@receiver(send_received)
def send_handler(sender, mail_obj, raw_message, *args, **kwargs):
...
Delivery
--------
Using signal 'delivery_received' for manager delivery email. For example::
from django_ses.signals import delivery_received
from django.dispatch import receiver
@receiver(delivery_received)
def delivery_handler(sender, mail_obj, delivery_obj, raw_message, *args, **kwargs):
...
Open
----
Using signal 'open_received' for manager open email. For example::
from django_ses.signals import open_received
from django.dispatch import receiver
@receiver(open_received)
def open_handler(sender, mail_obj, open_obj, raw_message, *args, **kwargs):
...
Click
-----
Using signal 'click_received' for manager send email. For example::
from django_ses.signals import click_received
from django.dispatch import receiver
@receiver(click_received)
def click_handler(sender, mail_obj, click_obj, raw_message, *args, **kwargs):
...
Testing Signals
===============
If you would like to test your signals, you can optionally disable `AWS_SES_VERIFY_EVENT_SIGNATURES` in settings. Examples for the JSON object AWS SNS sends can be found here: https://docs.aws.amazon.com/sns/latest/dg/sns-message-and-json-formats.html#http-subscription-confirmation-json
SES Event Monitoring with Configuration Sets
============================================
You can track your SES email sending at a granular level using `SES Event Publishing`_.
To do this, you set up an SES Configuration Set and