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("toUpper", genericTemplateFunctionGetter(strings.ToUpper))
|
||||||
tplFuncs.Register("followDate", genericTemplateFunctionGetter(twitch.GetFollowDate))
|
tplFuncs.Register("followDate", genericTemplateFunctionGetter(twitch.GetFollowDate))
|
||||||
tplFuncs.Register("concat", genericTemplateFunctionGetter(func(delim string, parts ...string) string { return strings.Join(parts, delim) }))
|
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 {
|
type storageFile struct {
|
||||||
Counters map[string]int64 `json:"counters"`
|
Counters map[string]int64 `json:"counters"`
|
||||||
Timers map[string]timerEntry `json:"timers"`
|
Timers map[string]timerEntry `json:"timers"`
|
||||||
|
Variables map[string]string `json:"variables"`
|
||||||
|
|
||||||
inMem bool
|
inMem bool
|
||||||
lock *sync.RWMutex
|
lock *sync.RWMutex
|
||||||
|
@ -20,8 +21,9 @@ type storageFile struct {
|
||||||
|
|
||||||
func newStorageFile(inMemStore bool) *storageFile {
|
func newStorageFile(inMemStore bool) *storageFile {
|
||||||
return &storageFile{
|
return &storageFile{
|
||||||
Counters: map[string]int64{},
|
Counters: map[string]int64{},
|
||||||
Timers: map[string]timerEntry{},
|
Timers: map[string]timerEntry{},
|
||||||
|
Variables: map[string]string{},
|
||||||
|
|
||||||
inMem: inMemStore,
|
inMem: inMemStore,
|
||||||
lock: new(sync.RWMutex),
|
lock: new(sync.RWMutex),
|
||||||
|
@ -35,6 +37,13 @@ func (s *storageFile) GetCounterValue(counter string) int64 {
|
||||||
return s.Counters[counter]
|
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 {
|
func (s *storageFile) HasTimer(id string) bool {
|
||||||
s.lock.RLock()
|
s.lock.RLock()
|
||||||
defer s.lock.RUnlock()
|
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")
|
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 {
|
func (s *storageFile) UpdateCounter(counter string, value int64, absolute bool) error {
|
||||||
s.lock.Lock()
|
s.lock.Lock()
|
||||||
defer s.lock.Unlock()
|
defer s.lock.Unlock()
|
||||||
|
|
|
@ -69,6 +69,11 @@ rules: # See below for examples
|
||||||
# Issue a timeout on the user who wrote the chat-line
|
# Issue a timeout on the user who wrote the chat-line
|
||||||
- timeout: 1s # Duration value: 1s / 1m / 1h
|
- 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!)
|
# 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
|
# 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
|
# 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
|
- `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
|
- `toLower <string>` - Converts the given string to lower-case
|
||||||
- `toUpper <string>` - Converts the given string to upper-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
|
## Command executions
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue