mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Allow customization of Google chat message (#43568)
* Allow customizable googlechat message via optional setting * Add optional message field in googlechat contact point configurator * Fix strange error message on send if template fails to fully evaluate * Elevate template evaluation failure logs to Warn level * Extract default.title template embed from all channels to shared constant
This commit is contained in:
parent
b826804ef7
commit
fd583a0e3b
@ -740,6 +740,12 @@ func GetAvailableNotifiers() []*alerting.NotifierPlugin {
|
||||
PropertyName: "url",
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Label: "Message",
|
||||
Element: alerting.ElementTypeTextArea,
|
||||
Placeholder: `{{ template "default.message" . }}`,
|
||||
PropertyName: "message",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -9,6 +9,8 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const DefaultMessageTitleEmbed = `{{ template "default.title" . }}`
|
||||
|
||||
var DefaultTemplateString = `
|
||||
{{ define "__subject" }}[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .GroupLabels.SortedPairs.Values | join " " }} {{ if gt (len .CommonLabels) (len .GroupLabels) }}({{ with .CommonLabels.Remove .GroupLabels.Names }}{{ .Values | join " " }}{{ end }}){{ end }}{{ end }}
|
||||
|
||||
|
@ -85,7 +85,7 @@ func TestDefaultTemplateString(t *testing.T) {
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
templateString: `{{ template "default.title" .}}`,
|
||||
templateString: DefaultMessageTitleEmbed,
|
||||
expected: `[FIRING:2] (alert1)`,
|
||||
},
|
||||
{
|
||||
|
@ -74,7 +74,7 @@ func (dd *DingDingNotifier) Notify(ctx context.Context, as ...*types.Alert) (boo
|
||||
tmpl, _ := TmplText(ctx, dd.tmpl, as, dd.log, &tmplErr)
|
||||
|
||||
message := tmpl(dd.Message)
|
||||
title := tmpl(`{{ template "default.title" . }}`)
|
||||
title := tmpl(DefaultMessageTitleEmbed)
|
||||
|
||||
var bodyMsg map[string]interface{}
|
||||
if tmpl(dd.MsgType) == "actionCard" {
|
||||
@ -102,7 +102,7 @@ func (dd *DingDingNotifier) Notify(ctx context.Context, as ...*types.Alert) (boo
|
||||
|
||||
u := tmpl(dd.URL)
|
||||
if tmplErr != nil {
|
||||
dd.log.Debug("failed to template DingDing message", "err", tmplErr.Error())
|
||||
dd.log.Warn("failed to template DingDing message", "err", tmplErr.Error())
|
||||
}
|
||||
|
||||
body, err := json.Marshal(bodyMsg)
|
||||
|
@ -86,7 +86,7 @@ func (d DiscordNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool,
|
||||
}
|
||||
|
||||
embed := simplejson.New()
|
||||
embed.Set("title", tmpl(`{{ template "default.title" . }}`))
|
||||
embed.Set("title", tmpl(DefaultMessageTitleEmbed))
|
||||
embed.Set("footer", footer)
|
||||
embed.Set("type", "rich")
|
||||
|
||||
@ -100,7 +100,7 @@ func (d DiscordNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool,
|
||||
|
||||
u := tmpl(d.WebhookURL)
|
||||
if tmplErr != nil {
|
||||
d.log.Debug("failed to template Discord message", "err", tmplErr.Error())
|
||||
d.log.Warn("failed to template Discord message", "err", tmplErr.Error())
|
||||
}
|
||||
|
||||
body, err := json.Marshal(bodyJSON)
|
||||
|
@ -63,7 +63,7 @@ func (en *EmailNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool,
|
||||
var tmplErr error
|
||||
tmpl, data := TmplText(ctx, en.tmpl, as, en.log, &tmplErr)
|
||||
|
||||
title := tmpl(`{{ template "default.title" . }}`)
|
||||
title := tmpl(DefaultMessageTitleEmbed)
|
||||
|
||||
alertPageURL := en.tmpl.ExternalURL.String()
|
||||
ruleURL := en.tmpl.ExternalURL.String()
|
||||
@ -100,7 +100,7 @@ func (en *EmailNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool,
|
||||
}
|
||||
|
||||
if tmplErr != nil {
|
||||
en.log.Debug("failed to template email message", "err", tmplErr.Error())
|
||||
en.log.Warn("failed to template email message", "err", tmplErr.Error())
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(ctx, cmd); err != nil {
|
||||
|
@ -19,9 +19,10 @@ import (
|
||||
// alert notifications to Google chat.
|
||||
type GoogleChatNotifier struct {
|
||||
*Base
|
||||
URL string
|
||||
log log.Logger
|
||||
tmpl *template.Template
|
||||
URL string
|
||||
log log.Logger
|
||||
tmpl *template.Template
|
||||
content string
|
||||
}
|
||||
|
||||
func NewGoogleChatNotifier(model *NotificationChannelConfig, t *template.Template) (*GoogleChatNotifier, error) {
|
||||
@ -34,6 +35,8 @@ func NewGoogleChatNotifier(model *NotificationChannelConfig, t *template.Templat
|
||||
return nil, receiverInitError{Cfg: *model, Reason: "could not find url property in settings"}
|
||||
}
|
||||
|
||||
content := model.Settings.Get("message").MustString(`{{ template "default.message" . }}`)
|
||||
|
||||
return &GoogleChatNotifier{
|
||||
Base: NewBase(&models.AlertNotification{
|
||||
Uid: model.UID,
|
||||
@ -42,9 +45,10 @@ func NewGoogleChatNotifier(model *NotificationChannelConfig, t *template.Templat
|
||||
DisableResolveMessage: model.DisableResolveMessage,
|
||||
Settings: model.Settings,
|
||||
}),
|
||||
URL: url,
|
||||
log: log.New("alerting.notifier.googlechat"),
|
||||
tmpl: t,
|
||||
URL: url,
|
||||
log: log.New("alerting.notifier.googlechat"),
|
||||
tmpl: t,
|
||||
content: content,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -57,7 +61,7 @@ func (gcn *GoogleChatNotifier) Notify(ctx context.Context, as ...*types.Alert) (
|
||||
|
||||
widgets := []widget{}
|
||||
|
||||
if msg := tmpl(`{{ template "default.message" . }}`); msg != "" {
|
||||
if msg := tmpl(gcn.content); msg != "" {
|
||||
// Add a text paragraph widget for the message if there is a message.
|
||||
// Google Chat API doesn't accept an empty text property.
|
||||
widgets = append(widgets, textParagraphWidget{
|
||||
@ -67,6 +71,11 @@ func (gcn *GoogleChatNotifier) Notify(ctx context.Context, as ...*types.Alert) (
|
||||
})
|
||||
}
|
||||
|
||||
if tmplErr != nil {
|
||||
gcn.log.Warn("failed to template Google Chat message", "err", tmplErr.Error())
|
||||
tmplErr = nil
|
||||
}
|
||||
|
||||
ruleURL := joinUrlPath(gcn.tmpl.ExternalURL.String(), "/alerting/list", gcn.log)
|
||||
// Add a button widget (link to Grafana).
|
||||
widgets = append(widgets, buttonWidget{
|
||||
@ -93,12 +102,12 @@ func (gcn *GoogleChatNotifier) Notify(ctx context.Context, as ...*types.Alert) (
|
||||
|
||||
// Nest the required structs.
|
||||
res := &outerStruct{
|
||||
PreviewText: tmpl(`{{ template "default.title" . }}`),
|
||||
FallbackText: tmpl(`{{ template "default.title" . }}`),
|
||||
PreviewText: tmpl(DefaultMessageTitleEmbed),
|
||||
FallbackText: tmpl(DefaultMessageTitleEmbed),
|
||||
Cards: []card{
|
||||
{
|
||||
Header: header{
|
||||
Title: tmpl(`{{ template "default.title" . }}`),
|
||||
Title: tmpl(DefaultMessageTitleEmbed),
|
||||
},
|
||||
Sections: []section{
|
||||
{
|
||||
@ -111,7 +120,7 @@ func (gcn *GoogleChatNotifier) Notify(ctx context.Context, as ...*types.Alert) (
|
||||
|
||||
u := tmpl(gcn.URL)
|
||||
if tmplErr != nil {
|
||||
gcn.log.Debug("failed to template GoogleChat message", "err", tmplErr.Error())
|
||||
gcn.log.Warn("failed to template GoogleChat message", "err", tmplErr.Error())
|
||||
}
|
||||
|
||||
body, err := json.Marshal(res)
|
||||
|
@ -152,6 +152,114 @@ func TestGoogleChatNotifier(t *testing.T) {
|
||||
name: "Error in initing",
|
||||
settings: `{}`,
|
||||
expInitError: `failed to validate receiver "googlechat_testing" of type "googlechat": could not find url property in settings`,
|
||||
}, {
|
||||
name: "Customized message",
|
||||
settings: `{"url": "http://localhost", "message": "I'm a custom template and you have {{ len .Alerts.Firing }} firing alert."}`,
|
||||
alerts: []*types.Alert{
|
||||
{
|
||||
Alert: model.Alert{
|
||||
Labels: model.LabelSet{"alertname": "alert1", "lbl1": "val1"},
|
||||
Annotations: model.LabelSet{"ann1": "annv1", "__dashboardUid__": "abcd", "__panelId__": "efgh"},
|
||||
},
|
||||
},
|
||||
},
|
||||
expMsg: &outerStruct{
|
||||
PreviewText: "[FIRING:1] (val1)",
|
||||
FallbackText: "[FIRING:1] (val1)",
|
||||
Cards: []card{
|
||||
{
|
||||
Header: header{
|
||||
Title: "[FIRING:1] (val1)",
|
||||
},
|
||||
Sections: []section{
|
||||
{
|
||||
Widgets: []widget{
|
||||
textParagraphWidget{
|
||||
Text: text{
|
||||
Text: "I'm a custom template and you have 1 firing alert.",
|
||||
},
|
||||
},
|
||||
buttonWidget{
|
||||
Buttons: []button{
|
||||
{
|
||||
TextButton: textButton{
|
||||
Text: "OPEN IN GRAFANA",
|
||||
OnClick: onClick{
|
||||
OpenLink: openLink{
|
||||
URL: "http://localhost/alerting/list",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
textParagraphWidget{
|
||||
Text: text{
|
||||
// RFC822 only has the minute, hence it works in most cases.
|
||||
Text: "Grafana v" + setting.BuildVersion + " | " + constNow.Format(time.RFC822),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expMsgError: nil,
|
||||
}, {
|
||||
name: "Invalid template",
|
||||
settings: `{"url": "http://localhost", "message": "I'm a custom template {{ .NotAField }} bad template"}`,
|
||||
alerts: []*types.Alert{
|
||||
{
|
||||
Alert: model.Alert{
|
||||
Labels: model.LabelSet{"alertname": "alert1", "lbl1": "val1"},
|
||||
Annotations: model.LabelSet{"ann1": "annv1", "__dashboardUid__": "abcd", "__panelId__": "efgh"},
|
||||
},
|
||||
},
|
||||
},
|
||||
expMsg: &outerStruct{
|
||||
PreviewText: "[FIRING:1] (val1)",
|
||||
FallbackText: "[FIRING:1] (val1)",
|
||||
Cards: []card{
|
||||
{
|
||||
Header: header{
|
||||
Title: "[FIRING:1] (val1)",
|
||||
},
|
||||
Sections: []section{
|
||||
{
|
||||
Widgets: []widget{
|
||||
textParagraphWidget{
|
||||
Text: text{
|
||||
Text: "I'm a custom template ",
|
||||
},
|
||||
},
|
||||
buttonWidget{
|
||||
Buttons: []button{
|
||||
{
|
||||
TextButton: textButton{
|
||||
Text: "OPEN IN GRAFANA",
|
||||
OnClick: onClick{
|
||||
OpenLink: openLink{
|
||||
URL: "http://localhost/alerting/list",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
textParagraphWidget{
|
||||
Text: text{
|
||||
// RFC822 only has the minute, hence it works in most cases.
|
||||
Text: "Grafana v" + setting.BuildVersion + " | " + constNow.Format(time.RFC822),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expMsgError: nil,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ func (kn *KafkaNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool,
|
||||
|
||||
bodyJSON := simplejson.New()
|
||||
bodyJSON.Set("alert_state", state)
|
||||
bodyJSON.Set("description", tmpl(`{{ template "default.title" . }}`))
|
||||
bodyJSON.Set("description", tmpl(DefaultMessageTitleEmbed))
|
||||
bodyJSON.Set("client", "Grafana")
|
||||
bodyJSON.Set("details", tmpl(`{{ template "default.message" . }}`))
|
||||
|
||||
@ -99,7 +99,7 @@ func (kn *KafkaNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool,
|
||||
topicURL := strings.TrimRight(kn.Endpoint, "/") + "/topics/" + tmpl(kn.Topic)
|
||||
|
||||
if tmplErr != nil {
|
||||
kn.log.Debug("failed to template Kafka message", "err", tmplErr.Error())
|
||||
kn.log.Warn("failed to template Kafka message", "err", tmplErr.Error())
|
||||
}
|
||||
|
||||
cmd := &models.SendWebhookSync{
|
||||
|
@ -65,12 +65,12 @@ func (ln *LineNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool, e
|
||||
|
||||
body := fmt.Sprintf(
|
||||
"%s\n%s\n\n%s",
|
||||
tmpl(`{{ template "default.title" . }}`),
|
||||
tmpl(DefaultMessageTitleEmbed),
|
||||
ruleURL,
|
||||
tmpl(`{{ template "default.message" . }}`),
|
||||
)
|
||||
if tmplErr != nil {
|
||||
ln.log.Debug("failed to template Line message", "err", tmplErr.Error())
|
||||
ln.log.Warn("failed to template Line message", "err", tmplErr.Error())
|
||||
}
|
||||
|
||||
form := url.Values{}
|
||||
|
@ -156,10 +156,10 @@ func (on *OpsgenieNotifier) buildOpsgenieMessage(ctx context.Context, alerts mod
|
||||
var tmplErr error
|
||||
tmpl, data := TmplText(ctx, on.tmpl, as, on.log, &tmplErr)
|
||||
|
||||
title := tmpl(`{{ template "default.title" . }}`)
|
||||
title := tmpl(DefaultMessageTitleEmbed)
|
||||
description := fmt.Sprintf(
|
||||
"%s\n%s\n\n%s",
|
||||
tmpl(`{{ template "default.title" . }}`),
|
||||
tmpl(DefaultMessageTitleEmbed),
|
||||
ruleURL,
|
||||
tmpl(`{{ template "default.message" . }}`),
|
||||
)
|
||||
@ -207,7 +207,7 @@ func (on *OpsgenieNotifier) buildOpsgenieMessage(ctx context.Context, alerts mod
|
||||
apiURL = tmpl(on.APIUrl)
|
||||
|
||||
if tmplErr != nil {
|
||||
on.log.Debug("failed to template Opsgenie message", "err", tmplErr.Error())
|
||||
on.log.Warn("failed to template Opsgenie message", "err", tmplErr.Error())
|
||||
}
|
||||
|
||||
return bodyJSON, apiURL, nil
|
||||
|
@ -72,7 +72,7 @@ func NewPagerdutyNotifier(model *NotificationChannelConfig, t *template.Template
|
||||
Class: model.Settings.Get("class").MustString("default"),
|
||||
Component: model.Settings.Get("component").MustString("Grafana"),
|
||||
Group: model.Settings.Get("group").MustString("default"),
|
||||
Summary: model.Settings.Get("summary").MustString(`{{ template "default.title" . }}`),
|
||||
Summary: model.Settings.Get("summary").MustString(DefaultMessageTitleEmbed),
|
||||
tmpl: t,
|
||||
log: log.New("alerting.notifier." + model.Name),
|
||||
}, nil
|
||||
@ -145,7 +145,7 @@ func (pn *PagerdutyNotifier) buildPagerdutyMessage(ctx context.Context, alerts m
|
||||
HRef: pn.tmpl.ExternalURL.String(),
|
||||
Text: "External URL",
|
||||
}},
|
||||
Description: tmpl(`{{ template "default.title" . }}`), // TODO: this can be configurable template.
|
||||
Description: tmpl(DefaultMessageTitleEmbed), // TODO: this can be configurable template.
|
||||
Payload: pagerDutyPayload{
|
||||
Component: tmpl(pn.Component),
|
||||
Summary: tmpl(pn.Summary),
|
||||
@ -167,7 +167,7 @@ func (pn *PagerdutyNotifier) buildPagerdutyMessage(ctx context.Context, alerts m
|
||||
}
|
||||
|
||||
if tmplErr != nil {
|
||||
pn.log.Debug("failed to template PagerDuty message", "err", tmplErr.Error())
|
||||
pn.log.Warn("failed to template PagerDuty message", "err", tmplErr.Error())
|
||||
}
|
||||
|
||||
return msg, eventType, nil
|
||||
|
@ -195,7 +195,7 @@ func (pn *PushoverNotifier) genPushoverBody(ctx context.Context, as ...*types.Al
|
||||
}
|
||||
|
||||
// Add title
|
||||
err = w.WriteField("title", tmpl(`{{ template "default.title" . }}`))
|
||||
err = w.WriteField("title", tmpl(DefaultMessageTitleEmbed))
|
||||
if err != nil {
|
||||
return nil, b, err
|
||||
}
|
||||
@ -218,7 +218,7 @@ func (pn *PushoverNotifier) genPushoverBody(ctx context.Context, as ...*types.Al
|
||||
}
|
||||
|
||||
if tmplErr != nil {
|
||||
pn.log.Debug("failed to template pushover message", "err", tmplErr.Error())
|
||||
pn.log.Warn("failed to template pushover message", "err", tmplErr.Error())
|
||||
}
|
||||
|
||||
// Mark as html message
|
||||
|
@ -128,7 +128,7 @@ func (sn *SensuGoNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool
|
||||
}
|
||||
|
||||
if tmplErr != nil {
|
||||
sn.log.Debug("failed to template sensugo message", "err", tmplErr.Error())
|
||||
sn.log.Warn("failed to template sensugo message", "err", tmplErr.Error())
|
||||
}
|
||||
|
||||
body, err := json.Marshal(bodyMsgType)
|
||||
|
@ -118,7 +118,7 @@ func NewSlackNotifier(model *NotificationChannelConfig, t *template.Template, fn
|
||||
IconURL: model.Settings.Get("icon_url").MustString(),
|
||||
Token: token,
|
||||
Text: model.Settings.Get("text").MustString(`{{ template "default.message" . }}`),
|
||||
Title: model.Settings.Get("title").MustString(`{{ template "default.title" . }}`),
|
||||
Title: model.Settings.Get("title").MustString(DefaultMessageTitleEmbed),
|
||||
log: log.New("alerting.notifier.slack"),
|
||||
tmpl: t,
|
||||
}, nil
|
||||
@ -269,7 +269,7 @@ func (sn *SlackNotifier) buildSlackMessage(ctx context.Context, as []*types.Aler
|
||||
},
|
||||
}
|
||||
if tmplErr != nil {
|
||||
sn.log.Debug("failed to template Slack message", "err", tmplErr.Error())
|
||||
sn.log.Warn("failed to template Slack message", "err", tmplErr.Error())
|
||||
}
|
||||
|
||||
mentionsBuilder := strings.Builder{}
|
||||
|
@ -56,7 +56,7 @@ func (tn *TeamsNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool,
|
||||
|
||||
ruleURL := joinUrlPath(tn.tmpl.ExternalURL.String(), "/alerting/list", tn.log)
|
||||
|
||||
title := tmpl(`{{ template "default.title" . }}`)
|
||||
title := tmpl(DefaultMessageTitleEmbed)
|
||||
body := map[string]interface{}{
|
||||
"@type": "MessageCard",
|
||||
"@context": "http://schema.org/extensions",
|
||||
@ -88,7 +88,7 @@ func (tn *TeamsNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool,
|
||||
|
||||
u := tmpl(tn.URL)
|
||||
if tmplErr != nil {
|
||||
tn.log.Debug("failed to template Teams message", "err", tmplErr.Error())
|
||||
tn.log.Warn("failed to template Teams message", "err", tmplErr.Error())
|
||||
}
|
||||
|
||||
b, err := json.Marshal(&body)
|
||||
|
@ -127,7 +127,7 @@ func (tn *TelegramNotifier) buildTelegramMessage(ctx context.Context, as []*type
|
||||
|
||||
message := tmpl(tn.Message)
|
||||
if tmplErr != nil {
|
||||
tn.log.Debug("failed to template Telegram message", "err", tmplErr.Error())
|
||||
tn.log.Warn("failed to template Telegram message", "err", tmplErr.Error())
|
||||
}
|
||||
|
||||
msg["text"] = message
|
||||
|
@ -101,14 +101,14 @@ func (tn *ThreemaNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool
|
||||
// Build message
|
||||
message := fmt.Sprintf("%s%s\n\n*Message:*\n%s\n*URL:* %s\n",
|
||||
stateEmoji,
|
||||
tmpl(`{{ template "default.title" . }}`),
|
||||
tmpl(DefaultMessageTitleEmbed),
|
||||
tmpl(`{{ template "default.message" . }}`),
|
||||
path.Join(tn.tmpl.ExternalURL.String(), "/alerting/list"),
|
||||
)
|
||||
data.Set("text", message)
|
||||
|
||||
if tmplErr != nil {
|
||||
tn.log.Debug("failed to template Threema message", "err", tmplErr.Error())
|
||||
tn.log.Warn("failed to template Threema message", "err", tmplErr.Error())
|
||||
}
|
||||
|
||||
cmd := &models.SendWebhookSync{
|
||||
|
@ -87,7 +87,7 @@ func (vn *VictoropsNotifier) Notify(ctx context.Context, as ...*types.Alert) (bo
|
||||
bodyJSON := simplejson.New()
|
||||
bodyJSON.Set("message_type", messageType)
|
||||
bodyJSON.Set("entity_id", groupKey.Hash())
|
||||
bodyJSON.Set("entity_display_name", tmpl(`{{ template "default.title" . }}`))
|
||||
bodyJSON.Set("entity_display_name", tmpl(DefaultMessageTitleEmbed))
|
||||
bodyJSON.Set("timestamp", time.Now().Unix())
|
||||
bodyJSON.Set("state_message", tmpl(`{{ template "default.message" . }}`))
|
||||
bodyJSON.Set("monitoring_tool", "Grafana v"+setting.BuildVersion)
|
||||
@ -97,7 +97,7 @@ func (vn *VictoropsNotifier) Notify(ctx context.Context, as ...*types.Alert) (bo
|
||||
|
||||
u := tmpl(vn.URL)
|
||||
if tmplErr != nil {
|
||||
vn.log.Debug("failed to template VictorOps message", "err", tmplErr.Error())
|
||||
vn.log.Warn("failed to template VictorOps message", "err", tmplErr.Error())
|
||||
}
|
||||
|
||||
b, err := bodyJSON.MarshalJSON()
|
||||
|
@ -92,7 +92,7 @@ func (wn *WebhookNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool
|
||||
GroupKey: groupKey.String(),
|
||||
TruncatedAlerts: numTruncated,
|
||||
OrgID: wn.orgID,
|
||||
Title: tmpl(`{{ template "default.title" . }}`),
|
||||
Title: tmpl(DefaultMessageTitleEmbed),
|
||||
Message: tmpl(`{{ template "default.message" . }}`),
|
||||
}
|
||||
if types.Alerts(as...).Status() == model.AlertFiring {
|
||||
@ -102,7 +102,7 @@ func (wn *WebhookNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool
|
||||
}
|
||||
|
||||
if tmplErr != nil {
|
||||
wn.log.Debug("failed to template webhook message", "err", tmplErr.Error())
|
||||
wn.log.Warn("failed to template webhook message", "err", tmplErr.Error())
|
||||
}
|
||||
|
||||
body, err := json.Marshal(msg)
|
||||
|
@ -56,7 +56,7 @@ func (w *WeComNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool, e
|
||||
"msgtype": "markdown",
|
||||
}
|
||||
content := fmt.Sprintf("# %s\n%s\n",
|
||||
tmpl(`{{ template "default.title" . }}`),
|
||||
tmpl(DefaultMessageTitleEmbed),
|
||||
tmpl(w.Message),
|
||||
)
|
||||
|
||||
|
@ -1487,6 +1487,22 @@ var expAvailableChannelJsonOutput = `
|
||||
"required": true,
|
||||
"validationRule": "",
|
||||
"secure": false
|
||||
},
|
||||
{
|
||||
"element": "textarea",
|
||||
"inputType": "",
|
||||
"label": "Message",
|
||||
"description": "",
|
||||
"placeholder": "{{ template \"default.message\" . }}",
|
||||
"propertyName": "message",
|
||||
"selectOptions": null,
|
||||
"showWhen": {
|
||||
"field": "",
|
||||
"is": ""
|
||||
},
|
||||
"required": false,
|
||||
"validationRule": "",
|
||||
"secure": false
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -81,6 +81,19 @@ export const grafanaNotifiersMock: NotifierDTO[] = [
|
||||
validationRule: '',
|
||||
secure: false,
|
||||
},
|
||||
{
|
||||
element: 'textarea',
|
||||
inputType: '',
|
||||
label: 'Message',
|
||||
description: '',
|
||||
placeholder: '{{ template "default.message" . }}',
|
||||
propertyName: 'message',
|
||||
selectOptions: null,
|
||||
showWhen: { field: '', is: '' },
|
||||
required: false,
|
||||
validationRule: '',
|
||||
secure: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user