Skip to content

Commit 6e696b8

Browse files
authored
SendGrid: report dropped "Bounced Address" webhook events as reason "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
1 parent 0f2eef7 commit 6e696b8

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

CHANGELOG.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ Features
5252
and ``tags`` when sending with a ``template_id``.
5353
(Requires boto3 v1.34.98 or later.)
5454

55+
Fixes
56+
~~~~~
57+
58+
* **SendGrid:** In the tracking webhook, correctly report "bounced address"
59+
(recipients dropped due to earlier bounces) as reject reason ``"bounced"``.
60+
(Thanks to `@vitaliyf`_.)
61+
5562

5663
v10.3
5764
-----
@@ -1672,4 +1679,5 @@ Features
16721679
.. _@Tobeyforce: https://github.com/Tobeyforce
16731680
.. _@varche1: https://github.com/varche1
16741681
.. _@vgrebenschikov: https://github.com/vgrebenschikov
1682+
.. _@vitaliyf: https://github.com/vitaliyf
16751683
.. _@yourcelf: https://github.com/yourcelf

anymail/webhooks/sendgrid.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def parse_events(self, request):
4646
"invalid": RejectReason.INVALID,
4747
"unsubscribed address": RejectReason.UNSUBSCRIBED,
4848
"bounce": RejectReason.BOUNCED,
49+
"bounced address": RejectReason.BOUNCED,
4950
"blocked": RejectReason.BLOCKED,
5051
"expired": RejectReason.TIMED_OUT,
5152
}

tests/test_sendgrid_webhooks.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,40 @@ def test_dropped_invalid_event(self):
144144
self.assertEqual(event.reject_reason, "invalid")
145145
self.assertEqual(event.mta_response, None)
146146

147+
def test_dropped_bounced(self):
148+
# https://www.twilio.com/docs/sendgrid/for-developers/tracking-events/event#dropped
149+
raw_events = [
150+
{
151+
"email": "example@example.com",
152+
"timestamp": 1513299569,
153+
"smtp-id": "<14c5d75ce93.dfd.64b469@ismtpd-555>",
154+
"event": "dropped",
155+
"category": "cat facts",
156+
"sg_event_id": "zmzJhfJgAfUSOW80yEbPyw==",
157+
"sg_message_id": "14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0",
158+
"reason": "Bounced Address",
159+
"status": "5.0.0",
160+
}
161+
]
162+
response = self.client.post(
163+
"/anymail/sendgrid/tracking/",
164+
content_type="application/json",
165+
data=json.dumps(raw_events),
166+
)
167+
self.assertEqual(response.status_code, 200)
168+
kwargs = self.assert_handler_called_once_with(
169+
self.tracking_handler,
170+
sender=SendGridTrackingWebhookView,
171+
event=ANY,
172+
esp_name="SendGrid",
173+
)
174+
event = kwargs["event"]
175+
self.assertIsInstance(event, AnymailTrackingEvent)
176+
self.assertEqual(event.event_type, "rejected")
177+
self.assertEqual(event.esp_event, raw_events[0])
178+
self.assertEqual(event.recipient, "example@example.com")
179+
self.assertEqual(event.reject_reason, "bounced")
180+
147181
def test_dropped_unsubscribed_event(self):
148182
raw_events = [
149183
{

0 commit comments

Comments
 (0)