twitch-bot/internal/actors/messagehook/actor.go

72 lines
1.7 KiB
Go
Raw Normal View History

// Package messagehook contains actors to send discord / slack webhook
// requests
package messagehook
import (
"bytes"
"context"
"encoding/json"
"io"
"net/http"
"time"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/Luzifer/twitch-bot/v3/plugins"
)
const (
postTimeout = 5 * time.Second
)
var formatMessage plugins.MsgFormatter
// Register provides the plugins.RegisterFunc
func Register(args plugins.RegistrationArguments) error {
formatMessage = args.FormatMessage
discordActor{}.register(args)
slackCompatibleActor{}.register(args)
return nil
}
func sendPayload(hookURL string, payload any, expRespCode int) (preventCooldown bool, err error) {
body := new(bytes.Buffer)
if err = json.NewEncoder(body).Encode(payload); err != nil {
return false, errors.Wrap(err, "marshalling payload")
}
logrus.WithField("payload", body.String()).Trace("sending webhook payload")
ctx, cancel := context.WithTimeout(context.Background(), postTimeout)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, hookURL, body)
if err != nil {
return false, errors.Wrap(err, "creating request")
}
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return false, errors.Wrap(err, "executing request")
}
defer func() {
if err := resp.Body.Close(); err != nil {
logrus.WithError(err).Error("closing response body (leaked fd)")
}
}()
if resp.StatusCode != expRespCode {
body, err := io.ReadAll(resp.Body)
if err != nil {
body = []byte(errors.Wrap(err, "reading body").Error())
}
return false, errors.Errorf("unexpected response code %d (Body: %s)", resp.StatusCode, body)
}
return false, nil
}