[templating] Add botHasBadge function

to allow checking for moderation permissions in channels

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2021-09-29 18:23:29 +02:00
parent 7e2f0ab020
commit 87df2040e4
Signed by: luzifer
GPG key ID: 0066F03ED215AD7D
4 changed files with 96 additions and 3 deletions

71
botUserState.go Normal file
View file

@ -0,0 +1,71 @@
package main
import (
"strconv"
"strings"
"sync"
"github.com/Luzifer/twitch-bot/twitch"
"github.com/go-irc/irc"
"github.com/pkg/errors"
)
type (
twitchUserState struct {
Badges twitch.BadgeCollection
Color string
DisplayName string
EmoteSets []int64
}
twitchUserStateStore struct {
states map[string]*twitchUserState
lock sync.RWMutex
}
)
func newTwitchUserStateStore() *twitchUserStateStore {
return &twitchUserStateStore{
states: make(map[string]*twitchUserState),
}
}
func parseTwitchUserState(m *irc.Message) (*twitchUserState, error) {
var (
color, _ = m.GetTag("color")
displayName, _ = m.GetTag("display-name")
emoteSets []int64
rawSets, _ = m.GetTag("emote-sets")
)
if rawSets != "" {
for _, sid := range strings.Split(rawSets, ",") {
id, err := strconv.ParseInt(sid, 10, 64)
if err != nil {
return nil, errors.Wrap(err, "parsing emote-set id")
}
emoteSets = append(emoteSets, id)
}
}
return &twitchUserState{
Badges: twitch.ParseBadgeLevels(m),
Color: color,
DisplayName: displayName,
EmoteSets: emoteSets,
}, nil
}
func (t *twitchUserStateStore) Get(channel string) *twitchUserState {
t.lock.RLock()
defer t.lock.RUnlock()
return t.states[channel]
}
func (t *twitchUserStateStore) Set(channel string, state *twitchUserState) {
t.lock.Lock()
defer t.lock.Unlock()
t.states[channel] = state
}

View file

@ -20,6 +20,12 @@ func init() {
}
})
tplFuncs.Register("botHasBadge", func(m *irc.Message, r *plugins.Rule, fields map[string]interface{}) interface{} {
return func(badge string) bool {
return botUserstate.Get(plugins.DeriveChannel(m, nil)).Badges.Has(badge)
}
})
tplFuncs.Register("fixUsername", plugins.GenericTemplateFunctionGetter(func(username string) string { return strings.TrimLeft(username, "@#") }))
tplFuncs.Register("group", func(m *irc.Message, r *plugins.Rule, fields map[string]interface{}) interface{} {

15
irc.go
View file

@ -145,6 +145,11 @@ func (i ircHandler) Handle(c *irc.Client, m *irc.Message) {
// Announces Twitch-specific events to the channel (for example, a users 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
@ -281,6 +286,16 @@ 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)
}

View file

@ -40,6 +40,7 @@ var (
config *configFile
configLock = new(sync.RWMutex)
botUserstate = newTwitchUserStateStore()
cronService *cron.Cron
ircHdl *ircHandler
router = mux.NewRouter()