twitch-bot/actions.go

90 lines
2.1 KiB
Go
Raw Normal View History

2020-12-21 00:32:39 +00:00
package main
import (
"sync"
"github.com/go-irc/irc"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
)
type (
Actor interface {
// Execute will be called after the config was read into the Actor
Execute(*irc.Client, *irc.Message, *Rule) (preventCooldown bool, err error)
// IsAsync may return true if the Execute function is to be executed
// in a Go routine as of long runtime. Normally it should return false
// except in very specific cases
IsAsync() bool
// Name must return an unique name for the actor in order to identify
// it in the logs for debugging purposes
Name() string
}
ActorCreationFunc func() Actor
)
2020-12-21 00:32:39 +00:00
var (
availableActions []ActorCreationFunc
2020-12-21 00:32:39 +00:00
availableActionsLock = new(sync.RWMutex)
)
func registerAction(af ActorCreationFunc) {
2020-12-21 00:32:39 +00:00
availableActionsLock.Lock()
defer availableActionsLock.Unlock()
availableActions = append(availableActions, af)
}
func triggerActions(c *irc.Client, m *irc.Message, rule *Rule, ra *RuleAction) (preventCooldown bool, err error) {
2020-12-21 00:32:39 +00:00
availableActionsLock.RLock()
defer availableActionsLock.RUnlock()
for _, acf := range availableActions {
var (
a = acf()
logger = log.WithField("actor", a.Name())
)
if err := ra.Unmarshal(a); err != nil {
logger.WithError(err).Trace("Unable to unmarshal config")
continue
}
if a.IsAsync() {
go func() {
if _, err := a.Execute(c, m, rule); err != nil {
logger.WithError(err).Error("Error in async actor")
}
}()
continue
}
apc, err := a.Execute(c, m, rule)
if err != nil {
return preventCooldown, errors.Wrap(err, "execute action")
2020-12-21 00:32:39 +00:00
}
preventCooldown = preventCooldown || apc
2020-12-21 00:32:39 +00:00
}
return preventCooldown, nil
2020-12-21 00:32:39 +00:00
}
func handleMessage(c *irc.Client, m *irc.Message, event *string) {
for _, r := range config.GetMatchingRules(m, event) {
var preventCooldown bool
2020-12-21 00:32:39 +00:00
for _, a := range r.Actions {
apc, err := triggerActions(c, m, r, a)
if err != nil {
2020-12-21 00:32:39 +00:00
log.WithError(err).Error("Unable to trigger action")
}
preventCooldown = preventCooldown || apc
2020-12-21 00:32:39 +00:00
}
// Lock command
if !preventCooldown {
r.setCooldown(m)
}
2020-12-21 00:32:39 +00:00
}
}