package main import ( "net" "strconv" "git.gensokyo.cafe/kkyy/tgbot_misaka_5882f7/utils" "github.com/go-errors/errors" "github.com/ilyakaznacheev/cleanenv" ) type ConfigDef struct { AdminUIDs []int64 `env:"TG_ADMIN_UIDS"` TGBotToken string `env:"TG_TOKEN" env-required:""` TGAnnounceCommands bool `env:"TG_ANNOUNCE_CMDS"` // API APIMasterKey string `env:"TG_API_MASTER_KEY" env-required:""` APIListen string `env:"TG_API_LISTEN" env-default:"127.0.0.1:8080"` // Traffic usage WatchedInterface string `env:"TG_WATCHED_INTERFACE"` MonthlyTrafficLimitGiB int `env:"TG_MONTHLY_TRAFFIC_LIMIT_GIB" env-default:"1000"` // AI OpenAIApiKey string `env:"TG_OPENAI_API_KEY"` // Parsed fields adminUidLookup map[int64]struct{} apiListenAddr net.Addr } func (c *ConfigDef) Parse() error { c.adminUidLookup = make(map[int64]struct{}, len(c.AdminUIDs)) for _, u := range c.AdminUIDs { if u <= 0 { return errors.New("invalid admin UID: " + strconv.FormatInt(u, 10)) } c.adminUidLookup[u] = struct{}{} } // validate API listen ip, port, err := net.SplitHostPort(c.APIListen) if err != nil { return errors.WrapPrefix(err, "invalid API listen address", 0) } if tIP := net.ParseIP(ip); tIP == nil { return errors.New("invalid API listen address: " + ip) } if tPort, err := strconv.Atoi(port); err != nil || tPort <= 0 || tPort > 65535 { return errors.New("invalid API listen port: " + port) } if c.WatchedInterface == "" { tIf, err := utils.FindDefaultAdapter() if err != nil { return errors.WrapPrefix(err, "Watched interface is not defined and failed to find a default one.", 0) } c.WatchedInterface = tIf.Name logger.Infof("Watching default interface %s", c.WatchedInterface) } return nil } func (c *ConfigDef) IsAdmin(id int64) bool { _, ok := c.adminUidLookup[id] return ok } func (c *ConfigDef) GetAPIListenAddr() net.Addr { return c.apiListenAddr } func configFromEnv() (*ConfigDef, error) { cfg := ConfigDef{} err := cleanenv.ReadEnv(&cfg) if err != nil { return nil, errors.Wrap(err, 0) } return &cfg, nil } var config *ConfigDef func LoadCfg() error { cfg, err := configFromEnv() if err != nil { return errors.WrapPrefix(err, "failed to load config from environment", 0) } if err = cfg.Parse(); err != nil { return errors.WrapPrefix(err, "failed to parse config", 0) } config = cfg return nil }