File: ntfy_config.go

package info (click to toggle)
golang-github-nicholas-fedor-shoutrrr 0.12.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,680 kB
  • sloc: sh: 74; makefile: 58
file content (138 lines) | stat: -rw-r--r-- 6,571 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package ntfy

import (
	"errors"
	"fmt"
	"net/url"
	"strings"

	"github.com/nicholas-fedor/shoutrrr/pkg/format"
	"github.com/nicholas-fedor/shoutrrr/pkg/types"
)

// Scheme is the identifying part of this service's configuration URL.
const (
	Scheme = "ntfy"
)

// ErrTopicRequired indicates that the topic is missing from the config URL.
var ErrTopicRequired = errors.New("topic is required")

// Config holds the configuration for the Ntfy service.
type Config struct {
	Title                  string   `default:""        desc:"Message title"                                                                                    key:"title"`
	Host                   string   `default:"ntfy.sh" desc:"Server hostname and port"                                                                                           url:"host"`
	Topic                  string   `                  desc:"Target topic name"                                                                                                  url:"path"     required:""`
	Password               string   `                  desc:"Auth password"                                                                                                      url:"password"             optional:""`
	Username               string   `                  desc:"Auth username"                                                                                                      url:"user"                 optional:""`
	Scheme                 string   `default:"https"   desc:"Server protocol, http or https"                                                                   key:"scheme"`
	Tags                   []string `                  desc:"List of tags that may or not map to emojis"                                                       key:"tags"                                   optional:""`
	Priority               priority `default:"default" desc:"Message priority with 1=min, 3=default and 5=max"                                                 key:"priority"`
	Actions                []string `                  desc:"Custom user action buttons for notifications, see https://docs.ntfy.sh/publish/#action-buttons"   key:"actions"                                optional:"" sep:";"`
	Click                  string   `                  desc:"Website opened when notification is clicked"                                                      key:"click"                                  optional:""`
	Attach                 string   `                  desc:"URL of an attachment, see attach via URL"                                                         key:"attach"                                 optional:""`
	Filename               string   `                  desc:"File name of the attachment"                                                                      key:"filename"                               optional:""`
	Delay                  string   `                  desc:"Timestamp or duration for delayed delivery, see https://docs.ntfy.sh/publish/#scheduled-delivery" key:"delay,at,in"                            optional:""`
	Email                  string   `                  desc:"E-mail address for e-mail notifications"                                                          key:"email"                                  optional:""`
	Icon                   string   `                  desc:"URL to use as notification icon"                                                                  key:"icon"                                   optional:""`
	Cache                  bool     `default:"yes"     desc:"Cache messages"                                                                                   key:"cache"`
	Firebase               bool     `default:"yes"     desc:"Send to firebase"                                                                                 key:"firebase"`
	DisableTLSVerification bool     `default:"no"      desc:"Disable TLS certificate verification"                                                             key:"disabletls"`
}

// Enums returns the fields that use an EnumFormatter for their values.
func (*Config) Enums() map[string]types.EnumFormatter {
	return map[string]types.EnumFormatter{
		"Priority": Priority.Enum,
	}
}

// GetURL returns a URL representation of the Config's current field values.
func (config *Config) GetURL() *url.URL {
	resolver := format.NewPropKeyResolver(config)

	return config.getURL(&resolver)
}

// SetURL updates the Config from a URL representation of its field values.
func (config *Config) SetURL(url *url.URL) error {
	resolver := format.NewPropKeyResolver(config)

	return config.setURL(&resolver, url)
}

// GetAPIURL constructs the API URL for the Ntfy service based on the configuration.
func (config *Config) GetAPIURL() string {
	path := config.Topic
	if !strings.HasPrefix(config.Topic, "/") {
		path = "/" + path
	}

	apiURL := url.URL{
		Scheme: config.Scheme,
		Host:   config.Host,
		Path:   path,
	}

	return apiURL.String()
}

// getURL constructs a URL from the Config's fields using the provided resolver.
func (config *Config) getURL(resolver types.ConfigQueryResolver) *url.URL {
	path := config.Topic
	if !strings.HasPrefix(config.Topic, "/") {
		path = "/" + path
	}

	result := &url.URL{
		Host:       config.Host,
		Scheme:     Scheme,
		ForceQuery: true,
		Path:       path,
		RawQuery:   format.BuildQuery(resolver),
	}
	if config.Username != "" {
		if config.Password != "" {
			result.User = url.UserPassword(config.Username, config.Password)
		} else {
			result.User = url.User(config.Username)
		}
	}

	return result
}

// setURL updates the Config from a URL using the provided resolver.
func (config *Config) setURL(resolver types.ConfigQueryResolver, url *url.URL) error {
	if url.User != nil {
		password, _ := url.User.Password()
		config.Password = password
		config.Username = url.User.Username()
	} else {
		config.Password = ""
		config.Username = ""
	}

	config.Host = url.Host
	config.Topic = strings.TrimPrefix(url.Path, "/")

	url.RawQuery = strings.ReplaceAll(url.RawQuery, ";", "%3b")
	for key, vals := range url.Query() {
		if err := resolver.Set(key, vals[0]); err != nil {
			return fmt.Errorf("setting query parameter %q to %q: %w", key, vals[0], err)
		}
	}

	if url.String() != "ntfy://dummy@dummy.com" {
		if config.Topic == "" {
			return ErrTopicRequired
		}
	}

	return nil
}

// QueryFields returns the list of query parameter names for the Config struct.
func (config *Config) QueryFields() []string {
	return format.GetConfigQueryResolver(config).QueryFields()
}