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 Management Interface 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:
from plone import api
try:
mail_host = api.portal.get_tool(name='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 mail_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)