add Apprise (#309)

* added apprise

* fixed yaml type, check for / at the end of url

* return error message

* adapted example config and gickup_spec

* re-format spec

* Revert "re-format spec"

This reverts commit b938a0587e.

* fix spec
This commit is contained in:
Andreas Wachter 2025-04-02 18:29:40 +09:00 committed by GitHub
parent 00d278094a
commit 377378ce3a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 126 additions and 4 deletions

View file

@ -311,6 +311,13 @@ metrics:
gotify:
- url: http(s)://url-to-gotify
token: your-token
apprise:
- url: http(s)://url-to-apprise
config: whatever-your-config-id-is
notification_urls:
- urls-to-notify(https://github.com/caronc/apprise/wiki)
tags:
- your-tag
---
# you can define separate source and destination pairs,

View file

@ -1107,6 +1107,37 @@
}
}
}
},
"apprise": {
"type": "array",
"description": "Send notification to apprise (apprise)",
"items": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "The url to your apprise server"
},
"config": {
"type": "string",
"description": "The id of your configuration in apprise"
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "A list of tags you want to send your message to"
},
"notification_urls": {
"type": "array",
"items": {
"type": "string"
},
"description": "A list of urls you want to send notifications to"
}
}
}
}
},
"additionalProperties": false
@ -1115,4 +1146,4 @@
"additionalProperties": false
}
}
}
}

12
main.go
View file

@ -28,6 +28,7 @@ import (
"github.com/cooperspencer/gickup/gogs"
"github.com/cooperspencer/gickup/local"
"github.com/cooperspencer/gickup/logger"
"github.com/cooperspencer/gickup/metrics/apprise"
"github.com/cooperspencer/gickup/metrics/gotify"
"github.com/cooperspencer/gickup/metrics/heartbeat"
"github.com/cooperspencer/gickup/metrics/ntfy"
@ -98,7 +99,7 @@ func readConfigFile(configfile string) []*types.Conf {
if !reflect.ValueOf(c).IsZero() {
if len(conf) > 0 {
if len(c.Metrics.PushConfigs.Gotify) == 0 && len(c.Metrics.PushConfigs.Ntfy) == 0 {
if len(c.Metrics.PushConfigs.Gotify) == 0 && len(c.Metrics.PushConfigs.Ntfy) == 0 && len(c.Metrics.PushConfigs.Apprise) == 0 {
c.Metrics.PushConfigs = conf[0].Metrics.PushConfigs
}
}
@ -873,6 +874,15 @@ func runBackup(conf *types.Conf, num int) {
}
}
if len(conf.Metrics.PushConfigs.Apprise) > 0 {
for _, pusher := range conf.Metrics.PushConfigs.Apprise {
err := apprise.Notify(fmt.Sprintf("backup took %v", duration), *pusher)
if err != nil {
log.Warn().Str("push", "apprise").Err(err).Msg("couldn't send message")
}
}
}
log.Info().
Str("duration", duration.String()).
Msg("Backup run complete")

View file

@ -0,0 +1,65 @@
package apprise
import (
"bytes"
"encoding/json"
"errors"
"io/ioutil"
"net/http"
"strings"
"github.com/cooperspencer/gickup/types"
)
type Request struct {
Body string `json:"body"`
Tags []string `json:"tags,omitempty"`
Urls []string `json:"urls",omitempty`
}
type ErrorMsg struct {
Error string `json:"error"`
}
func Notify(msg string, config types.AppriseConfig) error {
payload := Request{
Body: msg,
Urls: config.Urls,
Tags: config.Tags,
}
jsonData, _ := json.Marshal(payload)
if !strings.HasSuffix(config.Url, "/") {
config.Url += "/"
}
url := config.Url + "notify/"
if config.Config != "" {
url += config.Config
}
resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData))
defer resp.Body.Close()
if err != nil {
return err
}
errormsg := ErrorMsg{}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
err = json.Unmarshal(body, &errormsg)
if err != nil {
return err
}
if errormsg.Error != "" {
return errors.New(errormsg.Error)
}
return nil
}

View file

@ -82,6 +82,14 @@ type PushConfig struct {
Url string `yaml:"url"`
}
// AppriseConfig TODO
type AppriseConfig struct {
Url string `yaml:"url"`
Tags []string `yaml:"tags"`
Config string `yaml:"config"`
Urls []string `yaml:"notification_urls"`
}
func (p *PushConfig) ResolveToken() {
if p.Password != "" {
p.Password = resolve(p.Password)
@ -102,8 +110,9 @@ func resolve(value string) string {
// PushConfigs TODO.
type PushConfigs struct {
Ntfy []*PushConfig `yaml:"ntfy"`
Gotify []*PushConfig `yaml:"gotify"`
Ntfy []*PushConfig `yaml:"ntfy"`
Gotify []*PushConfig `yaml:"gotify"`
Apprise []*AppriseConfig `yaml:"apprise"`
}
// Metrics TODO.