Almost read to publish
parent
4fcb3891a2
commit
0f495b881a
|
@ -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
|
||||||
|
**Self-hosting your own ntfy server** is pretty straight forward. Just install the binary, package or Docker image, then
|
||||||
|
configure it and run it. Just like any other software. No fuzz.
|
||||||
|
|
||||||
|
!!! info
|
||||||
The following steps are only required if you want to **self-host your own ntfy server**. If you just want to
|
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. Just use `curl`
|
[send messages using ntfy.sh](publish.md), you don't need to install anything.
|
||||||
or your favorite HTTP client.
|
|
||||||
|
|
||||||
## 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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 90 KiB |
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>
|
<a href="docs/"><img width="100%" src="static/img/screenshot-docs.png"/></a>
|
||||||
|
<figcaption>Check out the documentation</figcaption>
|
||||||
|
</figure>
|
||||||
|
|
||||||
<h3 id="free-software" class="anchor">Forever free, forever 100% free software</h3>
|
<h3 id="free-software" class="anchor">100% open source & forever free</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,7 +272,7 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,8 +285,7 @@ code {
|
||||||
#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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
Binary file not shown.
After Width: | Height: | Size: 270 KiB |
Loading…
Reference in New Issue