Added Pushover notification

This commit is contained in:
Magnus Åhall 2024-07-04 19:21:02 +02:00
parent 5d24baedac
commit 257a4968ec
5 changed files with 246 additions and 2 deletions

View file

@ -24,6 +24,16 @@ func ServiceFactory(t string, config []byte, prio int, ackURL string, logger *sl
}
ntfy.SetLogger(logger)
return ntfy, nil
case "PUSHOVER":
pushover, err := NewPushover(config, prio, ackURL)
if err != nil {
err = werr.Wrap(err).WithData(config)
return nil, err
}
pushover.SetLogger(logger)
return pushover, nil
case "SCRIPT":
script, err := NewScript(config, prio, ackURL)
if err != nil {
@ -41,6 +51,8 @@ func NewInstance(typ string) Service {
switch typ {
case "NTFY":
return new(NTFY)
case "PUSHOVER":
return new(Pushover)
case "SCRIPT":
return new(Script)
}

183
notification/pushover.go Normal file
View file

@ -0,0 +1,183 @@
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 Pushover struct {
UserKey string `json:"user_key"`
APIKey string `json:"api_key"`
DeviceName string `json:"device_name"`
Prio int
AcknowledgeURL string
logger *slog.Logger
exists bool
updated Service
}
func init() {
allServices = append(allServices, &Pushover{})
}
func NewPushover(config []byte, prio int, ackURL string) (instance *Pushover, err error) {
instance = new(Pushover)
err = json.Unmarshal(config, &instance)
if err != nil {
err = werr.Wrap(err).WithData(config)
return
}
instance.Prio = prio
instance.AcknowledgeURL = ackURL
return instance, nil
}
func (po *Pushover) SetLogger(l *slog.Logger) {
po.logger = l
}
func (po *Pushover) GetType() string {
return "PUSHOVER"
}
func (po *Pushover) GetPrio() int {
return po.Prio
}
func (po *Pushover) SetPrio(prio int) {
po.Prio = prio
}
func (po *Pushover) SetExists(exists bool) {
po.exists = exists
}
func (po Pushover) Exists() bool {
return po.exists
}
func (po *Pushover) String() string {
return fmt.Sprintf("%s, %s", po.UserKey, po.APIKey)
}
func (po Pushover) Send(problemID int, msg []byte) (err error) {
var req *http.Request
var res *http.Response
pushoverRequest, _ := json.Marshal(map[string]string{
"token": po.APIKey,
"user": po.UserKey,
"device": po.DeviceName,
"message": string(msg),
})
req, err = http.NewRequest("POST", "https://api.pushover.net/1/messages.json", bytes.NewReader(pushoverRequest))
if err != nil {
err = werr.Wrap(err).WithData(struct {
UserKey string
APIKey string
Msg []byte
}{
po.UserKey,
po.APIKey,
msg,
},
)
return
}
//ackURL := fmt.Sprintf("http, OK, %s/notification/ack?problemID=%d", po.AcknowledgeURL, problemID)
req.Header.Add("Content-Type", "application/json")
res, err = http.DefaultClient.Do(req)
if err != nil {
err = werr.Wrap(err)
return
}
body, _ := io.ReadAll(res.Body)
poResp := struct {
Status int
Errors []string
}{}
err = json.Unmarshal(body, &poResp)
if err != nil {
err = werr.Wrap(err).WithData(body)
return
}
if poResp.Status != 1 {
err = werr.New("%s", strings.Join(poResp.Errors, ", "))
return
}
if res.StatusCode != 200 {
err = werr.New("Invalid Pushover response").WithData(body)
return
}
return
}
func (po *Pushover) Update(values url.Values) (err error) {
updated := Pushover{}
po.updated = &updated
updated.Prio, err = strconv.Atoi(values.Get("prio"))
if err != nil {
return werr.Wrap(err)
}
givenAPIKey := values.Get("api_key")
if strings.TrimSpace(givenAPIKey) == "" {
return werr.New("API key cannot be empty")
}
updated.APIKey = strings.TrimSpace(givenAPIKey)
givenUserKey := values.Get("user_key")
if strings.TrimSpace(givenUserKey) == "" {
return werr.New("User key cannot be empty")
}
updated.UserKey = strings.TrimSpace(givenUserKey)
updated.DeviceName = strings.TrimSpace(values.Get("device_name"))
return
}
func (po *Pushover) Updated() Service {
return po.updated
}
func (po *Pushover) Commit() {
updatedPushover := po.updated.(*Pushover)
po.Prio = updatedPushover.Prio
po.APIKey = updatedPushover.APIKey
po.UserKey = updatedPushover.UserKey
po.DeviceName = updatedPushover.DeviceName
}
func (po Pushover) JSON() []byte {
data := struct {
APIKey string `json:"api_key"`
UserKey string `json:"user_key"`
DeviceName string `json:"device_name"`
}{
po.APIKey,
po.UserKey,
po.DeviceName,
}
j, _ := json.Marshal(data)
return j
}