Skip to content

Commit

Permalink
Merge pull request #89 from themartorana/django-backend-message-ids
Browse files Browse the repository at this point in the history
Return message IDs in django backend optional
  • Loading branch information
nicholasserra committed Nov 3, 2020
2 parents f7f4522 + 7250ec4 commit c35c7de
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 13 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,11 @@ POSTMARK_API_KEY = 'your-key'
POSTMARK_SENDER = 'sender@signature.com'
POSTMARK_TEST_MODE = [True/False]
POSTMARK_TRACK_OPENS = [True/False]
POSTMARK_RETURN_MESSAGE_ID = [True/False] Return list of sent message-ids while using Django backend. Defaults to False, returns count.
```

to your settings.py file, and when you create a new PMMail object, it will grab the API key and sender automatically. Make sure the sender email address is one of your Sender Signature email addresses in Postmark. You can also customize the name on the sender by changing the format from 'email@address.com' to 'Sender Name <email@address.com>' as long as the email part is part of a Sender Signature in Postmark.

Using `POSTMARK_TEST_MODE=True` will not actually send the email, but instead dump the JSON packet that would be sent to Postmarkapp.com. By default this setting is False, and if not specified, will be assumed to be False.

To reroute all Django E-Mail functions like `send_mail()` and `mail_admins()` through postmark use the following setting:
Expand Down
5 changes: 5 additions & 0 deletions postmark/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ def __init__(self, **kwargs):
except ImportError:
pass

@property
def messages(self):
"""Convenience method to mimic batch messages property, return list of self."""
return [self]

#
# Properties

Expand Down
13 changes: 9 additions & 4 deletions postmark/django_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def __init__(self, api_key=None, default_sender=None, **kwargs):
raise ImproperlyConfigured('POSTMARK API key must be set in Django settings file or passed to backend constructor.')
self.default_sender = getattr(settings, 'POSTMARK_SENDER', default_sender)
self.test_mode = getattr(settings, 'POSTMARK_TEST_MODE', False)
self.return_message_id = getattr(settings, 'POSTMARK_RETURN_MESSAGE_ID', False)

def send_messages(self, email_messages):
"""
Expand All @@ -61,8 +62,12 @@ def send_messages(self, email_messages):
"""
if not email_messages:
return
sent = self._send(email_messages)
if sent:

sent, instance = self._send(email_messages)

if sent and self.return_message_id:
return [m.message_id for m in instance.messages]
elif sent:
return len(email_messages)
return 0

Expand Down Expand Up @@ -147,6 +152,6 @@ def _send(self, messages):
to_send.send(test=self.test_mode)
except:
if self.fail_silently:
return False
return False, to_send
raise
return True
return True, to_send
137 changes: 130 additions & 7 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@

from io import BytesIO

from django.core import mail
from django.core.mail import EmailMultiAlternatives, EmailMessage
from django.test import override_settings, TestCase
from django.test import TestCase

from postmark.django_backend import EmailBackend

Expand Down Expand Up @@ -233,13 +234,10 @@ def test_activate(self):

class EmailBackendTests(TestCase):

def setUp(self):
self.backend = EmailBackend(api_key='dummy')

def test_send_multi_alternative_html_email(self):
# build a message and send it
message = EmailMultiAlternatives(
connection=self.backend,
connection=EmailBackend(api_key='dummy'),
from_email='from@test.com', to=['recipient@test.com'], subject='html test', body='hello there'
)
message.attach_alternative('<b>hello</b> there', 'text/html')
Expand All @@ -253,7 +251,7 @@ def test_send_multi_alternative_html_email(self):
def test_send_content_subtype_email(self):
# build a message and send it
message = EmailMessage(
connection=self.backend,
connection=EmailBackend(api_key='dummy'),
from_email='from@test.com', to=['recipient@test.com'], subject='html test', body='<b>hello</b> there'
)
message.content_subtype = 'html'
Expand All @@ -271,7 +269,7 @@ def test_send_multi_alternative_with_subtype_html_email(self):
:return:
"""
message = EmailMultiAlternatives(
connection=self.backend,
connection=EmailBackend(api_key='dummy'),
from_email='from@test.com', to=['recipient@test.com'], subject='html test', body='<b>hello</b> there'
)
# NO alternatives attached. subtype specified instead
Expand All @@ -283,6 +281,129 @@ def test_send_multi_alternative_with_subtype_html_email(self):
self.assertFalse('TextBody' in data)
self.assertEqual('<b>hello</b> there', data['HtmlBody'])

def test_message_count_single(self):
"""Test backend returns count sending single message."""
with self.settings(POSTMARK_RETURN_MESSAGE_ID=False):
message = EmailMessage(
connection=EmailBackend(api_key='dummy'),
from_email='from@test.com', to=['recipient@test.com'], subject='html test', body='<b>hello</b> there'
)

with mock.patch('postmark.core.urlopen') as transport:
transport.return_value.read.return_value.decode.return_value = """
{
"To": "recipient@test.com",
"SubmittedAt": "2014-02-17T07:25:01.4178645-05:00",
"MessageID": "0a129aee-e1cd-480d-b08d-4f48548ff48d",
"ErrorCode": 0,
"Message": "OK"
}
"""
transport.return_value.code = 200
response = message.send()
self.assertEqual(response, 1)

def test_message_count_batch(self):
"""Test backend returns count sending batch messages."""
with self.settings(POSTMARK_RETURN_MESSAGE_ID=False):

message1 = EmailMessage(
connection=EmailBackend(api_key='dummy'),
from_email='from@test.com', to=['recipient@test.com'], subject='html test', body='<b>hello</b> there'
)
message2 = EmailMessage(
connection=EmailBackend(api_key='dummy'),
from_email='from@test.com', to=['recipient@test.com'], subject='html test', body='<b>hello</b> there'
)

with mock.patch('postmark.core.urlopen') as transport:
transport.return_value.read.return_value.decode.return_value = """
[
{
"ErrorCode": 0,
"Message": "OK",
"MessageID": "b7bc2f4a-e38e-4336-af7d-e6c392c2f817",
"SubmittedAt": "2010-11-26T12:01:05.1794748-05:00",
"To": "receiver1@example.com"
},
{
"ErrorCode": 0,
"Message": "OK",
"MessageID": "e2ecbbfc-fe12-463d-b933-9fe22915106d",
"SubmittedAt": "2010-11-26T12:01:05.1794748-05:00",
"To": "receiver2@example.com"
}
]
"""
transport.return_value.code = 200

# Directly send bulk mail via django
connection = mail.get_connection()
sent_messages = connection.send_messages([message1, message2])
self.assertEqual(sent_messages, 2)

def test_message_id_single(self):
"""Test backend returns message sending single message with setting True"""
with self.settings(POSTMARK_RETURN_MESSAGE_ID=True):
message = EmailMessage(
connection=EmailBackend(api_key='dummy'),
from_email='from@test.com', to=['recipient@test.com'], subject='html test', body='<b>hello</b> there'
)

with mock.patch('postmark.core.urlopen') as transport:
transport.return_value.read.return_value.decode.return_value = """
{
"To": "recipient@test.com",
"SubmittedAt": "2014-02-17T07:25:01.4178645-05:00",
"MessageID": "0a129aee-e1cd-480d-b08d-4f48548ff48d",
"ErrorCode": 0,
"Message": "OK"
}
"""
transport.return_value.code = 200
message_ids = message.send()
self.assertEqual(message_ids[0], "0a129aee-e1cd-480d-b08d-4f48548ff48d")

def test_message_id_batch(self):
"""Test backend returns message sending batch messages with setting True"""
with self.settings(POSTMARK_RETURN_MESSAGE_ID=True):

message1 = EmailMessage(
connection=EmailBackend(api_key='dummy'),
from_email='from@test.com', to=['recipient@test.com'], subject='html test', body='<b>hello</b> there'
)
message2 = EmailMessage(
connection=EmailBackend(api_key='dummy'),
from_email='from@test.com', to=['recipient@test.com'], subject='html test', body='<b>hello</b> there'
)

with mock.patch('postmark.core.urlopen') as transport:
transport.return_value.read.return_value.decode.return_value = """
[
{
"ErrorCode": 0,
"Message": "OK",
"MessageID": "b7bc2f4a-e38e-4336-af7d-e6c392c2f817",
"SubmittedAt": "2010-11-26T12:01:05.1794748-05:00",
"To": "receiver1@example.com"
},
{
"ErrorCode": 0,
"Message": "OK",
"MessageID": "e2ecbbfc-fe12-463d-b933-9fe22915106d",
"SubmittedAt": "2010-11-26T12:01:05.1794748-05:00",
"To": "receiver2@example.com"
}
]
"""
transport.return_value.code = 200

# Directly send bulk mail via django
connection = mail.get_connection()
sent_messages = connection.send_messages([message1, message2])
self.assertIn('b7bc2f4a-e38e-4336-af7d-e6c392c2f817', sent_messages)
self.assertIn('e2ecbbfc-fe12-463d-b933-9fe22915106d', sent_messages)


if __name__ == '__main__':
if not settings.configured:
Expand All @@ -296,6 +417,8 @@ def test_send_multi_alternative_with_subtype_html_email(self):
INSTALLED_APPS=[
],
MIDDLEWARE_CLASSES=[],
EMAIL_BACKEND = 'postmark.django_backend.EmailBackend',
POSTMARK_API_KEY='dummy',
)

unittest.main()

0 comments on commit c35c7de

Please sign in to comment.