~xenrox/ntfy-alertmanager

e85b5e6ea55cf1403d0e9dee86b7244bc1ee0b26 — Thorben Günther a month ago f448353
Let a label specify its own ntfy topic

References: https://todo.xenrox.net/~xenrox/ntfy-alertmanager/9
5 files changed, 30 insertions(+), 4 deletions(-)

M README.md
M config.scfg
M config/config.go
M config/config_test.go
M main.go
M README.md => README.md +1 -1
@@ 20,7 20,7 @@ Furthermore you can take a look at [my deployment].

ntfy-alertmanager has support for setting ntfy [priority], [tags], [icon], [action buttons]
(which can be used to e.g. create an Alertmanager silence or open the alert's Prometheus URL), [email notifications] and [phone calls].
Define a decreasing order of labels in the config file and map those labels to tags, priority, an icon or an email address.
Define a decreasing order of labels in the config file and map those labels to tags, priority, an icon, an email address or an alternative ntfy topic.

- For priority and icon the first found value will be chosen. Settings for "resolved" alerts will take precedence.
- Tags are added together.

M config.scfg => config.scfg +1 -0
@@ 51,6 51,7 @@ labels {
    }

    instance "example.com" {
        topic https://ntfy.sh/homeserver
        tags "computer,example"
    }
}

M config/config.go => config/config.go +8 -0
@@ 58,6 58,7 @@ type labelConfig struct {
	Icon         string
	EmailAddress string
	Call         string
	Topic        string
}

// CacheConfig is the configuration of the cache.


@@ 213,6 214,13 @@ func parseBlock(block scfg.Block, config *Config) error {
					}
				}

				d = labelDir.Children.Get("topic")
				if d != nil {
					if err := d.ParseParams(&labelConfig.Topic); err != nil {
						return err
					}
				}

				labels[fmt.Sprintf("%s:%s", labelName, name)] = *labelConfig
			}
		}

M config/config_test.go => config/config_test.go +5 -2
@@ 36,6 36,7 @@ labels {

    instance "example.com" {
        tags "computer,example"
        topic https://ntfy.sh/homeserver
    }
}



@@ 92,8 93,10 @@ cache {
					EmailAddress: "foo@example.com",
					Call:         "yes",
				},
				"severity:info":        {Priority: "1"},
				"instance:example.com": {Tags: []string{"computer", "example"}},
				"severity:info": {Priority: "1"},
				"instance:example.com": {
					Tags:  []string{"computer", "example"},
					Topic: "https://ntfy.sh/homeserver"},
			},
		},
		Cache: CacheConfig{

M main.go => main.go +15 -1
@@ 69,6 69,7 @@ type notification struct {
	fingerprint  string
	status       string
	generatorURL string
	topic        string
}

type ntfyError struct {


@@ 154,6 155,10 @@ func (br *bridge) singleAlertNotifications(p *payload) []*notification {
				n.call = labelConfig.Call
			}

			if n.topic == "" {
				n.topic = labelConfig.Topic
			}

			for _, val := range labelConfig.Tags {
				if !slices.Contains(tags, val) {
					tags = append(tags, val)


@@ 264,6 269,10 @@ func (br *bridge) multiAlertNotification(p *payload) *notification {
			n.call = labelConfig.Call
		}

		if n.topic == "" {
			n.topic = labelConfig.Topic
		}

		for _, val := range labelConfig.Tags {
			if !slices.Contains(tags, val) {
				tags = append(tags, val)


@@ 293,7 302,12 @@ func (br *bridge) multiAlertNotification(p *payload) *notification {
}

func (br *bridge) publish(n *notification) error {
	req, err := http.NewRequest(http.MethodPost, br.cfg.Ntfy.Topic, strings.NewReader(n.body))
	url := br.cfg.Ntfy.Topic
	if n.topic != "" {
		url = n.topic
	}

	req, err := http.NewRequest(http.MethodPost, url, strings.NewReader(n.body))
	if err != nil {
		return err
	}