Discord notifier: Add username and avatar_url (#4081)
* Feat(discord): Allow for custom username and avatar URLs to be set in discord notifications. Add `username` and `avatar_url` to discord configuration, default empty string. Re-implement #3821 Signed-off-by: Jeff Wong <awole20@gmail.com> * Test the new fields Signed-off-by: gotjosh <josue.abreu@gmail.com> * These are not templeatable strings Signed-off-by: gotjosh <josue.abreu@gmail.com> --------- Signed-off-by: Jeff Wong <awole20@gmail.com> Signed-off-by: gotjosh <josue.abreu@gmail.com> Co-authored-by: gotjosh <josue.abreu@gmail.com>
This commit is contained in:
parent
615d5ffa30
commit
95655dccb8
|
@ -251,9 +251,11 @@ type DiscordConfig struct {
|
||||||
WebhookURL *SecretURL `yaml:"webhook_url,omitempty" json:"webhook_url,omitempty"`
|
WebhookURL *SecretURL `yaml:"webhook_url,omitempty" json:"webhook_url,omitempty"`
|
||||||
WebhookURLFile string `yaml:"webhook_url_file,omitempty" json:"webhook_url_file,omitempty"`
|
WebhookURLFile string `yaml:"webhook_url_file,omitempty" json:"webhook_url_file,omitempty"`
|
||||||
|
|
||||||
Content string `yaml:"content,omitempty" json:"content,omitempty"`
|
Content string `yaml:"content,omitempty" json:"content,omitempty"`
|
||||||
Title string `yaml:"title,omitempty" json:"title,omitempty"`
|
Title string `yaml:"title,omitempty" json:"title,omitempty"`
|
||||||
Message string `yaml:"message,omitempty" json:"message,omitempty"`
|
Message string `yaml:"message,omitempty" json:"message,omitempty"`
|
||||||
|
Username string `yaml:"username,omitempty" json:"username,omitempty"`
|
||||||
|
AvatarURL string `yaml:"avatar_url,omitempty" json:"avatar_url,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalYAML implements the yaml.Unmarshaler interface.
|
// UnmarshalYAML implements the yaml.Unmarshaler interface.
|
||||||
|
|
|
@ -886,6 +886,12 @@ webhook_url_file: <filepath>
|
||||||
# Message content template. Limited to 2000 characters.
|
# Message content template. Limited to 2000 characters.
|
||||||
[ content: <tmpl_string> | default = '{{ template "discord.default.content" . }}' ]
|
[ content: <tmpl_string> | default = '{{ template "discord.default.content" . }}' ]
|
||||||
|
|
||||||
|
# Message username.
|
||||||
|
[ username: <string> | default = '' ]
|
||||||
|
|
||||||
|
# Message avatar URL.
|
||||||
|
[ avatar_url: <string> | default = '' ]
|
||||||
|
|
||||||
# The HTTP client's configuration.
|
# The HTTP client's configuration.
|
||||||
[ http_config: <http_config> | default = global.http_config ]
|
[ http_config: <http_config> | default = global.http_config ]
|
||||||
```
|
```
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
netUrl "net/url"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -76,8 +77,10 @@ func New(c *config.DiscordConfig, t *template.Template, l log.Logger, httpOpts .
|
||||||
}
|
}
|
||||||
|
|
||||||
type webhook struct {
|
type webhook struct {
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
Embeds []webhookEmbed `json:"embeds"`
|
Embeds []webhookEmbed `json:"embeds"`
|
||||||
|
Username string `json:"username,omitempty"`
|
||||||
|
AvatarURL string `json:"avatar_url,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type webhookEmbed struct {
|
type webhookEmbed struct {
|
||||||
|
@ -145,7 +148,8 @@ func (n *Notifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
w := webhook{
|
w := webhook{
|
||||||
Content: content,
|
Content: content,
|
||||||
|
Username: n.conf.Username,
|
||||||
Embeds: []webhookEmbed{{
|
Embeds: []webhookEmbed{{
|
||||||
Title: title,
|
Title: title,
|
||||||
Description: description,
|
Description: description,
|
||||||
|
@ -153,6 +157,14 @@ func (n *Notifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error)
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(n.conf.AvatarURL) != 0 {
|
||||||
|
if _, err := netUrl.Parse(n.conf.AvatarURL); err == nil {
|
||||||
|
w.AvatarURL = n.conf.AvatarURL
|
||||||
|
} else {
|
||||||
|
level.Warn(n.logger).Log("msg", "Bad avatar url", "key", key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var payload bytes.Buffer
|
var payload bytes.Buffer
|
||||||
if err = json.NewEncoder(&payload).Encode(w); err != nil {
|
if err = json.NewEncoder(&payload).Encode(w); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
|
|
@ -201,6 +201,8 @@ func TestDiscord_Notify(t *testing.T) {
|
||||||
Title: "Test Title",
|
Title: "Test Title",
|
||||||
Message: "Test Message",
|
Message: "Test Message",
|
||||||
Content: "Test Content",
|
Content: "Test Content",
|
||||||
|
Username: "Test Username",
|
||||||
|
AvatarURL: "http://example.com/avatar.png",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new Discord notifier
|
// Create a new Discord notifier
|
||||||
|
@ -227,5 +229,5 @@ func TestDiscord_Notify(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.False(t, ok)
|
require.False(t, ok)
|
||||||
|
|
||||||
require.Equal(t, "{\"content\":\"Test Content\",\"embeds\":[{\"title\":\"Test Title\",\"description\":\"Test Message\",\"color\":10038562}]}\n", resp)
|
require.Equal(t, "{\"content\":\"Test Content\",\"embeds\":[{\"title\":\"Test Title\",\"description\":\"Test Message\",\"color\":10038562}],\"username\":\"Test Username\",\"avatar_url\":\"http://example.com/avatar.png\"}\n", resp)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue