Skip to content

Commit

Permalink
SparkPost: remove empty content params with template_id
Browse files Browse the repository at this point in the history
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
  • Loading branch information
medmunds committed Jun 24, 2016
1 parent 0c5911c commit f95be24
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 4 deletions.
9 changes: 9 additions & 0 deletions anymail/backends/sparkpost.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,15 @@ def get_api_params(self):
if recipients:
self.params['recipients'] = recipients

# Must remove empty string "content" params when using stored template
if self.params.get('template', None):
for content_param in ['subject', 'text', 'html']:
try:
if not self.params[content_param]:
del self.params[content_param]
except KeyError:
pass

return self.params

def set_from_email(self, email):
Expand Down
7 changes: 5 additions & 2 deletions docs/esps/sparkpost.rst
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,11 @@ and :ref:`batch sending <batch-send>` with per-recipient merge data.

You can use a SparkPost stored template by setting a message's
:attr:`~anymail.message.AnymailMessage.template_id` to the
template's unique id. Alternatively, you can refer to merge fields
directly in an EmailMessage---the message itself is used as an
template's unique id. (When using a stored template, SparkPost prohibits
setting the EmailMessage's subject, text body, or html body.)

Alternatively, you can refer to merge fields directly in an EmailMessage's
subject, body, and other fields---the message itself is used as an
on-the-fly template.

In either case, supply the merge data values with Anymail's
Expand Down
9 changes: 7 additions & 2 deletions tests/test_sparkpost_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,10 +390,15 @@ def test_tracking(self):
self.assertEqual(params['track_clicks'], True)

def test_template_id(self):
self.message.template_id = "welcome_template"
self.message.send()
message = mail.EmailMultiAlternatives(from_email='from@example.com', to=['to@example.com'])
message.template_id = "welcome_template"
message.send()
params = self.get_send_params()
self.assertEqual(params['template'], "welcome_template")
# SparkPost disallows all content (even empty strings) with stored template:
self.assertNotIn('subject', params)
self.assertNotIn('text', params)
self.assertNotIn('html', params)

def test_merge_data(self):
self.set_mock_response(accepted=2)
Expand Down
17 changes: 17 additions & 0 deletions tests/test_sparkpost_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,23 @@ def test_merge_data(self):
self.assertEqual(recipient_status['to1@test.sink.sparkpostmail.com'].status, 'queued')
self.assertEqual(recipient_status['to2@test.sink.sparkpostmail.com'].status, 'queued')

def test_stored_template(self):
message = AnymailMessage(
template_id='test-template', # a real template in our SparkPost test account
to=["to1@test.sink.sparkpostmail.com"],
merge_data={
'to1@test.sink.sparkpostmail.com': {
'name': "Test Recipient",
}
},
merge_global_data={
'order': '12345',
},
)
message.send()
recipient_status = message.anymail_status.recipients
self.assertEqual(recipient_status['to1@test.sink.sparkpostmail.com'].status, 'queued')

@override_settings(ANYMAIL_SPARKPOST_API_KEY="Hey, that's not an API key!")
def test_invalid_api_key(self):
with self.assertRaises(AnymailAPIError) as cm:
Expand Down

0 comments on commit f95be24

Please sign in to comment.