Generate mails from a template

This commit is contained in:
David Baker 2016-04-20 18:35:29 +01:00
parent 05adc6c2de
commit 2ed0adb075
4 changed files with 49 additions and 31 deletions

View file

@ -28,19 +28,32 @@ class EmailConfig(Config):
email_config = config.get("email", None) email_config = config.get("email", None)
if email_config: if email_config:
self.email_enable_notifs = email_config.get("enable_notifs", True) self.email_enable_notifs = email_config.get("enable_notifs", True)
if (
"smtp_host" not in email_config or required = [
"smtp_port" not in email_config or "smtp_host",
"notif_from" not in email_config "smtp_port",
): "notif_from",
"template_dir",
"notif_template_html",
]
missing = []
for k in required:
if k not in email_config:
missing.append(k)
if (len(missing) > 0):
raise RuntimeError( raise RuntimeError(
"You must set smtp_host, smtp_port and notif_from " "email.enable_notifs is True but required keys are missing: %s" %
"to send email notifications" (", ".join(["email."+k for k in missing]),)
) )
self.email_smtp_host = email_config["smtp_host"] self.email_smtp_host = email_config["smtp_host"]
self.email_smtp_port = email_config["smtp_port"] self.email_smtp_port = email_config["smtp_port"]
self.email_notif_from = email_config["notif_from"] self.email_notif_from = email_config["notif_from"]
self.email_template_dir = email_config["template_dir"]
self.email_notif_template_html = email_config["notif_template_html"]
# make sure it's valid # make sure it's valid
parsed = email.utils.parseaddr(self.email_notif_from) parsed = email.utils.parseaddr(self.email_notif_from)
@ -48,9 +61,8 @@ class EmailConfig(Config):
raise RuntimeError("Invalid notif_from address") raise RuntimeError("Invalid notif_from address")
else: else:
self.email_enable_notifs = False self.email_enable_notifs = False
self.email_smtp_host = None # Not much point setting defaults for the rest: it would be an
self.email_smtp_port = None # error for them to be used.
self.email_notif_from = None
def default_config(self, config_dir_path, server_name, **kwargs): def default_config(self, config_dir_path, server_name, **kwargs):
return """ return """
@ -59,4 +71,7 @@ class EmailConfig(Config):
# enable_notifs: false # enable_notifs: false
# smtp_host: "localhost" # smtp_host: "localhost"
# smtp_port: 25 # smtp_port: 25
# notif_from: Your Friendly Matrix Home Server <noreply@example.com>
# template_dir: res/templates
# notif_template_html: notif.html
""" """

View file

@ -61,11 +61,7 @@ class EmailPusher(object):
self.processing = False self.processing = False
if self.hs.config.email_enable_notifs: if self.hs.config.email_enable_notifs:
self.mailer = Mailer( self.mailer = Mailer(self.hs)
self.store,
self.hs.config.email_smtp_host, self.hs.config.email_smtp_port,
self.hs.config.email_notif_from,
)
else: else:
self.mailer = None self.mailer = None
@ -149,7 +145,7 @@ class EmailPusher(object):
# *one* email updating the user on their notifications, # *one* email updating the user on their notifications,
# we then consider all previously outstanding notifications # we then consider all previously outstanding notifications
# to be delivered. # to be delivered.
yield self.send_notification(push_action) yield self.send_notification(unprocessed)
yield self.save_last_stream_ordering_and_success(max([ yield self.save_last_stream_ordering_and_success(max([
ea['stream_ordering'] for ea in unprocessed ea['stream_ordering'] for ea in unprocessed
@ -252,8 +248,8 @@ class EmailPusher(object):
) )
@defer.inlineCallbacks @defer.inlineCallbacks
def send_notification(self, push_action): def send_notification(self, push_actions):
logger.info("Sending notif email for user %r", self.user_id) logger.info("Sending notif email for user %r", self.user_id)
yield self.mailer.send_notification_mail( yield self.mailer.send_notification_mail(
self.user_id, self.email, push_action self.user_id, self.email, push_actions
) )

View file

@ -15,34 +15,38 @@
from twisted.internet import defer from twisted.internet import defer
import smtplib from twisted.mail.smtp import sendmail
import email.utils import email.utils
import email.mime.multipart import email.mime.multipart
from email.mime.text import MIMEText from email.mime.text import MIMEText
import jinja2
class Mailer(object): class Mailer(object):
def __init__(self, store, smtp_host, smtp_port, notif_from): def __init__(self, hs):
self.store = store self.hs = hs
self.smtp_host = smtp_host loader = jinja2.FileSystemLoader(self.hs.config.email_template_dir)
self.smtp_port = smtp_port env = jinja2.Environment(loader=loader)
self.notif_from = notif_from self.notif_template = env.get_template(self.hs.config.email_notif_template_html)
@defer.inlineCallbacks @defer.inlineCallbacks
def send_notification_mail(self, user_id, email_address, push_action): def send_notification_mail(self, user_id, email_address, push_actions):
raw_from = email.utils.parseaddr(self.notif_from)[1] raw_from = email.utils.parseaddr(self.hs.config.email_notif_from)[1]
raw_to = email.utils.parseaddr(email_address)[1] raw_to = email.utils.parseaddr(email_address)[1]
if raw_to == '': if raw_to == '':
raise RuntimeError("Invalid 'to' address") raise RuntimeError("Invalid 'to' address")
plainText = "yo dawg, you got notifications!" plainText = self.notif_template.render()
text_part = MIMEText(plainText, "plain") text_part = MIMEText(plainText, "plain")
text_part['Subject'] = "New Matrix Notifications" text_part['Subject'] = "New Matrix Notifications"
text_part['From'] = self.notif_from text_part['From'] = self.hs.config.email_notif_from
text_part['To'] = email_address text_part['To'] = email_address
smtp = smtplib.SMTP(self.smtp_host, self.smtp_port) yield sendmail(
smtp.sendmail(raw_from, raw_to, text_part.as_string()) self.hs.config.email_smtp_host,
smtp.quit() raw_from, raw_to, text_part.as_string(),
port=self.hs.config.email_smtp_port
)

View file

@ -45,6 +45,9 @@ CONDITIONAL_REQUIREMENTS = {
"preview_url": { "preview_url": {
"netaddr>=0.7.18": ["netaddr"], "netaddr>=0.7.18": ["netaddr"],
}, },
"email.enable_notifs": {
"Jinja2": ["Jinja2"],
},
} }