Skip to content

Commit

Permalink
SendGrid: report dropped "Bounced Address" webhook events as reason "…
Browse files Browse the repository at this point in the history
…bounced"

In SendGrid tracking webhook, handle event="dropped", reason="Bounced Address" 
events as type "dropped", reject_reason "bounced" (rather than reject_reason "other").

See https://www.twilio.com/docs/sendgrid/for-developers/tracking-events/event#dropped
  • Loading branch information
vitaliyf authored Jun 20, 2024
1 parent 0f2eef7 commit 6e696b8
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 0 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ Features
and ``tags`` when sending with a ``template_id``.
(Requires boto3 v1.34.98 or later.)

Fixes
~~~~~

* **SendGrid:** In the tracking webhook, correctly report "bounced address"
(recipients dropped due to earlier bounces) as reject reason ``"bounced"``.
(Thanks to `@vitaliyf`_.)


v10.3
-----
Expand Down Expand Up @@ -1672,4 +1679,5 @@ Features
.. _@Tobeyforce: https://github.com/Tobeyforce
.. _@varche1: https://github.com/varche1
.. _@vgrebenschikov: https://github.com/vgrebenschikov
.. _@vitaliyf: https://github.com/vitaliyf
.. _@yourcelf: https://github.com/yourcelf
1 change: 1 addition & 0 deletions anymail/webhooks/sendgrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def parse_events(self, request):
"invalid": RejectReason.INVALID,
"unsubscribed address": RejectReason.UNSUBSCRIBED,
"bounce": RejectReason.BOUNCED,
"bounced address": RejectReason.BOUNCED,
"blocked": RejectReason.BLOCKED,
"expired": RejectReason.TIMED_OUT,
}
Expand Down
34 changes: 34 additions & 0 deletions tests/test_sendgrid_webhooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,40 @@ def test_dropped_invalid_event(self):
self.assertEqual(event.reject_reason, "invalid")
self.assertEqual(event.mta_response, None)

def test_dropped_bounced(self):
# https://www.twilio.com/docs/sendgrid/for-developers/tracking-events/event#dropped
raw_events = [
{
"email": "example@example.com",
"timestamp": 1513299569,
"smtp-id": "<14c5d75ce93.dfd.64b469@ismtpd-555>",
"event": "dropped",
"category": "cat facts",
"sg_event_id": "zmzJhfJgAfUSOW80yEbPyw==",
"sg_message_id": "14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0",
"reason": "Bounced Address",
"status": "5.0.0",
}
]
response = self.client.post(
"/anymail/sendgrid/tracking/",
content_type="application/json",
data=json.dumps(raw_events),
)
self.assertEqual(response.status_code, 200)
kwargs = self.assert_handler_called_once_with(
self.tracking_handler,
sender=SendGridTrackingWebhookView,
event=ANY,
esp_name="SendGrid",
)
event = kwargs["event"]
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "rejected")
self.assertEqual(event.esp_event, raw_events[0])
self.assertEqual(event.recipient, "example@example.com")
self.assertEqual(event.reject_reason, "bounced")

def test_dropped_unsubscribed_event(self):
raw_events = [
{
Expand Down

0 comments on commit 6e696b8

Please sign in to comment.