Commit Graph

27 Commits

Author SHA1 Message Date
Mike Edmunds
85cec5e9dc Drop Python 2 and Django 1.11 support
Minimum supported versions are now Django 2.0, Python 3.5.

This touches a lot of code, to:
* Remove obsolete portability code and workarounds
  (six, backports of email parsers, test utils, etc.)
* Use Python 3 syntax (class defs, raise ... from, etc.)
* Correct inheritance for mixin classes
* Fix outdated docs content and links
* Suppress Python 3 "unclosed SSLSocket" ResourceWarnings
  that are beyond our control (in integration tests due to boto3, 
  python-sparkpost)
2020-08-01 14:53:10 -07:00
medmunds
bb20ebf0e9 Docs: clarify behavior of Anymail's added send options 2020-07-29 14:25:25 -07:00
A Lee
1fc44a4e15 Docs: fix typos and other minor text edits
- remove extraneous parens
- a few minor suggested text edits for readability
2019-10-15 14:40:17 -07:00
Mike Edmunds
75d7671056 Add merge_metadata for other ESPs
Support merge_metadata in Mailgun, Mailjet, Mandrill, Postmark, 
SparkPost, and Test backends. (SendGrid covered in earlier PR.)

Also:
* Add `merge_metadata` to AnymailMessage, AnymailMessageMixin
* Add `is_batch()` logic to BasePayload, for consistent handling
* Docs

Note: Mailjet implementation switches *all* batch sending from their 
"Recipients" field to to the "Messages" array bulk sending option.
This allows an independent payload for each batch recipient.
In addition to supporting merge_metadata, this also removes the
prior limitation on mixing Cc/Bcc with merge_data.

