diff --git a/pkg/services/alerting/notifiers/dingding.go b/pkg/services/alerting/notifiers/dingding.go index 1ef085c82f1..3e3496622b7 100644 --- a/pkg/services/alerting/notifiers/dingding.go +++ b/pkg/services/alerting/notifiers/dingding.go @@ -1,6 +1,10 @@ package notifiers import ( + "fmt" + "net/url" + "strings" + "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/log" @@ -8,19 +12,26 @@ import ( "github.com/grafana/grafana/pkg/services/alerting" ) -func init() { - alerting.RegisterNotifier(&alerting.NotifierPlugin{ - Type: "dingding", - Name: "DingDing", - Description: "Sends HTTP POST request to DingDing", - Factory: NewDingDingNotifier, - OptionsTemplate: ` +const DefaultDingdingMsgType = "link" +const DingdingOptionsTemplate = `

DingDing settings

Url - +
- `, +
+ MessageType + +
+` + +func init() { + alerting.RegisterNotifier(&alerting.NotifierPlugin{ + Type: "dingding", + Name: "DingDing", + Description: "Sends HTTP POST request to DingDing", + Factory: NewDingDingNotifier, + OptionsTemplate: DingdingOptionsTemplate, }) } @@ -31,8 +42,11 @@ func NewDingDingNotifier(model *m.AlertNotification) (alerting.Notifier, error) return nil, alerting.ValidationError{Reason: "Could not find url property in settings"} } + msgType := model.Settings.Get("msgType").MustString(DefaultDingdingMsgType) + return &DingDingNotifier{ NotifierBase: NewNotifierBase(model), + MsgType: msgType, Url: url, log: log.New("alerting.notifier.dingding"), }, nil @@ -40,8 +54,9 @@ func NewDingDingNotifier(model *m.AlertNotification) (alerting.Notifier, error) type DingDingNotifier struct { NotifierBase - Url string - log log.Logger + MsgType string + Url string + log log.Logger } func (this *DingDingNotifier) Notify(evalContext *alerting.EvalContext) error { @@ -52,6 +67,16 @@ func (this *DingDingNotifier) Notify(evalContext *alerting.EvalContext) error { this.log.Error("Failed to get messageUrl", "error", err, "dingding", this.Name) messageUrl = "" } + + q := url.Values{ + "pc_slide": {"false"}, + "url": {messageUrl}, + } + + // Use special link to auto open the message url outside of Dingding + // Refer: https://open-doc.dingtalk.com/docs/doc.htm?treeId=385&articleId=104972&docType=1#s9 + messageUrl = "dingtalk://dingtalkclient/page/link?" + q.Encode() + this.log.Info("messageUrl:" + messageUrl) message := evalContext.Rule.Message @@ -61,15 +86,39 @@ func (this *DingDingNotifier) Notify(evalContext *alerting.EvalContext) error { message = title } - bodyJSON, err := simplejson.NewJson([]byte(`{ - "msgtype": "link", - "link": { - "text": "` + message + `", - "title": "` + title + `", - "picUrl": "` + picUrl + `", - "messageUrl": "` + messageUrl + `" + for i, match := range evalContext.EvalMatches { + message += fmt.Sprintf("\\n%2d. %s: %s", i+1, match.Metric, match.Value) + } + + var bodyStr string + if this.MsgType == "actionCard" { + // Embed the pic into the markdown directly because actionCard doesn't have a picUrl field + if picUrl != "" { + message = "![](" + picUrl + ")\\n\\n" + message } - }`)) + + bodyStr = `{ + "msgtype": "actionCard", + "actionCard": { + "text": "` + strings.Replace(message, `"`, "'", -1) + `", + "title": "` + strings.Replace(title, `"`, "'", -1) + `", + "singleTitle": "More", + "singleURL": "` + messageUrl + `" + } + }` + } else { + bodyStr = `{ + "msgtype": "link", + "link": { + "text": "` + message + `", + "title": "` + title + `", + "picUrl": "` + picUrl + `", + "messageUrl": "` + messageUrl + `" + } + }` + } + + bodyJSON, err := simplejson.NewJson([]byte(bodyStr)) if err != nil { this.log.Error("Failed to create Json data", "error", err, "dingding", this.Name)