Skip to content

Commit 9600b08

Browse files
committed
SparkPost: remove empty content params with template_id
When using a stored template, SparkPost disallows subject, text, and html. Django's EmailMessage default empty strings are enough to provoke "Both content object and template_id are specified" from SparkPost, so remove them (if empty) when using stored templates. Update docs and tests; add integration test for template_id. Fixes #24 (cherry picked from commit f95be24)
1 parent 91caf14 commit 9600b08

File tree

4 files changed

+38
-4
lines changed

4 files changed

+38
-4
lines changed

anymail/backends/sparkpost.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,15 @@ def get_api_params(self):
104104
if recipients:
105105
self.params['recipients'] = recipients
106106

107+
# Must remove empty string "content" params when using stored template
108+
if self.params.get('template', None):
109+
for content_param in ['subject', 'text', 'html']:
110+
try:
111+
if not self.params[content_param]:
112+
del self.params[content_param]
113+
except KeyError:
114+
pass
115+
107116
return self.params
108117

109118
def set_from_email(self, email):

docs/esps/sparkpost.rst

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,11 @@ and :ref:`batch sending <batch-send>` with per-recipient merge data.
140140

141141
You can use a SparkPost stored template by setting a message's
142142
:attr:`~anymail.message.AnymailMessage.template_id` to the
143-
template's unique id. Alternatively, you can refer to merge fields
144-
directly in an EmailMessage---the message itself is used as an
143+
template's unique id. (When using a stored template, SparkPost prohibits
144+
setting the EmailMessage's subject, text body, or html body.)
145+
146+
Alternatively, you can refer to merge fields directly in an EmailMessage's
147+
subject, body, and other fields---the message itself is used as an
145148
on-the-fly template.
146149

147150
In either case, supply the merge data values with Anymail's

tests/test_sparkpost_backend.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,10 +390,15 @@ def test_tracking(self):
390390
self.assertEqual(params['track_clicks'], True)
391391

392392
def test_template_id(self):
393-
self.message.template_id = "welcome_template"
394-
self.message.send()
393+
message = mail.EmailMultiAlternatives(from_email='[email protected]', to=['[email protected]'])
394+
message.template_id = "welcome_template"
395+
message.send()
395396
params = self.get_send_params()
396397
self.assertEqual(params['template'], "welcome_template")
398+
# SparkPost disallows all content (even empty strings) with stored template:
399+
self.assertNotIn('subject', params)
400+
self.assertNotIn('text', params)
401+
self.assertNotIn('html', params)
397402

398403
def test_merge_data(self):
399404
self.set_mock_response(accepted=2)

tests/test_sparkpost_integration.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,23 @@ def test_merge_data(self):
107107
self.assertEqual(recipient_status['[email protected]'].status, 'queued')
108108
self.assertEqual(recipient_status['[email protected]'].status, 'queued')
109109

110+
def test_stored_template(self):
111+
message = AnymailMessage(
112+
template_id='test-template', # a real template in our SparkPost test account
113+
114+
merge_data={
115+
116+
'name': "Test Recipient",
117+
}
118+
},
119+
merge_global_data={
120+
'order': '12345',
121+
},
122+
)
123+
message.send()
124+
recipient_status = message.anymail_status.recipients
125+
self.assertEqual(recipient_status['[email protected]'].status, 'queued')
126+
110127
@override_settings(ANYMAIL_SPARKPOST_API_KEY="Hey, that's not an API key!")
111128
def test_invalid_api_key(self):
112129
with self.assertRaises(AnymailAPIError) as cm:

0 commit comments

Comments
 (0)