Skip to content

Commit

Permalink
feat: support signal rest api notifications (#650)
Browse files Browse the repository at this point in the history
  • Loading branch information
MrRagga- committed Oct 8, 2022
1 parent 34316bc commit 42e684d
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 13 deletions.
27 changes: 14 additions & 13 deletions docs/config/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ You can override this using the [`--config` flag or `CONFIG` env var with `serve
```yaml
db:
path: diun.db

watch:
workers: 10
schedule: "0 */6 * * *"
firstCheckNotif: false

notif:
amqp:
host: localhost
Expand Down Expand Up @@ -82,7 +82,7 @@ You can override this using the [`--config` flag or `CONFIG` env var with `serve
content-type: application/json
authorization: Token123456
timeout: 10s

regopts:
- name: "myregistry"
username: foo
Expand All @@ -93,7 +93,7 @@ You can override this using the [`--config` flag or `CONFIG` env var with `serve
selector: image
username: foo2
password: bar2

providers:
docker:
watchStopped: true
Expand All @@ -115,12 +115,12 @@ All configuration from file can be transposed into environment variables. As an
```yaml
db:
path: diun.db

watch:
workers: 10
schedule: "0 */6 * * *"
firstCheckNotif: false

notif:
gotify:
endpoint: http://gotify.foo.com
Expand All @@ -139,7 +139,7 @@ All configuration from file can be transposed into environment variables. As an
content-type: application/json
authorization: Token123456
timeout: 10s

regopts:
- name: "docker.io"
selector: image
Expand All @@ -164,25 +164,25 @@ Can be transposed to:
??? example "environment variables"
```
DIUN_DB_PATH=diun.db

DIUN_WATCH_WORKERS=10
DIUN_WATCH_SCHEDULE=0 */6 * * *
DIUN_WATCH_FIRSTCHECKNOTIF=false

DIUN_NOTIF_GOTIFY_ENDPOINT=http://gotify.foo.com
DIUN_NOTIF_GOTIFY_TOKEN=Token123456
DIUN_NOTIF_GOTIFY_PRIORITY=1
DIUN_NOTIF_GOTIFY_TIMEOUT=10s

DIUN_NOTIF_TELEGRAM_TOKEN=aabbccdd:11223344
DIUN_NOTIF_TELEGRAM_CHATIDS=123456789,987654321

DIUN_NOTIF_WEBHOOK_ENDPOINT=http://webhook.foo.com/sd54qad89azd5a
DIUN_NOTIF_WEBHOOK_METHOD=GET
DIUN_NOTIF_WEBHOOK_HEADERS_CONTENT-TYPE=application/json
DIUN_NOTIF_WEBHOOK_HEADERS_AUTHORIZATION=Token123456
DIUN_NOTIF_WEBHOOK_TIMEOUT=10s

DIUN_REGOPTS_0_NAME=docker.io
DIUN_REGOPTS_0_SELECTOR=image
DIUN_REGOPTS_0_USERNAME=foo
Expand All @@ -192,7 +192,7 @@ Can be transposed to:
DIUN_REGOPTS_1_USERNAME=fii
DIUN_REGOPTS_1_PASSWORD=bor
DIUN_REGOPTS_1_TIMEOUT=20s

PROVIDERS_KUBERNETES_TLSINSECURE=false
PROVIDERS_KUBERNETES_NAMESPACES=default,production
```
Expand All @@ -212,6 +212,7 @@ Can be transposed to:
* [rocketchat](../notif/rocketchat.md)
* [script](../notif/script.md)
* [slack](../notif/slack.md)
* [signal-rest](../notif/signalrest.md)
* [teams](../notif/teams.md)
* [telegram](../notif/telegram.md)
* [webhook](../notif/webhook.md)
Expand Down
1 change: 1 addition & 0 deletions docs/config/notif.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* [`pushover`](../notif/pushover.md)
* [`rocketchat`](../notif/rocketchat.md)
* [`script`](../notif/script.md)
* [`signal-rest`](../notif/signalrest.md)
* [`slack`](../notif/slack.md)
* [`teams`](../notif/teams.md)
* [`telegram`](../notif/telegram.md)
Expand Down
41 changes: 41 additions & 0 deletions docs/notif/signalrest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Signal-REST notifications

The notification uses the [Signal REST API](https://github.com/bbernhard/signal-cli-rest-api).

You can send Signal notifications via the Signal REST API with the following settings.

## Configuration

!!! example "File"
```yaml
notif:
signalrest:
endpoint: http://192.168.42.50:8080/v2/send
number: "+00471147111337"
recipients:
- "+00472323111337"
timeout: 10s
```

| Name | Default | Description |
|--------------------|---------------------------------|-----------------------------------------------------------|
| `endpoint` | `http://localhost:8080/v2/send` | URL of the Signal REST API endpoint |
| `number`[^1] | | The senders number you registered |
| `recipients`[^1] | | A list of recipients, either phone numbers or group ID's |
| `timeout` | `10s` | Timeout specifies a time limit for the request to be made |

!!! abstract "Environment variables"
* `DIUN_NOTIF_SIGNALREST_ENDPOINT`
* `DIUN_NOTIF_SIGNALREST_NUMBER`
* `DIUN_NOTIF_SIGNALREST_RECIPIENTS_<KEY>`
* `DIUN_NOTIF_SIGNALREST_TIMEOUT`

## Sample

The message you receive in your Signal App will look like this:

```text
Docker tag docker.io/diun/testnotif:latest which you subscribed to through file provider new has been updated on docker.io registry (triggered by5bfaae601770 host).
```

[^1]: Value required
1 change: 1 addition & 0 deletions internal/model/notif.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type Notif struct {
Pushover *NotifPushover `yaml:"pushover,omitempty" json:"pushover,omitempty"`
RocketChat *NotifRocketChat `yaml:"rocketchat,omitempty" json:"rocketchat,omitempty"`
Script *NotifScript `yaml:"script,omitempty" json:"script,omitempty"`
SignalRest *NotifSignalRest `yaml:"signalrest,omitempty" json:"signalrest,omitempty"`
Slack *NotifSlack `yaml:"slack,omitempty" json:"slack,omitempty"`
Teams *NotifTeams `yaml:"teams,omitempty" json:"teams,omitempty"`
Telegram *NotifTelegram `yaml:"telegram,omitempty" json:"telegram,omitempty"`
Expand Down
29 changes: 29 additions & 0 deletions internal/model/notif_signalrest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package model

import (
"time"

"github.com/crazy-max/diun/v4/pkg/utl"
)

// NotifSignalRest holds SignalRest notification configuration details
type NotifSignalRest struct {
Endpoint string `yaml:"endpoint,omitempty" json:"endpoint,omitempty" validate:"required"`
Number string `yaml:"number,omitempty" json:"method,omitempty" validate:"required"`
Recipients []string `yaml:"recipients,omitempty" json:"recipients,omitempty" validate:"omitempty"`
Headers map[string]string `yaml:"headers,omitempty" json:"headers,omitempty" validate:"omitempty"`
Timeout *time.Duration `yaml:"timeout,omitempty" json:"timeout,omitempty" validate:"required"`
}

// GetDefaults gets the default values
func (s *NotifSignalRest) GetDefaults() *NotifSignalRest {
n := &NotifSignalRest{}
n.SetDefaults()
return n
}

// SetDefaults sets the default values
func (s *NotifSignalRest) SetDefaults() {
s.Timeout = utl.NewDuration(10 * time.Second)
s.Endpoint = "http://localhost:8080/v2/send"
}
4 changes: 4 additions & 0 deletions internal/notif/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/crazy-max/diun/v4/internal/notif/pushover"
"github.com/crazy-max/diun/v4/internal/notif/rocketchat"
"github.com/crazy-max/diun/v4/internal/notif/script"
"github.com/crazy-max/diun/v4/internal/notif/signalrest"
"github.com/crazy-max/diun/v4/internal/notif/slack"
"github.com/crazy-max/diun/v4/internal/notif/teams"
"github.com/crazy-max/diun/v4/internal/notif/telegram"
Expand Down Expand Up @@ -69,6 +70,9 @@ func New(config *model.Notif, meta model.Meta) (*Client, error) {
if config.Script != nil {
c.notifiers = append(c.notifiers, script.New(config.Script, meta))
}
if config.SignalRest != nil {
c.notifiers = append(c.notifiers, signalrest.New(config.SignalRest, meta))
}
if config.Slack != nil {
c.notifiers = append(c.notifiers, slack.New(config.Slack, meta))
}
Expand Down
69 changes: 69 additions & 0 deletions internal/notif/signalrest/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package signalrest

import (
"bytes"
"encoding/json"
"net/http"

"github.com/crazy-max/diun/v4/internal/model"
"github.com/crazy-max/diun/v4/internal/notif/notifier"
)

// Client represents an active signalrest notification object
type Client struct {
*notifier.Notifier
cfg *model.NotifSignalRest
meta model.Meta
}

// New creates a new signalrest notification instance
func New(config *model.NotifSignalRest, meta model.Meta) notifier.Notifier {
return notifier.Notifier{
Handler: &Client{
cfg: config,
meta: meta,
},
}
}

// Name returns notifier's name
func (c *Client) Name() string {
return "signalrest"
}

// Send creates and sends a signalrest notification with an entry
func (c *Client) Send(entry model.NotifEntry) error {
hc := http.Client{
Timeout: *c.cfg.Timeout,
}

body, err := json.Marshal(struct {
Message string `json:"message"`
Number string `json:"number"`
Recipients []string `json:"recipients"`
}{
Message: "Docker tag " + entry.Image.String() + " which you subscribed to through " + entry.Provider + " provider " + string(entry.Status) + " has been updated on " + entry.Image.Domain + " registry (triggered by" + c.meta.Hostname + " host).",
Number: c.cfg.Number,
Recipients: c.cfg.Recipients,
})
if err != nil {
return err
}

req, err := http.NewRequest("POST", c.cfg.Endpoint, bytes.NewBuffer(body))
if err != nil {
return err
}

if len(c.cfg.Headers) > 0 {
for key, value := range c.cfg.Headers {
req.Header.Add(key, value)
}
}

req.Header.Set("Content-Type", "application/json")
req.Header.Set("User-Agent", c.meta.UserAgent)

_, err = hc.Do(req)
return err
}
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ nav:
- Pushover: notif/pushover.md
- Rocket.Chat: notif/rocketchat.md
- Script: notif/script.md
- Signal (REST API): notif/signalrest.md
- Slack: notif/slack.md
- Teams: notif/teams.md
- Telegram: notif/telegram.md
Expand Down

0 comments on commit 42e684d

Please sign in to comment.