Skip to content

Commit 2a36da5

Browse files
authored
Postmark: Fix sending templated email to a single recipient
Fix a bug where sending an email with a template_id and a single to address would cause a Postmark API error. Thanks @jc-ee for finding and fixing.
1 parent 920d8dd commit 2a36da5

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ vNext
3333
Fixes
3434
~~~~~
3535

36+
* **Postmark:** Fix API error when sending with template to single recipient.
37+
(Thanks to `@jc-ee`_ for finding and fixing the issue.)
3638
* **SendGrid:** Allow non-batch template send to multiple recipients when
3739
`merge_global_data` is set without `merge_data`. (Broken in v6.0. Thanks to
3840
`@vgrebenschikov`_ for the bug report.)
@@ -1026,6 +1028,7 @@ Features
10261028
.. _@ewingrj: https://github.com/ewingrj
10271029
.. _@fdemmer: https://github.com/fdemmer
10281030
.. _@janneThoft: https://github.com/janneThoft
1031+
.. _@jc-ee: https://github.com/jc-ee
10291032
.. _@joshkersey: https://github.com/joshkersey
10301033
.. _@Lekensteyn: https://github.com/Lekensteyn
10311034
.. _@lewistaylor: https://github.com/lewistaylor

anymail/backends/postmark.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,19 @@ def get_request_params(self, api_url):
179179
return params
180180

181181
def serialize_data(self):
182-
data = self.data
183182
api_endpoint = self.get_api_endpoint()
184-
if api_endpoint == "email/batchWithTemplates":
183+
if api_endpoint == "email":
184+
data = self.data
185+
elif api_endpoint == "email/batchWithTemplates":
185186
data = {"Messages": [self.data_for_recipient(to) for to in self.to_emails]}
186187
elif api_endpoint == "email/batch":
187188
data = [self.data_for_recipient(to) for to in self.to_emails]
189+
elif api_endpoint == "email/withTemplate/":
190+
assert len(self.to_emails) == 1
191+
data = self.data_for_recipient(self.to_emails[0])
192+
else:
193+
raise AssertionError("PostmarkPayload.serialize_data missing"
194+
" case for api_endpoint %r" % api_endpoint)
188195
return self.serialize_json(data)
189196

190197
def data_for_recipient(self, to):

tests/test_postmark_backend.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,34 @@ def test_merge_data(self):
450450
self.assertEqual(recipients['[email protected]'].status, 'sent')
451451
self.assertEqual(recipients['[email protected]'].message_id, 'e2ecbbfc-fe12-463d-b933-9fe22915106d')
452452

453+
def test_merge_data_single_recipient(self):
454+
self.set_mock_response(raw=self._mock_batch_response)
455+
message = AnymailMessage(
456+
from_email='[email protected]',
457+
template_id=1234567, # Postmark only supports merge_data content in a template
458+
459+
merge_data={
460+
'[email protected]': {'name': "Alice", 'group': "Developers"},
461+
'[email protected]': {'name': "Not a recipient for this message"},
462+
},
463+
merge_global_data={'group': "Users", 'site': "ExampleCo"}
464+
)
465+
message.send()
466+
467+
self.assert_esp_called('/email/withTemplate/')
468+
data = self.get_api_call_json()
469+
470+
self.assertEqual(data, {
471+
"From": "[email protected]",
472+
473+
"TemplateId": 1234567,
474+
"TemplateModel": {"name": "Alice", "group": "Developers", "site": "ExampleCo"},
475+
})
476+
477+
recipients = message.anymail_status.recipients
478+
self.assertEqual(recipients['[email protected]'].status, 'sent')
479+
self.assertEqual(recipients['[email protected]'].message_id, 'b7bc2f4a-e38e-4336-af7d-e6c392c2f817')
480+
453481
def test_merge_data_no_template(self):
454482
# merge_data={} can be used to force batch sending without a template
455483
self.set_mock_response(raw=self._mock_batch_response)

0 commit comments

Comments
 (0)