5
5
package notification
6
6
7
7
import (
8
+ "bufio"
8
9
"bytes"
9
10
"encoding/json"
10
11
"fmt"
11
12
"io"
12
13
"net/http"
14
+ "slices"
13
15
"strings"
14
16
"time"
15
17
@@ -66,8 +68,18 @@ func NewDiscordSender(log logger.Logger, config *config.AppConfig) domain.Sender
66
68
}
67
69
}
68
70
71
+ func (s * discordSender ) Name () string {
72
+ return "discord"
73
+ }
74
+
69
75
func (s * discordSender ) Send (statusCode int , payload domain.NotificationPayload ) error {
70
76
if ! s .isEnabled () {
77
+ s .log .Debug ().Msg ("no webhook defined, skipping notification" )
78
+ return nil
79
+ }
80
+
81
+ if ! s .shouldSend (statusCode ) {
82
+ s .log .Debug ().Msg ("no notification wanted for this status, skipping notification" )
71
83
return nil
72
84
}
73
85
@@ -78,34 +90,34 @@ func (s *discordSender) Send(statusCode int, payload domain.NotificationPayload)
78
90
79
91
jsonData , err := json .Marshal (m )
80
92
if err != nil {
81
- return errors .Wrap (err , "discord client could not marshal data : %+v " , m )
93
+ return errors .Wrap (err , "could not marshal json request for status : %v payload: %v " , statusCode , payload )
82
94
}
83
95
84
96
req , err := http .NewRequest (http .MethodPost , s .cfg .Config .Notifications .Discord , bytes .NewBuffer (jsonData ))
85
97
if err != nil {
86
- return errors .Wrap (err , "discord client could not create request" )
98
+ return errors .Wrap (err , "could not create request for status: %v payload: %v" , statusCode , payload )
87
99
}
88
100
89
101
req .Header .Set ("Content-Type" , "application/json" )
90
- //req.Header.Set("User-Agent", "seasonpackarr")
102
+ // req.Header.Set("User-Agent", "seasonpackarr")
91
103
92
104
res , err := s .httpClient .Do (req )
93
105
if err != nil {
94
- return errors .Wrap (err , "discord client could not make request : %+v " , req )
106
+ return errors .Wrap (err , "client request error for status : %v payload: %v " , statusCode , payload )
95
107
}
96
108
97
109
defer res .Body .Close ()
98
110
99
- body , err := io .ReadAll (res .Body )
100
- if err != nil {
101
- return errors .Wrap (err , "discord client could not read data" )
102
- }
103
-
104
- s .log .Trace ().Msgf ("discord status: %v response: %v" , res .StatusCode , string (body ))
111
+ s .log .Trace ().Msgf ("discord response status: %d" , res .StatusCode )
105
112
106
113
// discord responds with 204, Notifiarr with 204 so lets take all 200 as ok
107
- if res .StatusCode >= 300 {
108
- return errors .New ("bad discord client status: %v body: %v" , res .StatusCode , string (body ))
114
+ if res .StatusCode != http .StatusOK && res .StatusCode != http .StatusNoContent {
115
+ body , err := io .ReadAll (bufio .NewReader (res .Body ))
116
+ if err != nil {
117
+ return errors .Wrap (err , "could not read body for status: %v payload: %v" , statusCode , payload )
118
+ }
119
+
120
+ return errors .New ("unexpected status: %v body: %v" , res .StatusCode , string (body ))
109
121
}
110
122
111
123
s .log .Debug ().Msg ("notification successfully sent to discord" )
@@ -114,20 +126,34 @@ func (s *discordSender) Send(statusCode int, payload domain.NotificationPayload)
114
126
}
115
127
116
128
func (s * discordSender ) isEnabled () bool {
117
- if s .cfg .Config .Notifications .Discord == "" {
118
- s .log .Warn ().Msg ("no webhook defined, skipping notification" )
129
+ return len (s .cfg .Config .Notifications .Discord ) != 0
130
+ }
131
+
132
+ func (s * discordSender ) shouldSend (statusCode int ) bool {
133
+ if len (s .cfg .Config .Notifications .NotificationLevel ) == 0 {
119
134
return false
120
135
}
121
136
122
- return true
137
+ statusCodes := make (map [int ]struct {})
138
+
139
+ for _ , level := range s .cfg .Config .Notifications .NotificationLevel {
140
+ if codes , ok := domain .StatusMap [level ]; ok {
141
+ for _ , code := range codes {
142
+ statusCodes [code ] = struct {}{}
143
+ }
144
+ }
145
+ }
146
+
147
+ _ , shouldSend := statusCodes [statusCode ]
148
+ return shouldSend
123
149
}
124
150
125
151
func (s * discordSender ) buildEmbed (statusCode int , payload domain.NotificationPayload ) DiscordEmbeds {
126
152
color := LIGHT_BLUE
127
153
128
- if ( statusCode >= 200 ) && ( statusCode < 250 ) { // not matching
154
+ if slices . Contains ( domain . StatusMap [ domain . NotificationLevelInfo ], statusCode ) { // not matching
129
155
color = GRAY
130
- } else if ( statusCode >= 400 ) && ( statusCode < 500 ) { // error processing
156
+ } else if slices . Contains ( domain . StatusMap [ domain . NotificationLevelError ], statusCode ) { // error processing
131
157
color = RED
132
158
} else { // success
133
159
color = GREEN
@@ -164,7 +190,7 @@ func (s *discordSender) buildEmbed(statusCode int, payload domain.NotificationPa
164
190
165
191
if payload .Error != nil {
166
192
// actual error?
167
- if statusCode >= 400 {
193
+ if slices . Contains ( domain . StatusMap [ domain . NotificationLevelError ], statusCode ) {
168
194
f := DiscordEmbedsFields {
169
195
Name : "Error" ,
170
196
Value : fmt .Sprintf ("```%s```" , payload .Error .Error ()),
0 commit comments