Slack: Support use of chat.postMessage (#25818)

* set bearer token if token is provided
* update slack notification document

Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>
This commit is contained in:
Mitsuhiro Tanda 2020-06-27 03:47:06 +09:00 committed by GitHub
parent 75706a4a8b
commit 9f82cd4713
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 7 deletions

View File

@ -99,15 +99,15 @@ provided, which starts with "xoxb".
Setting | Description
---------- | -----------
Url | Slack incoming webhook URL.
Url | Slack incoming webhook URL, or eventually the [chat.postMessage](https://api.slack.com/methods/chat.postMessage) Slack API endpoint.
Username | Set the username for the bot's message.
Recipient | Allows you to override the Slack recipient. You must either provide a channel Slack ID, a user Slack ID, a username reference (@&lt;user&gt;, all lowercase, no whitespace), or a channel reference (#&lt;channel&gt;, all lowercase, no whitespace).
Recipient | Allows you to override the Slack recipient. You must either provide a channel Slack ID, a user Slack ID, a username reference (@&lt;user&gt;, all lowercase, no whitespace), or a channel reference (#&lt;channel&gt;, all lowercase, no whitespace). If you use the `chat.postMessage` Slack API endpoint, this is required.
Icon emoji | Provide an emoji to use as the icon for the bot's message. Ex :smile:
Icon URL | Provide a URL to an image to use as the icon for the bot's message.
Mention Users | Optionally mention one or more users in the Slack notification sent by Grafana. You have to refer to users, comma-separated, via their corresponding Slack IDs (which you can find by clicking the overflow button on each user's Slack profile).
Mention Groups | Optionally mention one or more groups in the Slack notification sent by Grafana. You have to refer to groups, comma-separated, via their corresponding Slack IDs (which you can get from each group's Slack profile URL).
Mention Channel | Optionally mention either all channel members or just active ones.
Token | If provided, Grafana will upload the generated image via Slack's file.upload API method, not the external image destination.
Token | If provided, Grafana will upload the generated image via Slack's file.upload API method, not the external image destination. If you use the `chat.postMessage` Slack API endpoint, this is required.
If you are using the token for a slack bot, then you have to invite the bot to the channel you want to send notifications and add the channel to the recipient field.

View File

@ -6,6 +6,7 @@ import (
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
"path/filepath"
"regexp"
@ -291,13 +292,15 @@ func (sn *SlackNotifier) Notify(evalContext *alerting.EvalContext) error {
attachment["image_url"] = imageURL
}
body := map[string]interface{}{
"text": evalContext.GetNotificationTitle(),
"blocks": blocks,
"text": evalContext.GetNotificationTitle(),
"attachments": []map[string]interface{}{
attachment,
},
"parse": "full", // to linkify urls, users and channels in alert message.
}
if len(blocks) > 0 {
body["blocks"] = blocks
}
//recipient override
if sn.Recipient != "" {
@ -317,7 +320,17 @@ func (sn *SlackNotifier) Notify(evalContext *alerting.EvalContext) error {
return err
}
cmd := &models.SendWebhookSync{Url: sn.URL, Body: string(data)}
cmd := &models.SendWebhookSync{
Url: sn.URL,
Body: string(data),
HttpMethod: http.MethodPost,
}
if sn.Token != "" {
sn.log.Debug("Adding authorization header to HTTP request")
cmd.HttpHeader = map[string]string{
"Authorization": fmt.Sprintf("Bearer %s", sn.Token),
}
}
if err := bus.DispatchCtx(evalContext.Ctx, cmd); err != nil {
sn.log.Error("Failed to send slack notification", "error", err, "webhook", sn.Name)
return err

View File

@ -76,6 +76,7 @@ func (ns *NotificationService) sendWebRequestSync(ctx context.Context, webhook *
defer resp.Body.Close()
if resp.StatusCode/100 == 2 {
ns.log.Debug("Webhook succeeded", "url", webhook.Url, "statuscode", resp.Status)
// flushing the body enables the transport to reuse the same connection
if _, err := io.Copy(ioutil.Discard, resp.Body); err != nil {
ns.log.Error("Failed to copy resp.Body to ioutil.Discard", "err", err)
@ -88,6 +89,6 @@ func (ns *NotificationService) sendWebRequestSync(ctx context.Context, webhook *
return err
}
ns.log.Debug("Webhook failed", "statuscode", resp.Status, "body", string(body))
ns.log.Debug("Webhook failed", "url", webhook.Url, "statuscode", resp.Status, "body", string(body))
return fmt.Errorf("Webhook response status %v", resp.Status)
}