Docs
This commit is contained in:
parent
edb6b0cf06
commit
85b4abde6c
5 changed files with 123 additions and 55 deletions
|
@ -5,14 +5,25 @@
|
||||||
#
|
#
|
||||||
# default-host: https://ntfy.sh
|
# default-host: https://ntfy.sh
|
||||||
|
|
||||||
# Subscriptions to topics and their actions. This option is only used by the "ntfy subscribe --from-config"
|
# Subscriptions to topics and their actions. This option is primarily used by the systemd service,
|
||||||
# command.
|
# or if you cann "ntfy subscribe --from-config" directly.
|
||||||
#
|
#
|
||||||
# Here's a (hopefully self-explanatory) example:
|
# Example:
|
||||||
# subscribe:
|
# subscribe:
|
||||||
# - topic: mytopic
|
# - topic: mytopic
|
||||||
# command: /usr/local/bin/mytopic-triggered.sh
|
# command: /usr/local/bin/mytopic-triggered.sh
|
||||||
# - topic: myserver.com/anothertopic
|
# - topic: myserver.com/anothertopic
|
||||||
# command: 'echo "$message"'
|
# command: 'echo "$message"'
|
||||||
#
|
#
|
||||||
|
# Variables:
|
||||||
|
# Variable Aliases Description
|
||||||
|
# --------------- --------------- -----------------------------------
|
||||||
|
# $NTFY_ID $id Unique message ID
|
||||||
|
# $NTFY_TIME $time Unix timestamp of the message delivery
|
||||||
|
# $NTFY_TOPIC $topic Topic name
|
||||||
|
# $NTFY_MESSAGE $message, $m Message body
|
||||||
|
# $NTFY_TITLE $title, $t Message title
|
||||||
|
# $NTFY_PRIORITY $priority, $p Message priority (1=min, 5=max)
|
||||||
|
# $NTFY_TAGS $tags, $ta Message tags (comma separated list)
|
||||||
|
#
|
||||||
# subscribe:
|
# subscribe:
|
||||||
|
|
|
@ -7,12 +7,12 @@ const (
|
||||||
|
|
||||||
// Config is the config struct for a Client
|
// Config is the config struct for a Client
|
||||||
type Config struct {
|
type Config struct {
|
||||||
DefaultHost string
|
DefaultHost string `yaml:"default-host"`
|
||||||
Subscribe []struct {
|
Subscribe []struct {
|
||||||
Topic string
|
Topic string `yaml:"topic"`
|
||||||
Command string
|
Command string `yaml:"command"`
|
||||||
// If []map[string]string TODO This would be cool
|
// If []map[string]string TODO This would be cool
|
||||||
}
|
} `yaml:"subscribe"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConfig creates a new Config struct for a Client
|
// NewConfig creates a new Config struct for a Client
|
||||||
|
|
|
@ -20,11 +20,6 @@ var cmdSubscribe = &cli.Command{
|
||||||
Usage: "Subscribe to one or more topics on a ntfy server",
|
Usage: "Subscribe to one or more topics on a ntfy server",
|
||||||
UsageText: "ntfy subscribe [OPTIONS..] [TOPIC]",
|
UsageText: "ntfy subscribe [OPTIONS..] [TOPIC]",
|
||||||
Action: execSubscribe,
|
Action: execSubscribe,
|
||||||
OnUsageError: func(context *cli.Context, err error, isSubcommand bool) error {
|
|
||||||
println("ee")
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
|
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{Name: "config", Aliases: []string{"c"}, Usage: "client config file"},
|
&cli.StringFlag{Name: "config", Aliases: []string{"c"}, Usage: "client config file"},
|
||||||
&cli.StringFlag{Name: "since", Aliases: []string{"s"}, Usage: "return events since `SINCE` (Unix timestamp, or all)"},
|
&cli.StringFlag{Name: "since", Aliases: []string{"s"}, Usage: "return events since `SINCE` (Unix timestamp, or all)"},
|
||||||
|
@ -109,26 +104,26 @@ func execSubscribe(c *cli.Context) error {
|
||||||
|
|
||||||
// Execute poll or subscribe
|
// Execute poll or subscribe
|
||||||
if poll {
|
if poll {
|
||||||
return execPoll(c, cl, conf, topic, command, options...)
|
return doPoll(c, cl, conf, topic, command, options...)
|
||||||
}
|
}
|
||||||
return execSubscribeInternal(c, cl, conf, topic, command, options...)
|
return doSubscribe(c, cl, conf, topic, command, options...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func execPoll(c *cli.Context, cl *client.Client, conf *client.Config, topic, command string, options ...client.SubscribeOption) error {
|
func doPoll(c *cli.Context, cl *client.Client, conf *client.Config, topic, command string, options ...client.SubscribeOption) error {
|
||||||
for _, s := range conf.Subscribe { // may be nil
|
for _, s := range conf.Subscribe { // may be nil
|
||||||
if err := execPollSingle(c, cl, s.Topic, s.Command, options...); err != nil {
|
if err := doPollSingle(c, cl, s.Topic, s.Command, options...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if topic != "" {
|
if topic != "" {
|
||||||
if err := execPollSingle(c, cl, topic, command, options...); err != nil {
|
if err := doPollSingle(c, cl, topic, command, options...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func execPollSingle(c *cli.Context, cl *client.Client, topic, command string, options ...client.SubscribeOption) error {
|
func doPollSingle(c *cli.Context, cl *client.Client, topic, command string, options ...client.SubscribeOption) error {
|
||||||
messages, err := cl.Poll(topic, options...)
|
messages, err := cl.Poll(topic, options...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -139,7 +134,7 @@ func execPollSingle(c *cli.Context, cl *client.Client, topic, command string, op
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func execSubscribeInternal(c *cli.Context, cl *client.Client, conf *client.Config, topic, command string, options ...client.SubscribeOption) error {
|
func doSubscribe(c *cli.Context, cl *client.Client, conf *client.Config, topic, command string, options ...client.SubscribeOption) error {
|
||||||
commands := make(map[string]string)
|
commands := make(map[string]string)
|
||||||
for _, s := range conf.Subscribe { // May be nil
|
for _, s := range conf.Subscribe { // May be nil
|
||||||
topicURL := cl.Subscribe(s.Topic, options...)
|
topicURL := cl.Subscribe(s.Topic, options...)
|
||||||
|
|
BIN
docs/static/img/cli-subscribe-video-3.webm
vendored
Normal file
BIN
docs/static/img/cli-subscribe-video-3.webm
vendored
Normal file
Binary file not shown.
|
@ -5,10 +5,10 @@ to topics via the ntfy CLI. The CLI is included in the same `ntfy` binary that c
|
||||||
!!! info
|
!!! info
|
||||||
The **ntfy CLI is not required to send or receive messages**. You can instead [send messages with curl](../publish.md),
|
The **ntfy CLI is not required to send or receive messages**. You can instead [send messages with curl](../publish.md),
|
||||||
and even use it to [subscribe to topics](api.md). It may be a little more convenient to use the ntfy CLI than writing
|
and even use it to [subscribe to topics](api.md). It may be a little more convenient to use the ntfy CLI than writing
|
||||||
your own script. Or it may not be. It all depends on the use case. 😀
|
your own script. It all depends on the use case. 😀
|
||||||
|
|
||||||
## Install + configure
|
## Install + configure
|
||||||
To install the ntfy CLI, simply follow the steps outlined on the [install page](../install.md). The ntfy server and
|
To install the ntfy CLI, simply **follow the steps outlined on the [install page](../install.md)**. The ntfy server and
|
||||||
client are the same binary, so it's all very convenient. After installing, you can (optionally) configure the client
|
client are the same binary, so it's all very convenient. After installing, you can (optionally) configure the client
|
||||||
by creating `~/.config/ntfy/client.yml` (for the non-root user), or `/etc/ntfy/client.yml` (for the root user). You
|
by creating `~/.config/ntfy/client.yml` (for the non-root user), or `/etc/ntfy/client.yml` (for the root user). You
|
||||||
can find a [skeleton config](https://github.com/binwiederhier/ntfy/blob/main/client/client.yml) on GitHub.
|
can find a [skeleton config](https://github.com/binwiederhier/ntfy/blob/main/client/client.yml) on GitHub.
|
||||||
|
@ -23,7 +23,7 @@ you may want to edit the `default-host` option:
|
||||||
default-host: https://ntfy.myhost.com
|
default-host: https://ntfy.myhost.com
|
||||||
```
|
```
|
||||||
|
|
||||||
## Publish using the ntfy CLI
|
## Publish messages
|
||||||
You can send messages with the ntfy CLI using the `ntfy publish` command (or any of its aliases `pub`, `send` or
|
You can send messages with the ntfy CLI using the `ntfy publish` command (or any of its aliases `pub`, `send` or
|
||||||
`trigger`). There are a lot of examples on the page about [publishing messages](../publish.md), but here are a few
|
`trigger`). There are a lot of examples on the page about [publishing messages](../publish.md), but here are a few
|
||||||
quick ones:
|
quick ones:
|
||||||
|
@ -56,20 +56,23 @@ quick ones:
|
||||||
ntfy pub mywebhook
|
ntfy pub mywebhook
|
||||||
```
|
```
|
||||||
|
|
||||||
## Subscribe using the ntfy CLI
|
## Subscribe to topics
|
||||||
You can subscribe to topics using `ntfy subscribe`. Depending on how it is called, this command
|
You can subscribe to topics using `ntfy subscribe`. Depending on how it is called, this command
|
||||||
will either print or execute a command for every arriving message. There are a few different ways
|
will either print or execute a command for every arriving message. There are a few different ways
|
||||||
in which the command can be run:
|
in which the command can be run:
|
||||||
|
|
||||||
### Stream messages and print JSON
|
### Stream messages as JSON
|
||||||
If run like this `ntfy subscribe TOPIC`, the command prints the JSON representation of every incoming
|
```
|
||||||
message. This is useful when you have a command that wants to stream-read incoming JSON messages.
|
ntfy subscribe TOPIC
|
||||||
Unless `--poll` is passed, this command stays open forever.
|
```
|
||||||
|
If you run the command like this, it prints the JSON representation of every incoming message. This is useful
|
||||||
|
when you have a command that wants to stream-read incoming JSON messages. Unless `--poll` is passed, this command
|
||||||
|
stays open forever.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ ntfy sub mytopic
|
$ ntfy sub mytopic
|
||||||
{"id":"nZ8PjH5oox","time":1639971913,"event":"message","topic":"mytopic","message":"hi there"}
|
{"id":"nZ8PjH5oox","time":1639971913,"event":"message","topic":"mytopic","message":"hi there"}
|
||||||
{"id":"sekSLWTujn","time":1639972063,"event":"message","topic":"mytopic","tags":["warning","skull"],"message":"Oh no, something went wrong"}
|
{"id":"sekSLWTujn","time":1639972063,"event":"message","topic":"mytopic",priority:5,"message":"Oh no!"}
|
||||||
```
|
```
|
||||||
|
|
||||||
<figure>
|
<figure>
|
||||||
|
@ -77,15 +80,28 @@ $ ntfy sub mytopic
|
||||||
<figcaption>Subscribe in JSON mode</figcaption>
|
<figcaption>Subscribe in JSON mode</figcaption>
|
||||||
</figure>
|
</figure>
|
||||||
|
|
||||||
### Execute a command for every incoming message
|
### Run command for every message
|
||||||
If run like this `ntfy subscribe TOPIC COMMAND`, a COMMAND is executed for every incoming messages.
|
```
|
||||||
The message fields are passed to the command as environment variables and can be used in scripts:
|
ntfy subscribe TOPIC COMMAND
|
||||||
|
```
|
||||||
|
If you run it like this, a COMMAND is executed for every incoming messages. Here are a few
|
||||||
|
examples:
|
||||||
|
|
||||||
|
```
|
||||||
|
ntfy sub mytopic 'notify-send "$m"'
|
||||||
|
ntfy sub topic1 /my/script.sh
|
||||||
|
ntfy sub topic1 'echo "Message $m was received. Its title was $t and it had priority $p'
|
||||||
|
```
|
||||||
|
|
||||||
<figure>
|
<figure>
|
||||||
<video controls muted autoplay loop width="650" src="../../static/img/cli-subscribe-video-2.webm"></video>
|
<video controls muted autoplay loop width="650" src="../../static/img/cli-subscribe-video-2.webm"></video>
|
||||||
<figcaption>Execute command on incoming messages</figcaption>
|
<figcaption>Execute command on incoming messages</figcaption>
|
||||||
</figure>
|
</figure>
|
||||||
|
|
||||||
|
The message fields are passed to the command as environment variables and can be used in scripts. Note that since
|
||||||
|
these are environment variables, you typically don't have to worry about quoting too much, as long as you enclose them
|
||||||
|
in double-quotes, you should be fine:
|
||||||
|
|
||||||
| Variable | Aliases | Description |
|
| Variable | Aliases | Description |
|
||||||
|---|---|---
|
|---|---|---
|
||||||
| `$NTFY_ID` | `$id` | Unique message ID |
|
| `$NTFY_ID` | `$id` | Unique message ID |
|
||||||
|
@ -96,32 +112,78 @@ The message fields are passed to the command as environment variables and can be
|
||||||
| `$NTFY_PRIORITY` | `$priority`, `$p` | Message priority (1=min, 5=max) |
|
| `$NTFY_PRIORITY` | `$priority`, `$p` | Message priority (1=min, 5=max) |
|
||||||
| `$NTFY_TAGS` | `$tags`, `$ta` | Message tags (comma separated list) |
|
| `$NTFY_TAGS` | `$tags`, `$ta` | Message tags (comma separated list) |
|
||||||
|
|
||||||
Examples:
|
### Subscribing to multiple topics
|
||||||
ntfy sub mytopic 'notify-send "$m"' # Execute command for incoming messages
|
```
|
||||||
ntfy sub topic1 /my/script.sh # Execute script for incoming messages
|
|
||||||
|
|
||||||
### Using a config file
|
|
||||||
ntfy subscribe --from-config
|
ntfy subscribe --from-config
|
||||||
Service mode (used in ntfy-client.service). This reads the config file (/etc/ntfy/client.yml
|
```
|
||||||
or ~/.config/ntfy/client.yml) and sets up subscriptions for every topic in the "subscribe:"
|
To subscribe to multiple topics at once, and run different commands for each one, you can use `ntfy subscribe --from-config`,
|
||||||
block (see config file).
|
which will read the `subscribe` config from the config file. Please also check out the [ntfy-client systemd service](#using-the-systemd-service).
|
||||||
|
|
||||||
Examples:
|
Here's an example config file that subscribes to three different topics, executing a different command for each of them:
|
||||||
ntfy sub --from-config # Read topics from config file
|
|
||||||
ntfy sub --config=/my/client.yml --from-config # Read topics from alternate config file
|
|
||||||
|
|
||||||
The default config file for all client commands is /etc/ntfy/client.yml (if root user),
|
=== "~/.config/ntfy/client.yml"
|
||||||
or ~/.config/ntfy/client.yml for all other users.
|
```yaml
|
||||||
|
subscribe:
|
||||||
|
- topic: echo-this
|
||||||
|
command: 'echo "Message received: $message"'
|
||||||
|
- topic: get-temp
|
||||||
|
command: |
|
||||||
|
temp="$(sensors | awk '/Package/ { print $4 }')"
|
||||||
|
ntfy publish --quiet temp "$temp";
|
||||||
|
echo "CPU temp is $temp; published to topic 'temp'"
|
||||||
|
- topic: alerts
|
||||||
|
command: notify-send "$m"
|
||||||
|
- topic: calc
|
||||||
|
command: 'gnome-calculator 2>/dev/null &'
|
||||||
|
```
|
||||||
|
|
||||||
|
In this example, when `ntfy subscribe --from-config` is executed:
|
||||||
|
|
||||||
|
* Messages to topic `echo-this` will be simply echoed to standard out
|
||||||
|
* Messages to topic `get-temp` will publish the CPU core temperature to topic `temp`
|
||||||
|
* Messages to topic `alerts` will be displayed as desktop notification using `notify-send`
|
||||||
|
* And messages to topic `calc` will open the gnome calculator 😀 (*because, why not*)
|
||||||
|
|
||||||
|
I hope this shows how powerful this command is. Here's a short video that demonstrates the above example:
|
||||||
|
|
||||||
|
<figure>
|
||||||
|
<video controls muted autoplay loop width="650" src="../../static/img/cli-subscribe-video-3.webm"></video>
|
||||||
|
<figcaption>Execute all the things</figcaption>
|
||||||
|
</figure>
|
||||||
|
|
||||||
### Using the systemd service
|
### Using the systemd service
|
||||||
|
You can use the `ntfy-client` systemd service (see [ntfy-client.service](https://github.com/binwiederhier/ntfy/blob/main/client/ntfy-client.service))
|
||||||
|
to subscribe to multiple topics just like in the example above. The service is automatically installed (but not started)
|
||||||
|
if you install the deb/rpm package. To configure it, simply edit `/etc/ntfy/client.yml` and run `sudo systemctl restart ntfy-client`.
|
||||||
|
|
||||||
|
!!! info
|
||||||
|
The `ntfy-client.service` runs as user `ntfy`, meaning that typical Linux permission restrictions apply. See below
|
||||||
|
for how to fix this.
|
||||||
|
|
||||||
|
If it runs on your personal desktop machine, you may want to override the service user/group (`User=` and `Group=`), and
|
||||||
|
adjust the `DISPLAY` and DBUS environment variables. This will allow you to run commands in your X session as the primary
|
||||||
|
machine user.
|
||||||
|
|
||||||
|
You can either manually override these systemd service entries with `sudo systemctl edit ntfy-client`, and add this
|
||||||
|
(assuming your user is `pheckel`):
|
||||||
|
|
||||||
|
=== "/etc/systemd/system/ntfy-client.service.d/override.conf"
|
||||||
```
|
```
|
||||||
[Service]
|
[Service]
|
||||||
User=pheckel
|
User=pheckel
|
||||||
Group=pheckel
|
Group=pheckel
|
||||||
Environment="DISPLAY=:0" "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus"
|
Environment="DISPLAY=:0" "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus"
|
||||||
```
|
```
|
||||||
|
Or you can run the following script that creates this override config for you:
|
||||||
|
|
||||||
Here's an example for a complete client config for a self-hosted server:
|
```
|
||||||
|
sudo sh -c 'cat > /etc/systemd/system/ntfy-client.service.d/override.conf' <<EOF
|
||||||
|
[Service]
|
||||||
|
User=$USER
|
||||||
|
Group=$USER
|
||||||
|
Environment="DISPLAY=:0" "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl restart ntfy-client
|
||||||
|
```
|
||||||
|
|
Loading…
Reference in a new issue