smon/notification/ntfy.go

147 lines
2.7 KiB
Go

package notification
import (
// External
werr "git.gibonuddevalla.se/go/wrappederror"
// Standard
"bytes"
"encoding/json"
"fmt"
"io"
"log/slog"
"net/http"
"net/url"
"strconv"
"strings"
)
type NTFY struct {
URL string
Prio int
AcknowledgeURL string
logger *slog.Logger
exists bool
updated Service
}
func init() {
allServices = append(allServices, &NTFY{})
}
func NewNTFY(config []byte, prio int, ackURL string) (instance *NTFY, err error) {
instance = new(NTFY)
err = json.Unmarshal(config, &instance)
if err != nil {
err = werr.Wrap(err).WithCode("002-0001").WithData(config)
return
}
instance.Prio = prio
instance.AcknowledgeURL = ackURL
return instance, nil
}
func (ntfy *NTFY) SetLogger(l *slog.Logger) {
ntfy.logger = l
}
func (ntfy *NTFY) GetType() string {
return "NTFY"
}
func (ntfy *NTFY) GetPrio() int {
return ntfy.Prio
}
func (ntfy *NTFY) SetPrio(prio int) {
ntfy.Prio = prio
}
func (ntfy *NTFY) SetExists(exists bool) {
ntfy.exists = exists
}
func (ntfy NTFY) Exists() bool {
return ntfy.exists
}
func (ntfy *NTFY) String() string {
return ntfy.URL
}
func (ntfy NTFY) Send(problemID int, msg []byte) (err error) {
var req *http.Request
var res *http.Response
req, err = http.NewRequest("POST", ntfy.URL, bytes.NewReader(msg))
if err != nil {
err = werr.Wrap(err).WithCode("002-0002").WithData(ntfy.URL)
return
}
ackURL := fmt.Sprintf("http, OK, %s/notification/ack?problemID=%d", ntfy.AcknowledgeURL, problemID)
req.Header.Add("X-Actions", ackURL)
req.Header.Add("X-Priority", "5")
req.Header.Add("X-Tags", "calendar")
res, err = http.DefaultClient.Do(req)
if err != nil {
err = werr.Wrap(err).WithCode("002-0003")
return
}
body, _ := io.ReadAll(res.Body)
if res.StatusCode != 200 {
err = werr.New("Invalid NTFY response").WithCode("002-0004").WithData(body)
return
}
ntfyResp := struct {
ID string
}{}
err = json.Unmarshal(body, &ntfyResp)
if err != nil {
err = werr.Wrap(err).WithCode("002-0005").WithData(body)
return
}
return
}
func (ntfy *NTFY) Update(values url.Values) (err error) {
updated := NTFY{}
ntfy.updated = &updated
updated.Prio, err = strconv.Atoi(values.Get("prio"))
if err != nil {
return werr.Wrap(err)
}
givenURL := values.Get("url")
if strings.TrimSpace(givenURL) == "" {
return werr.New("URL cannot be empty")
}
updated.URL = strings.TrimSpace(givenURL)
return
}
func (ntfy *NTFY) Updated() Service {
return ntfy.updated
}
func (ntfy *NTFY) Commit() {
updatedNTFY := ntfy.updated.(*NTFY)
ntfy.Prio = updatedNTFY.Prio
ntfy.URL = updatedNTFY.URL
}
func (ntfy NTFY) JSON() []byte {
data := struct {
URL string `json:"url"`
}{
ntfy.URL,
}
j, _ := json.Marshal(data)
return j
}