mirror of
https://github.com/Luzifer/twitch-bot.git
synced 2024-12-20 20:01:17 +00:00
Add support for dynamic variables
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
50a155ddb2
commit
13a6dd5695
4 changed files with 91 additions and 4 deletions
47
action_setvar.go
Normal file
47
action_setvar.go
Normal file
|
@ -0,0 +1,47 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/go-irc/irc"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerAction(func() Actor { return &ActorSetVariable{} })
|
||||
}
|
||||
|
||||
type ActorSetVariable struct {
|
||||
Variable string `json:"variable" yaml:"variable"`
|
||||
Clear bool `json:"clear" yaml:"clear"`
|
||||
Set string `json:"set" yaml:"set"`
|
||||
}
|
||||
|
||||
func (a ActorSetVariable) Execute(c *irc.Client, m *irc.Message, r *Rule) error {
|
||||
if a.Variable == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
varName, err := formatMessage(a.Variable, m, r, nil)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "preparing variable name")
|
||||
}
|
||||
|
||||
if a.Clear {
|
||||
return errors.Wrap(
|
||||
store.RemoveVariable(varName),
|
||||
"removing variable",
|
||||
)
|
||||
}
|
||||
|
||||
value, err := formatMessage(a.Set, m, r, nil)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "preparing value")
|
||||
}
|
||||
|
||||
return errors.Wrap(
|
||||
store.SetVariable(varName, value),
|
||||
"setting variable",
|
||||
)
|
||||
}
|
||||
|
||||
func (a ActorSetVariable) IsAsync() bool { return false }
|
||||
func (a ActorSetVariable) Name() string { return "setvariable" }
|
|
@ -62,4 +62,11 @@ func init() {
|
|||
tplFuncs.Register("toUpper", genericTemplateFunctionGetter(strings.ToUpper))
|
||||
tplFuncs.Register("followDate", genericTemplateFunctionGetter(twitch.GetFollowDate))
|
||||
tplFuncs.Register("concat", genericTemplateFunctionGetter(func(delim string, parts ...string) string { return strings.Join(parts, delim) }))
|
||||
tplFuncs.Register("variable", genericTemplateFunctionGetter(func(name string, defVal ...string) string {
|
||||
value := store.GetVariable(name)
|
||||
if value == "" && len(defVal) > 0 {
|
||||
return defVal[0]
|
||||
}
|
||||
return value
|
||||
}))
|
||||
}
|
||||
|
|
35
store.go
35
store.go
|
@ -11,8 +11,9 @@ import (
|
|||
)
|
||||
|
||||
type storageFile struct {
|
||||
Counters map[string]int64 `json:"counters"`
|
||||
Timers map[string]timerEntry `json:"timers"`
|
||||
Counters map[string]int64 `json:"counters"`
|
||||
Timers map[string]timerEntry `json:"timers"`
|
||||
Variables map[string]string `json:"variables"`
|
||||
|
||||
inMem bool
|
||||
lock *sync.RWMutex
|
||||
|
@ -20,8 +21,9 @@ type storageFile struct {
|
|||
|
||||
func newStorageFile(inMemStore bool) *storageFile {
|
||||
return &storageFile{
|
||||
Counters: map[string]int64{},
|
||||
Timers: map[string]timerEntry{},
|
||||
Counters: map[string]int64{},
|
||||
Timers: map[string]timerEntry{},
|
||||
Variables: map[string]string{},
|
||||
|
||||
inMem: inMemStore,
|
||||
lock: new(sync.RWMutex),
|
||||
|
@ -35,6 +37,13 @@ func (s *storageFile) GetCounterValue(counter string) int64 {
|
|||
return s.Counters[counter]
|
||||
}
|
||||
|
||||
func (s *storageFile) GetVariable(key string) string {
|
||||
s.lock.RLock()
|
||||
defer s.lock.RUnlock()
|
||||
|
||||
return s.Variables[key]
|
||||
}
|
||||
|
||||
func (s *storageFile) HasTimer(id string) bool {
|
||||
s.lock.RLock()
|
||||
defer s.lock.RUnlock()
|
||||
|
@ -121,6 +130,24 @@ func (s *storageFile) SetTimer(kind timerType, id string, expiry time.Time) erro
|
|||
return errors.Wrap(s.Save(), "saving store")
|
||||
}
|
||||
|
||||
func (s *storageFile) SetVariable(key, value string) error {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
s.Variables[key] = value
|
||||
|
||||
return errors.Wrap(s.Save(), "saving store")
|
||||
}
|
||||
|
||||
func (s *storageFile) RemoveVariable(key string) error {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
delete(s.Variables, key)
|
||||
|
||||
return errors.Wrap(s.Save(), "saving store")
|
||||
}
|
||||
|
||||
func (s *storageFile) UpdateCounter(counter string, value int64, absolute bool) error {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
|
|
@ -69,6 +69,11 @@ rules: # See below for examples
|
|||
# Issue a timeout on the user who wrote the chat-line
|
||||
- timeout: 1s # Duration value: 1s / 1m / 1h
|
||||
|
||||
# Set a variable to value defined for later usage
|
||||
- variable: myvar # String, name of the variable to set (applies templating)
|
||||
clear: false # Boolean, clear the variable
|
||||
set: '{{ .channel }}' # String, value to set the variable to (applies templating)
|
||||
|
||||
# Send a whisper (ATTENTION: You need to have a known / verified bot for this!)
|
||||
# Without being known / verified your whisper will just silently get dropped by Twitch
|
||||
# Go here to get that verification: https://dev.twitch.tv/limit-increase
|
||||
|
@ -154,6 +159,7 @@ Additionally there are some functions available in the templates:
|
|||
- `tag <tagname>` - Takes the message sent to the channel, returns the value of the tag specified
|
||||
- `toLower <string>` - Converts the given string to lower-case
|
||||
- `toUpper <string>` - Converts the given string to upper-case
|
||||
- `variable <name> [default]` - Returns the variable value or default in case it is empty
|
||||
|
||||
## Command executions
|
||||
|
||||
|
|
Loading…
Reference in a new issue