Skip to content

Commit

Permalink
SparkPost: add subaccount support
Browse files Browse the repository at this point in the history
  • Loading branch information
medmunds committed Sep 11, 2020
1 parent 61660cd commit 985143b
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 2 deletions.
6 changes: 4 additions & 2 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@ Breaking changes
Features
~~~~~~~~

* **SparkPost:** Add support for AMP for Email, via
``message.attach_alternative("...AMPHTML content...", "text/x-amp-html")``.
* **SparkPost:** Add support for subaccounts (new ``"SPARKPOST_SUBACCOUNT"`` Anymail
setting), AMP for Email (via ``message.attach_alternative(..., "text/x-amp-html")``),
and A/B testing and other SparkPost sending features (via ``esp_extra``). (See
`docs <https://anymail.readthedocs.io/en/latest/esps/sparkpost/>`__.)


v7.2.1
Expand Down
4 changes: 4 additions & 0 deletions anymail/backends/sparkpost.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ def __init__(self, **kwargs):
"""Init options from Django settings"""
self.api_key = get_anymail_setting('api_key', esp_name=self.esp_name,
kwargs=kwargs, allow_bare=True)
self.subaccount = get_anymail_setting('subaccount', esp_name=self.esp_name,
kwargs=kwargs, default=None)
api_url = get_anymail_setting('api_url', esp_name=self.esp_name, kwargs=kwargs,
default="https://api.sparkpost.com/api/v1/")
if not api_url.endswith("/"):
Expand Down Expand Up @@ -57,6 +59,8 @@ def __init__(self, message, defaults, backend, *args, **kwargs):
'Authorization': backend.api_key,
'Content-Type': 'application/json',
}
if backend.subaccount is not None:
http_headers['X-MSYS-SUBACCOUNT'] = backend.subaccount
self.recipients = [] # all recipients, for backend parse_recipient_status
self.cc_and_bcc = [] # for _finalize_recipients
super().__init__(message, defaults, backend, headers=http_headers, *args, **kwargs)
Expand Down
19 changes: 19 additions & 0 deletions docs/esps/sparkpost.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,25 @@ nor ``ANYMAIL_SPARKPOST_API_KEY`` is set.
.. _SparkPost account API keys: https://app.sparkpost.com/account/credentials


.. setting:: ANYMAIL_SPARKPOST_SUBACCOUNT

.. rubric:: SPARKPOST_SUBACCOUNT

.. versionadded:: 8.0

An optional `SparkPost subaccount`_ numeric id. This can be used, along with the API key
for the master account, to send mail on behalf of a subaccount. (Do not set this when
using a subaccount's own API key.)

Like all Anymail settings, you can include this in the global settings.py ANYMAIL dict
to apply to all sends, or supply it as a :func:`~django.core.mail.get_connection`
keyword parameter (``connection = get_connection(subaccount=123)``) to send a particular
message with a subaccount. See :ref:`multiple-backends` for more information on using
connections.

.. _SparkPost subaccount: https://www.sparkpost.com/docs/user-guide/subaccounts/


.. setting:: ANYMAIL_SPARKPOST_API_URL

.. rubric:: SPARKPOST_API_URL
Expand Down
14 changes: 14 additions & 0 deletions tests/test_sparkpost_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -689,3 +689,17 @@ def test_sparkpost_api_url(self):
mail.send_mail('Subject', 'Message', '[email protected]', ['[email protected]'],
connection=connection)
self.assert_esp_called("https://api.sparkpost.com/api/labs/transmissions/")

def test_subaccount(self):
# A likely use case is supplying subaccount for a particular message.
# (For all messages, just set SPARKPOST_SUBACCOUNT in ANYMAIL settings.)
connection = mail.get_connection(subaccount=123)
mail.send_mail('Subject', 'Message', '[email protected]', ['[email protected]'],
connection=connection)
headers = self.get_api_call_headers()
self.assertEqual(headers["X-MSYS-SUBACCOUNT"], 123)

# Make sure we're not setting the header on non-subaccount sends
mail.send_mail('Subject', 'Message', '[email protected]', ['[email protected]'])
headers = self.get_api_call_headers()
self.assertNotIn("X-MSYS-SUBACCOUNT", headers)

0 comments on commit 985143b

Please sign in to comment.