Add merge_metadata for other ESPs

Support merge_metadata in Mailgun, Mailjet, Mandrill, Postmark, 
SparkPost, and Test backends. (SendGrid covered in earlier PR.)

Also:
* Add `merge_metadata` to AnymailMessage, AnymailMessageMixin
* Add `is_batch()` logic to BasePayload, for consistent handling
* Docs

Note: Mailjet implementation switches *all* batch sending from their 
"Recipients" field to to the "Messages" array bulk sending option.
This allows an independent payload for each batch recipient.
In addition to supporting merge_metadata, this also removes the
prior limitation on mixing Cc/Bcc with merge_data.

Closes #141.
This commit is contained in:
Mike Edmunds
2019-02-23 13:32:28 -08:00
committed by GitHub
parent 85dce5fd6a
commit 75d7671056
22 changed files with 468 additions and 132 deletions

View File

@@ -68,6 +68,11 @@ Limitations and quirks
:attr:`~anymail.message.AnymailMessage.tags` feature. See :ref:`amazon-ses-tags`
below for more information and additional options.
**No merge_metadata**
Amazon SES's batch sending API does not support the custom headers Anymail uses
for metadata, so Anymail's :attr:`~anymail.message.AnymailMessage.merge_metadata`
feature is not available. (See :ref:`amazon-ses-tags` below for more information.)
**Open and click tracking overrides**
Anymail's :attr:`~anymail.message.AnymailMessage.track_opens` and
:attr:`~anymail.message.AnymailMessage.track_clicks` are not supported.
@@ -164,7 +169,8 @@ For more complex use cases, set the SES `Tags` parameter directly in Anymail's
:ref:`esp_extra <amazon-ses-esp-extra>`. See the example below. (Because custom headers do not
work with SES's SendBulkTemplatedEmail call, esp_extra Tags is the only way to attach
data to SES messages also using Anymail's :attr:`~anymail.message.AnymailMessage.template_id`
and :attr:`~anymail.message.AnymailMessage.merge_data` features.)
and :attr:`~anymail.message.AnymailMessage.merge_data` features, and the
:attr:`~anymail.message.AnymailMessage.merge_metadata` cannot be supported.)
.. _Introducing Sending Metrics:

View File

@@ -38,6 +38,7 @@ Email Service Provider |Amazon SES| |Mailgun| |Mailje
---------------------------------------------------------------------------------------------------------------------------------------------------
:attr:`~AnymailMessage.envelope_sender` Yes Domain only Yes Domain only No No No Yes
:attr:`~AnymailMessage.metadata` Yes Yes Yes Yes Yes Yes Yes Yes
:attr:`~AnymailMessage.merge_metadata` No Yes Yes Yes Yes Yes No Yes
:attr:`~AnymailMessage.send_at` No Yes No Yes No Yes No Yes
:attr:`~AnymailMessage.tags` Yes Yes Max 1 tag Yes Max 1 tag Yes Max 1 tag Max 1 tag
:attr:`~AnymailMessage.track_clicks` No Yes Yes Yes Yes Yes No Yes

View File

@@ -179,6 +179,29 @@ Limitations and quirks
obvious reasons, only the domain portion applies. You can use anything before
the @, and it will be ignored.
**Using merge_metadata with merge_data**
If you use both Anymail's :attr:`~anymail.message.AnymailMessage.merge_data`
and :attr:`~anymail.message.AnymailMessage.merge_metadata` features, make sure your
merge_data keys do not start with ``v:``. (It's a good idea anyway to avoid colons
and other special characters in merge_data keys, as this isn't generally portable
to other ESPs.)
The same underlying Mailgun feature ("recipient-variables") is used to implement
both Anymail features. To avoid conflicts, Anymail prepends ``v:`` to recipient
variables needed for merge_metadata. (This prefix is stripped as Mailgun prepares
the message to send, so it won't be present in your Mailgun API logs or the metadata
that is sent to tracking webhooks.)
**merge_metadata values default to empty string**
If you use Anymail's :attr:`~anymail.message.AnymailMessage.merge_metadata` feature,
and you supply metadata keys for some recipients but not others, Anymail will first
try to resolve the missing keys in :attr:`~anymail.message.AnymailMessage.metadata`,
and if they are not found there will default them to an empty string value.
Your tracking webhooks will receive metadata values (either that you provided or the
default empty string) for *every* key used with *any* recipient in the send.
.. _undocumented API requirement:
https://mailgun.uservoice.com/forums/156243-feature-requests/suggestions/35668606

