@@ -16,9 +16,9 @@ import (
16
16
17
17
// Discord color values
18
18
const (
19
- ColorRed = 10038562
20
- ColorGreen = 3066993
21
- ColorGrey = 9807270
19
+ ColorRed = 0x992D22
20
+ ColorGreen = 0x2ECC71
21
+ ColorGrey = 0x95A5A6
22
22
)
23
23
24
24
type alertManAlert struct {
@@ -70,32 +70,106 @@ type discordEmbedField struct {
70
70
71
71
const defaultListenAddress = "127.0.0.1:9094"
72
72
73
- func main () {
74
- envWhURL := os .Getenv ("DISCORD_WEBHOOK" )
75
- whURL := flag .String ("webhook.url" , envWhURL , "Discord WebHook URL." )
76
-
77
- envListenAddress := os .Getenv ("LISTEN_ADDRESS" )
78
- listenAddress := flag .String ("listen.address" , envListenAddress , "Address:Port to listen on." )
79
-
80
- flag .Parse ()
73
+ var (
74
+ whURL = flag .String ("webhook.url" , os .Getenv ("DISCORD_WEBHOOK" ), "Discord WebHook URL." )
75
+ listenAddress = flag .String ("listen.address" , os .Getenv ("LISTEN_ADDRESS" ), "Address:Port to listen on." )
76
+ )
81
77
82
- if * whURL == "" {
78
+ func checkWhURL (whURL string ) {
79
+ if whURL == "" {
83
80
log .Fatalf ("Environment variable 'DISCORD_WEBHOOK' or CLI parameter 'webhook.url' not found." )
84
81
}
85
-
86
- if * listenAddress == "" {
87
- * listenAddress = defaultListenAddress
88
- }
89
-
90
- _ , err := url .Parse (* whURL )
82
+ _ , err := url .Parse (whURL )
91
83
if err != nil {
92
84
log .Fatalf ("The Discord WebHook URL doesn't seem to be a valid URL." )
93
85
}
94
86
95
87
re := regexp .MustCompile (`https://discord(?:app)?.com/api/webhooks/[0-9]{18}/[a-zA-Z0-9_-]+` )
96
- if ok := re .Match ([]byte (* whURL )); ! ok {
88
+ if ok := re .Match ([]byte (whURL )); ! ok {
97
89
log .Printf ("The Discord WebHook URL doesn't seem to be valid." )
98
90
}
91
+ }
92
+
93
+ func sendWebhook (amo * alertManOut ) {
94
+ groupedAlerts := make (map [string ][]alertManAlert )
95
+
96
+ for _ , alert := range amo .Alerts {
97
+ groupedAlerts [alert .Status ] = append (groupedAlerts [alert .Status ], alert )
98
+ }
99
+
100
+ for status , alerts := range groupedAlerts {
101
+ DO := discordOut {}
102
+
103
+ RichEmbed := discordEmbed {
104
+ Title : fmt .Sprintf ("[%s:%d] %s" , strings .ToUpper (status ), len (alerts ), amo .CommonLabels .Alertname ),
105
+ Description : amo .CommonAnnotations .Summary ,
106
+ Color : ColorGrey ,
107
+ Fields : []discordEmbedField {},
108
+ }
109
+
110
+ if status == "firing" {
111
+ RichEmbed .Color = ColorRed
112
+ } else if status == "resolved" {
113
+ RichEmbed .Color = ColorGreen
114
+ }
115
+
116
+ if amo .CommonAnnotations .Summary != "" {
117
+ DO .Content = fmt .Sprintf (" === %s === \n " , amo .CommonAnnotations .Summary )
118
+ }
119
+
120
+ for _ , alert := range alerts {
121
+ realname := alert .Labels ["instance" ]
122
+ if strings .Contains (realname , "localhost" ) && alert .Labels ["exported_instance" ] != "" {
123
+ realname = alert .Labels ["exported_instance" ]
124
+ }
125
+
126
+ RichEmbed .Fields = append (RichEmbed .Fields , discordEmbedField {
127
+ Name : fmt .Sprintf ("[%s]: %s on %s" , strings .ToUpper (status ), alert .Labels ["alertname" ], realname ),
128
+ Value : alert .Annotations .Description ,
129
+ })
130
+ }
131
+
132
+ DO .Embeds = []discordEmbed {RichEmbed }
133
+
134
+ DOD , _ := json .Marshal (DO )
135
+ http .Post (* whURL , "application/json" , bytes .NewReader (DOD ))
136
+ }
137
+ }
138
+
139
+ func sendRawPromAlertWarn () {
140
+ badString := `This program is suppose to be fed by alertmanager.` + "\n " +
141
+ `It is not a replacement for alertmanager, it is a ` + "\n " +
142
+ `webhook target for it. Please read the README.md ` + "\n " +
143
+ `for guidance on how to configure it for alertmanager` + "\n " +
144
+ `or https://prometheus.io/docs/alerting/latest/configuration/#webhook_config`
145
+
146
+ log .Print (`/!\ -- You have misconfigured this software -- /!\` )
147
+ log .Print (`--- -- -- ---` )
148
+ log .Print (badString )
149
+
150
+ DO := discordOut {
151
+ Content : "" ,
152
+ Embeds : []discordEmbed {
153
+ {
154
+ Title : "You have misconfigured this software" ,
155
+ Description : badString ,
156
+ Color : ColorGrey ,
157
+ Fields : []discordEmbedField {},
158
+ },
159
+ },
160
+ }
161
+
162
+ DOD , _ := json .Marshal (DO )
163
+ http .Post (* whURL , "application/json" , bytes .NewReader (DOD ))
164
+ }
165
+
166
+ func main () {
167
+ flag .Parse ()
168
+ checkWhURL (* whURL )
169
+
170
+ if * listenAddress == "" {
171
+ * listenAddress = defaultListenAddress
172
+ }
99
173
100
174
log .Printf ("Listening on: %s" , * listenAddress )
101
175
http .ListenAndServe (* listenAddress , http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
@@ -110,30 +184,7 @@ func main() {
110
184
err = json .Unmarshal (b , & amo )
111
185
if err != nil {
112
186
if isRawPromAlert (b ) {
113
- badString := `This program is suppose to be fed by alertmanager.` + "\n " +
114
- `It is not a replacement for alertmanager, it is a ` + "\n " +
115
- `webhook target for it. Please read the README.md ` + "\n " +
116
- `for guidance on how to configure it for alertmanager` + "\n " +
117
- `or https://prometheus.io/docs/alerting/latest/configuration/#webhook_config`
118
-
119
- log .Print (`/!\ -- You have misconfigured this software -- /!\` )
120
- log .Print (`--- -- -- ---` )
121
- log .Print (badString )
122
-
123
- DO := discordOut {
124
- Content : "" ,
125
- Embeds : []discordEmbed {
126
- {
127
- Title : "You have misconfigured this software" ,
128
- Description : badString ,
129
- Color : ColorGrey ,
130
- Fields : []discordEmbedField {},
131
- },
132
- },
133
- }
134
-
135
- DOD , _ := json .Marshal (DO )
136
- http .Post (* whURL , "application/json" , bytes .NewReader (DOD ))
187
+ sendRawPromAlertWarn ()
137
188
return
138
189
}
139
190
@@ -147,48 +198,6 @@ func main() {
147
198
return
148
199
}
149
200
150
- groupedAlerts := make (map [string ][]alertManAlert )
151
-
152
- for _ , alert := range amo .Alerts {
153
- groupedAlerts [alert .Status ] = append (groupedAlerts [alert .Status ], alert )
154
- }
155
-
156
- for status , alerts := range groupedAlerts {
157
- DO := discordOut {}
158
-
159
- RichEmbed := discordEmbed {
160
- Title : fmt .Sprintf ("[%s:%d] %s" , strings .ToUpper (status ), len (alerts ), amo .CommonLabels .Alertname ),
161
- Description : amo .CommonAnnotations .Summary ,
162
- Color : ColorGrey ,
163
- Fields : []discordEmbedField {},
164
- }
165
-
166
- if status == "firing" {
167
- RichEmbed .Color = ColorRed
168
- } else if status == "resolved" {
169
- RichEmbed .Color = ColorGreen
170
- }
171
-
172
- if amo .CommonAnnotations .Summary != "" {
173
- DO .Content = fmt .Sprintf (" === %s === \n " , amo .CommonAnnotations .Summary )
174
- }
175
-
176
- for _ , alert := range alerts {
177
- realname := alert .Labels ["instance" ]
178
- if strings .Contains (realname , "localhost" ) && alert .Labels ["exported_instance" ] != "" {
179
- realname = alert .Labels ["exported_instance" ]
180
- }
181
-
182
- RichEmbed .Fields = append (RichEmbed .Fields , discordEmbedField {
183
- Name : fmt .Sprintf ("[%s]: %s on %s" , strings .ToUpper (status ), alert .Labels ["alertname" ], realname ),
184
- Value : alert .Annotations .Description ,
185
- })
186
- }
187
-
188
- DO .Embeds = []discordEmbed {RichEmbed }
189
-
190
- DOD , _ := json .Marshal (DO )
191
- http .Post (* whURL , "application/json" , bytes .NewReader (DOD ))
192
- }
201
+ sendWebhook (& amo )
193
202
}))
194
203
}
0 commit comments