Skip to content

Commit b664ee3

Browse files
committed
SparkPost: work around json recipients problem
python-sparkpost generates a transmissions.send payload which is now considered invalid by the API, if you try to use both `cc` (or `bcc`) and the `recipients` dict structure required for merge_data. [Anymail had been generating that recipients dict structure in all cases, for simplicity. Sometime between 2016-06-07 and 2016-06-22, SparkPost began rejecting that if it appeared in the `header_to` constructed by python-sparkpost.]
1 parent 5adb07a commit b664ee3

File tree

2 files changed

+17
-18
lines changed

2 files changed

+17
-18
lines changed

anymail/backends/sparkpost.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,20 @@ def init_payload(self):
8787
def get_api_params(self):
8888
# Compose recipients param from to_emails and merge_data (if any)
8989
recipients = []
90-
for email in self.to_emails:
91-
rcpt = {'address': {'email': email.email}}
92-
if email.name:
93-
rcpt['address']['name'] = email.name
94-
try:
95-
rcpt['substitution_data'] = self.merge_data[email.email]
96-
except KeyError:
97-
pass # no merge_data or none for this recipient
98-
recipients.append(rcpt)
90+
if len(self.merge_data) > 0:
91+
# Build JSON recipient structures
92+
for email in self.to_emails:
93+
rcpt = {'address': {'email': email.email}}
94+
if email.name:
95+
rcpt['address']['name'] = email.name
96+
try:
97+
rcpt['substitution_data'] = self.merge_data[email.email]
98+
except KeyError:
99+
pass # no merge_data or none for this recipient
100+
recipients.append(rcpt)
101+
else:
102+
# Just use simple recipients list
103+
recipients = [email.address for email in self.to_emails]
99104
if recipients:
100105
self.params['recipients'] = recipients
101106

tests/test_sparkpost_backend.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def test_send_mail(self):
9999
self.assertEqual(params['subject'], "Subject here")
100100
self.assertEqual(params['text'], "Here is the message.")
101101
self.assertEqual(params['from_email'], "[email protected]")
102-
self.assertEqual(params['recipients'], [{'address': {'email': "[email protected]"}}])
102+
self.assertEqual(params['recipients'], ["[email protected]"])
103103

104104
self.assertEqual(self.get_send_api_key(), 'test_api_key')
105105

@@ -118,10 +118,7 @@ def test_name_addr(self):
118118
params = self.get_send_params()
119119
self.assertEqual(params['from_email'], "From Name <[email protected]>")
120120
# We pre-parse the to-field emails (merge_data also gets attached there):
121-
self.assertEqual(params['recipients'], [
122-
{'address': {'email': '[email protected]', 'name': 'Recipient #1'}},
123-
{'address': {'email': '[email protected]'}}
124-
])
121+
self.assertEqual(params['recipients'], ['Recipient #1 <[email protected]>', '[email protected]'])
125122
# We let python-sparkpost parse the other email fields:
126123
self.assertEqual(params['cc'], ['Carbon Copy <[email protected]>', '[email protected]'])
127124
self.assertEqual(params['bcc'], ['Blind Copy <[email protected]>', '[email protected]'])
@@ -141,10 +138,7 @@ def test_email_message(self):
141138
self.assertEqual(params['subject'], "Subject")
142139
self.assertEqual(params['text'], "Body goes here")
143140
self.assertEqual(params['from_email'], "[email protected]")
144-
self.assertEqual(params['recipients'], [
145-
{'address': {'email': '[email protected]'}},
146-
{'address': {'email': '[email protected]', 'name': 'Also To'}}
147-
])
141+
self.assertEqual(params['recipients'], ['[email protected]', 'Also To <[email protected]>'])
148142
self.assertEqual(params['bcc'], ['[email protected]', 'Also BCC <[email protected]>'])
149143
self.assertEqual(params['cc'], ['[email protected]', 'Also CC <[email protected]>'])
150144
self.assertEqual(params['custom_headers'], {

0 commit comments

Comments
 (0)