mirror of
https://github.com/pacnpal/django-anymail.git
synced 2025-12-20 03:41:05 -05:00
Document webhook support
This commit is contained in:
@@ -9,3 +9,4 @@ Théo Crevon
|
|||||||
Rafael E. Belliard
|
Rafael E. Belliard
|
||||||
Jared Morse
|
Jared Morse
|
||||||
peillis
|
peillis
|
||||||
|
José Padilla
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ package. It includes:
|
|||||||
* Support for HTML, attachments, extra headers, and other features of
|
* Support for HTML, attachments, extra headers, and other features of
|
||||||
`Django's built-in email <https://docs.djangoproject.com/en/dev/topics/email/>`_
|
`Django's built-in email <https://docs.djangoproject.com/en/dev/topics/email/>`_
|
||||||
* Mandrill-specific extensions like tags, metadata, tracking, and MailChimp templates
|
* Mandrill-specific extensions like tags, metadata, tracking, and MailChimp templates
|
||||||
|
* Optional support for Mandrill inbound email and other webhook notifications,
|
||||||
|
via Django signals
|
||||||
* An optional Django admin interface
|
* An optional Django admin interface
|
||||||
|
|
||||||
Djrill is released under the BSD license. It is tested against Django 1.3, 1.4, and 1.5
|
Djrill is released under the BSD license. It is tested against Django 1.3, 1.4, and 1.5
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ Release Notes
|
|||||||
|
|
||||||
Version 0.5 (development):
|
Version 0.5 (development):
|
||||||
|
|
||||||
|
* Support for incoming mail and other Mandrill webhooks
|
||||||
* Support for Mandrill send options :attr:`auto_html`, :attr:`tracking_domain`
|
* Support for Mandrill send options :attr:`auto_html`, :attr:`tracking_domain`
|
||||||
and :attr:`signing_domain`.
|
and :attr:`signing_domain`.
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ Documentation
|
|||||||
usage/sending_mail
|
usage/sending_mail
|
||||||
usage/templates
|
usage/templates
|
||||||
usage/multiple_backends
|
usage/multiple_backends
|
||||||
|
usage/webhooks
|
||||||
contributing
|
contributing
|
||||||
history
|
history
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,13 @@ In your project's :file:`settings.py`:
|
|||||||
EMAIL_BACKEND = "djrill.mail.backends.djrill.DjrillBackend"
|
EMAIL_BACKEND = "djrill.mail.backends.djrill.DjrillBackend"
|
||||||
|
|
||||||
|
|
||||||
|
Mandrill Webhooks (Optional)
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Djrill includes optional support for Mandrill webhooks, including inbound email.
|
||||||
|
See the Djrill :ref:`webhooks <webhooks>` section for configuration details.
|
||||||
|
|
||||||
|
|
||||||
Admin (Optional)
|
Admin (Optional)
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
|||||||
152
docs/usage/webhooks.rst
Normal file
152
docs/usage/webhooks.rst
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
.. _webhooks:
|
||||||
|
|
||||||
|
Mandrill Webhooks and Inbound Email
|
||||||
|
===================================
|
||||||
|
|
||||||
|
`Mandrill webhooks`_ are used for notification about outbound messages
|
||||||
|
(bounces, clicks, etc.), and also for delivering inbound email
|
||||||
|
processed through Mandrill.
|
||||||
|
|
||||||
|
Djrill includes optional support for Mandrill's webhook notifications.
|
||||||
|
If enabled, it will send a Django signal for each event in a webhook.
|
||||||
|
Your code can connect to this signal for further processing.
|
||||||
|
|
||||||
|
.. versionadded:: 0.5
|
||||||
|
Webhook support
|
||||||
|
|
||||||
|
|
||||||
|
.. warning:: Webhook Security
|
||||||
|
|
||||||
|
Webhooks are ordinary urls---they're wide open to the internet.
|
||||||
|
You must take steps to secure webhooks, or anyone could submit
|
||||||
|
random (or malicious) data to your app simply by invoking your
|
||||||
|
webhook URL. For security:
|
||||||
|
|
||||||
|
* Your webhook should only be accessible over SSL (https).
|
||||||
|
(This is beyond the scope of Djrill.)
|
||||||
|
|
||||||
|
* Your webhook must include a random, secret key, known only to your
|
||||||
|
app and Mandrill. Djrill will verify calls to your webhook, and will
|
||||||
|
reject calls without the correct key.
|
||||||
|
|
||||||
|
|
||||||
|
.. _Mandrill webhooks: http://help.mandrill.com/entries/21738186-Introduction-to-Webhooks
|
||||||
|
.. _securing webhooks: http://apidocs.mailchimp.com/webhooks/#securing-webhooks
|
||||||
|
|
||||||
|
|
||||||
|
.. _webhooks-config:
|
||||||
|
|
||||||
|
Configuration
|
||||||
|
-------------
|
||||||
|
|
||||||
|
To enable Djrill webhook processing you need to create and set a webhook
|
||||||
|
secret in your project settings, include the Djrill url routing, and
|
||||||
|
then add the webhook in the Mandrill control panel.
|
||||||
|
|
||||||
|
1. In your project's :file:`settings.py`, add a :setting:`DJRILL_WEBHOOK_SECRET`:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
DJRILL_WEBHOOK_SECRET = "<create your own random secret>"
|
||||||
|
|
||||||
|
substituting a secret you've generated just for Mandrill webhooks.
|
||||||
|
(Do *not* use your Mandrill API key or Django SECRET_KEY for this!)
|
||||||
|
|
||||||
|
An easy way to generate a random secret is to run the command below in a shell:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ python -c "from django.utils import crypto; print crypto.get_random_string(16)"
|
||||||
|
|
||||||
|
|
||||||
|
2. In your base :file:`urls.py`, add routing for the Djrill urls:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
urlpatterns = patterns('',
|
||||||
|
...
|
||||||
|
url(r'^djrill/', include(djrill.urls)),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
3. Now you need to tell Mandrill about your webhook:
|
||||||
|
|
||||||
|
* For receiving events on sent messages (e.g., bounces or clickthroughs),
|
||||||
|
you'll do this in Mandrill's `webhooks control panel`_.
|
||||||
|
* For setting up inbound email through Mandrill, you'll add your webhook
|
||||||
|
to Mandrill's `inbound settings`_ under "Routes" for your domain.
|
||||||
|
* And if you want both, you'll need to add the webhook in both places.
|
||||||
|
|
||||||
|
In all cases, the "Post to URL" is
|
||||||
|
:samp:`{https://yoursite.example.com}/djrill/webhook/?secret={your-secret}`
|
||||||
|
substituting your app's own domain, and changing *your-secret* to the secret
|
||||||
|
you created in step 1.
|
||||||
|
|
||||||
|
(For sent-message webhooks, don't forget to tick the "Trigger on Events"
|
||||||
|
checkboxes for the events you want to receive.)
|
||||||
|
|
||||||
|
|
||||||
|
Once you've completed these steps and your Django app is live on your site,
|
||||||
|
you can use the Mandrill "Test" commands to verify your webhook configuration.
|
||||||
|
Then see the next section for setting up Django signal handlers to process
|
||||||
|
the webhooks.
|
||||||
|
|
||||||
|
Incidentally, you have some control over the webhook url.
|
||||||
|
If you'd like to change the "djrill" prefix, that comes from
|
||||||
|
the url config in step 2. And if you'd like to change
|
||||||
|
the *name* of the "secret" query string parameter, you can set
|
||||||
|
:setting:`DJRILL_WEBHOOK_SECRET_NAME` in your :file:`settings.py`.
|
||||||
|
|
||||||
|
|
||||||
|
.. _webhooks control panel: https://mandrillapp.com/settings/webhooks
|
||||||
|
.. _inbound settings: https://mandrillapp.com/inbound
|
||||||
|
|
||||||
|
|
||||||
|
.. _webhook-usage:
|
||||||
|
|
||||||
|
Webhook Notifications
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Once you've enabled webhooks, Djrill will send a ``djrill.signals.webhook_event``
|
||||||
|
custom `Django signal`_ for each Mandrill event it receives.
|
||||||
|
You can connect to this signal for further processing.
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from djrill.signals import webhook_event
|
||||||
|
from django.dispatch import receiver
|
||||||
|
|
||||||
|
@receiver(webhook_event)
|
||||||
|
def handle_bounce(sender, event_type, data, **kwargs):
|
||||||
|
if event_type == 'hard_bounce' or event_type == 'soft_bounce':
|
||||||
|
print "Message to %s bounced: %s" % (
|
||||||
|
data['msg']['email'],
|
||||||
|
data['msg']['bounce_description']
|
||||||
|
)
|
||||||
|
|
||||||
|
@receiver(webhook_event)
|
||||||
|
def handle_inbound(sender, event_type, data, **kwargs):
|
||||||
|
if event_type == 'inbound':
|
||||||
|
print "Inbound message from %s: %s" % (
|
||||||
|
data['msg']['from_email'],
|
||||||
|
data['msg']['subject']
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
Note that your webhook_event signal handlers will be called for all Mandrill
|
||||||
|
webhook callbacks, so you should always check the `event_type` param as shown
|
||||||
|
in the examples above to ensure you're processing the expected events.
|
||||||
|
|
||||||
|
Mandrill batches up multiple events into a single webhook call.
|
||||||
|
Djrill will invoke your signal handler once for each event in the batch.
|
||||||
|
|
||||||
|
The available fields in the `data` param are described in Mandrill's documentation:
|
||||||
|
`sent-message webhooks`_ and `inbound webhooks`_.
|
||||||
|
|
||||||
|
.. _Django signal: https://docs.djangoproject.com/en/dev/topics/signals/
|
||||||
|
.. _inbound webhooks:
|
||||||
|
http://help.mandrill.com/entries/22092308-What-is-the-format-of-inbound-email-webhooks-
|
||||||
|
.. _sent-message webhooks: http://help.mandrill.com/entries/21738186-Introduction-to-Webhooks
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user