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

@@ -100,7 +100,11 @@ class PostmarkPayload(RequestsPayload):
super(PostmarkPayload, self).__init__(message, defaults, backend, headers=headers, *args, **kwargs)
def get_api_endpoint(self):
return "email"
if 'TemplateId' in self.data or 'TemplateModel' in self.data:
# This is the one Postmark API documented to have a trailing slash. (Typo?)
return "email/withTemplate/"
else:
return "email"
def get_request_params(self, api_url):
params = super(PostmarkPayload, self).get_request_params(api_url)
@@ -185,6 +189,14 @@ class PostmarkPayload(RequestsPayload):
def set_track_opens(self, track_opens):
self.data["TrackOpens"] = track_opens
def set_template_id(self, template_id):
self.data["TemplateId"] = template_id
# merge_data: Postmark doesn't support per-recipient substitutions
def set_merge_global_data(self, merge_global_data):
self.data["TemplateModel"] = merge_global_data
def set_esp_extra(self, extra):
self.data.update(extra)
# Special handling for 'server_token':