Closes #141.
2019-02-23 13:32:28 -08:00
Leo Antunes
64f7d31d14 also consider Content-ID when marking attachment as inline (#126)
Handle MIME attachments with Content-ID as inline by default.

Treat MIME attachments that have a *Content-ID* but no explicit *Content-Disposition*
header as inline, matching the behavior of many email clients.
2018-10-11 14:29:00 -07:00
medmunds
e6431a62f0 Change attach_inline_image default domain from hostname to "inline".
This avoids problems with ESPs that don't distinguish *Content-ID*
from attachment filename, where a local hostname ending in ".com" could
cause Gmail to block messages sent with inline attachments.
(Mailgun, Mailjet, Mandrill and SparkPost have APIs affected by this.)

Fixes #112.
2018-07-06 16:30:27 -07:00
Mike Edmunds
ef69fa3bf7 Amazon SES support
Integrate Amazon SES.

Closes #54.
2018-04-11 10:35:23 -07:00
medmunds
0c3e3e9bad Docs: css tweaks
* Add vertical space between items in "open" lists
  (rtfd/sphinx_rtd_theme#590)
* Distinguish shell prompts in console examples,
  and omit them if the code is copied
* Add css and js extras directly from Sphinx conf.py
  (no need to override template)
2018-03-16 12:16:57 -07:00
medmunds
06c7077e37 Fix: flag extra_headers["To"] as unsupported
Django's SMTP EmailBackend allows spoofing the To header by setting
`message.extra_headers["To"]`` different from `message.to`.

No current Anymail ESP supports this. Treat extra_headers["To"] as
an unsupported ESP feature, to flag attempts to use it.

Also document Anymail's special header handling that replicates
Django's SMTP EmailBackend behavior.
2018-02-27 13:43:58 -08:00
medmunds
07fbeac6bd 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.
2018-02-26 18:42:19 -08:00
medmunds
0a95f1346a Docs: add info on handling transient ESP errors
Closes #55
2017-09-08 14:27:49 -07:00
medmunds
90b9dc6cfa Docs: simplify PyPI links
Use `:pypi:` sphinx-ext-extlink role for links to PyPI,
and add some missing package links.
2017-09-08 14:16:09 -07:00
medmunds
2faa5f96cb Clean up and document Anymail's test EmailBackend
* Change Anymail's test EmailBackend to collect sent messages in
  django.core.mail.outbox, same as Django's own locmem EmailBackend.
  (So Django's test runner will automatically clear accumulated mail
  between test cases.)

* Rename EmailMessage `test_response` attr to `anymail_test_response`
  to avoid conflicts, and record merged ESP send params in
  new `anymail_send_params` attr.

* Add docs

Closes #36.
2017-09-01 13:13:25 -07:00
medmunds
fc59707133 Webhooks: default tracking event tags=[], metadata={}
If a tracking event doesn't contain tags or metadata, set the event
record fields to tags=[] or metadata={} to simplify checking values.

Closes #67
2017-06-30 16:56:36 -07:00
medmunds
d0596d100b Raise error for invalidly-formatted email addresses.
A message's `from_email` and each address in its `to`, `cc`, and `bcc` lists must contain exactly one email address. Previous code would silently ignore additional addresses, leading to unusual behavior. Now, raises new `AnymailInvalidAddress` exception.

Example: `from_email='Widgets, Inc. <widgets@example.com>'` is invalid: it needs double-quotes around the "Widgets, Inc." display-name portion. In earlier versions, this probably would have sent the message from something like "From: Widgets <@localhost>". Now, it will raise an exception.

**Potentially-breaking change:** If your code is using an unquoted display-name containing a comma in an email address, it will now raise an error. In earlier versions, this may have appeared to succeed, but was almost certainly not doing what you intended.

Fixes #44.
2016-12-15 13:57:49 -08:00
medmunds
60dc11559d AnymailMessage: initialize anymail_status to empty AnymailStatus
Allows clients that use AnymailMessage or AnymailMessageMixin
to access (e.g.) message.anymail_status.message_id without
an AttributeError, even when using a non-Anymail backend
(e.g., during testing).

Also clarify docs of anymail_status attribute to note it only gets
attached to a normal Django EmailMessage when sent through
an Anymail backend.

(May help with situation described in #36)
2016-10-20 11:50:31 -07:00
Pierre Drescher
ac3c1cbf1a Fix typo on documentation for 'recipients' attribute (#35) 2016-10-05 16:16:35 -07:00
medmunds
742868d68c Docs: missed param in pre_send signature
[ci skip]
2016-05-13 12:17:27 -07:00
medmunds
f8eafba0df Add pre_send and post_send signals
Closes #8
2016-05-12 21:18:04 -07:00
medmunds
75730e8219 Add ESP templates, batch send and merge
* message.template_id to use ESP stored templates
* message.merge_data and merge_global_data
  to supply per-recipient/global merge variables
  (with or without an ESP stored template)
* When using per-recipient merge_data, tell ESP to use
  batch send: individual message per "to" address.
  (Mailgun does this automatically; SendGrid requires
  using a different "to" field; Mandrill requires
  `preserve_recipients=False`; Postmark doesn't
  support *this type* of batch sending with merge data.)
* Allow message.from_email=None (must be set after
  init) and message.subject=None to suppress those
  fields in API calls (for ESPs that allow "From" and
  "Subject" in their template definitions).

Mailgun:
* Emulate merge_global_data by copying to
  recipient-variables for each recipient.

SendGrid:
* Add delimiters to merge field names via
  esp_extra['merge_field_format'] or
  ANYMAIL_SENDGRID_MERGE_FIELD_FORMAT setting.

Mandrill:
* Remove Djrill versions of these features;
  update migration notes.

Closes #5.
2016-05-06 12:27:11 -07:00
medmunds
d3f914be12 Event-tracking webhooks
Closes #3
2016-04-29 18:10:50 -07:00
Mike Edmunds
ca7dbdcec6 Docs: clarify ESP templates not yet implemented 2016-04-26 09:39:41 -07:00
medmunds
9462d03dc1 Docs: add ESP feature support matrix
[ci skip]
2016-03-14 11:34:33 -07:00
medmunds
54827579d3 Improve inline-image handling
* Add filename param to attach_inline_image

* Add attach_inline_image_file function
  (parallels EmailMessage.attach and attach_file)

* Use `Content-Disposition: inline` to decide
  whether an attachment should be handled inline
  (whether or not it's an image, and whether or not
  it has a Content-ID)

* Stop conflating filename and Content-ID, for
  ESPs that allow both. (Solves problem where
  Google Inbox was displaying inline images
  as attachments when sent through SendGrid.)
2016-03-11 19:14:11 -08:00
medmunds
7920a4537c Docs: Clarify AnymailMessage not required 2016-03-10 16:57:26 -08:00
medmunds
1e80c3ec37 Invert unsupported-features setting
Change from UNSUPPORTED_FEATURE_ERRORS
(default True) to IGNORE_UNSUPPORTED_FEATURES
(default False). Parallels IGNORE_RECIPIENT_STATUS.
2016-03-09 18:47:42 -08:00
medmunds
20c6350140 Update (almost) all the docs 2016-03-09 18:37:11 -08:00