diff --git a/README.md b/README.md index 8de12f2..d08cced 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ Use it like a standard email backend with an additional feature that allows sett The `.from_email` attribute must be present in `GETRESPONSE_ADDRESSES` as key, with FromFiledId as value (see settings below). +The same goes for `.reply_to`: GetResponse names a reply-to address by FromFieldId as well, so an address set there has to be registered on the account and listed in `GETRESPONSE_ADDRESSES` too. At most one is supported, because the API holds one. + Result returned from sending mail is an int with extra attribute `getresponse_ids`. ## Settings diff --git a/getresponse/mail.py b/getresponse/mail.py index c7db83c..06680bd 100644 --- a/getresponse/mail.py +++ b/getresponse/mail.py @@ -88,6 +88,15 @@ def message_to_payload(self, msg): else: raise ValueError("Only single text/html alternative is supported by GetResponse backend.") + if msg.reply_to: + # GetResponse names a reply-to address the way it names a sender, by + # the id of a from-field registered on the account, and holds one. + if len(msg.reply_to) != 1: + raise ValueError("At most one msg.reply_to address is supported by GetResponse backend.") + payload['replyTo'] = { + 'fromFieldId': self.get_sender(msg.reply_to[0]), + } + if tag_id := getattr(msg, 'tag_id', None): payload['tag'] = { 'tagId': tag_id, @@ -95,9 +104,9 @@ def message_to_payload(self, msg): return payload def get_sender(self, from_email): - # if msg.from_email is listed in users settings with FieldId as value, use this address + # if the address is listed in users settings with FieldId as value, use this address if not settings.GETRESPONSE_ADDRESSES.get(from_email): - raise ValueError(f"Given from_email ({from_email}) is not present in GETRESPONSE_ADDRESSES.") + raise ValueError(f"Given address ({from_email}) is not present in GETRESPONSE_ADDRESSES.") return settings.GETRESPONSE_ADDRESSES.get(from_email) def attachments_to_payload(self, attachments): diff --git a/tests/test_payload.py b/tests/test_payload.py new file mode 100644 index 0000000..3807c34 --- /dev/null +++ b/tests/test_payload.py @@ -0,0 +1,42 @@ +import pytest +from django.core.mail import EmailMessage + +from getresponse.mail import GetResponseBackend + + +@pytest.fixture +def backend(settings): + settings.GETRESPONSE_ADDRESSES = { + 'webmaster@localhost': 'gr-id-1', + 'replies@example.com': 'gr-id-2', + } + return GetResponseBackend() + + +def message(**kwargs): + return EmailMessage( + subject='Test subject', + body='Test body', + to=['john.doe@example.com'], + **kwargs, + ) + + +def test_reply_to_travels_as_the_from_field_registered_for_it(backend): + payload = backend.message_to_payload(message(reply_to=['replies@example.com'])) + + assert payload['replyTo'] == {'fromFieldId': 'gr-id-2'} + + +def test_a_message_without_a_reply_to_sends_none(backend): + assert 'replyTo' not in backend.message_to_payload(message()) + + +def test_an_unregistered_reply_to_is_refused(backend): + with pytest.raises(ValueError): + backend.message_to_payload(message(reply_to=['nobody@example.com'])) + + +def test_more_than_one_reply_to_is_refused(backend): + with pytest.raises(ValueError): + backend.message_to_payload(message(reply_to=['replies@example.com', 'webmaster@localhost']))