Add ESP templates, batch send and merge

* message.template_id to use ESP stored templates
* message.merge_data and merge_global_data
  to supply per-recipient/global merge variables
  (with or without an ESP stored template)
* When using per-recipient merge_data, tell ESP to use
  batch send: individual message per "to" address.
  (Mailgun does this automatically; SendGrid requires
  using a different "to" field; Mandrill requires
  `preserve_recipients=False`; Postmark doesn't
  support *this type* of batch sending with merge data.)
* Allow message.from_email=None (must be set after
  init) and message.subject=None to suppress those
  fields in API calls (for ESPs that allow "From" and
  "Subject" in their template definitions).

Mailgun:
* Emulate merge_global_data by copying to
  recipient-variables for each recipient.

SendGrid:
* Add delimiters to merge field names via
  esp_extra['merge_field_format'] or
  ANYMAIL_SENDGRID_MERGE_FIELD_FORMAT setting.

Mandrill:
* Remove Djrill versions of these features;
  update migration notes.

Closes #5.
This commit is contained in:
medmunds
2016-05-03 18:25:37 -07:00
parent 271eb5c926
commit 75730e8219
20 changed files with 882 additions and 245 deletions

View File

@@ -329,6 +329,44 @@ class MailgunBackendAnymailFeatureTests(MailgunBackendMockAPITestCase):
self.assertEqual(data['o:tracking-opens'], 'no')
self.assertEqual(data['o:tracking-clicks'], 'yes')
# template_id: Mailgun doesn't support stored templates
def test_merge_data(self):
self.message.to = ['alice@example.com', 'Bob <bob@example.com>']
self.message.body = "Hi %recipient.name%. Welcome to %recipient.group% at %recipient.site%."
self.message.merge_data = {
'alice@example.com': {'name': "Alice", 'group': "Developers"},
'bob@example.com': {'name': "Bob"}, # and leave group undefined
}
self.message.merge_global_data = {
'group': "Users", # default
'site': "ExampleCo",
}
self.message.send()
data = self.get_api_call_data()
self.assertJSONEqual(data['recipient-variables'], {
'alice@example.com': {'name': "Alice", 'group': "Developers", 'site': "ExampleCo"},
'bob@example.com': {'name': "Bob", 'group': "Users", 'site': "ExampleCo"},
})
# Make sure we didn't modify original dicts on message:
self.assertEqual(self.message.merge_data, {
'alice@example.com': {'name': "Alice", 'group': "Developers"},
'bob@example.com': {'name': "Bob"},
})
self.assertEqual(self.message.merge_global_data, {'group': "Users", 'site': "ExampleCo"})
def test_only_merge_global_data(self):
# Make sure merge_global_data distributed to recipient-variables
# even when merge_data not set
self.message.to = ['alice@example.com', 'Bob <bob@example.com>']
self.message.merge_global_data = {'test': "value"}
self.message.send()
data = self.get_api_call_data()
self.assertJSONEqual(data['recipient-variables'], {
'alice@example.com': {'test': "value"},
'bob@example.com': {'test': "value"},
})
def test_sender_domain(self):
"""Mailgun send domain can come from from_email or esp_extra"""
# You could also use ANYMAIL_SEND_DEFAULTS={'esp_extra': {'sender_domain': 'your-domain.com'}}