diff --git a/pkg/services/ngalert/notifier/available_channels.go b/pkg/services/ngalert/notifier/available_channels.go index c69da86f84e..5a5e8eeffaa 100644 --- a/pkg/services/ngalert/notifier/available_channels.go +++ b/pkg/services/ngalert/notifier/available_channels.go @@ -740,6 +740,12 @@ func GetAvailableNotifiers() []*alerting.NotifierPlugin { PropertyName: "url", Required: true, }, + { + Label: "Message", + Element: alerting.ElementTypeTextArea, + Placeholder: `{{ template "default.message" . }}`, + PropertyName: "message", + }, }, }, { diff --git a/pkg/services/ngalert/notifier/channels/default_template.go b/pkg/services/ngalert/notifier/channels/default_template.go index 968df727203..a9f28345a11 100644 --- a/pkg/services/ngalert/notifier/channels/default_template.go +++ b/pkg/services/ngalert/notifier/channels/default_template.go @@ -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 }} diff --git a/pkg/services/ngalert/notifier/channels/default_template_test.go b/pkg/services/ngalert/notifier/channels/default_template_test.go index a42422a8345..4e61ac59015 100644 --- a/pkg/services/ngalert/notifier/channels/default_template_test.go +++ b/pkg/services/ngalert/notifier/channels/default_template_test.go @@ -85,7 +85,7 @@ func TestDefaultTemplateString(t *testing.T) { expected string }{ { - templateString: `{{ template "default.title" .}}`, + templateString: DefaultMessageTitleEmbed, expected: `[FIRING:2] (alert1)`, }, { diff --git a/pkg/services/ngalert/notifier/channels/dingding.go b/pkg/services/ngalert/notifier/channels/dingding.go index 9372ed257a8..a2ac90b45a7 100644 --- a/pkg/services/ngalert/notifier/channels/dingding.go +++ b/pkg/services/ngalert/notifier/channels/dingding.go @@ -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) diff --git a/pkg/services/ngalert/notifier/channels/discord.go b/pkg/services/ngalert/notifier/channels/discord.go index 175030ea3bc..f710581683c 100644 --- a/pkg/services/ngalert/notifier/channels/discord.go +++ b/pkg/services/ngalert/notifier/channels/discord.go @@ -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) diff --git a/pkg/services/ngalert/notifier/channels/email.go b/pkg/services/ngalert/notifier/channels/email.go index 1ff7bc72b14..8228c058b8e 100644 --- a/pkg/services/ngalert/notifier/channels/email.go +++ b/pkg/services/ngalert/notifier/channels/email.go @@ -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 { diff --git a/pkg/services/ngalert/notifier/channels/googlechat.go b/pkg/services/ngalert/notifier/channels/googlechat.go index 20ed8381b90..98c8c01ae5c 100644 --- a/pkg/services/ngalert/notifier/channels/googlechat.go +++ b/pkg/services/ngalert/notifier/channels/googlechat.go @@ -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) diff --git a/pkg/services/ngalert/notifier/channels/googlechat_test.go b/pkg/services/ngalert/notifier/channels/googlechat_test.go index 7eed132f83e..c260d95c591 100644 --- a/pkg/services/ngalert/notifier/channels/googlechat_test.go +++ b/pkg/services/ngalert/notifier/channels/googlechat_test.go @@ -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, }, } diff --git a/pkg/services/ngalert/notifier/channels/kafka.go b/pkg/services/ngalert/notifier/channels/kafka.go index d2ec5e1145d..ad68265a3b2 100644 --- a/pkg/services/ngalert/notifier/channels/kafka.go +++ b/pkg/services/ngalert/notifier/channels/kafka.go @@ -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{ diff --git a/pkg/services/ngalert/notifier/channels/line.go b/pkg/services/ngalert/notifier/channels/line.go index 2b4239ebd77..7b67b7e19eb 100644 --- a/pkg/services/ngalert/notifier/channels/line.go +++ b/pkg/services/ngalert/notifier/channels/line.go @@ -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{} diff --git a/pkg/services/ngalert/notifier/channels/opsgenie.go b/pkg/services/ngalert/notifier/channels/opsgenie.go index 47ace372832..4a5c5fd1a05 100644 --- a/pkg/services/ngalert/notifier/channels/opsgenie.go +++ b/pkg/services/ngalert/notifier/channels/opsgenie.go @@ -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 diff --git a/pkg/services/ngalert/notifier/channels/pagerduty.go b/pkg/services/ngalert/notifier/channels/pagerduty.go index 2211c6c0c40..2258b2ad0d7 100644 --- a/pkg/services/ngalert/notifier/channels/pagerduty.go +++ b/pkg/services/ngalert/notifier/channels/pagerduty.go @@ -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 diff --git a/pkg/services/ngalert/notifier/channels/pushover.go b/pkg/services/ngalert/notifier/channels/pushover.go index eb7f1b8c022..4c574604552 100644 --- a/pkg/services/ngalert/notifier/channels/pushover.go +++ b/pkg/services/ngalert/notifier/channels/pushover.go @@ -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 diff --git a/pkg/services/ngalert/notifier/channels/sensugo.go b/pkg/services/ngalert/notifier/channels/sensugo.go index 915f270c193..5bb061703d6 100644 --- a/pkg/services/ngalert/notifier/channels/sensugo.go +++ b/pkg/services/ngalert/notifier/channels/sensugo.go @@ -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) diff --git a/pkg/services/ngalert/notifier/channels/slack.go b/pkg/services/ngalert/notifier/channels/slack.go index e91b5d41328..66713312ed8 100644 --- a/pkg/services/ngalert/notifier/channels/slack.go +++ b/pkg/services/ngalert/notifier/channels/slack.go @@ -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{} diff --git a/pkg/services/ngalert/notifier/channels/teams.go b/pkg/services/ngalert/notifier/channels/teams.go index 2bca24e7614..e3f0eec926e 100644 --- a/pkg/services/ngalert/notifier/channels/teams.go +++ b/pkg/services/ngalert/notifier/channels/teams.go @@ -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) diff --git a/pkg/services/ngalert/notifier/channels/telegram.go b/pkg/services/ngalert/notifier/channels/telegram.go index 81d4e3e05c8..301bed12fa7 100644 --- a/pkg/services/ngalert/notifier/channels/telegram.go +++ b/pkg/services/ngalert/notifier/channels/telegram.go @@ -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 diff --git a/pkg/services/ngalert/notifier/channels/threema.go b/pkg/services/ngalert/notifier/channels/threema.go index 844f43a5f7c..7bfdaa46816 100644 --- a/pkg/services/ngalert/notifier/channels/threema.go +++ b/pkg/services/ngalert/notifier/channels/threema.go @@ -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{ diff --git a/pkg/services/ngalert/notifier/channels/victorops.go b/pkg/services/ngalert/notifier/channels/victorops.go index e95cdbfd063..72e1f362833 100644 --- a/pkg/services/ngalert/notifier/channels/victorops.go +++ b/pkg/services/ngalert/notifier/channels/victorops.go @@ -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() diff --git a/pkg/services/ngalert/notifier/channels/webhook.go b/pkg/services/ngalert/notifier/channels/webhook.go index 6f31a4aa702..1969b21c098 100644 --- a/pkg/services/ngalert/notifier/channels/webhook.go +++ b/pkg/services/ngalert/notifier/channels/webhook.go @@ -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) diff --git a/pkg/services/ngalert/notifier/channels/wecom.go b/pkg/services/ngalert/notifier/channels/wecom.go index 51b73303375..37ee36f1a2d 100644 --- a/pkg/services/ngalert/notifier/channels/wecom.go +++ b/pkg/services/ngalert/notifier/channels/wecom.go @@ -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), ) diff --git a/pkg/tests/api/alerting/api_available_channel_test.go b/pkg/tests/api/alerting/api_available_channel_test.go index 2c97655a0f4..003984ca1b1 100644 --- a/pkg/tests/api/alerting/api_available_channel_test.go +++ b/pkg/tests/api/alerting/api_available_channel_test.go @@ -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 } ] }, diff --git a/public/app/features/alerting/unified/mocks/grafana-notifiers.ts b/public/app/features/alerting/unified/mocks/grafana-notifiers.ts index 8bac7507d4a..876672ed19b 100644 --- a/public/app/features/alerting/unified/mocks/grafana-notifiers.ts +++ b/public/app/features/alerting/unified/mocks/grafana-notifiers.ts @@ -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, + }, ], }, {