...
1
2
3
4
5
6
7
8
9
10
11
12
13
14 package discord
15
16 import (
17 "bytes"
18 "context"
19 "encoding/json"
20 "net/http"
21
22 "github.com/go-kit/log"
23 "github.com/go-kit/log/level"
24 commoncfg "github.com/prometheus/common/config"
25 "github.com/prometheus/common/model"
26
27 "github.com/prometheus/alertmanager/config"
28 "github.com/prometheus/alertmanager/notify"
29 "github.com/prometheus/alertmanager/template"
30 "github.com/prometheus/alertmanager/types"
31 )
32
33 const (
34 colorRed = 0x992D22
35 colorGreen = 0x2ECC71
36 colorGrey = 0x95A5A6
37 )
38
39
40 type Notifier struct {
41 conf *config.DiscordConfig
42 tmpl *template.Template
43 logger log.Logger
44 client *http.Client
45 retrier *notify.Retrier
46 webhookURL *config.SecretURL
47 }
48
49
50 func New(c *config.DiscordConfig, t *template.Template, l log.Logger, httpOpts ...commoncfg.HTTPClientOption) (*Notifier, error) {
51 client, err := commoncfg.NewClientFromConfig(*c.HTTPConfig, "discord", httpOpts...)
52 if err != nil {
53 return nil, err
54 }
55 n := &Notifier{
56 conf: c,
57 tmpl: t,
58 logger: l,
59 client: client,
60 retrier: ¬ify.Retrier{},
61 webhookURL: c.WebhookURL,
62 }
63 return n, nil
64 }
65
66 type webhook struct {
67 Content string `json:"content"`
68 Embeds []webhookEmbed `json:"embeds"`
69 }
70
71 type webhookEmbed struct {
72 Title string `json:"title"`
73 Description string `json:"description"`
74 Color int `json:"color"`
75 }
76
77
78 func (n *Notifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error) {
79 key, err := notify.ExtractGroupKey(ctx)
80 if err != nil {
81 return false, err
82 }
83
84 level.Debug(n.logger).Log("incident", key)
85
86 alerts := types.Alerts(as...)
87 data := notify.GetTemplateData(ctx, n.tmpl, as, n.logger)
88 tmpl := notify.TmplText(n.tmpl, data, &err)
89 if err != nil {
90 return false, err
91 }
92
93 title := tmpl(n.conf.Title)
94 if err != nil {
95 return false, err
96 }
97 description := tmpl(n.conf.Message)
98 if err != nil {
99 return false, err
100 }
101
102 color := colorGrey
103 if alerts.Status() == model.AlertFiring {
104 color = colorRed
105 }
106 if alerts.Status() == model.AlertResolved {
107 color = colorGreen
108 }
109
110 w := webhook{
111 Embeds: []webhookEmbed{{
112 Title: title,
113 Description: description,
114 Color: color,
115 }},
116 }
117
118 var payload bytes.Buffer
119 if err = json.NewEncoder(&payload).Encode(w); err != nil {
120 return false, err
121 }
122
123 resp, err := notify.PostJSON(ctx, n.client, n.webhookURL.String(), &payload)
124 if err != nil {
125 return true, notify.RedactURL(err)
126 }
127
128 shouldRetry, err := n.retrier.Check(resp.StatusCode, resp.Body)
129 if err != nil {
130 return shouldRetry, err
131 }
132 return false, nil
133 }
134
View as plain text