File: generic_config.go

package info (click to toggle)
golang-github-nicholas-fedor-shoutrrr 0.8.17-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,332 kB
  • sloc: sh: 61; makefile: 5
file content (123 lines) | stat: -rw-r--r-- 4,181 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
package generic

import (
	"fmt"
	"net/url"

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

// Scheme identifies this service in configuration URLs.
const (
	Scheme               = "generic"
	DefaultWebhookScheme = "https"
)

// Config holds settings for the generic notification service.
type Config struct {
	standard.EnumlessConfig
	webhookURL    *url.URL
	headers       map[string]string
	extraData     map[string]string
	ContentType   string `default:"application/json" desc:"The value of the Content-Type header"               key:"contenttype"`
	DisableTLS    bool   `default:"No"                                                                         key:"disabletls"`
	Template      string `                           desc:"The template used for creating the request payload" key:"template"    optional:""`
	Title         string `default:""                                                                           key:"title"`
	TitleKey      string `default:"title"            desc:"The key that will be used for the title value"      key:"titlekey"`
	MessageKey    string `default:"message"          desc:"The key that will be used for the message value"    key:"messagekey"`
	RequestMethod string `default:"POST"                                                                       key:"method"`
}

// DefaultConfig creates a new Config with default values and its associated PropKeyResolver.
func DefaultConfig() (*Config, format.PropKeyResolver) {
	config := &Config{}
	pkr := format.NewPropKeyResolver(config)
	_ = pkr.SetDefaultProps(config)

	return config, pkr
}

// ConfigFromWebhookURL constructs a Config from a parsed webhook URL.
func ConfigFromWebhookURL(webhookURL url.URL) (*Config, format.PropKeyResolver, error) {
	config, pkr := DefaultConfig()

	webhookQuery := webhookURL.Query()
	headers, extraData := stripCustomQueryValues(webhookQuery)
	escapedQuery := url.Values{}

	for key, values := range webhookQuery {
		if len(values) > 0 {
			escapedQuery.Set(format.EscapeKey(key), values[0])
		}
	}

	_, err := format.SetConfigPropsFromQuery(&pkr, escapedQuery)
	if err != nil {
		return nil, pkr, fmt.Errorf("setting config properties from query: %w", err)
	}

	webhookURL.RawQuery = webhookQuery.Encode()
	config.webhookURL = &webhookURL
	config.headers = headers
	config.extraData = extraData
	config.DisableTLS = webhookURL.Scheme == "http"

	return config, pkr, nil
}

// WebhookURL returns the configured webhook URL, adjusted for TLS settings.
func (config *Config) WebhookURL() *url.URL {
	webhookURL := *config.webhookURL
	webhookURL.Scheme = DefaultWebhookScheme

	if config.DisableTLS {
		webhookURL.Scheme = "http" // Truncate to "http" if TLS is disabled
	}

	return &webhookURL
}

// GetURL generates a URL from the current configuration values.
func (config *Config) GetURL() *url.URL {
	resolver := format.NewPropKeyResolver(config)

	return config.getURL(&resolver)
}

// SetURL updates the configuration from a service URL.
func (config *Config) SetURL(serviceURL *url.URL) error {
	resolver := format.NewPropKeyResolver(config)

	return config.setURL(&resolver, serviceURL)
}

func (config *Config) getURL(resolver types.ConfigQueryResolver) *url.URL {
	serviceURL := *config.webhookURL
	webhookQuery := config.webhookURL.Query()
	serviceQuery := format.BuildQueryWithCustomFields(resolver, webhookQuery)
	appendCustomQueryValues(serviceQuery, config.headers, config.extraData)
	serviceURL.RawQuery = serviceQuery.Encode()
	serviceURL.Scheme = Scheme

	return &serviceURL
}

func (config *Config) setURL(resolver types.ConfigQueryResolver, serviceURL *url.URL) error {
	webhookURL := *serviceURL
	serviceQuery := serviceURL.Query()
	headers, extraData := stripCustomQueryValues(serviceQuery)

	customQuery, err := format.SetConfigPropsFromQuery(resolver, serviceQuery)
	if err != nil {
		return fmt.Errorf("setting config properties from service URL query: %w", err)
	}

	webhookURL.RawQuery = customQuery.Encode()
	config.webhookURL = &webhookURL
	config.headers = headers
	config.extraData = extraData

	return nil
}