Added notification manager
This commit is contained in:
parent
317c233255
commit
49af9dc33c
6 changed files with 318 additions and 51 deletions
23
notification/factory.go
Normal file
23
notification/factory.go
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
package notification
|
||||
|
||||
import (
|
||||
// External
|
||||
werr "git.gibonuddevalla.se/go/wrappederror"
|
||||
|
||||
// Standard
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
func ServiceFactory(t string, config []byte, prio int, ackURL string, logger *slog.Logger) (Service, error) {
|
||||
switch t {
|
||||
case "NTFY":
|
||||
ntfy, err := NewNTFY(config, prio, ackURL)
|
||||
if err != nil {
|
||||
err = werr.Wrap(err).WithData(config)
|
||||
return nil, err
|
||||
}
|
||||
return ntfy, nil
|
||||
}
|
||||
|
||||
return nil, werr.New("Unknown notification service, '%s'", t).WithCode("002-0000")
|
||||
}
|
||||
83
notification/ntfy.go
Normal file
83
notification/ntfy.go
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
package notification
|
||||
|
||||
import (
|
||||
// External
|
||||
werr "git.gibonuddevalla.se/go/wrappederror"
|
||||
|
||||
// Standard
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type NTFY struct {
|
||||
URL string
|
||||
Prio int
|
||||
AcknowledgeURL string
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
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) Send(uuid string, 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?uuid=%s", ntfy.AcknowledgeURL, uuid)
|
||||
req.Header.Add("X-Actions", ackURL)
|
||||
req.Header.Add("X-Priority", "3") // XXX: should be 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
|
||||
}
|
||||
61
notification/pkg.go
Normal file
61
notification/pkg.go
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
package notification
|
||||
|
||||
import (
|
||||
// External
|
||||
werr "git.gibonuddevalla.se/go/wrappederror"
|
||||
|
||||
// Standard
|
||||
"log/slog"
|
||||
"slices"
|
||||
)
|
||||
|
||||
type Service interface {
|
||||
SetLogger(*slog.Logger)
|
||||
GetPrio() int
|
||||
GetType() string
|
||||
Send(string, []byte) error
|
||||
}
|
||||
|
||||
type Manager struct {
|
||||
services []Service
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func NewManager(logger *slog.Logger) (nm Manager) {
|
||||
nm.services = []Service{}
|
||||
nm.logger = logger
|
||||
return
|
||||
}
|
||||
|
||||
func (nm *Manager) AddService(service Service) {
|
||||
nm.services = append(nm.services, service)
|
||||
slices.SortFunc(nm.services, func(a, b Service) int {
|
||||
if a.GetPrio() < b.GetPrio() {
|
||||
return -1
|
||||
}
|
||||
if a.GetPrio() > b.GetPrio() {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
})
|
||||
}
|
||||
|
||||
func (nm *Manager) Send(uuid string, msg []byte) (err error) {
|
||||
for _, service := range nm.services {
|
||||
nm.logger.Info("notification", "service", service.GetType(), "prio", service.GetPrio())
|
||||
if err = service.Send(uuid, msg); err == nil {
|
||||
break
|
||||
} else {
|
||||
data := struct {
|
||||
UUID string
|
||||
Msg []byte
|
||||
}{
|
||||
uuid,
|
||||
msg,
|
||||
}
|
||||
werr.Wrap(err).WithData(data).Log()
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue