Mailjet: Upgrade to Send API v3.1 [breaking]

Switch from Mailjet's older v3.0 Send API to the newer v3.1 version.

This is a breaking change for code using the Mailjet backend and:
* Using `esp_extra`, which must be updated to the new API format
* Using multiple `reply_to` addresses, which the v3.1 API doesn't allow

Closes #81
This commit is contained in:
Mike Edmunds
2020-09-08 14:50:26 -07:00
committed by GitHub
parent cca653fcba
commit bc1156149a
5 changed files with 397 additions and 483 deletions

View File

@@ -3,23 +3,19 @@
Mailjet
=======
Anymail integrates with the `Mailjet`_ email service, using their transactional `Send API`_ (v3).
Anymail integrates with the `Mailjet`_ email service, using their transactional `Send API v3.1`_.
.. _mailjet-v31-api:
.. versionchanged:: 8.0
.. note::
Mailjet has released a newer `v3.1 Send API`_, but due to mismatches between its
documentation and actual behavior, Anymail has been unable to switch to it.
Anymail's maintainers have reported the problems to Mailjet, and if and when they
are resolved, Anymail will switch to the v3.1 API. This change should be largely
transparent to your code, unless you are using Anymail's
:ref:`esp_extra <mailjet-esp-extra>` feature to set API-specific options.
Earlier Anymail versions used Mailjet's older `Send API v3`_. The change to v3.1 fixes
some limitations of the earlier API, and should only affect your code if you use Anymail's
:ref:`esp_extra <mailjet-esp-extra>` feature to set API-specific options or if you are
trying to send messages with :ref:`multiple reply-to addresses <mailjet-quirks>`.
.. _Mailjet: https://www.mailjet.com/
.. _Send API: https://dev.mailjet.com/guides/#choose-sending-method
.. _v3.1 Send API: https://dev.mailjet.com/guides/#send-api-v3-1-beta
.. _Send API v3.1: https://dev.mailjet.com/guides/#send-api-v3-1
.. _Send API v3: https://dev.mailjet.com/guides/#send-api-v3
Settings
@@ -68,9 +64,8 @@ nor ``ANYMAIL_MAILJET_API_KEY`` is set.
The base url for calling the Mailjet API.
The default is ``MAILJET_API_URL = "https://api.mailjet.com/v3"``
(It's unlikely you would need to change this. This setting cannot be used
to opt into a newer API version; the parameters are not backwards compatible.)
The default is ``MAILJET_API_URL = "https://api.mailjet.com/v3.1/"``
(It's unlikely you would need to change this.)
.. _mailjet-esp-extra:
@@ -80,39 +75,50 @@ esp_extra support
To use Mailjet features not directly supported by Anymail, you can
set a message's :attr:`~anymail.message.AnymailMessage.esp_extra` to
a `dict` of Mailjet's `Send API json properties`_.
Your :attr:`esp_extra` dict will be merged into the
parameters Anymail has constructed for the send, with `esp_extra`
having precedence in conflicts.
a `dict` of Mailjet's `Send API body parameters`_.
Your :attr:`esp_extra` dict will be deeply merged into the Mailjet
API payload, with `esp_extra` having precedence in conflicts.
.. note::
Any ``esp_extra`` settings will need to be updated when Anymail changes
to use Mailjet's upcoming v3.1 API. (See :ref:`note above <mailjet-v31-api>`.)
(Note that it's *not* possible to merge into the ``"Messages"`` key;
any value you supply would override ``"Messages"`` completely. Use ``"Globals"``
for options to apply to all messages.)
Example:
.. code-block:: python
message.esp_extra = {
# Mailjet v3.0 Send API options:
"Mj-prio": 3, # Use Mailjet critically-high priority queue
"Mj-CustomID": my_event_tracking_id,
# Most "Messages" options can be included under Globals:
"Globals": {
"Priority": 3, # Use Mailjet critically-high priority queue
"TemplateErrorReporting": {"Email": "dev+mailtemplatebug@example.com"},
},
# A few options must be at the root:
"SandboxMode": True,
"AdvanceErrorHandling": True,
# *Don't* try to set Messages:
# "Messages": [... this would override *all* recipients, not be merged ...]
}
(You can also set `"esp_extra"` in Anymail's
:ref:`global send defaults <send-defaults>` to apply it to all
messages.)
.. _Send API json properties: https://dev.mailjet.com/guides/#send-api-json-properties
(You can also set `"esp_extra"` in Anymail's :ref:`global send defaults <send-defaults>`
to apply it to all messages.)
.. _Send API body parameters:
https://dev.mailjet.com/email/reference/send-emails#v3_1_post_send
.. _mailjet-quirks:
Limitations and quirks
----------------------
**Single reply_to**
Mailjet's API only supports a single Reply-To email address. If your message
has two or more, you'll get an :exc:`~anymail.exceptions.AnymailUnsupportedFeature`
error---or if you've enabled :setting:`ANYMAIL_IGNORE_UNSUPPORTED_FEATURES`,
Anymail will use only the first `reply_to` address.
**Single tag**
Anymail uses Mailjet's `campaign`_ option for tags, and Mailjet allows
only a single campaign per message. If your message has two or more
@@ -131,27 +137,26 @@ Limitations and quirks
Mailjet, but this may result in an API error if you have not received
special approval from Mailjet support to use custom senders.
**Commas in recipient names**
Mailjet's v3 API does not properly handle commas in recipient display-names.
(Tested July, 2017, and confirmed with Mailjet API support.)
**message_id is MessageID (not MessageUUID)**
Mailjet's Send API v3.1 returns both a "legacy" MessageID and a newer
MessageUUID for each successfully sent message. Anymail uses the MessageID
as the :attr:`~anymail.message.AnymailStatus.message_id` when reporting
:ref:`esp-send-status`, because Mailjet's other (statistics, event tracking)
APIs don't yet support MessageUUID.
If your message would be affected, Anymail attempts to work around
the problem by switching to `MIME encoded-word`_ syntax where needed.
Most modern email clients should support this syntax, but if you run
into issues, you might want to strip commas from all
recipient names (in ``to``, ``cc``, *and* ``bcc``) before sending.
(This should be resolved in a future release when
Anymail :ref:`switches <mailjet-v31-api>` to Mailjet's upcoming v3.1 API.)
.. _MIME encoded-word: https://en.wikipedia.org/wiki/MIME#Encoded-Word
**Older limitations**
.. versionchanged:: 6.0
Earlier versions of Anymail were unable to mix ``cc`` or ``bcc`` fields
and :attr:`~anymail.message.AnymailMessage.merge_data` in the same Mailjet message.
This limitation was removed in Anymail 6.0.
Earlier versions of Anymail were unable to mix ``cc`` or ``bcc`` fields
and :attr:`~anymail.message.AnymailMessage.merge_data` in the same Mailjet message.
This limitation was removed in Anymail 6.0.
.. versionchanged:: 8.0
Earlier Anymail versions had special handling to work around a Mailjet v3 API bug
with commas in recipient display names. Anymail 8.0 uses Mailjet's v3.1 API, which
does not have the bug.
.. _mailjet-templates:
@@ -162,6 +167,17 @@ Batch sending/merge and ESP templates
Mailjet offers both :ref:`ESP stored templates <esp-stored-templates>`
and :ref:`batch sending <batch-send>` with per-recipient merge data.
When you send a message with multiple ``to`` addresses, the
:attr:`~anymail.message.AnymailMessage.merge_data` determines how many
distinct messages are sent:
* If :attr:`~anymail.message.AnymailMessage.merge_data` is *not* set (the default),
Anymail will tell Mailjet to send a single message, and all recipients will see
the complete list of To addresses.
* If :attr:`~anymail.message.AnymailMessage.merge_data` *is* set---even to an empty
`{}` dict, Anymail will tell Mailjet to send a separate message for each ``to``
address, and the recipients won't see the other To addresses.
You can use a Mailjet stored transactional template by setting a message's
:attr:`~anymail.message.AnymailMessage.template_id` to the
template's *numeric* template ID. (*Not* the template's name. To get the