diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7312320..499178c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -40,6 +40,12 @@ Breaking changes code depended on "temporary failure" showing up as "bounced" you will need to update it. (Thanks `@costela`_.) +Features +~~~~~~~~ + +* **Postmark:** Allow either template alias (string) or numeric template id for + Anymail's `template_id` when sending with Postmark templates. + Fixes ~~~~~ diff --git a/anymail/backends/postmark.py b/anymail/backends/postmark.py index 2ae8e87..f46f6ca 100644 --- a/anymail/backends/postmark.py +++ b/anymail/backends/postmark.py @@ -139,7 +139,7 @@ class PostmarkPayload(RequestsPayload): def get_api_endpoint(self): batch_send = self.merge_data is not None and len(self.to_emails) > 1 - if 'TemplateId' in self.data or 'TemplateModel' in self.data: + if 'TemplateAlias' in self.data or 'TemplateId' in self.data or 'TemplateModel' in self.data: if batch_send: return "email/batchWithTemplates" else: @@ -257,7 +257,11 @@ class PostmarkPayload(RequestsPayload): self.data["TrackOpens"] = track_opens def set_template_id(self, template_id): - self.data["TemplateId"] = template_id + try: + self.data["TemplateId"] = int(template_id) + except ValueError: + self.data["TemplateAlias"] = template_id + # Subject, TextBody, and HtmlBody aren't allowed with TemplateId; # delete Django default subject and body empty strings: for field in ("Subject", "TextBody", "HtmlBody"): diff --git a/docs/esps/postmark.rst b/docs/esps/postmark.rst index 44d459a..c4c2a3b 100644 --- a/docs/esps/postmark.rst +++ b/docs/esps/postmark.rst @@ -137,9 +137,14 @@ and :ref:`batch sending ` with per-recipient merge data. :attr:`~anymail.message.AnymailMessage.merge_global_data` with Postmark.) To use a Postmark template, set the message's -:attr:`~anymail.message.AnymailMessage.template_id` to the numeric Postmark -"TemplateID" (*not* its name or "TemplateAlias"). You can find a template's -numeric id near the top right in Postmark's template editor. +:attr:`~anymail.message.AnymailMessage.template_id` to either the numeric Postmark +"TemplateID" or its string "TemplateAlias" (which is *not* the template's name). +You can find a template's numeric id near the top right in Postmark's template editor, +and set the alias near the top right above the name. + +.. versionchanged:: 5.0 + + Earlier Anymail releases only allowed numeric template IDs. Supply the Postmark "TemplateModel" variables using Anymail's normalized :attr:`~anymail.message.AnymailMessage.merge_data` and @@ -151,7 +156,7 @@ Supply the Postmark "TemplateModel" variables using Anymail's normalized # (subject and body come from the template, so don't include those) to=["alice@example.com", "Bob "] ) - message.template_id = 80801 # Postmark template id + message.template_id = 80801 # Postmark template id or alias message.merge_data = { 'alice@example.com': {'name': "Alice", 'order_no': "12345"}, 'bob@example.com': {'name': "Bob", 'order_no': "54321"}, diff --git a/tests/test_postmark_backend.py b/tests/test_postmark_backend.py index c2fd6dc..87038fa 100644 --- a/tests/test_postmark_backend.py +++ b/tests/test_postmark_backend.py @@ -385,6 +385,17 @@ class PostmarkBackendAnymailFeatureTests(PostmarkBackendMockAPITestCase): self.assertNotIn('HtmlBody', data) self.assertNotIn('TextBody', data) + def test_template_alias(self): + # Anymail template_id can be either Postmark TemplateId or TemplateAlias + message = AnymailMessage( + from_email='from@example.com', to=['to@example.com'], + template_id='welcome-message', + ) + message.send() + self.assert_esp_called('/email/withTemplate/') + data = self.get_api_call_json() + self.assertEqual(data['TemplateAlias'], 'welcome-message') + def test_merge_data(self): self.set_mock_response(raw=json.dumps([{ "ErrorCode": 0,