2017-06-11 06:54:18 +02:00
|
|
|
|
# Email
|
|
|
|
|
|
|
|
|
|
This page has developer documentation on the Zulip email system. If you're
|
|
|
|
|
trying to configure your server to send email, you might be looking for our
|
2017-11-08 17:55:36 +01:00
|
|
|
|
guide to [sending outgoing email](../production/email.html). If you're trying to
|
2017-06-11 06:54:18 +02:00
|
|
|
|
configure an email integration to receive incoming email (e.g. so that users
|
|
|
|
|
can reply to missed message emails via email), you might be interested in
|
|
|
|
|
our instructions for
|
2017-07-25 03:15:21 +02:00
|
|
|
|
[setting up an email integration](https://zulipchat.com/integrations/doc/email).
|
2017-06-11 06:54:18 +02:00
|
|
|
|
|
|
|
|
|
On to the documentation. Zulip's email system is fairly straightforward,
|
|
|
|
|
with only a few things you need to know to get started.
|
|
|
|
|
|
|
|
|
|
* All email templates are in `templates/zerver/emails/`. Each email has three
|
|
|
|
|
template files: `<template_prefix>.subject`, `<template_prefix>.txt`, and
|
2018-04-25 00:30:05 +02:00
|
|
|
|
`<template_prefix>.source.html`. Email templates, along with all other templates
|
2017-06-11 06:54:18 +02:00
|
|
|
|
in the `templates/` directory, are Jinja2 templates.
|
|
|
|
|
* Most of the CSS and HTML layout for emails is in `email_base.html`. Note
|
|
|
|
|
that email has to ship with all of its CSS and HTML, so nothing in
|
|
|
|
|
`static/` is useful for an email. If you're adding new CSS or HTML for an
|
|
|
|
|
email, there's a decent chance it should go in `email_base.html`.
|
|
|
|
|
* All email is eventually sent by `zerver.lib.send_email.send_email`. There
|
|
|
|
|
are several other functions in `zerver.lib.send_email`, but all of them
|
|
|
|
|
eventually call the `send_email` function. The most interesting one is
|
2017-07-02 21:10:41 +02:00
|
|
|
|
`send_future_email`. The `ScheduledEmail` entries are eventually processed
|
2017-08-04 00:46:34 +02:00
|
|
|
|
by a supervisor job that runs `zerver/management/commands/deliver_email.py`.
|
2017-06-11 06:54:18 +02:00
|
|
|
|
* A good way to find a bunch of example email pathways is to `git grep` for
|
|
|
|
|
`zerver/emails` in the `zerver/` directory.
|
|
|
|
|
|
|
|
|
|
One slightly complicated decision you may have to make when adding an email
|
|
|
|
|
is figuring out how to schedule it. There are 3 ways to schedule email.
|
|
|
|
|
* Send it immediately, in the current Django process, e.g. by calling
|
|
|
|
|
`send_email` directly. An example of this is the `confirm_registration`
|
|
|
|
|
email.
|
|
|
|
|
* Add it to a queue. An example is the `invitation` email.
|
|
|
|
|
* Send it (approximately) at a specified time in the future, using
|
|
|
|
|
`send_future_email`. An example is the `followup_day2` email.
|
|
|
|
|
|
|
|
|
|
Email takes about a quarter second per email to process and send. Generally
|
|
|
|
|
speaking, if you're sending just one email, doing it in the current process
|
|
|
|
|
is fine. If you're sending emails in a loop, you probably want to send it
|
|
|
|
|
from a queue. Documentation on our queueing system is available
|
2017-11-08 17:55:36 +01:00
|
|
|
|
[here](../subsystems/queuing.html).
|
2017-06-11 06:54:18 +02:00
|
|
|
|
|
2017-10-04 20:36:40 +02:00
|
|
|
|
## Development and testing
|
2017-06-11 06:54:18 +02:00
|
|
|
|
|
2017-10-04 20:36:40 +02:00
|
|
|
|
All the emails sent in the development environment can be accessed by
|
|
|
|
|
visiting `/emails` in the browser. The way that this works is that
|
|
|
|
|
we've set the email backend (aka what happens when you call the email
|
|
|
|
|
`.send()` method in Django) in the development environment to be our
|
|
|
|
|
our custom backend, `EmailLogBackEnd`. It does the following:
|
|
|
|
|
|
|
|
|
|
* Logs any sent emails to `var/log/email_content.log`. This log is
|
|
|
|
|
displayed by the `/emails` endpoint
|
|
|
|
|
(e.g. http://zulip.zulipdev.com:9991/emails).
|
|
|
|
|
* Print a friendly message on console advertising `/emails` to make
|
|
|
|
|
this nice and discoverable.
|
|
|
|
|
|
2017-10-25 01:58:05 +02:00
|
|
|
|
You can also forward all the emails sent in the development environment
|
|
|
|
|
to an email id of your choice by clicking on **Forward emails to a mail
|
|
|
|
|
account** in `/emails` page. This feature can be used for testing how
|
|
|
|
|
emails gets rendered by different email clients. Before enabling this
|
|
|
|
|
you have to first configure the following SMTP settings.
|
|
|
|
|
|
|
|
|
|
* The hostname `EMAIL_HOST` in `zproject/dev_settings.py`
|
|
|
|
|
* The username `EMAIL_HOST_USER` in `zproject/dev_settings.py`.
|
|
|
|
|
* The password `email_password` in `zproject/dev-secrets.conf`.
|
|
|
|
|
|
2017-11-08 17:55:36 +01:00
|
|
|
|
See [this](../production/email.html#free-outgoing-email-services)
|
2017-10-25 01:58:05 +02:00
|
|
|
|
section for instructions on obtaining SMTP details.
|
|
|
|
|
|
|
|
|
|
**Note: The base_image_uri of the images in forwarded emails would be replaced
|
|
|
|
|
with `https://chat.zulip.org/static/images/emails` inorder for the email clients
|
|
|
|
|
to render the images. See `zproject/email_backends.py` for more details.**
|
|
|
|
|
|
2017-10-04 20:36:40 +02:00
|
|
|
|
While running the backend test suite, we use
|
|
|
|
|
`django.core.mail.backends.locmem.EmailBackend` as the email
|
|
|
|
|
backend. The `locmem` backend stores messages in a special attribute
|
|
|
|
|
of the django.core.mail module, "outbox". The outbox attribute is
|
|
|
|
|
created when the first message is sent. It’s a list with an
|
|
|
|
|
EmailMessage instance for each message that would be sent.
|
2018-04-25 00:30:05 +02:00
|
|
|
|
|
|
|
|
|
Other notes:
|
|
|
|
|
* After changing any HTML email or `email_base.html`, you need to run
|
|
|
|
|
`tools/inline-email-css` for the changes to be reflected in the dev
|
|
|
|
|
environment. The script generates files like
|
|
|
|
|
`templates/zerver/emails/compiled/<template_prefix>.html`.
|