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 { Description string 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 { if po.Description != "" { return po.Description } 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 // Prio updated.Prio, err = strconv.Atoi(values.Get("prio")) if err != nil { return werr.Wrap(err) } // Description updated.Description = strings.TrimSpace(values.Get("description")) // API (application) key givenAPIKey := values.Get("api_key") if strings.TrimSpace(givenAPIKey) == "" { return werr.New("API key cannot be empty") } updated.APIKey = strings.TrimSpace(givenAPIKey) // User key givenUserKey := values.Get("user_key") if strings.TrimSpace(givenUserKey) == "" { return werr.New("User key cannot be empty") } updated.UserKey = strings.TrimSpace(givenUserKey) // Device name 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.Description = updatedPushover.Description po.APIKey = updatedPushover.APIKey po.UserKey = updatedPushover.UserKey po.DeviceName = updatedPushover.DeviceName } func (po Pushover) JSON() []byte { data := struct { Description string APIKey string `json:"api_key"` UserKey string `json:"user_key"` DeviceName string `json:"device_name"` }{ po.Description, po.APIKey, po.UserKey, po.DeviceName, } j, _ := json.Marshal(data) return j }