Adds ntfy.sh notification option

This commit is contained in:
Ben Tea
2023-02-18 17:29:14 -08:00
parent 9ef735a499
commit 1da9ec5308
11 changed files with 244 additions and 0 deletions

View File

@@ -127,6 +127,15 @@ for <code>{{ .Entry.Manifest.Platform }}</code> platform.
Topic: "docker/diun",
QoS: 0,
},
Ntfy: &model.NotifNtfy{
Endpoint: "https://ntfy.sh",
Topic: "diun-acce65a0-b777-46f9-9a11-58c67d1579c4",
Priority: 3,
Tags: []string{"package"},
Timeout: utl.NewDuration(10 * time.Second),
TemplateTitle: model.NotifDefaultTemplateTitle,
TemplateBody: model.NotifDefaultTemplateBody,
},
Pushover: &model.NotifPushover{
Token: "uQiRzpo4DXghDmr9QzzfQu27cmVRsG",
Recipient: "gznej3rKEVAvPUxu9vvNnqpmZpokzF",

View File

@@ -63,6 +63,13 @@ notif:
client: "diun"
topic: "docker/diun"
qos: 0
ntfy:
endpoint: https://ntfy.sh
topic: diun-acce65a0-b777-46f9-9a11-58c67d1579c4
priority: 3
tags:
- package
timeout: 10s
pushover:
token: uQiRzpo4DXghDmr9QzzfQu27cmVRsG
recipient: gznej3rKEVAvPUxu9vvNnqpmZpokzF

View File

@@ -61,6 +61,13 @@ notif:
client: "diun"
topic: "docker/diun"
qos: 0
ntfy:
endpoint: https://ntfy.sh
topic: diun-acce65a0-b777-46f9-9a11-58c67d1579c4
priority: 3
tags:
- package
timeout: 10s
pushover:
token: uQiRzpo4DXghDmr9QzzfQu27cmVRsG
recipient: gznej3rKEVAvPUxu9vvNnqpmZpokzF

View File

@@ -38,6 +38,7 @@ type Notif struct {
Mail *NotifMail `yaml:"mail,omitempty" json:"mail,omitempty"`
Matrix *NotifMatrix `yaml:"matrix,omitempty" json:"matrix,omitempty"`
Mqtt *NotifMqtt `yaml:"mqtt,omitempty" json:"mqtt,omitempty"`
Ntfy *NotifNtfy `yaml:"ntfy,omitempty" json:"ntfy,omitempty"`
Pushover *NotifPushover `yaml:"pushover,omitempty" json:"pushover,omitempty"`
RocketChat *NotifRocketChat `yaml:"rocketchat,omitempty" json:"rocketchat,omitempty"`
Script *NotifScript `yaml:"script,omitempty" json:"script,omitempty"`

View File

@@ -0,0 +1,35 @@
package model
import (
"time"
"github.com/crazy-max/diun/v4/pkg/utl"
)
// NotifNtfy holds ntfy notification configuration details
type NotifNtfy struct {
Endpoint string `yaml:"endpoint,omitempty" json:"endpoint,omitempty" validate:"required"`
Topic string `yaml:"topic,omitempty" json:"topic,omitempty" validate:"required"`
Priority int `yaml:"priority,omitempty" json:"priority,omitempty" validate:"omitempty,min=0"`
Tags []string `yaml:"tags,omitempty" json:"tags,omitempty" validate:"required"`
Timeout *time.Duration `yaml:"timeout,omitempty" json:"timeout,omitempty" validate:"required"`
TemplateTitle string `yaml:"templateTitle,omitempty" json:"templateTitle,omitempty" validate:"required"`
TemplateBody string `yaml:"templateBody,omitempty" json:"templateBody,omitempty" validate:"required"`
}
// GetDefaults gets the default values
func (s *NotifNtfy) GetDefaults() *NotifNtfy {
n := &NotifNtfy{}
n.SetDefaults()
return n
}
// SetDefaults sets the default values
func (s *NotifNtfy) SetDefaults() {
s.Endpoint = "https://ntfy.sh"
s.Priority = 3
s.Tags = []string{"package"}
s.Timeout = utl.NewDuration(10 * time.Second)
s.TemplateTitle = NotifDefaultTemplateTitle
s.TemplateBody = NotifDefaultTemplateBody
}

View File

@@ -11,6 +11,7 @@ import (
"github.com/crazy-max/diun/v4/internal/notif/matrix"
"github.com/crazy-max/diun/v4/internal/notif/mqtt"
"github.com/crazy-max/diun/v4/internal/notif/notifier"
"github.com/crazy-max/diun/v4/internal/notif/ntfy"
"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"
@@ -61,6 +62,9 @@ func New(config *model.Notif, meta model.Meta) (*Client, error) {
if config.Mqtt != nil {
c.notifiers = append(c.notifiers, mqtt.New(config.Mqtt, meta))
}
if config.Ntfy != nil {
c.notifiers = append(c.notifiers, ntfy.New(config.Ntfy, meta))
}
if config.Pushover != nil {
c.notifiers = append(c.notifiers, pushover.New(config.Pushover, meta))
}

View File

@@ -0,0 +1,110 @@
package ntfy
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/crazy-max/diun/v4/internal/model"
"github.com/crazy-max/diun/v4/internal/msg"
"github.com/crazy-max/diun/v4/internal/notif/notifier"
)
// Client represents an active ntfy notification object
type Client struct {
*notifier.Notifier
cfg *model.NotifNtfy
meta model.Meta
}
// New creates a new ntfy notification instance
func New(config *model.NotifNtfy, 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 "ntfy"
}
// Send creates and sends a ntfy notification with an entry
func (c *Client) Send(entry model.NotifEntry) error {
hc := http.Client{
Timeout: *c.cfg.Timeout,
}
message, err := msg.New(msg.Options{
Meta: c.meta,
Entry: entry,
TemplateTitle: c.cfg.TemplateTitle,
TemplateBody: c.cfg.TemplateBody,
})
if err != nil {
return err
}
title, body, err := message.RenderMarkdown()
if err != nil {
return err
}
dataBuf := new(bytes.Buffer)
if err := json.NewEncoder(dataBuf).Encode(struct {
Topic string `json:"topic"`
Message string `json:"message"`
Title string `json:"title"`
Priority int `json:"priority"`
Tags []string `json:"tags"`
}{
Topic: c.cfg.Topic,
Message: string(body),
Title: string(title),
Priority: c.cfg.Priority,
Tags: c.cfg.Tags,
}); err != nil {
return err
}
u, err := url.Parse(c.cfg.Endpoint)
if err != nil {
return err
}
q := u.Query()
u.RawQuery = q.Encode()
req, err := http.NewRequest("POST", u.String(), dataBuf)
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("User-Agent", c.meta.UserAgent)
resp, err := hc.Do(req)
if err != nil {
return err
}
if resp.StatusCode != http.StatusOK {
var errBody struct {
Error string `json:"error"`
ErrorCode int `json:"errorCode"`
ErrorDescription string `json:"errorDescription"`
}
err := json.NewDecoder(resp.Body).Decode(&errBody)
if err != nil {
return err
}
return fmt.Errorf("%d %s: %s", errBody.ErrorCode, errBody.Error, errBody.ErrorDescription)
}
return nil
}