View File

@@ -11,9 +11,11 @@ Anymail integrates with the `Mailjet`_ email service, using their transactional
.. note::
Mailjet is developing an improved `v3.1 Send API`_ (in public beta as of mid-2017).
Once the v3.1 API is released, Anymail will switch to it. This change should be
largely transparent to your code, unless you are using Anymail's
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.
@@ -132,26 +134,26 @@ Limitations and quirks
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
*if* your message also uses the ``cc`` or ``bcc`` fields.
Mailjet's v3 API does not properly handle commas in recipient display-names.
(Tested July, 2017, and confirmed with Mailjet API support.)
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 either avoid using ``cc`` and ``bcc``, or strip commas from all
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
**Merge data not compatible with cc/bcc**
Mailjet's v3 API is not capable of representing both ``cc`` or ``bcc`` fields
and :attr:`~anymail.message.AnymailMessage.merge_data` in the same message.
If you attempt to combine them, Anymail will raise an error at send time.
.. versionchanged:: 6.0
(The latter two limitations should be resolved in a future release when
Anymail :ref:`switches <mailjet-v31-api>` to Mailjet's upcoming v3.1 API.)
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.
.. _mailjet-templates:

View File

@@ -178,7 +178,8 @@ SendinBlue supports :ref:`ESP stored templates <esp-stored-templates>`
populated with global merge data for all recipients, but does not
offer :ref:`batch sending <batch-send>` with per-recipient merge data.
Anymail's :attr:`~anymail.message.AnymailMessage.merge_data`
message attribute is not supported with the SendinBlue backend.
and :attr:`~anymail.message.AnymailMessage.merge_metadata`
message attributes are not supported with the SendinBlue backend.
To use a SendinBlue template, set the message's
:attr:`~anymail.message.AnymailMessage.template_id` to the numeric

View File

@@ -115,6 +115,31 @@ ESP send options (AnymailMessage)
as metadata. See :ref:`formatting-merge-data`.
.. attribute:: merge_metadata
Set this to a `dict` of *per-recipient* metadata values the ESP should store
with the message, for later search and retrieval. Each key in the dict is a
recipient email (address portion only), and its value is a dict of metadata
for that recipient:
.. code-block:: python
message.to = ["wile@example.com", "Mr. Runner <rr@example.com>"]
message.merge_metadata = {
"wile@example.com": {"customer": 123, "order": "acme-zxyw"},
"rr@example.com": {"customer": 45678, "order": "acme-wblt"},
}
When :attr:`!merge_metadata` is set, Anymail will use the ESP's
:ref:`batch sending <batch-send>` option, so that each `to` recipient gets an
individual message (and doesn't see the other emails on the `to` list).
All of the notes on :attr:`metadata` keys and value formatting also apply
to :attr:`!merge_metadata`. If there are conflicting keys, the
:attr:`!merge_metadata` values will take precedence over :attr:`!metadata`
for that recipient.
.. attribute:: tags
Set this to a `list` of `str` tags to apply to the message (usually
@@ -131,7 +156,8 @@ ESP send options (AnymailMessage)
.. caution::
Some ESPs put :attr:`metadata` and :attr:`tags` in email headers,
Some ESPs put :attr:`metadata` (and a recipient's :attr:`merge_metadata`)
and :attr:`tags` in email headers,
which are included with the email when it is delivered. Anything you
put in them **could be exposed to the recipients,** so don't
include sensitive data.

View File

@@ -125,7 +125,8 @@ To use batch sending with Anymail (for ESPs that support it):
.. caution::
It's critical to set the :attr:`~AnymailMessage.merge_data` attribute:
It's critical to set the :attr:`~AnymailMessage.merge_data`
(or :attr:`~AnymailMessage.merge_metadata`) attribute:
this is how Anymail recognizes the message as a batch send.
When you provide merge_data, Anymail will tell the ESP to send an individual customized