mirror of
https://github.com/pacnpal/django-anymail.git
synced 2025-12-20 03:41:05 -05:00
Webhooks: default tracking event tags=[], metadata={}
If a tracking event doesn't contain tags or metadata, set the event
record fields to tags=[] or metadata={} to simplify checking values.
Closes #67
This commit is contained in:
@@ -32,11 +32,11 @@ class AnymailTrackingEvent(AnymailEvent):
|
|||||||
self.click_url = kwargs.pop('click_url', None) # str
|
self.click_url = kwargs.pop('click_url', None) # str
|
||||||
self.description = kwargs.pop('description', None) # str, usually human-readable, not normalized
|
self.description = kwargs.pop('description', None) # str, usually human-readable, not normalized
|
||||||
self.message_id = kwargs.pop('message_id', None) # str, format may vary
|
self.message_id = kwargs.pop('message_id', None) # str, format may vary
|
||||||
self.metadata = kwargs.pop('metadata', None) # dict
|
self.metadata = kwargs.pop('metadata', {}) # dict
|
||||||
self.mta_response = kwargs.pop('mta_response', None) # str, may include SMTP codes, not normalized
|
self.mta_response = kwargs.pop('mta_response', None) # str, may include SMTP codes, not normalized
|
||||||
self.recipient = kwargs.pop('recipient', None) # str email address (just the email portion; no name)
|
self.recipient = kwargs.pop('recipient', None) # str email address (just the email portion; no name)
|
||||||
self.reject_reason = kwargs.pop('reject_reason', None) # normalized to a RejectReason str
|
self.reject_reason = kwargs.pop('reject_reason', None) # normalized to a RejectReason str
|
||||||
self.tags = kwargs.pop('tags', None) # list of str
|
self.tags = kwargs.pop('tags', []) # list of str
|
||||||
self.user_agent = kwargs.pop('user_agent', None) # str
|
self.user_agent = kwargs.pop('user_agent', None) # str
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ class MailgunTrackingWebhookView(MailgunBaseWebhookView):
|
|||||||
try:
|
try:
|
||||||
headers = json.loads(esp_event['message-headers'])
|
headers = json.loads(esp_event['message-headers'])
|
||||||
except (KeyError, ):
|
except (KeyError, ):
|
||||||
metadata = None
|
metadata = {}
|
||||||
else:
|
else:
|
||||||
variables = [value for [field, value] in headers
|
variables = [value for [field, value] in headers
|
||||||
if field == 'X-Mailgun-Variables']
|
if field == 'X-Mailgun-Variables']
|
||||||
@@ -121,10 +121,10 @@ class MailgunTrackingWebhookView(MailgunBaseWebhookView):
|
|||||||
# Each X-Mailgun-Variables value is JSON. Parse and merge them all into single dict:
|
# Each X-Mailgun-Variables value is JSON. Parse and merge them all into single dict:
|
||||||
metadata = combine(*[json.loads(value) for value in variables])
|
metadata = combine(*[json.loads(value) for value in variables])
|
||||||
else:
|
else:
|
||||||
metadata = None
|
metadata = {}
|
||||||
|
|
||||||
# tags are sometimes delivered as X-Mailgun-Tag fields, sometimes as tag
|
# tags are sometimes delivered as X-Mailgun-Tag fields, sometimes as tag
|
||||||
tags = esp_event.getlist('tag', esp_event.getlist('X-Mailgun-Tag', None))
|
tags = esp_event.getlist('tag', esp_event.getlist('X-Mailgun-Tag', []))
|
||||||
|
|
||||||
return AnymailTrackingEvent(
|
return AnymailTrackingEvent(
|
||||||
event_type=event_type,
|
event_type=event_type,
|
||||||
|
|||||||
@@ -128,12 +128,12 @@ class MandrillTrackingWebhookView(MandrillBaseWebhookView):
|
|||||||
try:
|
try:
|
||||||
metadata = esp_event['msg']['metadata']
|
metadata = esp_event['msg']['metadata']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
metadata = None
|
metadata = {}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
tags = esp_event['msg']['tags']
|
tags = esp_event['msg']['tags']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
tags = None
|
tags = []
|
||||||
|
|
||||||
return AnymailTrackingEvent(
|
return AnymailTrackingEvent(
|
||||||
click_url=esp_event.get('url', None),
|
click_url=esp_event.get('url', None),
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ class PostmarkTrackingWebhookView(PostmarkBaseWebhookView):
|
|||||||
try:
|
try:
|
||||||
tags = [esp_event['Tag']]
|
tags = [esp_event['Tag']]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
tags = None
|
tags = []
|
||||||
|
|
||||||
return AnymailTrackingEvent(
|
return AnymailTrackingEvent(
|
||||||
description=esp_event.get('Description', None),
|
description=esp_event.get('Description', None),
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class SendGridTrackingWebhookView(SendGridBaseWebhookView):
|
|||||||
if len(metadata_keys) > 0:
|
if len(metadata_keys) > 0:
|
||||||
metadata = {key: esp_event[key] for key in metadata_keys}
|
metadata = {key: esp_event[key] for key in metadata_keys}
|
||||||
else:
|
else:
|
||||||
metadata = None
|
metadata = {}
|
||||||
|
|
||||||
return AnymailTrackingEvent(
|
return AnymailTrackingEvent(
|
||||||
event_type=event_type,
|
event_type=event_type,
|
||||||
@@ -82,7 +82,7 @@ class SendGridTrackingWebhookView(SendGridBaseWebhookView):
|
|||||||
recipient=esp_event.get('email', None),
|
recipient=esp_event.get('email', None),
|
||||||
reject_reason=reject_reason,
|
reject_reason=reject_reason,
|
||||||
mta_response=mta_response,
|
mta_response=mta_response,
|
||||||
tags=esp_event.get('category', None),
|
tags=esp_event.get('category', []),
|
||||||
metadata=metadata,
|
metadata=metadata,
|
||||||
click_url=esp_event.get('url', None),
|
click_url=esp_event.get('url', None),
|
||||||
user_agent=esp_event.get('useragent', None),
|
user_agent=esp_event.get('useragent', None),
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ class SparkPostTrackingWebhookView(SparkPostBaseWebhookView):
|
|||||||
tag = event['campaign_id'] # not 'rcpt_tags' -- those don't come from sending a message
|
tag = event['campaign_id'] # not 'rcpt_tags' -- those don't come from sending a message
|
||||||
tags = [tag] if tag else None
|
tags = [tag] if tag else None
|
||||||
except KeyError:
|
except KeyError:
|
||||||
tags = None
|
tags = []
|
||||||
|
|
||||||
try:
|
try:
|
||||||
reject_reason = self.reject_reasons.get(event['bounce_class'], RejectReason.OTHER)
|
reject_reason = self.reject_reasons.get(event['bounce_class'], RejectReason.OTHER)
|
||||||
@@ -129,7 +129,7 @@ class SparkPostTrackingWebhookView(SparkPostBaseWebhookView):
|
|||||||
mta_response=event.get('raw_reason', None),
|
mta_response=event.get('raw_reason', None),
|
||||||
# description=???,
|
# description=???,
|
||||||
tags=tags,
|
tags=tags,
|
||||||
metadata=event.get('rcpt_meta', None) or None, # message + recipient metadata
|
metadata=event.get('rcpt_meta', None) or {}, # message + recipient metadata
|
||||||
click_url=event.get('target_link_url', None),
|
click_url=event.get('target_link_url', None),
|
||||||
user_agent=event.get('user_agent', None),
|
user_agent=event.get('user_agent', None),
|
||||||
esp_event=raw_event,
|
esp_event=raw_event,
|
||||||
|
|||||||
@@ -139,12 +139,14 @@ Normalized tracking event
|
|||||||
|
|
||||||
.. attribute:: metadata
|
.. attribute:: metadata
|
||||||
|
|
||||||
A `dict` of unique data attached to the message, or `None`.
|
A `dict` of unique data attached to the message. Will be empty if the ESP
|
||||||
|
doesn't provide metadata with its tracking events.
|
||||||
(See :attr:`AnymailMessage.metadata <anymail.message.AnymailMessage.metadata>`.)
|
(See :attr:`AnymailMessage.metadata <anymail.message.AnymailMessage.metadata>`.)
|
||||||
|
|
||||||
.. attribute:: tags
|
.. attribute:: tags
|
||||||
|
|
||||||
A `list` of `str` tags attached to the message, or `None`.
|
A `list` of `str` tags attached to the message. Will be empty if the ESP
|
||||||
|
doesn't provide tags with its tracking events.
|
||||||
(See :attr:`AnymailMessage.tags <anymail.message.AnymailMessage.tags>`.)
|
(See :attr:`AnymailMessage.tags <anymail.message.AnymailMessage.tags>`.)
|
||||||
|
|
||||||
.. attribute:: reject_reason
|
.. attribute:: reject_reason
|
||||||
|
|||||||
@@ -109,6 +109,8 @@ class MailgunDeliveryTestCase(WebhookTestCase):
|
|||||||
self.assertEqual(event.event_id, "06c96bafc3f42a66b9edd546347a2fe18dc23461fe80dc52f0")
|
self.assertEqual(event.event_id, "06c96bafc3f42a66b9edd546347a2fe18dc23461fe80dc52f0")
|
||||||
self.assertEqual(event.recipient, "recipient@example.com")
|
self.assertEqual(event.recipient, "recipient@example.com")
|
||||||
self.assertEqual(querydict_to_postdict(event.esp_event), raw_event)
|
self.assertEqual(querydict_to_postdict(event.esp_event), raw_event)
|
||||||
|
self.assertEqual(event.tags, [])
|
||||||
|
self.assertEqual(event.metadata, {})
|
||||||
|
|
||||||
def test_dropped_bounce(self):
|
def test_dropped_bounce(self):
|
||||||
raw_event = mailgun_sign({
|
raw_event = mailgun_sign({
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ class PostmarkDeliveryTestCase(WebhookTestCase):
|
|||||||
self.assertEqual(event.message_id, "883953f4-6105-42a2-a16a-77a8eac79483")
|
self.assertEqual(event.message_id, "883953f4-6105-42a2-a16a-77a8eac79483")
|
||||||
self.assertEqual(event.recipient, "recipient@example.com")
|
self.assertEqual(event.recipient, "recipient@example.com")
|
||||||
self.assertEqual(event.tags, ["welcome-email"])
|
self.assertEqual(event.tags, ["welcome-email"])
|
||||||
|
self.assertEqual(event.metadata, {})
|
||||||
|
|
||||||
def test_open_event(self):
|
def test_open_event(self):
|
||||||
raw_event = {
|
raw_event = {
|
||||||
@@ -106,3 +107,5 @@ class PostmarkDeliveryTestCase(WebhookTestCase):
|
|||||||
self.assertEqual(event.message_id, "f4830d10-9c35-4f0c-bca3-3d9b459821f8")
|
self.assertEqual(event.message_id, "f4830d10-9c35-4f0c-bca3-3d9b459821f8")
|
||||||
self.assertEqual(event.recipient, "recipient@example.com")
|
self.assertEqual(event.recipient, "recipient@example.com")
|
||||||
self.assertEqual(event.user_agent, "Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko Firefox/11.0")
|
self.assertEqual(event.user_agent, "Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko Firefox/11.0")
|
||||||
|
self.assertEqual(event.tags, [])
|
||||||
|
self.assertEqual(event.metadata, {})
|
||||||
|
|||||||
@@ -73,8 +73,8 @@ class SendGridDeliveryTestCase(WebhookTestCase):
|
|||||||
self.assertEqual(event.event_id, "nOSv8m0eTQ-vxvwNwt3fZQ")
|
self.assertEqual(event.event_id, "nOSv8m0eTQ-vxvwNwt3fZQ")
|
||||||
self.assertEqual(event.recipient, "recipient@example.com")
|
self.assertEqual(event.recipient, "recipient@example.com")
|
||||||
self.assertEqual(event.mta_response, "250 2.0.0 OK 1461095248 m143si2210036ioe.159 - gsmtp ")
|
self.assertEqual(event.mta_response, "250 2.0.0 OK 1461095248 m143si2210036ioe.159 - gsmtp ")
|
||||||
self.assertEqual(event.tags, None)
|
self.assertEqual(event.tags, [])
|
||||||
self.assertEqual(event.metadata, None)
|
self.assertEqual(event.metadata, {})
|
||||||
|
|
||||||
def test_dropped_invalid_event(self):
|
def test_dropped_invalid_event(self):
|
||||||
raw_events = [{
|
raw_events = [{
|
||||||
|
|||||||
@@ -97,8 +97,8 @@ class SparkPostDeliveryTestCase(WebhookTestCase):
|
|||||||
self.assertIsInstance(event, AnymailTrackingEvent)
|
self.assertIsInstance(event, AnymailTrackingEvent)
|
||||||
self.assertEqual(event.event_type, "delivered")
|
self.assertEqual(event.event_type, "delivered")
|
||||||
self.assertEqual(event.recipient, "Recipient@example.com")
|
self.assertEqual(event.recipient, "Recipient@example.com")
|
||||||
self.assertEqual(event.tags, None)
|
self.assertEqual(event.tags, [])
|
||||||
self.assertEqual(event.metadata, None)
|
self.assertEqual(event.metadata, {})
|
||||||
|
|
||||||
def test_bounce_event(self):
|
def test_bounce_event(self):
|
||||||
raw_events = [{
|
raw_events = [{
|
||||||
|
|||||||
Reference in New Issue
Block a user