diff --git a/lib/discord.go b/lib/discord.go index cf99f86..b7bafdd 100644 --- a/lib/discord.go +++ b/lib/discord.go @@ -5,15 +5,17 @@ import ( "crypto/tls" "encoding/json" "errors" - "github.com/sirupsen/logrus" "io" "io/ioutil" "math" "net" "net/http" + "net/url" "strconv" "strings" "time" + + "github.com/sirupsen/logrus" ) var client *http.Client @@ -213,6 +215,15 @@ func GetBotUser(token string) (*BotUserResponse, error) { } func doDiscordReq(ctx context.Context, path string, method string, body io.ReadCloser, header http.Header, query string) (*http.Response, error) { + route := GetMetricsPath(path) + if route == "/channels/!/messages/!/reactions/!/!" { + segs := strings.Split(path, "/") + unescaped, _ := url.PathUnescape(segs[7]) + if segs[7] == unescaped { + segs[7] = url.PathEscape(segs[7]) + } + path = strings.Join(segs, "/") + } discordReq, err := http.NewRequestWithContext(ctx, method, "https://discord.com"+path+"?"+query, body) if err != nil { return nil, err @@ -229,7 +240,6 @@ func doDiscordReq(ctx context.Context, path string, method string, body io.ReadC } if err == nil { - route := GetMetricsPath(path) status := discordResp.Status method := discordResp.Request.Method elapsed := time.Since(startTime).Seconds() diff --git a/lib/queue.go b/lib/queue.go index 203383a..eab5eb8 100644 --- a/lib/queue.go +++ b/lib/queue.go @@ -1,17 +1,21 @@ package lib import ( + "bytes" "context" "errors" - "github.com/Clever/leakybucket" - "github.com/Clever/leakybucket/memory" - "github.com/sirupsen/logrus" + "io" + "io/ioutil" "net/http" "strconv" "strings" "sync" "sync/atomic" "time" + + "github.com/Clever/leakybucket" + "github.com/Clever/leakybucket/memory" + "github.com/sirupsen/logrus" ) type QueueItem struct { @@ -272,6 +276,11 @@ func return401(item *QueueItem) { item.doneChan <- nil } +func isUnknownWebhook(_body io.ReadCloser) bool { + body, _ := ioutil.ReadAll(_body); + return bytes.Contains(body, []byte("\"code\": 10015")) +} + func isInteraction(url string) bool { parts := strings.Split(strings.SplitN(url, "?", 1)[0], "/") for _, p := range parts { @@ -348,7 +357,7 @@ func (q *RequestQueue) subscribe(ch *QueueChannel, path string, pathHash uint64) }).Warn("Unexpected 429") } - if resp.StatusCode == 404 && strings.HasPrefix(path, "/webhooks/") && !isInteraction(item.Req.URL.String()) { + if resp.StatusCode == 404 && isUnknownWebhook(resp.Body) && !isInteraction(item.Req.URL.String()) { logger.WithFields(logrus.Fields{ "bucket": path, "route": item.Req.URL.String(),