diff --git a/README.md b/README.md
index c99d2d4f..487d5dea 100644
--- a/README.md
+++ b/README.md
@@ -48,6 +48,8 @@ Third party libraries and resources:
* [Mixkit sound](https://mixkit.co/free-sound-effects/notification/) (Mixkit Free License) used as notification sound
* [Lato Font](https://www.latofonts.com/) (OFL) is used as a font in the Web UI
* [GoReleaser](https://goreleaser.com/) (MIT) is used to create releases
+* [go-smtp](https://github.com/emersion/go-smtp) (MIT) is used to receive e-mails
+* [stretchr/testify](https://github.com/stretchr/testify) (MIT) is used for unit and integration tests
* [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) (MIT) is used to provide the persistent message cache
* [Firebase Admin SDK](https://github.com/firebase/firebase-admin-go) (Apache 2.0) is used to send FCM messages
* [github/gemoji](https://github.com/github/gemoji) (MIT) is used for emoji support (specifically the [emoji.json](https://raw.githubusercontent.com/github/gemoji/master/db/emoji.json) file)
diff --git a/cmd/serve.go b/cmd/serve.go
index 3da824fd..5545206f 100644
--- a/cmd/serve.go
+++ b/cmd/serve.go
@@ -22,10 +22,10 @@ var flagsServe = []cli.Flag{
altsrc.NewDurationFlag(&cli.DurationFlag{Name: "cache-duration", Aliases: []string{"b"}, EnvVars: []string{"NTFY_CACHE_DURATION"}, Value: server.DefaultCacheDuration, Usage: "buffer messages for this time to allow `since` requests"}),
altsrc.NewDurationFlag(&cli.DurationFlag{Name: "keepalive-interval", Aliases: []string{"k"}, EnvVars: []string{"NTFY_KEEPALIVE_INTERVAL"}, Value: server.DefaultKeepaliveInterval, Usage: "interval of keepalive messages"}),
altsrc.NewDurationFlag(&cli.DurationFlag{Name: "manager-interval", Aliases: []string{"m"}, EnvVars: []string{"NTFY_MANAGER_INTERVAL"}, Value: server.DefaultManagerInterval, Usage: "interval of for message pruning and stats printing"}),
- altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-sender-addr", Aliases: []string{"smtp-addr"}, EnvVars: []string{"NTFY_SMTP_SENDER_ADDR"}, Usage: "SMTP server address (host:port) for outgoing emails"}),
- altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-sender-user", Aliases: []string{"smtp-user"}, EnvVars: []string{"NTFY_SMTP_SENDER_USER"}, Usage: "SMTP user (if e-mail sending is enabled)"}),
- altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-sender-pass", Aliases: []string{"smtp-pass"}, EnvVars: []string{"NTFY_SMTP_SENDER_PASS"}, Usage: "SMTP password (if e-mail sending is enabled)"}),
- altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-sender-from", Aliases: []string{"smtp-from"}, EnvVars: []string{"NTFY_SMTP_SENDER_FROM"}, Usage: "SMTP sender address (if e-mail sending is enabled)"}),
+ altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-sender-addr", EnvVars: []string{"NTFY_SMTP_SENDER_ADDR"}, Usage: "SMTP server address (host:port) for outgoing emails"}),
+ altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-sender-user", EnvVars: []string{"NTFY_SMTP_SENDER_USER"}, Usage: "SMTP user (if e-mail sending is enabled)"}),
+ altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-sender-pass", EnvVars: []string{"NTFY_SMTP_SENDER_PASS"}, Usage: "SMTP password (if e-mail sending is enabled)"}),
+ altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-sender-from", EnvVars: []string{"NTFY_SMTP_SENDER_FROM"}, Usage: "SMTP sender address (if e-mail sending is enabled)"}),
altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-server-listen", EnvVars: []string{"NTFY_SMTP_SERVER_LISTEN"}, Usage: "SMTP server address (ip:port) for incoming emails, e.g. :25"}),
altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-server-domain", EnvVars: []string{"NTFY_SMTP_SERVER_DOMAIN"}, Usage: "SMTP domain for incoming e-mail, e.g. ntfy.sh"}),
altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-server-addr-prefix", EnvVars: []string{"NTFY_SMTP_SERVER_ADDR_PREFIX"}, Usage: "SMTP email address prefix for topics to prevent spam (e.g. 'ntfy-')"}),
@@ -102,7 +102,9 @@ func execServe(c *cli.Context) error {
} else if listenHTTPS != "" && (keyFile == "" || certFile == "") {
return errors.New("if listen-https is set, both key-file and cert-file must be set")
} else if smtpSenderAddr != "" && (baseURL == "" || smtpSenderUser == "" || smtpSenderPass == "" || smtpSenderFrom == "") {
- return errors.New("if smtp-addr is set, base-url, smtp-user, smtp-pass and smtp-from must also be set")
+ return errors.New("if smtp-sender-addr is set, base-url, smtp-sender-user, smtp-sender-pass and smtp-sender-from must also be set")
+ } else if smtpServerListen != "" && smtpServerDomain == "" {
+ return errors.New("if smtp-server-listen is set, smtp-server-domain must also be set")
}
// Run server
diff --git a/docs/config.md b/docs/config.md
index e1d74e27..93d41025 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -36,7 +36,7 @@ Subscribers can retrieve cached messaging using the [`poll=1` parameter](subscri
[`since=` parameter](subscribe/api.md#fetch-cached-messages).
## E-mail notifications
-To allow forwarding messages via e-mail, you can configure an SMTP server for outgoing messages. Once configured,
+To allow forwarding messages via e-mail, you can configure an **SMTP server for outgoing messages**. Once configured,
you can set the `X-Email` header to [send messages via e-mail](publish.md#e-mail-notifications) (e.g.
`curl -d "hi there" -H "X-Email: phil@example.com" ntfy.sh/mytopic`).
@@ -44,13 +44,57 @@ As of today, only SMTP servers with PLAIN auth and STARTLS are supported. To ena
following settings:
* `base-url` is the root URL for the ntfy server; this is needed for e-mail footer
-* `smtp-addr` is the hostname:port of the SMTP server
-* `smtp-user` and `smtp-pass` are the username and password of the SMTP user
-* `smtp-from` is the e-mail address of the sender
+* `smtp-sender-addr` is the hostname:port of the SMTP server
+* `smtp-sender-user` and `smtp-sender-pass` are the username and password of the SMTP user
+* `smtp-sender-from` is the e-mail address of the sender
+
+Here's an example config using [Amazon SES](https://aws.amazon.com/ses/) for outgoing mail (this is how it is
+configured for `ntfy.sh`):
+
+=== "/etc/ntfy/server.yml"
+ ``` yaml
+ base-url: "https://ntfy.sh"
+ smtp-sender-addr: "email-smtp.us-east-2.amazonaws.com:587"
+ smtp-sender-user: "AKIDEADBEEFAFFE12345"
+ smtp-sender-pass: "Abd13Kf+sfAk2DzifjafldkThisIsNotARealKeyOMG."
+ smtp-sender-from: "ntfy@ntfy.sh"
+ ```
Please also refer to the [rate limiting](#rate-limiting) settings below, specifically `visitor-email-limit-burst`
and `visitor-email-limit-burst`. Setting these conservatively is necessary to avoid abuse.
+## E-mail publishing
+To allow publishing messages via e-mail, ntfy can run a lightweight **SMTP server for incoming messages**. Once configured,
+users can [send emails to a topic e-mail address](publish.md#e-mail-publishing) (e.g. `mytopic@ntfy.sh` or
+`myprefix-mytopic@ntfy.sh`) to publish messages to a topic. This is useful for e-mail based integrations such as for
+statuspage.io (though these days most services also support webhooks and HTTP calls).
+
+To configure the SMTP server, you must at least set `smtp-server-listen` and `smtp-server-domain`:
+
+* `smtp-server-listen` defines the IP address and port the SMTP server will listen on, e.g. `:25` or `1.2.3.4:25`
+* `smtp-server-domain` is the e-mail domain, e.g. `ntfy.sh`
+* `smtp-server-addr-prefix` is an optional prefix for the e-mail addresses to prevent spam. If set to `ntfy-`, for instance,
+ only e-mails to `ntfy-$topic@ntfy.sh` will be accepted. If this is not set, all emails to `$topic@ntfy.sh` will be
+ accepted (which may obviously be a spam problem).
+
+Here's an example config (this is how it is configured for `ntfy.sh`):
+
+=== "/etc/ntfy/server.yml"
+ ``` yaml
+ smtp-server-listen: ":25"
+ smtp-server-domain: "ntfy.sh"
+ smtp-server-addr-prefix: "ntfy-"
+ ```
+
+In addition to configuring the ntfy server, you have to create two DNS records (an [MX record](https://en.wikipedia.org/wiki/MX_record)
+and a corresponding A record), so incoming mail will find its way to your server. Here's an example of how `ntfy.sh` is
+configured (in [Amazon Route 53](https://aws.amazon.com/route53/)):
+
+
+
## Behind a proxy (TLS, etc.)
!!! warning
If you are running ntfy behind a proxy, you must set the `behind-proxy` flag. Otherwise, all visitors are
@@ -66,7 +110,7 @@ as opposed to the remote IP address. If the `behind-proxy` flag is not set, all
be counted as one, because from the perspective of the ntfy server, they all share the proxy's IP address.
=== "/etc/ntfy/server.yml"
- ```
+ ``` yaml
# Tell ntfy to use "X-Forwarded-For" to identify visitors
behind-proxy: true
```
diff --git a/docs/publish.md b/docs/publish.md
index 85cfaf86..c75ea941 100644
--- a/docs/publish.md
+++ b/docs/publish.md
@@ -691,6 +691,28 @@ Here's what that looks like in Google Mail:
E-mail notification
+## E-mail publishing
+You can publish messages to a topic via e-mail, i.e. by sending an email to a specific address. For instance, you can
+publish a message to the topic `sometopic` by sending an e-mail to `ntfy-sometopic@ntfy.sh`. This is useful for e-mail
+based integrations such as for statuspage.io (though these days most services also support webhooks and HTTP calls).
+
+Depending on the [server configuration](config.md#e-mail-publishing), the e-mail address format can have a prefix to
+prevent spam on topics. For ntfy.sh, the prefix is configured to `ntfy-`, meaning that the general e-mail address
+format is:
+
+```
+ntfy-$topic@ntfy.sh
+```
+
+As of today, e-mail publishing only supports adding a [message title](#message-title) (the e-mail subject). Tags, priority,
+delay and other features are not supported (yet). Here's an example that will publish a message with the
+title `You've Got Mail` to topic `sometopic` (see [ntfy.sh/sometopic](https://ntfy.sh/sometopic)):
+
+
+
## Advanced features
### Message caching
@@ -846,7 +868,7 @@ but just in case, let's list them all:
|---|---|
| **Message length** | Each message can be up to 512 bytes long. Longer messages are truncated. |
| **Requests** | By default, the server is configured to allow 60 requests at once, and then refills the your allowed requests bucket at a rate of one request per 10 seconds. You can read more about this in the [rate limiting](config.md#rate-limiting) section. |
-| **E-mails** | By default, the server is configured to allow 16 e-mails at once, and then refills the your allowed e-mail bucket at a rate of one per hour. You can read more about this in the [rate limiting](config.md#rate-limiting) section. |
+| **E-mails** | By default, the server is configured to allow sending 16 e-mails at once, and then refills the your allowed e-mail bucket at a rate of one per hour. You can read more about this in the [rate limiting](config.md#rate-limiting) section. |
| **Subscription limits** | By default, the server allows each visitor to keep 30 connections to the server open. |
| **Total number of topics** | By default, the server is configured to allow 5,000 topics. The ntfy.sh server has higher limits though. |
diff --git a/docs/static/img/screenshot-email-publishing-dns.png b/docs/static/img/screenshot-email-publishing-dns.png
new file mode 100644
index 00000000..d67b057a
Binary files /dev/null and b/docs/static/img/screenshot-email-publishing-dns.png differ
diff --git a/docs/static/img/screenshot-email-publishing-gmail.png b/docs/static/img/screenshot-email-publishing-gmail.png
new file mode 100644
index 00000000..0d8a58e8
Binary files /dev/null and b/docs/static/img/screenshot-email-publishing-gmail.png differ
diff --git a/server/server.yml b/server/server.yml
index bc1bd573..847b7d63 100644
--- a/server/server.yml
+++ b/server/server.yml
@@ -60,7 +60,15 @@
# smtp-sender-pass:
# smtp-sender-from:
-# XXXXXXXXXXXXXXXXXXXXxx
+# If enabled, ntfy will launch a lightweight SMTP server for incoming messages. Once configured, users can send
+# emails to a topic e-mail address to publish messages to a topic.
+#
+# - smtp-server-listen defines the IP address and port the SMTP server will listen on, e.g. :25 or 1.2.3.4:25
+# - smtp-server-domain is the e-mail domain, e.g. ntfy.sh
+# - smtp-server-addr-prefix is an optional prefix for the e-mail addresses to prevent spam. If set to "ntfy-",
+# for instance, only e-mails to ntfy-$topic@ntfy.sh will be accepted. If this is not set, all emails to
+# $topic@ntfy.sh will be accepted (which may obviously be a spam problem).
+#
# smtp-server-listen:
# smtp-server-domain:
# smtp-server-addr-prefix: