diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b17ad43..09d322c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -40,6 +40,12 @@ Breaking changes * **SendGrid:** Remove the legacy SendGrid *v2* EmailBackend (Anymail has defaulted to SendGrid's newer v3 API since Anymail v0.8.) +Features +~~~~~~~~ + +* **Postmark:** Add support for Anymail's normalized `metadata` in sending + and webhooks. + Fixes ~~~~~ diff --git a/anymail/backends/postmark.py b/anymail/backends/postmark.py index b12df82..653fd01 100644 --- a/anymail/backends/postmark.py +++ b/anymail/backends/postmark.py @@ -178,8 +178,8 @@ class PostmarkPayload(RequestsPayload): self.make_attachment(attachment) for attachment in attachments ] - # Postmark doesn't support metadata - # def set_metadata(self, metadata): + def set_metadata(self, metadata): + self.data["Metadata"] = metadata # Postmark doesn't support delayed sending # def set_send_at(self, send_at): diff --git a/anymail/webhooks/postmark.py b/anymail/webhooks/postmark.py index f387514..a46782b 100644 --- a/anymail/webhooks/postmark.py +++ b/anymail/webhooks/postmark.py @@ -102,6 +102,7 @@ class PostmarkTrackingWebhookView(PostmarkBaseWebhookView): except KeyError: event_id = None + metadata = esp_event.get('Metadata', {}) try: tags = [esp_event['Tag']] except KeyError: @@ -113,6 +114,7 @@ class PostmarkTrackingWebhookView(PostmarkBaseWebhookView): event_id=event_id, event_type=event_type, message_id=esp_event.get('MessageID', None), + metadata=metadata, mta_response=esp_event.get('Details', None), recipient=recipient, reject_reason=reject_reason, diff --git a/docs/esps/postmark.rst b/docs/esps/postmark.rst index f243788..606ffa2 100644 --- a/docs/esps/postmark.rst +++ b/docs/esps/postmark.rst @@ -100,10 +100,6 @@ see :ref:`unsupported-features`. if you've enabled :setting:`ANYMAIL_IGNORE_UNSUPPORTED_FEATURES`, Anymail will use only the first tag. -**No metadata** - Postmark does not support attaching :attr:`~anymail.message.AnymailMessage.metadata` - to messages. - **No delayed sending** Postmark does not support :attr:`~anymail.message.AnymailMessage.send_at`. diff --git a/tests/test_postmark_backend.py b/tests/test_postmark_backend.py index 55151b4..55210f5 100644 --- a/tests/test_postmark_backend.py +++ b/tests/test_postmark_backend.py @@ -330,8 +330,9 @@ class PostmarkBackendAnymailFeatureTests(PostmarkBackendMockAPITestCase): def test_metadata(self): self.message.metadata = {'user_id': "12345", 'items': 6} - with self.assertRaisesMessage(AnymailUnsupportedFeature, 'metadata'): - self.message.send() + self.message.send() + data = self.get_api_call_json() + self.assertEqual(data['Metadata'], {'user_id': "12345", 'items': 6}) def test_send_at(self): self.message.send_at = 1651820889 # 2022-05-06 07:08:09 UTC @@ -403,6 +404,7 @@ class PostmarkBackendAnymailFeatureTests(PostmarkBackendMockAPITestCase): """ self.message.send() data = self.get_api_call_json() + self.assertNotIn('Metadata', data) self.assertNotIn('Tag', data) self.assertNotIn('TemplateId', data) self.assertNotIn('TemplateModel', data) diff --git a/tests/test_postmark_integration.py b/tests/test_postmark_integration.py index aff182b..79e5908 100644 --- a/tests/test_postmark_integration.py +++ b/tests/test_postmark_integration.py @@ -51,7 +51,8 @@ class PostmarkBackendIntegrationTests(SimpleTestCase, AnymailTestMixin): reply_to=["reply1@example.com", "Reply 2 "], headers={"X-Anymail-Test": "value"}, - # no metadata, send_at, track_clicks support + # no send_at, track_clicks support + metadata={"meta1": "simple string", "meta2": 2}, tags=["tag 1"], # max one tag track_opens=True, track_clicks=True, diff --git a/tests/test_postmark_webhooks.py b/tests/test_postmark_webhooks.py index 500bf7b..d3101f4 100644 --- a/tests/test_postmark_webhooks.py +++ b/tests/test_postmark_webhooks.py @@ -66,6 +66,10 @@ class PostmarkDeliveryTestCase(WebhookTestCase): "MessageID": "883953f4-6105-42a2-a16a-77a8eac79483", "Recipient": "recipient@example.com", "Tag": "welcome-email", + "Metadata": { + "cohort": "2014-08-A", + "userid": "12345", # Postmark metadata is always converted to string + }, "DeliveredAt": "2014-08-01T13:28:10.2735393-04:00", "Details": "Test delivery webhook details" } @@ -83,7 +87,7 @@ class PostmarkDeliveryTestCase(WebhookTestCase): self.assertEqual(event.message_id, "883953f4-6105-42a2-a16a-77a8eac79483") self.assertEqual(event.recipient, "recipient@example.com") self.assertEqual(event.tags, ["welcome-email"]) - self.assertEqual(event.metadata, {}) + self.assertEqual(event.metadata, {"cohort": "2014-08-A", "userid": "12345"}) def test_open_event(self): raw_event = {