2019-07-05 17:33:48 +02:00
|
|
|
# Incoming email integration
|
|
|
|
|
|
|
|
Zulip's incoming email gateway integration makes it possible to send
|
2021-08-20 21:53:28 +02:00
|
|
|
messages into Zulip by sending an email. It's highly recommended
|
2019-07-05 17:33:48 +02:00
|
|
|
because it enables:
|
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- When users reply to one of Zulip's message notification emails
|
2021-04-20 23:27:25 +02:00
|
|
|
from their email client, the reply can go directly
|
2019-07-05 17:33:48 +02:00
|
|
|
into Zulip.
|
2021-08-20 21:45:39 +02:00
|
|
|
- Integrating third-party services that can send email notifications
|
2021-08-20 21:53:28 +02:00
|
|
|
into Zulip. See the [integration
|
2020-06-08 23:04:39 +02:00
|
|
|
documentation](https://zulip.com/integrations/doc/email) for
|
2019-07-05 17:33:48 +02:00
|
|
|
details.
|
|
|
|
|
2019-07-10 22:44:06 +02:00
|
|
|
Once this integration is configured, each stream will have a special
|
2021-08-20 21:53:28 +02:00
|
|
|
email address displayed on the stream settings page. Emails sent to
|
2019-07-05 17:33:48 +02:00
|
|
|
that address will be delivered into the stream.
|
|
|
|
|
2019-07-10 22:44:06 +02:00
|
|
|
There are two ways to configure Zulip's email gateway:
|
2019-07-05 17:33:48 +02:00
|
|
|
|
2021-08-20 22:54:08 +02:00
|
|
|
1. Local delivery (recommended): A postfix server runs on the Zulip
|
|
|
|
server and passes the emails directly to Zulip.
|
|
|
|
1. Polling: A cron job running on the Zulip server checks an IMAP
|
|
|
|
inbox (`username@example.com`) every minute for new emails.
|
2019-07-05 17:33:48 +02:00
|
|
|
|
|
|
|
The local delivery configuration is preferred for production because
|
2021-08-20 21:53:28 +02:00
|
|
|
it supports nicer looking email addresses and has no cron delay. The
|
2019-07-05 17:33:48 +02:00
|
|
|
polling option is convenient for testing/developing this feature
|
2023-06-07 16:40:42 +02:00
|
|
|
because it doesn't require a public IP address, setting up MX
|
|
|
|
records in DNS, or adjusting firewalls.
|
2019-07-05 17:33:48 +02:00
|
|
|
|
2021-08-10 07:55:12 +02:00
|
|
|
:::{note}
|
|
|
|
Incoming emails are rate-limited, with the following limits:
|
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- 50 emails per minute.
|
|
|
|
- 120 emails per 5 minutes.
|
|
|
|
- 600 emails per hour.
|
2021-08-20 21:39:32 +02:00
|
|
|
|
2021-08-10 07:55:12 +02:00
|
|
|
:::
|
2021-02-27 08:19:13 +01:00
|
|
|
|
2019-07-05 17:33:48 +02:00
|
|
|
## Local delivery setup
|
|
|
|
|
2020-10-23 02:43:28 +02:00
|
|
|
Zulip's Puppet configuration provides everything needed to run this
|
2019-07-11 23:01:29 +02:00
|
|
|
integration; you just need to enable and configure it as follows.
|
2019-07-05 17:33:48 +02:00
|
|
|
|
2019-07-11 23:01:29 +02:00
|
|
|
The main decision you need to make is what email domain you want to
|
|
|
|
use for the gateway; for this discussion we'll use
|
2021-08-20 21:53:28 +02:00
|
|
|
`emaildomain.example.com`. The email addresses used by the gateway
|
2019-07-11 23:01:29 +02:00
|
|
|
will look like `foo@emaildomain.example.com`, so we recommend using
|
|
|
|
`EXTERNAL_HOST` here.
|
|
|
|
|
|
|
|
We will use `hostname.example.com` as the hostname of the Zulip server
|
|
|
|
(this will usually also be the same as `EXTERNAL_HOST`, unless you are
|
|
|
|
using an [HTTP reverse proxy][reverse-proxy]).
|
|
|
|
|
|
|
|
1. Using your DNS provider, create a DNS MX (mail exchange) record
|
|
|
|
configuring email for `emaildomain.example.com` to be processed by
|
2021-08-20 21:53:28 +02:00
|
|
|
`hostname.example.com`. You can check your work using this command:
|
2019-07-05 17:33:48 +02:00
|
|
|
|
2021-08-20 22:54:08 +02:00
|
|
|
```console
|
|
|
|
$ dig +short emaildomain.example.com -t MX
|
|
|
|
1 hostname.example.com
|
|
|
|
```
|
2019-07-05 17:33:48 +02:00
|
|
|
|
2023-06-07 16:40:42 +02:00
|
|
|
1. If you have a network firewall enabled, configure it to allow incoming access
|
|
|
|
to port 25 on the Zulip server from the public internet. Other mail servers
|
|
|
|
will need to use it to deliver emails to Zulip.
|
|
|
|
|
2020-08-11 02:20:10 +02:00
|
|
|
1. Log in to your Zulip server; the remaining steps all happen there.
|
2019-07-05 17:33:48 +02:00
|
|
|
|
2019-07-11 23:01:29 +02:00
|
|
|
1. Add `, zulip::postfix_localmail` to `puppet_classes` in
|
2021-08-20 21:53:28 +02:00
|
|
|
`/etc/zulip/zulip.conf`. A typical value after this change is:
|
2021-08-20 22:54:08 +02:00
|
|
|
|
2021-08-20 07:09:04 +02:00
|
|
|
```ini
|
2020-10-20 03:49:23 +02:00
|
|
|
puppet_classes = zulip::profile::standalone, zulip::postfix_localmail
|
2019-07-11 23:01:29 +02:00
|
|
|
```
|
|
|
|
|
2021-08-20 22:54:08 +02:00
|
|
|
1. If `hostname.example.com` is different from
|
2019-07-11 23:01:29 +02:00
|
|
|
`emaildomain.example.com`, add a section to `/etc/zulip/zulip.conf`
|
|
|
|
on your Zulip server like this:
|
2019-07-05 17:33:48 +02:00
|
|
|
|
2021-08-20 22:54:08 +02:00
|
|
|
```ini
|
|
|
|
[postfix]
|
|
|
|
mailname = emaildomain.example.com
|
|
|
|
```
|
2019-07-05 17:33:48 +02:00
|
|
|
|
2023-01-17 21:22:44 +01:00
|
|
|
This tells postfix to expect to receive emails at addresses ending with
|
|
|
|
`@emaildomain.example.com`, overriding the default of
|
|
|
|
`@hostname.example.com`. It will also identify itself as
|
|
|
|
`emaildomain.example.com` on any outgoing emails it sends.
|
2019-07-05 17:33:48 +02:00
|
|
|
|
|
|
|
1. Run `/home/zulip/deployments/current/scripts/zulip-puppet-apply`
|
|
|
|
(and answer `y`) to apply your new `/etc/zulip/zulip.conf`
|
|
|
|
configuration to your Zulip server.
|
|
|
|
|
|
|
|
1. Edit `/etc/zulip/settings.py`, and set `EMAIL_GATEWAY_PATTERN`
|
2019-07-11 23:01:29 +02:00
|
|
|
to `"%s@emaildomain.example.com"`.
|
2019-07-05 17:33:48 +02:00
|
|
|
|
|
|
|
1. Restart your Zulip server with
|
|
|
|
`/home/zulip/deployments/current/scripts/restart-server`.
|
|
|
|
|
2021-08-20 21:53:28 +02:00
|
|
|
Congratulations! The integration should be fully operational.
|
2019-07-05 17:33:48 +02:00
|
|
|
|
2022-02-16 01:39:15 +01:00
|
|
|
[reverse-proxy]: deployment.md#putting-the-zulip-application-behind-a-reverse-proxy
|
2019-07-05 17:33:48 +02:00
|
|
|
|
|
|
|
## Polling setup
|
|
|
|
|
2019-07-10 22:44:06 +02:00
|
|
|
1. Create an email account dedicated to Zulip's email gateway
|
2021-08-20 22:54:08 +02:00
|
|
|
messages. We assume the address is of the form
|
|
|
|
`username@example.com`. The email provider needs to support the
|
|
|
|
standard model of delivering emails sent to
|
|
|
|
`username+stuff@example.com` to the `username@example.com` inbox.
|
2019-07-05 17:33:48 +02:00
|
|
|
|
|
|
|
1. Edit `/etc/zulip/settings.py`, and set `EMAIL_GATEWAY_PATTERN` to
|
|
|
|
`"username+%s@example.com"`.
|
|
|
|
|
|
|
|
1. Set up IMAP for your email account and obtain the authentication details.
|
2021-08-20 22:54:08 +02:00
|
|
|
([Here's how it works with Gmail](https://support.google.com/mail/answer/7126229?hl=en))
|
2019-07-05 17:33:48 +02:00
|
|
|
|
|
|
|
1. Configure IMAP access in the appropriate Zulip settings:
|
2021-08-20 22:54:08 +02:00
|
|
|
|
|
|
|
- Login and server connection details in `/etc/zulip/settings.py`
|
|
|
|
in the email gateway integration section (`EMAIL_GATEWAY_LOGIN` and others).
|
|
|
|
- Password in `/etc/zulip/zulip-secrets.conf` as `email_gateway_password`.
|
2019-07-05 17:33:48 +02:00
|
|
|
|
2021-10-14 23:46:00 +02:00
|
|
|
1. Test your configuration by sending emails to the target email
|
|
|
|
account and then running the Zulip tool to poll that inbox:
|
|
|
|
|
2023-05-31 01:18:00 +02:00
|
|
|
```bash
|
2021-10-14 23:46:00 +02:00
|
|
|
su zulip -c '/home/zulip/deployments/current/manage.py email_mirror'
|
|
|
|
```
|
|
|
|
|
2022-01-20 14:02:17 +01:00
|
|
|
1. Once everything is working, install the cron job which will poll
|
2021-10-14 23:46:00 +02:00
|
|
|
the inbox every minute for new messages using the tool you tested
|
|
|
|
in the last step:
|
2021-08-20 22:54:08 +02:00
|
|
|
```bash
|
|
|
|
cd /home/zulip/deployments/current/
|
|
|
|
sudo cp puppet/zulip/files/cron.d/email-mirror /etc/cron.d/
|
|
|
|
```
|
2019-07-05 17:33:48 +02:00
|
|
|
|
2021-08-20 21:53:28 +02:00
|
|
|
Congratulations! The integration should be fully operational.
|