tgbot_misaka_5882f7/cfg.go

98 lines
2.4 KiB
Go

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
}