Almost read to publish
This commit is contained in:
parent
4fcb3891a2
commit
0f495b881a
25 changed files with 229 additions and 70 deletions
|
@ -21,7 +21,7 @@ If desired, ntfy can temporarily keep notifications in an in-memory or an on-dis
|
||||||
of time is important to allow [phones](subscribe/phone.md) and other devices with brittle Internet connections to be able to retrieve
|
of time is important to allow [phones](subscribe/phone.md) and other devices with brittle Internet connections to be able to retrieve
|
||||||
notifications that they may have missed.
|
notifications that they may have missed.
|
||||||
|
|
||||||
By default, ntfy keeps messages in memory for 12 hours, which means that **cached messages do not survive an application
|
By default, ntfy keeps messages **in-memory for 12 hours**, which means that **cached messages do not survive an application
|
||||||
restart**. You can override this behavior using the following config settings:
|
restart**. You can override this behavior using the following config settings:
|
||||||
|
|
||||||
* `cache-file`: if set, ntfy will store messages in a SQLite based cache (default is empty, which means in-memory cache).
|
* `cache-file`: if set, ntfy will store messages in a SQLite based cache (default is empty, which means in-memory cache).
|
||||||
|
@ -29,7 +29,7 @@ restart**. You can override this behavior using the following config settings:
|
||||||
* `cache-duration`: defines the duration for which messages are stored in the cache (default is `12h`)
|
* `cache-duration`: defines the duration for which messages are stored in the cache (default is `12h`)
|
||||||
|
|
||||||
Subscribers can retrieve cached messaging using the [`poll=1` parameter](subscribe/api.md#polling), as well as the
|
Subscribers can retrieve cached messaging using the [`poll=1` parameter](subscribe/api.md#polling), as well as the
|
||||||
[`since=` parameter](subscribe/api.md#since).
|
[`since=` parameter](subscribe/api.md#fetching-cached-messages).
|
||||||
|
|
||||||
## Behind a proxy (TLS, etc.)
|
## Behind a proxy (TLS, etc.)
|
||||||
|
|
||||||
|
@ -42,27 +42,27 @@ flag. This will instruct the [rate limiting](#rate-limiting) logic to use the `X
|
||||||
identifier for a visitor, as opposed to the remote IP address. If the `behind-proxy` flag is not set, all visitors will
|
identifier for a visitor, as opposed to the remote IP address. If the `behind-proxy` flag is not set, all visitors will
|
||||||
be counted as one, because from the perspective of the ntfy server, they all share the proxy's IP address.
|
be counted as one, because from the perspective of the ntfy server, they all share the proxy's IP address.
|
||||||
|
|
||||||
**TLS/SSL:** ntfy supports HTTPS/TLS by setting the `listen-https` config option. However, if you are behind a proxy, it is
|
**TLS/SSL:** ntfy supports HTTPS/TLS by setting the `listen-https` [config option](#config-options). However, if you
|
||||||
recommended that TLS/SSL termination is done by the proxy itself.
|
are behind a proxy, it is recommended that TLS/SSL termination is done by the proxy itself.
|
||||||
|
|
||||||
## Firebase (FCM)
|
## Firebase (FCM)
|
||||||
!!! info
|
!!! info
|
||||||
Using Firebase is **optional** and only works if you modify and build your own Android .apk.
|
Using Firebase is **optional** and only works if you modify and [build your own Android .apk](develop.md#android-app).
|
||||||
For a self-hosted instance, it's easier to just not bother with FCM.
|
For a self-hosted instance, it's easier to just not bother with FCM.
|
||||||
|
|
||||||
[Firebase Cloud Messaging (FCM)](https://firebase.google.com/docs/cloud-messaging) is the Google approved way to send
|
[Firebase Cloud Messaging (FCM)](https://firebase.google.com/docs/cloud-messaging) is the Google approved way to send
|
||||||
push messages to Android devices. FCM is the only method that an Android app can receive messages without having to run a
|
push messages to Android devices. FCM is the only method that an Android app can receive messages without having to run a
|
||||||
[foreground service](https://developer.android.com/guide/components/foreground-services).
|
[foreground service](https://developer.android.com/guide/components/foreground-services).
|
||||||
|
|
||||||
For the main host [ntfy.sh](https://ntfy.sh), the [ntfy Android App](subscribe/phone.md) uses Firebase to send messages
|
For the main host [ntfy.sh](https://ntfy.sh), the [ntfy Android app](subscribe/phone.md) uses Firebase to send messages
|
||||||
to the device. For other hosts, instant delivery is used and FCM is not involved.
|
to the device. For other hosts, instant delivery is used and FCM is not involved.
|
||||||
|
|
||||||
To configure FCM for your self-hosted instance of the ntfy server, follow these steps:
|
To configure FCM for your self-hosted instance of the ntfy server, follow these steps:
|
||||||
|
|
||||||
1. Sign up for a [Firebase account](https://console.firebase.google.com/)
|
1. Sign up for a [Firebase account](https://console.firebase.google.com/)
|
||||||
2. Create an app and download the key file (e.g. `myapp-firebase-adminsdk-ahnce-....json`)
|
2. Create a Firebase app and download the key file (e.g. `myapp-firebase-adminsdk-...json`)
|
||||||
3. Place the key file in `/etc/ntfy`, set the `firebase-key-file` in `config.yml` accordingly and restart the ntfy server
|
3. Place the key file in `/etc/ntfy`, set the `firebase-key-file` in `config.yml` accordingly and restart the ntfy server
|
||||||
4. Build your own Android .apk following [these instructions]()
|
4. Build your own Android .apk following [these instructions](develop.md#android-app)
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```
|
```
|
||||||
|
@ -100,7 +100,7 @@ During normal usage, you shouldn't encounter this limit at all, and even if you
|
||||||
reconnect after a connection drop), it shouldn't have any effect.
|
reconnect after a connection drop), it shouldn't have any effect.
|
||||||
|
|
||||||
## Config options
|
## Config options
|
||||||
Each config options can be set in the config file `/etc/ntfy/config.yml` (e.g. `listen-http: :80`) or as a
|
Each config option can be set in the config file `/etc/ntfy/config.yml` (e.g. `listen-http: :80`) or as a
|
||||||
CLI option (e.g. `--listen-http :80`. Here's a list of all available options. Alternatively, you can set an environment
|
CLI option (e.g. `--listen-http :80`. Here's a list of all available options. Alternatively, you can set an environment
|
||||||
variable before running the `ntfy` command (e.g. `export NTFY_LISTEN_HTTP=:80`).
|
variable before running the `ntfy` command (e.g. `export NTFY_LISTEN_HTTP=:80`).
|
||||||
|
|
||||||
|
@ -110,8 +110,8 @@ variable before running the `ntfy` command (e.g. `export NTFY_LISTEN_HTTP=:80`).
|
||||||
| `listen-https` | `NTFY_LISTEN_HTTPS` | `[host]:port` | - | Listen address for the HTTPS web server. If set, you also need to set `key-file` and `cert-file`. |
|
| `listen-https` | `NTFY_LISTEN_HTTPS` | `[host]:port` | - | Listen address for the HTTPS web server. If set, you also need to set `key-file` and `cert-file`. |
|
||||||
| `key-file` | `NTFY_KEY_FILE` | *filename* | - | HTTPS/TLS private key file, only used if `listen-https` is set. |
|
| `key-file` | `NTFY_KEY_FILE` | *filename* | - | HTTPS/TLS private key file, only used if `listen-https` is set. |
|
||||||
| `cert-file` | `NTFY_CERT_FILE` | *filename* | - | HTTPS/TLS certificate file, only used if `listen-https` is set. |
|
| `cert-file` | `NTFY_CERT_FILE` | *filename* | - | HTTPS/TLS certificate file, only used if `listen-https` is set. |
|
||||||
| `firebase-key-file` | `NTFY_FIREBASE_KEY_FILE` | *filename* | - | If set, also publish messages to a Firebase Cloud Messaging (FCM) topic for your app. This is optional and only required to save battery when using the Android app. |
|
| `firebase-key-file` | `NTFY_FIREBASE_KEY_FILE` | *filename* | - | If set, also publish messages to a Firebase Cloud Messaging (FCM) topic for your app. This is optional and only required to save battery when using the Android app. See [Firebase (FCM](#firebase-fcm). |
|
||||||
| `cache-file` | `NTFY_CACHE_FILE` | *filename* | - | If set, messages are cached in a local SQLite database instead of only in-memory. This allows for service restarts without losing messages in support of the since= parameter. |
|
| `cache-file` | `NTFY_CACHE_FILE` | *filename* | - | If set, messages are cached in a local SQLite database instead of only in-memory. This allows for service restarts without losing messages in support of the since= parameter. See [message cache](#message-cache). |
|
||||||
| `cache-duration` | `NTFY_CACHE_DURATION` | *duration* | 12h | Duration for which messages will be buffered before they are deleted. This is required to support the `since=...` and `poll=1` parameter. |
|
| `cache-duration` | `NTFY_CACHE_DURATION` | *duration* | 12h | Duration for which messages will be buffered before they are deleted. This is required to support the `since=...` and `poll=1` parameter. |
|
||||||
| `keepalive-interval` | `NTFY_KEEPALIVE_INTERVAL` | *duration* | 30s | Interval in which keepalive messages are sent to the client. This is to prevent intermediaries closing the connection for inactivity. Note that the Android app has a hardcoded timeout at 77s, so it should be less than that. |
|
| `keepalive-interval` | `NTFY_KEEPALIVE_INTERVAL` | *duration* | 30s | Interval in which keepalive messages are sent to the client. This is to prevent intermediaries closing the connection for inactivity. Note that the Android app has a hardcoded timeout at 77s, so it should be less than that. |
|
||||||
| `manager-interval` | `$NTFY_MANAGER_INTERVAL` | *duration* | 1m | Interval in which the manager prunes old messages, deletes topics and prints the stats. |
|
| `manager-interval` | `$NTFY_MANAGER_INTERVAL` | *duration* | 1m | Interval in which the manager prunes old messages, deletes topics and prints the stats. |
|
||||||
|
|
|
@ -18,7 +18,7 @@ rsync -a root@laptop /backups/laptop \
|
||||||
|
|
||||||
## Server-sent messages in your web app
|
## Server-sent messages in your web app
|
||||||
Just as you can [subscribe to topics in the Web UI](subscribe/web.md), you can use ntfy in your own
|
Just as you can [subscribe to topics in the Web UI](subscribe/web.md), you can use ntfy in your own
|
||||||
web application. Check out the <a href="example.html">live example</a> or just look the source of this page.
|
web application. Check out the <a href="/example.html">live example</a> or just look the source of this page.
|
||||||
|
|
||||||
## Notify on SSH login
|
## Notify on SSH login
|
||||||
Years ago my home server was broken into. That shook me hard, so every time someone logs into any machine that I
|
Years ago my home server was broken into. That shook me hard, so every time someone logs into any machine that I
|
||||||
|
|
19
docs/faq.md
19
docs/faq.md
|
@ -22,23 +22,24 @@ client network disruptions.
|
||||||
|
|
||||||
## Can I self-host it?
|
## Can I self-host it?
|
||||||
Yes. The server (including this Web UI) can be self-hosted, and the Android app supports adding topics from
|
Yes. The server (including this Web UI) can be self-hosted, and the Android app supports adding topics from
|
||||||
your own server as well. There are <a href="https://github.com/binwiederhier/ntfy#installation">install instructions</a>
|
your own server as well. Check out the [install instructions](install.md).
|
||||||
on GitHub.
|
|
||||||
|
|
||||||
## Why is Firebase used?
|
## Why is Firebase used?
|
||||||
In addition to caching messages locally and delivering them to long-polling subscribers, all messages are also
|
In addition to caching messages locally and delivering them to long-polling subscribers, all messages are also
|
||||||
published to Firebase Cloud Messaging (FCM) (if `FirebaseKeyFile` is set, which it is on ntfy.sh). This
|
published to Firebase Cloud Messaging (FCM) (if `FirebaseKeyFile` is set, which it is on ntfy.sh). This
|
||||||
is to facilitate instant notifications on Android.
|
is to facilitate notifications on Android.
|
||||||
</p>
|
|
||||||
|
If you do not care for Firebase, I suggest you install the [F-Droid version](https://f-droid.org/en/packages/io.heckel.ntfy/)
|
||||||
|
of the app and [self-host your own ntfy server](install.md).
|
||||||
|
|
||||||
## How much battery does the Android app use?
|
## How much battery does the Android app use?
|
||||||
If you use the ntfy.sh server and you don't use the <i>instant delivery</i> feature, the Android app uses no
|
If you use the ntfy.sh server and you don't use the [instant delivery](subscribe/phone.md#instant-delivery) feature,
|
||||||
additional battery, since Firebase Cloud Messaging (FCM) is used. If you use your own server, or you use
|
the Android app uses no additional battery, since Firebase Cloud Messaging (FCM) is used. If you use your own server,
|
||||||
<i>instant delivery</i>, the app has to maintain a constant connection to the server, which consumes about 4% of
|
or you use *instant delivery*, the app has to maintain a constant connection to the server, which consumes about 4% of
|
||||||
battery in 17h of use (on my phone). I use it and it makes no difference to me.
|
battery in 17h of use (on my phone). I use it, and it makes no difference to me.
|
||||||
|
|
||||||
## What is instant delivery?
|
## What is instant delivery?
|
||||||
Instant delivery is a feature in the Android app. If turned on, the app maintains a constant connection to the
|
[Instant delivery](subscribe/phone.md#instant-delivery) is a feature in the Android app. If turned on, the app maintains a constant connection to the
|
||||||
server and listens for incoming notifications. This consumes <a href="#battery-usage">additional battery</a>,
|
server and listens for incoming notifications. This consumes <a href="#battery-usage">additional battery</a>,
|
||||||
but delivers notifications instantly.
|
but delivers notifications instantly.
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,79 @@
|
||||||
# Getting started
|
# Getting started
|
||||||
|
ntfy lets you **send push notifications to your phone or desktop via scripts from any computer**, using simple HTTP PUT
|
||||||
|
or POST requests. I use it to notify myself when scripts fail, or long-running commands complete.
|
||||||
|
|
||||||
**ntfy** (pronounce: *notify*) is a simple HTTP-based [pub-sub](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern)
|
## Step 1: Get the app
|
||||||
notification service. It allows you to **send push notifications to your phone or desktop via scripts from any computer**,
|
<a href="https://play.google.com/store/apps/details?id=io.heckel.ntfy"><img src="../../static/img/badge-googleplay.png"></a>
|
||||||
entirely **without signup, cost or setup**. It's [open source](https://github.com/binwiederhier/ntfy) if you want to run your own.
|
<a href="https://f-droid.org/en/packages/io.heckel.ntfy/"><img src="../../static/img/badge-fdroid.png"></a>
|
||||||
|
<a href="https://github.com/binwiederhier/ntfy/issues/4"><img src="../../static/img/badge-appstore.png"></a>
|
||||||
|
|
||||||
|
To [receive notifications on your phone](subscribe/phone.md), install the app, either via Google Play or F-Droid.
|
||||||
|
Once installed, open it and subscribe to a topic of your choosing. Topics don't have to explicitly be created, so just
|
||||||
|
pick a name and use it later when you [publish a message](publish.md). Note that **topic names are public, so it's wise
|
||||||
|
to choose something that cannot be guessed easily.**
|
||||||
|
|
||||||
|
For this guide, we'll just use `mytopic` as our topic name:
|
||||||
|
|
||||||
|
<figure markdown>
|
||||||
|
![adding a topic](static/img/getting-started-add.png){ width=500 }
|
||||||
|
<figcaption>Creating/adding your first topic</figcaption>
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
That's it. After you tap "Subscribe", the app is listening for new messages on that topic.
|
||||||
|
|
||||||
|
## Step 2: Send a message
|
||||||
|
Now let's [send a message](publish.md) to our topic. It's easy in every language, since we're just using HTTP PUT or POST. The message
|
||||||
|
is in the request body. Here's an example showing how to publish a simple message using a POST request:
|
||||||
|
|
||||||
|
=== "Command line (curl)"
|
||||||
|
```
|
||||||
|
curl -d "Backup successful 😀" ntfy.sh/mytopic
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "HTTP"
|
||||||
|
``` http
|
||||||
|
POST /mytopic HTTP/1.1
|
||||||
|
Host: ntfy.sh
|
||||||
|
|
||||||
|
Backup successful 😀
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "JavaScript"
|
||||||
|
``` javascript
|
||||||
|
fetch('https://ntfy.sh/mytopic', {
|
||||||
|
method: 'POST', // PUT works too
|
||||||
|
body: 'Backup successful 😀'
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Go"
|
||||||
|
``` go
|
||||||
|
http.Post("https://ntfy.sh/mytopic", "text/plain",
|
||||||
|
strings.NewReader("Backup successful 😀"))
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "PHP"
|
||||||
|
``` php-inline
|
||||||
|
file_get_contents('https://ntfy.sh/mytopic', false, stream_context_create([
|
||||||
|
'http' => [
|
||||||
|
'method' => 'POST', // PUT also works
|
||||||
|
'header' => 'Content-Type: text/plain',
|
||||||
|
'content' => 'Backup successful 😀'
|
||||||
|
]
|
||||||
|
]));
|
||||||
|
```
|
||||||
|
|
||||||
|
This will create a notification that looks like this:
|
||||||
|
|
||||||
|
<figure markdown>
|
||||||
|
![basic notification](static/img/basic-notification.png){ width=500 }
|
||||||
|
<figcaption>Android notification</figcaption>
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
That's it. You're all set. Go play and read the rest of the docs. I highly recommend reading at least the page on
|
||||||
|
[publishing messages](publish.md), as well as the detailed page on the [Android app](subscribe/phone.md).
|
||||||
|
|
||||||
|
Here's another video showing the entire process:
|
||||||
|
|
||||||
<figure>
|
<figure>
|
||||||
<video controls muted autoplay loop width="650" src="static/img/overview.mp4"></video>
|
<video controls muted autoplay loop width="650" src="static/img/overview.mp4"></video>
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
# Install your own ntfy server
|
# Install your own ntfy server
|
||||||
The following steps are only required if you want to **self-host your own ntfy server**. If you just want to
|
**Self-hosting your own ntfy server** is pretty straight forward. Just install the binary, package or Docker image, then
|
||||||
[send messages using ntfy.sh](publish.md), you don't need to install anything. Just use `curl`
|
configure it and run it. Just like any other software. No fuzz.
|
||||||
or your favorite HTTP client.
|
|
||||||
|
!!! info
|
||||||
|
The following steps are only required if you want to **self-host your own ntfy server**. If you just want to
|
||||||
|
[send messages using ntfy.sh](publish.md), you don't need to install anything.
|
||||||
|
|
||||||
## General steps
|
## General steps
|
||||||
The ntfy server comes as a statically linked binary and is shipped as tarball, deb/rpm packages and as a Docker image.
|
The ntfy server comes as a statically linked binary and is shipped as tarball, deb/rpm packages and as a Docker image.
|
||||||
|
@ -129,7 +132,7 @@ The [ntfy image](https://hub.docker.com/r/binwiederhier/ntfy) is available for a
|
||||||
straight forward to use.
|
straight forward to use.
|
||||||
|
|
||||||
The server exposes its web UI and the API on port 80, so you need to expose that in Docker. To use the persistent
|
The server exposes its web UI and the API on port 80, so you need to expose that in Docker. To use the persistent
|
||||||
message cache, you also need to map a volume to `/var/cache/ntfy`. To change other settings, you should map `/etc/ntfy`,
|
[message cache](config.md#message-cache), you also need to map a volume to `/var/cache/ntfy`. To change other settings, you should map `/etc/ntfy`,
|
||||||
so you can edit `/etc/ntfy/config.yml`.
|
so you can edit `/etc/ntfy/config.yml`.
|
||||||
|
|
||||||
Basic usage (no cache or additional config):
|
Basic usage (no cache or additional config):
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Privacy policy
|
# Privacy policy
|
||||||
|
|
||||||
I love free software, and I'm doing this because it's fun. I have no bad intentions, and I will
|
I love free software, and I'm doing this because it's fun. I have no bad intentions, and **I will
|
||||||
never monetize or sell your information. This service will always stay free and open.
|
never monetize or sell your information, and this service and software will always stay free and open.**
|
||||||
|
|
||||||
Neither the server nor the app record any personal information, or share any of the messages and topics with
|
Neither the server nor the app record any personal information, or share any of the messages and topics with
|
||||||
any outside service. All data is exclusively used to make the service function properly. The only external service
|
any outside service. All data is exclusively used to make the service function properly. The only external service
|
||||||
|
|
9
docs/static/css/extra.css
vendored
9
docs/static/css/extra.css
vendored
|
@ -6,9 +6,14 @@ article {
|
||||||
padding-bottom: 50px;
|
padding-bottom: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
figure img {
|
figure iframe, figure img, figure video {
|
||||||
|
filter: drop-shadow(3px 3px 3px #ccc);
|
||||||
border-radius: 7px;
|
border-radius: 7px;
|
||||||
filter: drop-shadow(3px 3px 5px #ccc);
|
}
|
||||||
|
|
||||||
|
figure video {
|
||||||
|
width: 100%;
|
||||||
|
max-height: 450px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.remove-md-box {
|
.remove-md-box {
|
||||||
|
|
BIN
docs/static/img/getting-started-add.png
vendored
Normal file
BIN
docs/static/img/getting-started-add.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 90 KiB |
BIN
docs/static/img/web-pin.png
vendored
Normal file
BIN
docs/static/img/web-pin.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
|
@ -168,12 +168,12 @@ format of the message. It's very straight forward:
|
||||||
| Field | Required | Type | Example | Description |
|
| Field | Required | Type | Example | Description |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
| `id` | ✔️ | *string* | `hwQ2YpKdmg` | Randomly chosen message identifier |
|
| `id` | ✔️ | *string* | `hwQ2YpKdmg` | Randomly chosen message identifier |
|
||||||
| `time` | ✔️ | *int* | 1635528741 | Message date time, as Unix time stamp |
|
| `time` | ✔️ | *int* | `1635528741` | Message date time, as Unix time stamp |
|
||||||
| `event` | ✔️ | `open`, `keepalive` or `message` | `message` | Message type, typically you'd be only interested in `message` |
|
| `event` | ✔️ | `open`, `keepalive` or `message` | `message` | Message type, typically you'd be only interested in `message` |
|
||||||
| `topic` | ✔️ | *string* | `topic1,topic2` | Comma-separated list of topics the message is associated with; only one for all `message` events, but may be a list in `open` events |
|
| `topic` | ✔️ | *string* | `topic1,topic2` | Comma-separated list of topics the message is associated with; only one for all `message` events, but may be a list in `open` events |
|
||||||
| `message` | - | *string* | `Some message` | Message body; always present in `message` events |
|
| `message` | - | *string* | `Some message` | Message body; always present in `message` events |
|
||||||
| `title` | - | *string* | `Some title` | Message [title](../publish.md#message-title); if not set defaults to `ntfy.sh/<topic>` |
|
| `title` | - | *string* | `Some title` | Message [title](../publish.md#message-title); if not set defaults to `ntfy.sh/<topic>` |
|
||||||
| `tags` | - | *string array* | `["tag1","tag2"]` | List of [tags](../publish.md#tags--emojis--) that may or not map to emojis |
|
| `tags` | - | *string array* | `["tag1","tag2"]` | List of [tags](../publish.md#tags-emojis) that may or not map to emojis |
|
||||||
| `priority` | - | *1, 2, 3, 4, or 5* | `4` | Message [priority](../publish.md#message-priority) with 1=min, 3=default and 5=max |
|
| `priority` | - | *1, 2, 3, 4, or 5* | `4` | Message [priority](../publish.md#message-priority) with 1=min, 3=default and 5=max |
|
||||||
|
|
||||||
Here's an example for each message type:
|
Here's an example for each message type:
|
||||||
|
|
|
@ -51,7 +51,7 @@ the settings (and custom sounds or vibration) for each of the priorities:
|
||||||
</figure>
|
</figure>
|
||||||
|
|
||||||
### Instant delivery
|
### Instant delivery
|
||||||
Instant delivery is allows you to receive messages on your phone instantly, **even when your phone is in doze mode**, i.e.
|
Instant delivery allows you to receive messages on your phone instantly, **even when your phone is in doze mode**, i.e.
|
||||||
when the screen turns off, and you leave it on the desk for a while. This is achieved with a foreground service, which
|
when the screen turns off, and you leave it on the desk for a while. This is achieved with a foreground service, which
|
||||||
you'll see as a permanent notification that looks like this:
|
you'll see as a permanent notification that looks like this:
|
||||||
|
|
||||||
|
|
|
@ -11,4 +11,10 @@ To learn how to send messages, check out the [publishing page](../publish.md).
|
||||||
<a href="../../static/img/web-detail.png"><img src="../../static/img/web-detail.png"/></a>
|
<a href="../../static/img/web-detail.png"><img src="../../static/img/web-detail.png"/></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
To keep receiving desktop notifications from ntfy, you need to keep the website open. What I do, and what I highly recommend,
|
||||||
|
is to pin the tab so that it's always open, but sort of out of the way:
|
||||||
|
|
||||||
|
<figure markdown>
|
||||||
|
![pinned](../static/img/web-pin.png){ width=500 }
|
||||||
|
<figcaption>Pin web app to move it out of the way</figcaption>
|
||||||
|
</figure>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
|
||||||
<title>ntfy.sh | PUT/POST push notifications to your phone</title>
|
<title>ntfy.sh | Send push notifications to your phone via PUT/POST</title>
|
||||||
<link rel="stylesheet" href="static/css/app.css" type="text/css">
|
<link rel="stylesheet" href="static/css/app.css" type="text/css">
|
||||||
|
|
||||||
<!-- Mobile view -->
|
<!-- Mobile view -->
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
<meta property="og:locale" content="en_US" />
|
<meta property="og:locale" content="en_US" />
|
||||||
<meta property="og:site_name" content="ntfy.sh" />
|
<meta property="og:site_name" content="ntfy.sh" />
|
||||||
<meta property="og:title" content="ntfy.sh | send push notifications to your phone or desktop via PUT/POST" />
|
<meta property="og:title" content="ntfy.sh | Send push notifications to your phone or desktop via PUT/POST" />
|
||||||
<meta property="og:description" content="ntfy is a simple HTTP-based pub-sub notification service. It allows you to send desktop notifications via scripts from any computer, entirely without signup or cost. Made with ❤ by Philipp C. Heckel, Apache License 2.0, source at https://heckel.io/ntfy." />
|
<meta property="og:description" content="ntfy is a simple HTTP-based pub-sub notification service. It allows you to send desktop notifications via scripts from any computer, entirely without signup or cost. Made with ❤ by Philipp C. Heckel, Apache License 2.0, source at https://heckel.io/ntfy." />
|
||||||
<meta property="og:image" content="/static/img/ntfy.png" />
|
<meta property="og:image" content="/static/img/ntfy.png" />
|
||||||
<meta property="og:url" content="https://ntfy.sh" />
|
<meta property="og:url" content="https://ntfy.sh" />
|
||||||
|
@ -38,12 +38,13 @@
|
||||||
<nav id="header">
|
<nav id="header">
|
||||||
<div id="headerBox">
|
<div id="headerBox">
|
||||||
<img id="logo" src="static/img/ntfy.png" alt="logo"/>
|
<img id="logo" src="static/img/ntfy.png" alt="logo"/>
|
||||||
<div id="name">ntfy.sh</div>
|
<div id="name">ntfy</div>
|
||||||
<ol>
|
<ol>
|
||||||
<li><a href="docs/">Getting started</a></li>
|
<li><a href="docs/">Getting started</a></li>
|
||||||
<li><a href="docs/subscribe/phone/">Android/iOS</a></li>
|
<li><a href="docs/subscribe/phone/">Android/iOS</a></li>
|
||||||
<li><a href="docs/publish/">API</a></li>
|
<li><a href="docs/publish/">API</a></li>
|
||||||
<li><a href="docs/install/">Self-hosting</a></li>
|
<li><a href="docs/install/">Self-hosting</a></li>
|
||||||
|
<li><a href="https://github.com/binwiederhier/ntfy">GitHub</a></li>
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -63,14 +64,10 @@
|
||||||
<a href="static/img/screenshot-phone-notification.jpg"><img src="static/img/screenshot-phone-notification.jpg"/></a>
|
<a href="static/img/screenshot-phone-notification.jpg"><img src="static/img/screenshot-phone-notification.jpg"/></a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<p>
|
|
||||||
There are many ways to use it: Notify yourself when a build finishes, when an rsync is done or a backup fails,
|
|
||||||
or know when somebody logs into your server. There are <a href="#examples">many more examples</a>, endless possibilities 😀.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2 id="publish" class="anchor">Publishing messages</h2>
|
<h2 id="publish" class="anchor">Publishing messages</h2>
|
||||||
<p>
|
<p>
|
||||||
Publishing messages can be done via PUT or POST. Topics are created on the fly by subscribing or publishing to them.
|
<a href="docs/publish/">Publishing messages</a> can be done via PUT or POST. Topics are created on the fly by subscribing or publishing to them.
|
||||||
Because there is no sign-up, <b>the topic is essentially a password</b>, so pick something that's not easily guessable.
|
Because there is no sign-up, <b>the topic is essentially a password</b>, so pick something that's not easily guessable.
|
||||||
</p>
|
</p>
|
||||||
<p class="smallMarginBottom">
|
<p class="smallMarginBottom">
|
||||||
|
@ -81,8 +78,8 @@
|
||||||
</code>
|
</code>
|
||||||
<p class="smallMarginBottom">
|
<p class="smallMarginBottom">
|
||||||
There are <a href="docs/publish/">more features</a> related to publishing messages: You can set a
|
There are <a href="docs/publish/">more features</a> related to publishing messages: You can set a
|
||||||
<a href="#docs/publish/#message-priority">notification priority</a>, a <a href="docs/publish/#message-title">title</a>,
|
<a href="docs/publish/#message-priority">notification priority</a>, a <a href="docs/publish/#message-title">title</a>,
|
||||||
and <a href="docs/publish/#tags--emojis--">tag messages</a>.
|
and <a href="docs/publish/#tags-emojis">tag messages</a>.
|
||||||
Here's an example using all of them:
|
Here's an example using all of them:
|
||||||
</p>
|
</p>
|
||||||
<code>
|
<code>
|
||||||
|
@ -93,6 +90,13 @@
|
||||||
-d "Remote access to $(hostname) detected. Act right away." \<br/>
|
-d "Remote access to $(hostname) detected. Act right away." \<br/>
|
||||||
<span class="ntfyUrl">ntfy.sh</span>/mytopic
|
<span class="ntfyUrl">ntfy.sh</span>/mytopic
|
||||||
</code>
|
</code>
|
||||||
|
<p>
|
||||||
|
Here's what that looks like in the <a href="docs/subscribe/phone/">Android app</a>:
|
||||||
|
</p>
|
||||||
|
<figure>
|
||||||
|
<img src="static/img/priority-notification.png" style="max-height: 200px"/>
|
||||||
|
<figcaption>Urgent notification with pop-over</figcaption>
|
||||||
|
</figure>
|
||||||
|
|
||||||
<h2 id="subscribe" class="anchor">Subscribe to a topic</h2>
|
<h2 id="subscribe" class="anchor">Subscribe to a topic</h2>
|
||||||
<p>
|
<p>
|
||||||
|
@ -110,9 +114,11 @@
|
||||||
<a href="https://f-droid.org/en/packages/io.heckel.ntfy/"><img src="static/img/badge-fdroid.png"></a>
|
<a href="https://f-droid.org/en/packages/io.heckel.ntfy/"><img src="static/img/badge-fdroid.png"></a>
|
||||||
<a href="https://github.com/binwiederhier/ntfy/issues/4"><img src="static/img/badge-appstore.png"></a>
|
<a href="https://github.com/binwiederhier/ntfy/issues/4"><img src="static/img/badge-appstore.png"></a>
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
Here's a video showing the app in action:
|
||||||
|
</p>
|
||||||
<figure>
|
<figure>
|
||||||
<video controls muted autoplay loop width="650" src="static/img/android-video-overview.mp4"></video>
|
<video controls muted autoplay loop src="static/img/android-video-overview.mp4" style="max-width: 650px"></video>
|
||||||
<figcaption>Sending push notifications to your Android phone</figcaption>
|
<figcaption>Sending push notifications to your Android phone</figcaption>
|
||||||
</figure>
|
</figure>
|
||||||
|
|
||||||
|
@ -143,7 +149,7 @@
|
||||||
as well as a <a href="docs/subscribe/api/#subscribe-as-raw-stream">plain text stream</a>.
|
as well as a <a href="docs/subscribe/api/#subscribe-as-raw-stream">plain text stream</a>.
|
||||||
</p>
|
</p>
|
||||||
<p class="smallMarginBottom">
|
<p class="smallMarginBottom">
|
||||||
Here's an example for JSON. Note that <b>the connection stays open</b>, so you can retrieve messages as they come in:
|
Here's an example for JSON. The <b>connection stays open</b>, so you can retrieve messages as they come in:
|
||||||
</p>
|
</p>
|
||||||
<code>
|
<code>
|
||||||
$ curl -s <span class="ntfyUrl">ntfy.sh</span>/mytopic/json<br/>
|
$ curl -s <span class="ntfyUrl">ntfy.sh</span>/mytopic/json<br/>
|
||||||
|
@ -152,24 +158,30 @@
|
||||||
{"id":"DGUDShMCsc","time":1635528787,"event":"keepalive","topic":"mytopic"}<br/>
|
{"id":"DGUDShMCsc","time":1635528787,"event":"keepalive","topic":"mytopic"}<br/>
|
||||||
...
|
...
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<script id="asciicast-453771" src="https://asciinema.org/a/453771.js" async></script>
|
Here's a short video demonstrating it in action:
|
||||||
</p>
|
</p>
|
||||||
|
<figure>
|
||||||
|
<video controls muted autoplay loop src="static/img/android-video-subscribe-api.mp4" style="max-width: 650px"></video>
|
||||||
|
<figcaption>Subscribing to the JSON stream with <tt>curl</tt></figcaption>
|
||||||
|
</figure>
|
||||||
|
|
||||||
<h3 id="more" class="anchor">More, more, more!</h3>
|
<h3 id="docs" class="anchor">Check out the docs!</h3>
|
||||||
<p>
|
<p>
|
||||||
ntfy has so <a href="docs/">many more features</a> and you can learn about all of them <a href="docs/">in the documentation</a>
|
ntfy has so many more features and you can learn about all of them <a href="docs/">in the documentation</a>
|
||||||
(I tried my very best to make it the best docs ever 😉, not sure if I succeeded, hehe).
|
(I tried my very best to make it the best docs ever 😉, not sure if I succeeded, hehe).
|
||||||
</p>
|
</p>
|
||||||
|
<figure>
|
||||||
|
<a href="docs/"><img width="100%" src="static/img/screenshot-docs.png"/></a>
|
||||||
|
<figcaption>Check out the documentation</figcaption>
|
||||||
|
</figure>
|
||||||
|
|
||||||
<a href="docs/"><img width="100%" src="static/img/screenshot-docs.png"/></a>
|
<h3 id="free-software" class="anchor">100% open source & forever free</h3>
|
||||||
|
|
||||||
<h3 id="free-software" class="anchor">Forever free, forever 100% free software</h3>
|
|
||||||
<p>
|
<p>
|
||||||
I love free software, and I'm doing this because it's fun. I have no bad intentions, and I will
|
I love free software, and I'm doing this because it's fun. I have no bad intentions, and I will
|
||||||
never monetize or sell your information. This service will always stay free and open. You can
|
never monetize or sell your information. This service will always stay
|
||||||
read more in the <a href="docs/faq/">FAQs</a> and in the <a href="docs/privacy/">privacy policy</a>.
|
<a href="https://github.com/binwiederhier/ntfy">free and open</a>.
|
||||||
|
You can read more in the <a href="docs/faq/">FAQs</a> and in the <a href="docs/privacy/">privacy policy</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<center id="ironicCenterTagDontFreakOut"><i>Made with ❤️ by <a href="https://heckel.io">Philipp C. Heckel</a></i></center>
|
<center id="ironicCenterTagDontFreakOut"><i>Made with ❤️ by <a href="https://heckel.io">Philipp C. Heckel</a></i></center>
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
/* general styling */
|
/* general styling */
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
font-family: 'Lato', sans-serif;
|
font-family: 'Roboto', sans-serif;
|
||||||
color: #333;
|
font-weight: 400;
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
|
color: #444;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
@ -29,31 +30,41 @@ h1 {
|
||||||
font-size: 2.5em;
|
font-size: 2.5em;
|
||||||
word-wrap: break-word; /* For very long topics */
|
word-wrap: break-word; /* For very long topics */
|
||||||
padding-right: 40px; /* For the X on the detail page */
|
padding-right: 40px; /* For the X on the detail page */
|
||||||
|
font-weight: 300;
|
||||||
|
color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
font-size: 1.8em;
|
font-size: 1.8em;
|
||||||
|
font-weight: 300;
|
||||||
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
margin-top: 25px;
|
margin-top: 25px;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
font-size: 1.3em;
|
font-size: 1.3em;
|
||||||
|
font-weight: 300;
|
||||||
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
font-size: 1.1em;
|
line-height: 160%;
|
||||||
line-height: 140%;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
p.smallMarginBottom {
|
p.smallMarginBottom {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
tt {
|
tt {
|
||||||
background: #eee;
|
background: #eee;
|
||||||
padding: 2px 7px;
|
padding: 2px 7px;
|
||||||
|
@ -72,16 +83,36 @@ code {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lato font (OFL), https://fonts.google.com/specimen/Lato#about,
|
/* Roboto font, embedded with the help of https://google-webfonts-helper.herokuapp.com/fonts/roboto?subsets=latin */
|
||||||
embedded with the help of https://google-webfonts-helper.herokuapp.com/fonts/lato?subsets=latin */
|
|
||||||
|
|
||||||
|
/* roboto-300 - latin */
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Lato';
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
src: local(''),
|
||||||
|
url('../font/roboto-v29-latin-300.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
|
||||||
|
url('../font/roboto-v29-latin-300.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* roboto-regular - latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
src: local(''),
|
src: local(''),
|
||||||
url('../font/lato-v17-latin-ext_latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
|
url('../font/roboto-v29-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
|
||||||
url('../font/lato-v17-latin-ext_latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
url('../font/roboto-v29-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* roboto-500 - latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
src: local(''),
|
||||||
|
url('../font/roboto-v29-latin-500.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
|
||||||
|
url('../font/roboto-v29-latin-500.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Main page */
|
/* Main page */
|
||||||
|
@ -119,6 +150,29 @@ code {
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Figures */
|
||||||
|
|
||||||
|
figure {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
figure img, figure video {
|
||||||
|
filter: drop-shadow(3px 3px 3px #ccc);
|
||||||
|
border-radius: 7px;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
figure video {
|
||||||
|
width: 100%;
|
||||||
|
max-height: 450px;
|
||||||
|
}
|
||||||
|
|
||||||
|
figcaption {
|
||||||
|
text-align: center;
|
||||||
|
font-style: italic;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Screenshots */
|
/* Screenshots */
|
||||||
|
|
||||||
#screenshots {
|
#screenshots {
|
||||||
|
@ -218,21 +272,20 @@ code {
|
||||||
float: left;
|
float: left;
|
||||||
color: white;
|
color: white;
|
||||||
font-size: 2.6em;
|
font-size: 2.6em;
|
||||||
font-weight: bold;
|
font-weight: 300;
|
||||||
margin: 35px 0 0 20px;
|
margin: 35px 0 0 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#header ol {
|
#header ol {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
float:right;
|
float: right;
|
||||||
margin-top: 80px;
|
margin-top: 80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#header ol li {
|
#header ol li {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: 0 10px;
|
margin: 0 10px;
|
||||||
font-weight: bold;
|
font-weight: 400;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#header ol li a, nav ol li a:visited {
|
#header ol li a, nav ol li a:visited {
|
||||||
|
@ -273,6 +326,14 @@ li {
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Hide top menu SMALL SCREEN */
|
||||||
|
@media only screen and (max-width: 780px) {
|
||||||
|
#header ol {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Subscribe box SMALL SCREEN */
|
/* Subscribe box SMALL SCREEN */
|
||||||
@media only screen and (max-width: 1599px) {
|
@media only screen and (max-width: 1599px) {
|
||||||
#subscribeBox #subscribeForm {
|
#subscribeBox #subscribeForm {
|
||||||
|
|
Binary file not shown.
Binary file not shown.
BIN
server/static/font/roboto-v29-latin-300.woff
Normal file
BIN
server/static/font/roboto-v29-latin-300.woff
Normal file
Binary file not shown.
BIN
server/static/font/roboto-v29-latin-300.woff2
Normal file
BIN
server/static/font/roboto-v29-latin-300.woff2
Normal file
Binary file not shown.
BIN
server/static/font/roboto-v29-latin-500.woff
Normal file
BIN
server/static/font/roboto-v29-latin-500.woff
Normal file
Binary file not shown.
BIN
server/static/font/roboto-v29-latin-500.woff2
Normal file
BIN
server/static/font/roboto-v29-latin-500.woff2
Normal file
Binary file not shown.
BIN
server/static/font/roboto-v29-latin-regular.woff
Normal file
BIN
server/static/font/roboto-v29-latin-regular.woff
Normal file
Binary file not shown.
BIN
server/static/font/roboto-v29-latin-regular.woff2
Normal file
BIN
server/static/font/roboto-v29-latin-regular.woff2
Normal file
Binary file not shown.
BIN
server/static/img/android-video-subscribe-api.mp4
Normal file
BIN
server/static/img/android-video-subscribe-api.mp4
Normal file
Binary file not shown.
BIN
server/static/img/basic-notification.png
Normal file
BIN
server/static/img/basic-notification.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
BIN
server/static/img/priority-notification.png
Normal file
BIN
server/static/img/priority-notification.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 270 KiB |
Loading…
Reference in a new issue