2021-08-19 13:33:56 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2021-08-25 18:53:04 +00:00
|
|
|
"fmt"
|
2021-09-22 13:36:45 +00:00
|
|
|
"net/http"
|
2021-08-25 18:53:04 +00:00
|
|
|
|
2024-01-01 18:50:20 +00:00
|
|
|
"github.com/gorilla/mux"
|
2021-11-25 22:48:16 +00:00
|
|
|
"github.com/pkg/errors"
|
|
|
|
log "github.com/sirupsen/logrus"
|
2023-09-11 17:51:38 +00:00
|
|
|
"gopkg.in/irc.v4"
|
2021-11-25 22:48:16 +00:00
|
|
|
|
2021-12-10 01:28:13 +00:00
|
|
|
"github.com/Luzifer/go_helpers/v2/backoff"
|
2024-04-03 19:00:28 +00:00
|
|
|
"github.com/Luzifer/go_helpers/v2/fieldcollection"
|
2021-10-23 15:22:58 +00:00
|
|
|
"github.com/Luzifer/go_helpers/v2/str"
|
2022-11-02 21:38:14 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/announce"
|
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/ban"
|
2023-08-14 00:52:51 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/clip"
|
2023-04-07 22:41:00 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/clipdetector"
|
2023-03-14 14:34:08 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/commercial"
|
2022-11-02 21:38:14 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/counter"
|
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/delay"
|
|
|
|
deleteactor "github.com/Luzifer/twitch-bot/v3/internal/actors/delete"
|
2023-02-20 18:41:03 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/eventmod"
|
2022-11-02 21:38:14 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/filesay"
|
2023-04-07 22:41:00 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/linkdetector"
|
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/linkprotect"
|
2023-01-01 13:41:57 +00:00
|
|
|
logActor "github.com/Luzifer/twitch-bot/v3/internal/actors/log"
|
2024-09-03 21:27:01 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/marker"
|
2023-08-14 20:57:33 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/messagehook"
|
2022-11-02 21:38:14 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/modchannel"
|
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/nuke"
|
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/punish"
|
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/quotedb"
|
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/raw"
|
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/respond"
|
2023-02-04 12:59:18 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/shield"
|
2023-01-20 11:13:59 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/shoutout"
|
2024-03-15 18:51:00 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/spotify"
|
2023-02-05 15:08:22 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/stopexec"
|
2022-11-02 21:38:14 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/timeout"
|
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/variables"
|
2022-12-05 17:58:49 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/vip"
|
2022-11-02 21:38:14 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/actors/whisper"
|
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/apimodules/customevent"
|
2024-02-15 17:25:16 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/apimodules/kofi"
|
2022-11-02 21:38:14 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/apimodules/msgformat"
|
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/apimodules/overlays"
|
2023-07-14 14:15:58 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/apimodules/raffle"
|
2022-11-02 21:38:14 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/service/access"
|
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/template/api"
|
2024-03-30 14:14:30 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/template/date"
|
2022-11-02 21:38:14 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/template/numeric"
|
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/template/random"
|
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/template/slice"
|
2023-08-25 11:14:23 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/template/strings"
|
2023-04-22 20:23:35 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/template/subscriber"
|
2023-09-03 11:01:57 +00:00
|
|
|
twitchFns "github.com/Luzifer/twitch-bot/v3/internal/template/twitch"
|
2023-10-26 16:39:20 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/internal/template/userstate"
|
2022-11-02 21:38:14 +00:00
|
|
|
"github.com/Luzifer/twitch-bot/v3/pkg/database"
|
|
|
|
"github.com/Luzifer/twitch-bot/v3/pkg/twitch"
|
|
|
|
"github.com/Luzifer/twitch-bot/v3/plugins"
|
2021-08-19 13:33:56 +00:00
|
|
|
)
|
|
|
|
|
2021-12-10 01:28:13 +00:00
|
|
|
const ircHandleWaitRetries = 10
|
|
|
|
|
2021-10-23 15:22:58 +00:00
|
|
|
var (
|
2021-11-19 21:53:30 +00:00
|
|
|
corePluginRegistrations = []plugins.RegisterFunc{
|
|
|
|
// Actors
|
2022-10-25 16:47:30 +00:00
|
|
|
announce.Register,
|
2021-10-23 15:22:58 +00:00
|
|
|
ban.Register,
|
2023-08-14 00:52:51 +00:00
|
|
|
clip.Register,
|
2023-04-07 22:41:00 +00:00
|
|
|
clipdetector.Register,
|
2023-03-14 14:34:08 +00:00
|
|
|
commercial.Register,
|
2022-09-10 11:39:07 +00:00
|
|
|
counter.Register,
|
2021-10-23 15:22:58 +00:00
|
|
|
delay.Register,
|
|
|
|
deleteactor.Register,
|
2023-02-20 18:41:03 +00:00
|
|
|
eventmod.Register,
|
2022-03-04 22:34:59 +00:00
|
|
|
filesay.Register,
|
2023-04-07 22:41:00 +00:00
|
|
|
linkdetector.Register,
|
|
|
|
linkprotect.Register,
|
2023-01-01 13:41:57 +00:00
|
|
|
logActor.Register,
|
2024-09-03 21:27:01 +00:00
|
|
|
marker.Register,
|
2023-08-14 20:57:33 +00:00
|
|
|
messagehook.Register,
|
2021-10-23 15:22:58 +00:00
|
|
|
modchannel.Register,
|
2021-10-25 21:21:52 +00:00
|
|
|
nuke.Register,
|
2021-10-23 15:22:58 +00:00
|
|
|
punish.Register,
|
|
|
|
quotedb.Register,
|
|
|
|
raw.Register,
|
|
|
|
respond.Register,
|
2023-02-04 12:59:18 +00:00
|
|
|
shield.Register,
|
2023-01-20 11:13:59 +00:00
|
|
|
shoutout.Register,
|
2023-02-05 15:08:22 +00:00
|
|
|
stopexec.Register,
|
2021-10-23 15:22:58 +00:00
|
|
|
timeout.Register,
|
2022-09-10 11:39:07 +00:00
|
|
|
variables.Register,
|
2022-12-05 17:58:49 +00:00
|
|
|
vip.Register,
|
2021-10-23 15:22:58 +00:00
|
|
|
whisper.Register,
|
2021-11-19 21:53:30 +00:00
|
|
|
|
|
|
|
// Template functions
|
2022-09-26 21:32:48 +00:00
|
|
|
api.Register,
|
2024-03-30 14:14:30 +00:00
|
|
|
date.Register,
|
2021-11-19 21:53:30 +00:00
|
|
|
numeric.Register,
|
|
|
|
random.Register,
|
2022-06-20 19:41:53 +00:00
|
|
|
slice.Register,
|
2024-03-15 18:51:00 +00:00
|
|
|
spotify.Register,
|
2023-08-25 11:14:23 +00:00
|
|
|
strings.Register,
|
2023-04-22 20:23:35 +00:00
|
|
|
subscriber.Register,
|
2023-09-03 11:01:57 +00:00
|
|
|
twitchFns.Register,
|
2023-10-26 16:39:20 +00:00
|
|
|
userstate.Register,
|
2022-01-20 01:03:52 +00:00
|
|
|
|
|
|
|
// API-only modules
|
2022-03-30 22:23:19 +00:00
|
|
|
customevent.Register,
|
2024-02-15 17:25:16 +00:00
|
|
|
kofi.Register,
|
2022-01-20 01:03:52 +00:00
|
|
|
msgformat.Register,
|
2022-02-08 18:58:19 +00:00
|
|
|
overlays.Register,
|
2023-07-14 14:15:58 +00:00
|
|
|
raffle.Register,
|
2021-10-23 15:22:58 +00:00
|
|
|
}
|
|
|
|
knownModules []string
|
|
|
|
)
|
2021-08-19 13:33:56 +00:00
|
|
|
|
2021-09-10 17:45:31 +00:00
|
|
|
func initCorePlugins() error {
|
2021-08-19 13:33:56 +00:00
|
|
|
args := getRegistrationArguments()
|
2022-10-22 22:08:02 +00:00
|
|
|
for idx, rf := range corePluginRegistrations {
|
2021-08-19 13:33:56 +00:00
|
|
|
if err := rf(args); err != nil {
|
2022-10-22 22:08:02 +00:00
|
|
|
return errors.Wrapf(err, "registering core plugin %d", idx)
|
2021-08-19 13:33:56 +00:00
|
|
|
}
|
|
|
|
}
|
2021-09-10 17:45:31 +00:00
|
|
|
return nil
|
2021-08-19 13:33:56 +00:00
|
|
|
}
|
|
|
|
|
2021-08-28 15:27:24 +00:00
|
|
|
func registerRoute(route plugins.HTTPRouteRegistrationArgs) error {
|
|
|
|
r := router.
|
|
|
|
PathPrefix(fmt.Sprintf("/%s/", route.Module)).
|
|
|
|
Subrouter()
|
|
|
|
|
2021-10-23 15:22:58 +00:00
|
|
|
if !str.StringInSlice(route.Module, knownModules) {
|
|
|
|
knownModules = append(knownModules, route.Module)
|
|
|
|
}
|
|
|
|
|
2021-09-22 13:36:45 +00:00
|
|
|
var hdl http.Handler = route.HandlerFunc
|
2021-10-23 15:22:58 +00:00
|
|
|
switch {
|
|
|
|
case route.RequiresEditorsAuth:
|
2023-07-14 14:15:58 +00:00
|
|
|
hdl = writeAuthMiddleware(hdl, moduleConfigEditor)
|
2021-10-23 15:22:58 +00:00
|
|
|
case route.RequiresWriteAuth:
|
|
|
|
hdl = writeAuthMiddleware(hdl, route.Module)
|
2021-09-22 13:36:45 +00:00
|
|
|
}
|
|
|
|
|
2024-01-01 18:50:20 +00:00
|
|
|
var muxRoute *mux.Route
|
2021-08-28 15:27:24 +00:00
|
|
|
if route.IsPrefix {
|
2024-01-01 18:50:20 +00:00
|
|
|
muxRoute = r.PathPrefix(route.Path).Handler(hdl)
|
2021-08-28 15:27:24 +00:00
|
|
|
} else {
|
2024-01-01 18:50:20 +00:00
|
|
|
muxRoute = r.Handle(route.Path, hdl)
|
|
|
|
}
|
|
|
|
|
|
|
|
if route.Method != "" {
|
|
|
|
muxRoute.Methods(route.Method)
|
2021-08-28 15:27:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if !route.SkipDocumentation {
|
|
|
|
return errors.Wrap(registerSwaggerRoute(route), "registering documentation")
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-08-19 13:33:56 +00:00
|
|
|
func getRegistrationArguments() plugins.RegistrationArguments {
|
|
|
|
return plugins.RegistrationArguments{
|
2021-09-22 13:36:45 +00:00
|
|
|
FormatMessage: formatMessage,
|
2023-07-14 14:15:58 +00:00
|
|
|
FrontendNotify: func(mt string) { frontendNotifyHooks.Ping(mt) },
|
2024-03-15 18:51:00 +00:00
|
|
|
GetBaseURL: func() string { return cfg.BaseURL },
|
2022-09-10 11:39:07 +00:00
|
|
|
GetDatabaseConnector: func() database.Connector { return db },
|
2021-09-22 13:36:45 +00:00
|
|
|
GetLogger: func(moduleName string) *log.Entry { return log.WithField("module", moduleName) },
|
|
|
|
GetTwitchClient: func() *twitch.Client { return twitchClient },
|
2022-12-05 17:57:41 +00:00
|
|
|
HasAnyPermissionForChannel: accessService.HasAnyPermissionForChannel,
|
|
|
|
HasPermissionForChannel: accessService.HasPermissionsForChannel,
|
2021-09-22 13:36:45 +00:00
|
|
|
RegisterActor: registerAction,
|
|
|
|
RegisterActorDocumentation: registerActorDocumentation,
|
|
|
|
RegisterAPIRoute: registerRoute,
|
|
|
|
RegisterCron: cronService.AddFunc,
|
2023-11-25 19:23:34 +00:00
|
|
|
RegisterCopyDatabaseFunc: registerDatabaseCopyFunc,
|
2022-02-08 18:58:19 +00:00
|
|
|
RegisterEventHandler: registerEventHandlers,
|
2022-10-25 16:47:30 +00:00
|
|
|
RegisterMessageModFunc: registerChatcommand,
|
2021-09-22 13:36:45 +00:00
|
|
|
RegisterRawMessageHandler: registerRawMessageHandler,
|
|
|
|
RegisterTemplateFunction: tplFuncs.Register,
|
|
|
|
SendMessage: sendMessage,
|
2023-12-04 13:12:01 +00:00
|
|
|
ValidateToken: authService.ValidateTokenFor,
|
2022-09-10 11:39:07 +00:00
|
|
|
|
2024-04-03 19:00:28 +00:00
|
|
|
CreateEvent: func(evt string, eventData *fieldcollection.FieldCollection) error {
|
2023-09-02 11:49:15 +00:00
|
|
|
handleMessage(ircHdl.Client(), nil, &evt, eventData)
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
|
2024-04-03 19:00:28 +00:00
|
|
|
GetModuleConfigForChannel: func(module, channel string) *fieldcollection.FieldCollection {
|
2023-09-02 11:49:15 +00:00
|
|
|
return config.ModuleConfig.GetChannelConfig(module, channel)
|
|
|
|
},
|
|
|
|
|
2022-09-10 11:39:07 +00:00
|
|
|
GetTwitchClientForChannel: func(channel string) (*twitch.Client, error) {
|
|
|
|
return accessService.GetTwitchClientForChannel(channel, access.ClientConfig{
|
|
|
|
TwitchClient: cfg.TwitchClient,
|
|
|
|
TwitchClientSecret: cfg.TwitchClientSecret,
|
|
|
|
})
|
|
|
|
},
|
2021-08-19 13:33:56 +00:00
|
|
|
}
|
|
|
|
}
|
2021-12-10 01:28:13 +00:00
|
|
|
|
|
|
|
func sendMessage(m *irc.Message) error {
|
2022-10-25 16:47:30 +00:00
|
|
|
err := handleChatcommandModifications(m)
|
|
|
|
switch {
|
|
|
|
case err == nil:
|
|
|
|
// There was no error, the message should be sent normally
|
|
|
|
|
|
|
|
case errors.Is(err, plugins.ErrSkipSendingMessage):
|
|
|
|
// One chatcommand handler cancelled sending the message
|
|
|
|
// (probably because it was handled otherwise)
|
|
|
|
return nil
|
|
|
|
|
|
|
|
default:
|
|
|
|
// Something in a chatcommand handler went wrong
|
|
|
|
return errors.Wrap(err, "handling chat commands")
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = backoff.NewBackoff().WithMaxIterations(ircHandleWaitRetries).Retry(func() error {
|
2021-12-10 01:28:13 +00:00
|
|
|
if ircHdl == nil {
|
|
|
|
return errors.New("irc handle not available")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}); err != nil {
|
|
|
|
return errors.Wrap(err, "waiting for IRC connection")
|
|
|
|
}
|
|
|
|
|
|
|
|
return ircHdl.SendMessage(m)
|
|
|
|
}
|