package main import ( "fmt" "github.com/go-chat-bot/bot/irc" "github.com/go-validator/validator" "github.com/spf13/viper" "log" "path/filepath" _ "ratbot/plugins/generate" _ "ratbot/plugins/roll" "reflect" ) type BotConfig struct { Server string `validate:"required"` Port int Channels []string `validate:"required"` Nick string `validate:"required"` User string Password string UseTLS bool `mapstructure:"use_tls"` // Needed due to `_` Debug bool } // createViper parses ENV vars and creates a Viper object // This purposely uses global state to share config with plugins func createViper() { viper.SetDefault("USE_TLS", true) viper.SetDefault("DEBUG", false) viper.SetEnvPrefix("RATBOT") viper.BindEnv("MAZE_RATS_API_URL") viper.BindEnv("IRC_SERVER") viper.BindEnv("IRC_PORT") viper.BindEnv("CHANNELS") viper.BindEnv("USER") viper.BindEnv("PASSWORD") viper.BindEnv("NICK") viper.BindEnv("USE_TLS") viper.BindEnv("DEBUG") viper.BindEnv("CONFIG") // Allow any config (e.g. TOML/YAML) in working dir or RATBOT_CONFIG dir viper.SetConfigName("config") viper.AddConfigPath(".") viper.AddConfigPath(filepath.Dir(viper.GetString("CONFIG"))) } func main() { createViper() if err := viper.ReadInConfig(); err != nil { log.Fatalf("ERROR: %v", err) } botConfig := BotConfig{} if err := viper.Unmarshal(&botConfig); err != nil { log.Fatalf("ERROR: Could not unmarshal config, %v", err) } validator.SetValidationFunc("required", validateRequired) if errs := validator.Validate(botConfig); errs != nil { log.Fatal(errs) } if botConfig.User == "" { botConfig.User = botConfig.Nick } irc.Run(&irc.Config{ Server: fmt.Sprintf("%v:%v", botConfig.Server, botConfig.Port), Channels: botConfig.Channels, User: botConfig.User, Nick: botConfig.Nick, Password: botConfig.Password, UseTLS: botConfig.UseTLS, Debug: botConfig.Debug, }) } func validateRequired(v interface{}, param string) error { if reflect.ValueOf(v).IsZero() { err := "Field not set. Please set using RATBOT_FIELD or set in config.yaml" return fmt.Errorf(err) } return nil }