forked from mirrors/ntfy
Continued docs
This commit is contained in:
parent
7ba268887b
commit
246061829b
17 changed files with 421 additions and 54 deletions
|
@ -1,6 +1,7 @@
|
|||
# Building
|
||||
|
||||
## ntfy server
|
||||
The ntfy server source code is available [on GitHub](https://github.com/binwiederhier/ntfy).
|
||||
To quickly build on amd64, you can use `make build-simple`:
|
||||
|
||||
```
|
||||
|
@ -29,6 +30,7 @@ Releasing (requires goreleaser):
|
|||
There are currently no platform-specific make targets, so they will build for all platforms (which may take a while).
|
||||
|
||||
## Android app
|
||||
The ntfy Android app source code is available [on GitHub](https://github.com/binwiederhier/ntfy-android).
|
||||
The Android app has two flavors:
|
||||
|
||||
* **Google Play:** The `play` flavor includes Firebase (FCM) and requires a Firebase account
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
# ntfy.sh | simple HTTP-based pub-sub
|
||||
# Getting started
|
||||
|
||||
**ntfy** (pronounce: *notify*) is a simple HTTP-based [pub-sub](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern)
|
||||
notification service. It allows you to send notifications to your phone or desktop via scripts from any computer,
|
||||
entirely **without signup, cost or setup**. It's also [open source](https://github.com/binwiederhier/ntfy) if you want
|
||||
to run your own.
|
||||
notification service. It allows you to **send push notifications to your phone or desktop via scripts from any computer**,
|
||||
entirely **without signup, cost or setup**. It's [open source](https://github.com/binwiederhier/ntfy) if you want to run your own.
|
||||
|
||||
<figure>
|
||||
<video controls muted autoplay loop width="650" src="static/img/overview.mp4"></video>
|
||||
<figcaption>Sending push notifications to your Android phone</figcaption>
|
||||
</figure>
|
||||
|
||||
(pub sub diagram)
|
||||
|
||||
(screenshot / video / gif)
|
||||
|
|
134
docs/install.md
134
docs/install.md
|
@ -15,47 +15,120 @@ We support amd64, armv7 and arm64.
|
|||
Please check out the [releases page](https://github.com/binwiederhier/ntfy/releases) for binaries and
|
||||
deb/rpm packages.
|
||||
|
||||
**x86_64/amd64:**
|
||||
```
|
||||
wget https://github.com/binwiederhier/ntfy/releases/download/v1.5.0/ntfy_1.5.0_linux_x86_64.tar.gz
|
||||
sudo tar -C /usr/bin -zxf ntfy_*.tar.gz ntfy
|
||||
```
|
||||
=== "x86_64/amd64"
|
||||
```bash
|
||||
wget https://github.com/binwiederhier/ntfy/releases/download/v1.5.0/ntfy_1.5.0_linux_x86_64.tar.gz
|
||||
sudo tar -C /usr/bin -zxf ntfy_*.tar.gz ntfy
|
||||
sudo ./ntfy
|
||||
```
|
||||
|
||||
**armv7:**
|
||||
```
|
||||
wget https://github.com/binwiederhier/ntfy/releases/download/v1.5.0/ntfy_1.5.0_linux_armv7.tar.gz
|
||||
sudo tar -C /usr/bin -zxf ntfy_*.tar.gz ntfy
|
||||
```
|
||||
=== "armv7/armhf"
|
||||
```bash
|
||||
wget https://github.com/binwiederhier/ntfy/releases/download/v1.5.0/ntfy_1.5.0_linux_armv7.tar.gz
|
||||
sudo tar -C /usr/bin -zxf ntfy_*.tar.gz ntfy
|
||||
sudo ./ntfy
|
||||
```
|
||||
|
||||
**arm64/v8:**
|
||||
```
|
||||
wget https://github.com/binwiederhier/ntfy/releases/download/v1.5.0/ntfy_1.5.0_linux_arm64.tar.gz
|
||||
sudo tar -C /usr/bin -zxf ntfy_*.tar.gz ntfy
|
||||
```
|
||||
=== "arm64"
|
||||
```bash
|
||||
wget https://github.com/binwiederhier/ntfy/releases/download/v1.5.0/ntfy_1.5.0_linux_arm64.tar.gz
|
||||
sudo tar -C /usr/bin -zxf ntfy_*.tar.gz ntfy
|
||||
sudo ./ntfy
|
||||
```
|
||||
|
||||
## Debian/Ubuntu repository
|
||||
Installation via Debian repository:
|
||||
```bash
|
||||
curl -sSL https://archive.heckel.io/apt/pubkey.txt | sudo apt-key add -
|
||||
sudo apt install apt-transport-https
|
||||
sudo sh -c "echo 'deb [arch=amd64] https://archive.heckel.io/apt debian main' > /etc/apt/sources.list.d/archive.heckel.io.list"
|
||||
sudo apt update
|
||||
sudo apt install ntfy
|
||||
```
|
||||
|
||||
=== "x86_64/amd64"
|
||||
```bash
|
||||
curl -sSL https://archive.heckel.io/apt/pubkey.txt | sudo apt-key add -
|
||||
sudo apt install apt-transport-https
|
||||
sudo sh -c "echo 'deb [arch=amd64] https://archive.heckel.io/apt debian main' \
|
||||
> /etc/apt/sources.list.d/archive.heckel.io.list"
|
||||
sudo apt update
|
||||
sudo apt install ntfy
|
||||
sudo systemctl enable ntfy
|
||||
sudo systemctl start ntfy
|
||||
```
|
||||
|
||||
=== "armv7/armhf"
|
||||
```bash
|
||||
curl -sSL https://archive.heckel.io/apt/pubkey.txt | sudo apt-key add -
|
||||
sudo apt install apt-transport-https
|
||||
sudo sh -c "echo 'deb [arch=armhf] https://archive.heckel.io/apt debian main' \
|
||||
> /etc/apt/sources.list.d/archive.heckel.io.list"
|
||||
sudo apt update
|
||||
sudo apt install ntfy
|
||||
sudo systemctl enable ntfy
|
||||
sudo systemctl start ntfy
|
||||
```
|
||||
|
||||
=== "arm64"
|
||||
```bash
|
||||
curl -sSL https://archive.heckel.io/apt/pubkey.txt | sudo apt-key add -
|
||||
sudo apt install apt-transport-https
|
||||
sudo sh -c "echo 'deb [arch=arm64] https://archive.heckel.io/apt debian main' \
|
||||
> /etc/apt/sources.list.d/archive.heckel.io.list"
|
||||
sudo apt update
|
||||
sudo apt install ntfy
|
||||
sudo systemctl enable ntfy
|
||||
sudo systemctl start ntfy
|
||||
```
|
||||
|
||||
Manually installing the .deb file:
|
||||
```bash
|
||||
wget https://github.com/binwiederhier/ntfy/releases/download/v1.5.0/ntfy_1.5.0_amd64.deb
|
||||
dpkg -i ntfy_1.5.0_amd64.deb
|
||||
```
|
||||
|
||||
=== "x86_64/amd64"
|
||||
```bash
|
||||
wget https://github.com/binwiederhier/ntfy/releases/download/v1.5.0/ntfy_1.5.0_linux_amd64.deb
|
||||
sudo dpkg -i ntfy_*.deb
|
||||
sudo systemctl enable ntfy
|
||||
sudo systemctl start ntfy
|
||||
```
|
||||
|
||||
=== "armv7/armhf"
|
||||
```bash
|
||||
wget https://github.com/binwiederhier/ntfy/releases/download/v1.5.0/ntfy_1.5.0_linux_armv7.deb
|
||||
sudo dpkg -i ntfy_*.deb
|
||||
sudo systemctl enable ntfy
|
||||
sudo systemctl start ntfy
|
||||
```
|
||||
|
||||
=== "arm64"
|
||||
```bash
|
||||
wget https://github.com/binwiederhier/ntfy/releases/download/v1.5.0/ntfy_1.5.0_linux_arm64.deb
|
||||
sudo dpkg -i ntfy_*.deb
|
||||
sudo systemctl enable ntfy
|
||||
sudo systemctl start ntfy
|
||||
```
|
||||
|
||||
## Fedora/RHEL/CentOS
|
||||
```bash
|
||||
rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v1.5.0/ntfy_1.5.0_amd64.rpm
|
||||
```
|
||||
|
||||
=== "x86_64/amd64"
|
||||
```bash
|
||||
sudo rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v1.5.0/ntfy_1.5.0_linux_amd64.rpm
|
||||
sudo systemctl enable ntfy
|
||||
sudo systemctl start ntfy
|
||||
```
|
||||
|
||||
=== "armv7/armhf"
|
||||
```bash
|
||||
sudo rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v1.5.0/ntfy_1.5.0_linux_armv7.rpm
|
||||
sudo systemctl enable ntfy
|
||||
sudo systemctl start ntfy
|
||||
```
|
||||
|
||||
=== "arm64"
|
||||
```bash
|
||||
sudo rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v1.5.0/ntfy_1.5.0_linux_arm64.rpm
|
||||
sudo systemctl enable ntfy
|
||||
sudo systemctl start ntfy
|
||||
```
|
||||
|
||||
## Docker
|
||||
The ntfy server exposes its web UI and the API on port 80, so you need to expose that in Docker. To use the persistent
|
||||
The [ntfy image](https://hub.docker.com/r/binwiederhier/ntfy) is available for amd64, armv7 and arm64. It should be pretty
|
||||
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
|
||||
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`.
|
||||
|
||||
|
@ -88,6 +161,7 @@ To install via Go, simply run:
|
|||
```bash
|
||||
go install heckel.io/ntfy@latest
|
||||
```
|
||||
|
||||
!!! info
|
||||
Please [let me know](https://github.com/binwiederhier/ntfy/issues) if there are any issues with this installation
|
||||
method. The SQLite bindings require CGO and it works for me, but I have the feeling it may not work for everyone.
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# Publishing
|
||||
|
||||
Publishing messages 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.
|
||||
Publishing messages can be done via HTTP PUT or POST. Topics are created on the fly by subscribing or publishing to them.
|
||||
Because there is no sign-up, **the topic is essentially a password**, so pick something that's not easily guessable.
|
||||
|
||||
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
|
||||
|
@ -31,7 +31,7 @@ Here's an example showing how to publish a simple message using a POST request:
|
|||
```
|
||||
|
||||
=== "PHP"
|
||||
``` php
|
||||
``` php-inline
|
||||
file_get_contents('https://ntfy.sh/mytopic', false, stream_context_create([
|
||||
'http' => [
|
||||
'method' => 'POST', // PUT also works
|
||||
|
@ -96,7 +96,7 @@ a [title](#message-title), and [tag messages](#tags-emojis) 🥳 🎉. Here's an
|
|||
```
|
||||
|
||||
=== "PHP"
|
||||
``` php
|
||||
``` php-inline
|
||||
file_get_contents('https://ntfy.sh/phil_alerts', false, stream_context_create([
|
||||
'http' => [
|
||||
'method' => 'POST', // PUT also works
|
||||
|
@ -152,7 +152,7 @@ you can set the `X-Title` header (or any of its aliases: `Title`, `ti`, or `t`).
|
|||
```
|
||||
|
||||
=== "PHP"
|
||||
``` php
|
||||
``` php-inline
|
||||
file_get_contents('https://ntfy.sh/controversial', false, stream_context_create([
|
||||
'http' => [
|
||||
'method' => 'POST',
|
||||
|
@ -218,7 +218,7 @@ You can set the priority with the header `X-Priority` (or any of its aliases: `P
|
|||
```
|
||||
|
||||
=== "PHP"
|
||||
``` php
|
||||
``` php-inline
|
||||
file_get_contents('https://ntfy.sh/phil_alerts', false, stream_context_create([
|
||||
'http' => [
|
||||
'method' => 'POST',
|
||||
|
@ -315,7 +315,7 @@ them with a comma, e.g. `tag1,tag2,tag3`.
|
|||
```
|
||||
|
||||
=== "PHP"
|
||||
``` php
|
||||
``` php-inline
|
||||
file_get_contents('https://ntfy.sh/backups', false, stream_context_create([
|
||||
'http' => [
|
||||
'method' => 'POST',
|
||||
|
|
BIN
docs/static/img/badge-appstore.png
vendored
Normal file
BIN
docs/static/img/badge-appstore.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.8 KiB |
BIN
docs/static/img/badge-fdroid.png
vendored
Normal file
BIN
docs/static/img/badge-fdroid.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
BIN
docs/static/img/badge-googleplay.png
vendored
Normal file
BIN
docs/static/img/badge-googleplay.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.7 KiB |
BIN
docs/static/img/overview.gif
vendored
Normal file
BIN
docs/static/img/overview.gif
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.7 MiB |
BIN
docs/static/img/overview.mp4
vendored
Normal file
BIN
docs/static/img/overview.mp4
vendored
Normal file
Binary file not shown.
BIN
docs/static/img/screenshot-web-notifcation.png
vendored
Normal file
BIN
docs/static/img/screenshot-web-notifcation.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 253 KiB |
BIN
docs/static/img/screenshot-web.png
vendored
Normal file
BIN
docs/static/img/screenshot-web.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
|
@ -1,6 +1,235 @@
|
|||
# Subscribe via API
|
||||
You can create and subscribe to a topic either in the [web UI](web.md), via the [phone app](phone.md), or in your own
|
||||
app or script by subscribing the API. This page describes how to subscribe via API. You may also want to check out the
|
||||
page that describes how to [publish messages](../publish.md).
|
||||
|
||||
The subscription API relies on a simple HTTP GET request with a streaming HTTP response, i.e **you open a GET request and
|
||||
the connection stays open forever**, sending messages back as they come in. There are three different API endpoints, which
|
||||
only differ in the response format:
|
||||
|
||||
* [JSON stream](#subscribe-as-json-stream): `<topic>/json` returns a JSON stream, with one JSON message object per line
|
||||
* [SSE stream](#subscribe-as-sse-stream): `<topic>/sse` returns messages as [Server-Sent Events (SSE)](https://en.wikipedia.org/wiki/Server-sent_events), which
|
||||
can be used with [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource)
|
||||
* [Raw stream](#subscribe-as-raw-stream): `<topic>/raw` returns messages as raw text, with one line per message
|
||||
|
||||
## Subscribe as JSON stream
|
||||
Here are a few examples of how to consume the JSON endpoint (`<topic>/json`). For almost all languages, **this is the
|
||||
recommended way to subscribe to a topic**. The notable exception is JavaScript, for which the
|
||||
[SSE/EventSource stream](#subscribe-as-sse-stream) is much easier to work with.
|
||||
|
||||
=== "Command line (curl)"
|
||||
```
|
||||
$ curl -s ntfy.sh/disk-alerts/json
|
||||
{"id":"SLiKI64DOt","time":1635528757,"event":"open","topic":"mytopic"}
|
||||
{"id":"hwQ2YpKdmg","time":1635528741,"event":"message","topic":"mytopic","message":"Disk full"}
|
||||
{"id":"DGUDShMCsc","time":1635528787,"event":"keepalive","topic":"mytopic"}
|
||||
...
|
||||
```
|
||||
|
||||
=== "HTTP"
|
||||
``` http
|
||||
GET /disk-alerts/json HTTP/1.1
|
||||
Host: ntfy.sh
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/x-ndjson; charset=utf-8
|
||||
Transfer-Encoding: chunked
|
||||
|
||||
## Fetching cached messages
|
||||
{"id":"SLiKI64DOt","time":1635528757,"event":"open","topic":"mytopic"}
|
||||
{"id":"hwQ2YpKdmg","time":1635528741,"event":"message","topic":"mytopic","message":"Disk full"}
|
||||
{"id":"DGUDShMCsc","time":1635528787,"event":"keepalive","topic":"mytopic"}
|
||||
...
|
||||
```
|
||||
|
||||
=== "Go"
|
||||
``` go
|
||||
resp, err := http.Get("https://ntfy.sh/disk-alerts/json")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
scanner := bufio.NewScanner(resp.Body)
|
||||
for scanner.Scan() {
|
||||
println(scanner.Text())
|
||||
}
|
||||
```
|
||||
|
||||
=== "PHP"
|
||||
``` php-inline
|
||||
$fp = fopen('https://ntfy.sh/disk-alerts/json', 'r');
|
||||
if (!$fp) die('cannot open stream');
|
||||
while (!feof($fp)) {
|
||||
echo fgets($fp, 2048);
|
||||
flush();
|
||||
}
|
||||
fclose($fp);
|
||||
```
|
||||
|
||||
## Subscribe as SSE stream
|
||||
Using [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) in JavaScript, you can consume
|
||||
notifications via a [Server-Sent Events (SSE)](https://en.wikipedia.org/wiki/Server-sent_events) stream. It's incredibly
|
||||
easy to use. Here's what it looks like. You may also want to check out the [live example](/example.html).
|
||||
|
||||
=== "Command line (curl)"
|
||||
```
|
||||
$ curl -s ntfy.sh/mytopic/sse
|
||||
event: open
|
||||
data: {"id":"weSj9RtNkj","time":1635528898,"event":"open","topic":"mytopic"}
|
||||
|
||||
data: {"id":"p0M5y6gcCY","time":1635528909,"event":"message","topic":"mytopic","message":"Hi!"}
|
||||
|
||||
event: keepalive
|
||||
data: {"id":"VNxNIg5fpt","time":1635528928,"event":"keepalive","topic":"test"}
|
||||
...
|
||||
```
|
||||
|
||||
=== "HTTP"
|
||||
``` http
|
||||
GET /mytopic/sse HTTP/1.1
|
||||
Host: ntfy.sh
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/event-stream; charset=utf-8
|
||||
Transfer-Encoding: chunked
|
||||
|
||||
event: open
|
||||
data: {"id":"weSj9RtNkj","time":1635528898,"event":"open","topic":"mytopic"}
|
||||
|
||||
data: {"id":"p0M5y6gcCY","time":1635528909,"event":"message","topic":"mytopic","message":"Hi!"}
|
||||
|
||||
event: keepalive
|
||||
data: {"id":"VNxNIg5fpt","time":1635528928,"event":"keepalive","topic":"test"}
|
||||
...
|
||||
```
|
||||
|
||||
=== "JavaScript"
|
||||
``` javascript
|
||||
const eventSource = new EventSource('https://ntfy.sh/mytopic/sse');
|
||||
eventSource.onmessage = (e) => {
|
||||
console.log(e.data);
|
||||
};
|
||||
```
|
||||
|
||||
## Subscribe as raw stream
|
||||
The `/raw` endpoint will output one line per message, and **will only include the message body**. It's useful for extremely
|
||||
simple scripts, and doesn't include all the data. Additional fields such as [priority](../publish.md#message-priority),
|
||||
[tags](../publish.md#tags--emojis--) or [message title](../publish.md#message-title) are not included in this output
|
||||
format. Keepalive messages are sent as empty lines.
|
||||
|
||||
=== "Command line (curl)"
|
||||
```
|
||||
$ curl -s ntfy.sh/disk-alerts/raw
|
||||
|
||||
Disk full
|
||||
...
|
||||
```
|
||||
|
||||
=== "HTTP"
|
||||
``` http
|
||||
GET /disk-alerts/raw HTTP/1.1
|
||||
Host: ntfy.sh
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/plain; charset=utf-8
|
||||
Transfer-Encoding: chunked
|
||||
|
||||
Disk full
|
||||
...
|
||||
```
|
||||
|
||||
=== "Go"
|
||||
``` go
|
||||
resp, err := http.Get("https://ntfy.sh/disk-alerts/raw")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
scanner := bufio.NewScanner(resp.Body)
|
||||
for scanner.Scan() {
|
||||
println(scanner.Text())
|
||||
}
|
||||
```
|
||||
|
||||
=== "PHP"
|
||||
``` php-inline
|
||||
$fp = fopen('https://ntfy.sh/disk-alerts/raw', 'r');
|
||||
if (!$fp) die('cannot open stream');
|
||||
while (!feof($fp)) {
|
||||
echo fgets($fp, 2048);
|
||||
flush();
|
||||
}
|
||||
fclose($fp);
|
||||
```
|
||||
|
||||
## JSON message format
|
||||
Both the [`/json` endpoint](#subscribe-as-json-stream) and the [`/sse` endpoint](#subscribe-as-sse-stream) return a JSON
|
||||
format of the message. It's very straight forward:
|
||||
|
||||
| Field | Required | Type | Example | Description |
|
||||
|---|---|---|---|---|
|
||||
| `id` | ✔️ | *string* | `hwQ2YpKdmg` | Randomly chosen message identifier |
|
||||
| `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` |
|
||||
| `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 |
|
||||
| `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 |
|
||||
| `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:
|
||||
|
||||
=== "Notification message"
|
||||
``` json
|
||||
{
|
||||
"id": "wze9zgqK41",
|
||||
"time": 1638542110,
|
||||
"event": "message",
|
||||
"topic": "phil_alerts",
|
||||
"priority": 5,
|
||||
"tags": [
|
||||
"warning",
|
||||
"skull"
|
||||
],
|
||||
"title": "Unauthorized access detected",
|
||||
"message": "Remote access to phils-laptop detected. Act right away."
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
=== "Notification message (minimal)"
|
||||
``` json
|
||||
{
|
||||
"id": "wze9zgqK41",
|
||||
"time": 1638542110,
|
||||
"event": "message",
|
||||
"topic": "phil_alerts",
|
||||
"message": "Remote access to phils-laptop detected. Act right away."
|
||||
}
|
||||
```
|
||||
|
||||
=== "Open message"
|
||||
``` json
|
||||
{
|
||||
"id": "2pgIAaGrQ8",
|
||||
"time": 1638542215,
|
||||
"event": "open",
|
||||
"topic": "phil_alerts"
|
||||
}
|
||||
```
|
||||
|
||||
=== "Keepalive message"
|
||||
``` json
|
||||
{
|
||||
"id": "371sevb0pD",
|
||||
"time": 1638542275,
|
||||
"event": "keepalive",
|
||||
"topic": "phil_alerts"
|
||||
}
|
||||
```
|
||||
|
||||
## Advanced features
|
||||
|
||||
### Fetching cached messages
|
||||
Messages may be cached for a couple of hours (see [message caching](../config.md#message-cache)) to account for network
|
||||
interruptions of subscribers. If the server has configured message caching, you can read back what you missed by using
|
||||
the `since=` query parameter. It takes either a duration (e.g. `10m` or `30s`), a Unix timestamp (e.g. `1635528757`)
|
||||
|
@ -10,7 +239,7 @@ or `all` (all cached messages).
|
|||
curl -s "ntfy.sh/mytopic/json?since=10m"
|
||||
```
|
||||
|
||||
## Polling
|
||||
### Polling
|
||||
You can also just poll for messages if you don't like the long-standing connection using the `poll=1`
|
||||
query parameter. The connection will end after all available messages have been read. This parameter can be
|
||||
combined with `since=` (defaults to `since=all`).
|
||||
|
@ -19,7 +248,7 @@ combined with `since=` (defaults to `since=all`).
|
|||
curl -s "ntfy.sh/mytopic/json?poll=1"
|
||||
```
|
||||
|
||||
## Subscribing to multiple topics
|
||||
### Subscribing to multiple topics
|
||||
It's possible to subscribe to multiple topics in one HTTP call by providing a
|
||||
comma-separated list of topics in the URL. This allows you to reduce the number of connections you have to maintain:
|
||||
|
||||
|
|
|
@ -3,5 +3,20 @@ You can use the [ntfy Android App](https://play.google.com/store/apps/details?id
|
|||
notifications directly on your phone. Just like the server, this app is also [open source](https://github.com/binwiederhier/ntfy-android).
|
||||
Since I don't have an iPhone or a Mac, I didn't make an iOS app yet. I'd be awesome if [someone else could help out](https://github.com/binwiederhier/ntfy/issues/4).
|
||||
|
||||
<a href="https://play.google.com/store/apps/details?id=io.heckel.ntfy"><img src="static/img/badge-googleplay.png"></a>
|
||||
<a href="https://github.com/binwiederhier/ntfy/issues/4"><img src="static/img/badge-appstore.png"></a>
|
||||
## Android
|
||||
You can get the Android app from both [Google Play](https://play.google.com/store/apps/details?id=io.heckel.ntfy) and
|
||||
from [F-Droid](https://f-droid.org/en/packages/io.heckel.ntfy/). Both are largely identical, with the one exception that
|
||||
the F-Droid flavor does not use Firebase.
|
||||
|
||||
<a href="https://play.google.com/store/apps/details?id=io.heckel.ntfy"><img src="../../static/img/badge-googleplay.png"></a>
|
||||
<a href="https://f-droid.org/en/packages/io.heckel.ntfy/"><img src="../../static/img/badge-fdroid.png"></a>
|
||||
|
||||
### Firebase + Instant delivery
|
||||
|
||||
|
||||
|
||||
## iPhone/iOS
|
||||
I almost feel devious for putting the *Download on the App Store* button on this page. Currently, there is no iOS app
|
||||
for ntfy, but it's in the works. You can track the status on GitHub.
|
||||
|
||||
<a href="https://github.com/binwiederhier/ntfy/issues/4"><img src="../../static/img/badge-appstore.png"></a>
|
||||
|
|
|
@ -1 +1,11 @@
|
|||
# Subscribe from the web UI
|
||||
# Subscribe from the Web UI
|
||||
You can use the Web UI to subscribe to topics as well. If you do, and you keep the website open, **notifications will
|
||||
pop up as desktop notifications**. Simply type in the topic name and click the *Subscribe* button. The browser will
|
||||
keep a connection open and listen for incoming notifications.
|
||||
|
||||
<figure markdown>
|
||||
![web subscribe](../static/img/screenshot-web.png){ width=300 }
|
||||
<figcaption>Subscribe via Web UI</figcaption>
|
||||
</figure>
|
||||
|
||||
Once subscribed, you can [publish messages](../publish.md) via `curl` or from without any of your scripts.
|
||||
|
|
19
examples/subscribe-go/main.go
Normal file
19
examples/subscribe-go/main.go
Normal file
|
@ -0,0 +1,19 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
resp, err := http.Get("https://ntfy.sh/phil_alerts/json")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
scanner := bufio.NewScanner(resp.Body)
|
||||
for scanner.Scan() {
|
||||
println(scanner.Text())
|
||||
}
|
||||
}
|
12
examples/subscribe-php/subscribe.php
Normal file
12
examples/subscribe-php/subscribe.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
$fp = fopen('https://ntfy.sh/phil_alerts/json', 'r');
|
||||
if (!$fp) {
|
||||
die('cannot open stream');
|
||||
}
|
||||
while (!feof($fp)) {
|
||||
$buffer = fgets($fp, 2048);
|
||||
echo $buffer;
|
||||
flush();
|
||||
}
|
||||
fclose($fp);
|
12
mkdocs.yml
12
mkdocs.yml
|
@ -33,6 +33,7 @@ theme:
|
|||
- search.highlight
|
||||
- search.share
|
||||
- navigation.sections
|
||||
- navigation.instant
|
||||
- toc.integrate
|
||||
- content.tabs.link
|
||||
extra_javascript:
|
||||
|
@ -42,17 +43,20 @@ extra_css:
|
|||
|
||||
markdown_extensions:
|
||||
- admonition
|
||||
- codehilite
|
||||
- meta
|
||||
- toc:
|
||||
permalink: true
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
- pymdownx.superfences
|
||||
- pymdownx.highlight
|
||||
- pymdownx.highlight:
|
||||
extend_pygments_lang:
|
||||
- name: php-inline
|
||||
lang: php
|
||||
options:
|
||||
startinline: true
|
||||
- pymdownx.tasklist:
|
||||
custom_checkbox: true
|
||||
- footnotes
|
||||
- attr_list
|
||||
- md_in_html
|
||||
|
||||
|
@ -71,7 +75,7 @@ nav:
|
|||
- "Publishing":
|
||||
- "Sending messages": publish.md
|
||||
- "Subscribing":
|
||||
- "From the Android/iOS app": subscribe/phone.md
|
||||
- "From your phone": subscribe/phone.md
|
||||
- "From the Web UI": subscribe/web.md
|
||||
- "Using the API": subscribe/api.md
|
||||
- "Other things":
|
||||
|
|
Loading…
Reference in a new issue