diff --git a/README.md b/README.md index ff1a079..b879ef4 100644 --- a/README.md +++ b/README.md @@ -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 ' 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: diff --git a/postmark/core.py b/postmark/core.py index 36767d8..d77a583 100644 --- a/postmark/core.py +++ b/postmark/core.py @@ -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 diff --git a/postmark/django_backend.py b/postmark/django_backend.py index b818c88..ff963d7 100644 --- a/postmark/django_backend.py +++ b/postmark/django_backend.py @@ -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): """ @@ -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 @@ -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 diff --git a/tests.py b/tests.py index 46e14e4..6c8548e 100644 --- a/tests.py +++ b/tests.py @@ -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 @@ -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('hello there', 'text/html') @@ -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='hello there' ) message.content_subtype = 'html' @@ -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='hello there' ) # NO alternatives attached. subtype specified instead @@ -283,6 +281,129 @@ def test_send_multi_alternative_with_subtype_html_email(self): self.assertFalse('TextBody' in data) self.assertEqual('hello 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='hello 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='hello there' + ) + message2 = EmailMessage( + connection=EmailBackend(api_key='dummy'), + from_email='from@test.com', to=['recipient@test.com'], subject='html test', body='hello 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='hello 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='hello there' + ) + message2 = EmailMessage( + connection=EmailBackend(api_key='dummy'), + from_email='from@test.com', to=['recipient@test.com'], subject='html test', body='hello 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: @@ -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()