mirror of
https://github.com/Luzifer/twitch-bot.git
synced 2024-12-20 11:51:17 +00:00
[core] Add channel specific module configuration interface
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
dc648d1dba
commit
0a53863b69
6 changed files with 100 additions and 4 deletions
|
@ -56,6 +56,7 @@ type (
|
|||
PermitAllowModerator bool `yaml:"permit_allow_moderator"`
|
||||
PermitTimeout time.Duration `yaml:"permit_timeout"`
|
||||
RawLog string `yaml:"raw_log"`
|
||||
ModuleConfig plugins.ModuleConfig `yaml:"module_config"`
|
||||
Rules []*plugins.Rule `yaml:"rules"`
|
||||
Variables map[string]interface{} `yaml:"variables"`
|
||||
|
||||
|
|
|
@ -77,6 +77,17 @@ auto_messages:
|
|||
# Disable message using templating, must yield string `true` to disable the automated message
|
||||
disable_on_template: '{{ ne .myvariable true }}'
|
||||
|
||||
# Module configuration by channel or defining bot-wide defaults. See
|
||||
# module specific documentation for options to configure in this
|
||||
# section. All modules come with internal defaults so there is no
|
||||
# need to configure this but you can overwrite the internal defaults.
|
||||
module_config:
|
||||
some-module: # Name of the module to configure
|
||||
default: # Bot-wide, fallback for all channels
|
||||
some_option: true
|
||||
mychannel: # Channel-specific, only valid for this channel
|
||||
some_option: false
|
||||
|
||||
# List of rules. See documentation for details or use web-interface
|
||||
# to configure.
|
||||
rules: # See below for examples
|
||||
|
|
|
@ -43,6 +43,8 @@ type (
|
|||
|
||||
LoggerCreationFunc func(moduleName string) *log.Entry
|
||||
|
||||
ModuleConfigGetterFunc func(module, channel string) *FieldCollection
|
||||
|
||||
MsgFormatter func(tplString string, m *irc.Message, r *Rule, fields *FieldCollection) (string, error)
|
||||
|
||||
MsgModificationFunc func(*irc.Message) error
|
||||
|
@ -65,6 +67,8 @@ type (
|
|||
GetDatabaseConnector func() database.Connector
|
||||
// GetLogger returns a sirupsen log.Entry pre-configured with the module name
|
||||
GetLogger LoggerCreationFunc
|
||||
// GetModuleConfigForChannel returns the module configuration for the given channel if available
|
||||
GetModuleConfigForChannel ModuleConfigGetterFunc
|
||||
// GetTwitchClient retrieves a fully configured Twitch client with initialized cache
|
||||
GetTwitchClient func() *twitch.Client
|
||||
// GetTwitchClientForChannel retrieves a fully configured Twitch client with initialized cache for extended permission channels
|
||||
|
|
37
plugins/moduleConfig.go
Normal file
37
plugins/moduleConfig.go
Normal file
|
@ -0,0 +1,37 @@
|
|||
package plugins
|
||||
|
||||
import "strings"
|
||||
|
||||
// DefaultConfigName is the name the default configuration must have
|
||||
// when defined
|
||||
const DefaultConfigName = "default"
|
||||
|
||||
type (
|
||||
// ModuleConfig represents a mapping of configurations per channel
|
||||
// and module
|
||||
ModuleConfig map[string]map[string]*FieldCollection
|
||||
)
|
||||
|
||||
// GetChannelConfig reads the channel specific configuration for the
|
||||
// given module. This is created by taking an empty FieldCollection,
|
||||
// merging in the default configuration and finally overwriting all
|
||||
// existing channel configurations.
|
||||
func (m ModuleConfig) GetChannelConfig(module, channel string) *FieldCollection {
|
||||
channel = strings.TrimLeft(channel, "#@")
|
||||
composed := NewFieldCollection()
|
||||
|
||||
for _, i := range []string{DefaultConfigName, channel} {
|
||||
f := m[module][i]
|
||||
if f == nil {
|
||||
// That config does not exist, don't apply
|
||||
continue
|
||||
}
|
||||
|
||||
for k, v := range f.Data() {
|
||||
// Overwrite all keys defined in this config
|
||||
composed.Set(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
return composed
|
||||
}
|
38
plugins/moduleConfig_test.go
Normal file
38
plugins/moduleConfig_test.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
package plugins
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestModuleConfigGet(t *testing.T) {
|
||||
strPtrEmpty := func(v string) *string { return &v }("")
|
||||
m := ModuleConfig{
|
||||
"test": map[string]*FieldCollection{
|
||||
DefaultConfigName: FieldCollectionFromData(map[string]any{
|
||||
"setindefault": DefaultConfigName,
|
||||
"setinboth": DefaultConfigName,
|
||||
}),
|
||||
"test": FieldCollectionFromData(map[string]any{
|
||||
"setinchannel": "channel",
|
||||
"setinboth": "channel",
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
fields := m.GetChannelConfig("module_does_not_exist", "test")
|
||||
require.NotNil(t, fields, "must always return a valid FieldCollection")
|
||||
assert.Len(t, fields.Data(), 0)
|
||||
|
||||
fields = m.GetChannelConfig("test", "test")
|
||||
assert.Equal(t, DefaultConfigName, fields.MustString("setindefault", strPtrEmpty))
|
||||
assert.Equal(t, "channel", fields.MustString("setinchannel", strPtrEmpty))
|
||||
assert.Equal(t, "channel", fields.MustString("setinboth", strPtrEmpty))
|
||||
|
||||
fields = m.GetChannelConfig("test", "channel_not_configured")
|
||||
assert.Equal(t, DefaultConfigName, fields.MustString("setindefault", strPtrEmpty))
|
||||
assert.Equal(t, "", fields.MustString("setinchannel", strPtrEmpty))
|
||||
assert.Equal(t, DefaultConfigName, fields.MustString("setinboth", strPtrEmpty))
|
||||
}
|
|
@ -148,10 +148,6 @@ func registerRoute(route plugins.HTTPRouteRegistrationArgs) error {
|
|||
|
||||
func getRegistrationArguments() plugins.RegistrationArguments {
|
||||
return plugins.RegistrationArguments{
|
||||
CreateEvent: func(evt string, eventData *plugins.FieldCollection) error {
|
||||
handleMessage(ircHdl.Client(), nil, &evt, eventData)
|
||||
return nil
|
||||
},
|
||||
FormatMessage: formatMessage,
|
||||
FrontendNotify: func(mt string) { frontendNotifyHooks.Ping(mt) },
|
||||
GetDatabaseConnector: func() database.Connector { return db },
|
||||
|
@ -170,6 +166,15 @@ func getRegistrationArguments() plugins.RegistrationArguments {
|
|||
SendMessage: sendMessage,
|
||||
ValidateToken: validateAuthToken,
|
||||
|
||||
CreateEvent: func(evt string, eventData *plugins.FieldCollection) error {
|
||||
handleMessage(ircHdl.Client(), nil, &evt, eventData)
|
||||
return nil
|
||||
},
|
||||
|
||||
GetModuleConfigForChannel: func(module, channel string) *plugins.FieldCollection {
|
||||
return config.ModuleConfig.GetChannelConfig(module, channel)
|
||||
},
|
||||
|
||||
GetTwitchClientForChannel: func(channel string) (*twitch.Client, error) {
|
||||
return accessService.GetTwitchClientForChannel(channel, access.ClientConfig{
|
||||
TwitchClient: cfg.TwitchClient,
|
||||
|
|
Loading…
Reference in a new issue