diff --git a/docs/content/configuration/templating.md b/docs/content/configuration/templating.md index 9bb4980..bc87998 100644 --- a/docs/content/configuration/templating.md +++ b/docs/content/configuration/templating.md @@ -84,7 +84,7 @@ Example: ``` # {{ botHasBadge "moderator" }} -< true +< false ``` ### `channelCounter` @@ -100,6 +100,19 @@ Example: < #example:test ``` +### `chatterHasBadge` + +Checks whether chatter writing the current line has the given badge in the current channel + +Syntax: `chatterHasBadge ` + +Example: + +``` +# {{ chatterHasBadge "moderator" }} +< true +``` + ### `counterRank` Returns the rank of the given counter and the total number of counters in given counter prefix @@ -415,7 +428,7 @@ Example: ``` # Your int this hour: {{ printf "%.0f" (mulf (seededRandom (list "int" .username (now | date "2006-01-02 15") | join ":")) 100) }}% -< Your int this hour: 43% +< Your int this hour: 37% ``` ### `streamUptime` diff --git a/functions_irc.go b/functions_irc.go index c103433..7534c5b 100644 --- a/functions_irc.go +++ b/functions_irc.go @@ -30,16 +30,16 @@ func init() { }, }) - tplFuncs.Register("botHasBadge", func(m *irc.Message, r *plugins.Rule, fields *plugins.FieldCollection) interface{} { + tplFuncs.Register("chatterHasBadge", func(m *irc.Message, r *plugins.Rule, fields *plugins.FieldCollection) interface{} { return func(badge string) bool { badges := twitch.ParseBadgeLevels(m) return badges.Has(badge) } }, plugins.TemplateFuncDocumentation{ - Description: "Checks whether bot has the given badge in the current channel", - Syntax: "botHasBadge ", + Description: "Checks whether chatter writing the current line has the given badge in the current channel", + Syntax: "chatterHasBadge ", Example: &plugins.TemplateFuncDocumentationExample{ - Template: `{{ botHasBadge "moderator" }}`, + Template: `{{ chatterHasBadge "moderator" }}`, ExpectedOutput: "true", }, }) diff --git a/internal/template/userstate/actor.go b/internal/template/userstate/actor.go new file mode 100644 index 0000000..2da5679 --- /dev/null +++ b/internal/template/userstate/actor.go @@ -0,0 +1,51 @@ +// Package userstate traces the bot state and provides template +// functions based on it +package userstate + +import ( + "github.com/Luzifer/twitch-bot/v3/plugins" + "github.com/pkg/errors" + "gopkg.in/irc.v4" +) + +var userState = newTwitchUserStateStore() + +func Register(args plugins.RegistrationArguments) error { + if err := args.RegisterRawMessageHandler(rawMessageHandler); err != nil { + return errors.Wrap(err, "registering raw message handler") + } + + args.RegisterTemplateFunction("botHasBadge", func(m *irc.Message, _ *plugins.Rule, fields *plugins.FieldCollection) interface{} { + return func(badge string) bool { + state := userState.Get(plugins.DeriveChannel(m, fields)) + if state == nil { + return false + } + return state.Badges.Has(badge) + } + }, plugins.TemplateFuncDocumentation{ + Description: "Checks whether bot has the given badge in the current channel", + Syntax: "botHasBadge ", + Example: &plugins.TemplateFuncDocumentationExample{ + Template: `{{ botHasBadge "moderator" }}`, + ExpectedOutput: "false", + }, + }) + + return nil +} + +func rawMessageHandler(m *irc.Message) error { + if m.Command != "USERSTATE" { + return nil + } + + state, err := parseTwitchUserState(m) + if err != nil { + return errors.Wrap(err, "parsing state") + } + + userState.Set(plugins.DeriveChannel(m, nil), state) + + return nil +} diff --git a/botUserState.go b/internal/template/userstate/botUserState.go similarity index 98% rename from botUserState.go rename to internal/template/userstate/botUserState.go index 4acef42..dedf3fd 100644 --- a/botUserState.go +++ b/internal/template/userstate/botUserState.go @@ -1,4 +1,4 @@ -package main +package userstate import ( "strings" diff --git a/irc.go b/irc.go index f8eed77..3ed1725 100644 --- a/irc.go +++ b/irc.go @@ -181,11 +181,6 @@ func (i ircHandler) Handle(c *irc.Client, m *irc.Message) { // Announces Twitch-specific events to the channel (for example, a user’s subscription notification). i.handleTwitchUsernotice(m) - case "USERSTATE": - // USERSTATE (Twitch Tags) - // Sends user-state data when a user joins a channel or sends a PRIVMSG to a channel. - i.handleTwitchUserstate(m) - case "WHISPER": // WHISPER (Twitch Commands) // Delivers whisper-messages received @@ -486,16 +481,6 @@ func (i ircHandler) handleTwitchUsernotice(m *irc.Message) { } } -func (i ircHandler) handleTwitchUserstate(m *irc.Message) { - state, err := parseTwitchUserState(m) - if err != nil { - log.WithError(err).Error("Unable to parse bot user-state") - return - } - - botUserstate.Set(plugins.DeriveChannel(m, nil), state) -} - func (i ircHandler) handleTwitchWhisper(m *irc.Message) { go handleMessage(i.c, m, eventTypeWhisper, nil) } diff --git a/main.go b/main.go index 8be7169..a5ba5b8 100644 --- a/main.go +++ b/main.go @@ -60,10 +60,9 @@ var ( config *configFile configLock = new(sync.RWMutex) - botUserstate = newTwitchUserStateStore() - cronService *cron.Cron - ircHdl *ircHandler - router = mux.NewRouter() + cronService *cron.Cron + ircHdl *ircHandler + router = mux.NewRouter() runID = uuid.Must(uuid.NewV4()).String() diff --git a/plugins_core.go b/plugins_core.go index 7d2f717..cfac10d 100644 --- a/plugins_core.go +++ b/plugins_core.go @@ -49,6 +49,7 @@ import ( "github.com/Luzifer/twitch-bot/v3/internal/template/strings" "github.com/Luzifer/twitch-bot/v3/internal/template/subscriber" twitchFns "github.com/Luzifer/twitch-bot/v3/internal/template/twitch" + "github.com/Luzifer/twitch-bot/v3/internal/template/userstate" "github.com/Luzifer/twitch-bot/v3/pkg/database" "github.com/Luzifer/twitch-bot/v3/pkg/twitch" "github.com/Luzifer/twitch-bot/v3/plugins" @@ -95,6 +96,7 @@ var ( strings.Register, subscriber.Register, twitchFns.Register, + userstate.Register, // API-only modules customevent.Register,