twitch-bot/internal/apimodules/customevent/customevent.go
2022-04-17 16:54:12 +02:00

99 lines
2.5 KiB
Go

package customevent
import (
"encoding/json"
"io"
"net/http"
"strings"
"github.com/gorilla/mux"
"github.com/pkg/errors"
"github.com/Luzifer/twitch-bot/plugins"
)
const actorName = "customevent"
var (
eventCreatorFunc plugins.EventHandlerFunc
formatMessage plugins.MsgFormatter
)
func Register(args plugins.RegistrationArguments) error {
eventCreatorFunc = args.CreateEvent
formatMessage = args.FormatMessage
args.RegisterActor(actorName, func() plugins.Actor { return &actor{} })
args.RegisterActorDocumentation(plugins.ActionDocumentation{
Description: "Create a custom event",
Name: "Custom Event",
Type: actorName,
Fields: []plugins.ActionDocumentationField{
{
Default: "{}",
Description: "JSON representation of fields in the event (`map[string]any`)",
Key: "fields",
Name: "Fields",
Optional: false,
SupportTemplate: true,
Type: plugins.ActionDocumentationFieldTypeString,
},
},
})
args.RegisterAPIRoute(plugins.HTTPRouteRegistrationArgs{
Description: "Creates an `custom` event containing the fields provided in the request body",
HandlerFunc: handleCreateEvent,
Method: http.MethodPost,
Module: "customevent",
Name: "Create custom event",
Path: "/{channel}",
RequiresWriteAuth: true,
ResponseType: plugins.HTTPRouteResponseTypeNo200,
RouteParams: []plugins.HTTPRouteParamDocumentation{
{
Description: "Channel to create the event in",
Name: "channel",
},
},
})
return nil
}
func handleCreateEvent(w http.ResponseWriter, r *http.Request) {
channel := mux.Vars(r)["channel"]
if channel == "" {
http.Error(w, errors.New("missing channel").Error(), http.StatusBadRequest)
return
}
channel = "#" + strings.TrimLeft(channel, "#") // Sanitize
if err := triggerEvent(channel, r.Body); err != nil {
http.Error(w, errors.Wrap(err, "creating event").Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusNoContent)
}
func triggerEvent(channel string, fieldData io.Reader) error {
payload := make(map[string]any)
if err := json.NewDecoder(fieldData).Decode(&payload); err != nil {
return errors.Wrap(err, "parsing event payload")
}
fields := plugins.FieldCollectionFromData(payload)
fields.Set("channel", "#"+strings.TrimLeft(channel, "#"))
if err := eventCreatorFunc("custom", fields); err != nil {
return errors.Wrap(err, "creating event")
}
return nil
}