Feature: Add envelope_sender

New EmailMessage attribute `envelope_sender` controls ESP's sender,
sending domain, or return path where supported:

* Mailgun: overrides SENDER_DOMAIN on individual message
  (domain portion only)
* Mailjet: becomes `Sender` API param
* Mandrill: becomes `return_path_domain` API param
  (domain portion only)
* SparkPost: becomes `return_path` API param
* Other ESPs: not believed to be supported

Also support undocumented Django SMTP backend behavior, where envelope
sender is given by `message.from_email` when
`message.extra_headers["From"]` is set. Fixes #91.
This commit is contained in:
medmunds
2018-02-26 18:42:19 -08:00
parent bd9d92f5a0
commit 07fbeac6bd
27 changed files with 246 additions and 28 deletions

View File

@@ -13,7 +13,6 @@ from django.core.mail.message import sanitize_address, DEFAULT_ATTACHMENT_MIME_T
from django.utils.encoding import force_text
from django.utils.functional import Promise
from django.utils.timezone import utc, get_fixed_timezone
# noinspection PyUnresolvedReferences
from six.moves.urllib.parse import urlsplit, urlunsplit
from .exceptions import AnymailConfigurationError, AnymailInvalidAddress
@@ -161,6 +160,21 @@ def parse_address_list(address_list):
return parsed
def parse_single_address(address):
"""Parses a single EmailAddress from str address, or raises AnymailInvalidAddress
:param str address: the fully-formatted email str to parse
:return :class:`EmailAddress`: if address contains a single email
:raises :exc:`AnymailInvalidAddress`: if address contains no or multiple emails
"""
parsed = parse_address_list([address])
count = len(parsed)
if count > 1:
raise AnymailInvalidAddress("Only one email address is allowed; found %d in %r" % (count, address))
else:
return parsed[0]
class EmailAddress(object):
"""A sanitized, complete email address with easy access
to display-name, addr-spec (email), etc.