Sending email¶
Description
How to programmatically send email in Plone
Introduction¶
This document tells how to send email from Plone.
Email can be sent:
- manually, by calling MailHost;
- using a Content Rule (content rules have an email-out action by default) which can be activated by a workflow transition, for example;
- triggering email-based password reset.
Configuring MailHost for a mail queue¶
Products.MailHost supports asynchronous sending in a separate thread via a mail queue.
Note
Using a mail queue is recommended for production sites.
To enable the queue, go to the ZMI and the MailHost tool. Here, check the "Use mail queue" setting and set the "Queue directory". The queue directory is given as an absolute path on your server, must have a maildir layout (it needs the directories 'cur', new' and 'tmp' in it) and must be writeable by the system user, under which the Zope thread runs.
Manually calling MailHost¶
After your
mail_text
is prepared, sending it is as simple as:
try:
host = getToolByName(self, 'MailHost')
# The ``immediate`` parameter causes an email to be sent immediately
# (if any error is raised) rather than sent at the transaction
# boundary or queued for later delivery.
return host.send(mail_text, immediate=True)
except SMTPRecipientsRefused:
# Don't disclose email address on failure
raise SMTPRecipientsRefused('Recipient address rejected by server')
Preparing mail text¶
mail_text
can be generated by calling a page template (.pt
) with keyword arguments. The values are accessed in
the template as
option/keyword
. For example, take a sample template:
<tal:root define="lt string:<;
gt string:>;
dummy python:request.RESPONSE.setHeader('Content-Type', 'text/plain;; charset=%s' % options['charset']);
member python:options['member'];"
>From: "<span tal:replace="python:here.email_from_name" />" <span tal:replace="structure lt"/><span tal:replace="python:here.email_from_address" /><span tal:replace="structure gt"/>
To: <span tal:replace="python:member.getProperty('email')" />
Subject: <span i18n:domain="yourproduct" i18n:translate="yoursubjectline" tal:omit-tag="">Subject Line</span>
Content-Type: text/plain; charset=<span tal:replace="python:options['charset']" />
Dear <span tal:replace="member/getFullname" />:
You can now log in as <span tal:replace="member/getId" /> at <span tal:replace="python:options['portal_url']" />
Cheers!
The website team
</tal:root>
This can be called with a
member
object and the
portal_url
:
mail_template = portal.mail_template_id
mail_text = mail_template(member=member,
portal_url=portal.absolute_url(),
charset=email_charset,
request=REQUEST)
For more complete examples (with i18n support, etc.) see
the password reset modules (particularly
Products.remember.tools.registration
).
Note
If you don't need to have third parties to override your email templates it might be cleaned to use Python string templates, as XML based TAL templates are not designed for plain text templating.
Graceful failing¶
In the case SMTP server rejects the connection. etc. don't abort the current transaction (which is the default behavior)