package main import ( "os" "strconv" "strings" "github.com/go-errors/errors" "github.com/samber/lo" ) type Config struct { AdminUIDs map[int64]struct{} TGBotToken string WatchedInterface string MonthlyTrafficLimitGiB int } var config *Config func LoadCfg() error { cfg := Config{} token := os.Getenv("TG_TOKEN") if token == "" { return errors.New("TG_TOKEN env not set") } cfg.TGBotToken = token adminUIDsEnv := os.Getenv("TG_ADMIN_UIDS") adminUIDs := lo.FilterMap(strings.Split(adminUIDsEnv, ","), func(s string, _ int) (string, bool) { trimmed := strings.TrimSpace(s) return trimmed, trimmed != "" }) cfg.AdminUIDs = make(map[int64]struct{}, len(adminUIDs)) for _, uidStr := range adminUIDs { uid, err := strconv.ParseInt(uidStr, 10, 64) if err != nil { return errors.New("invalid admin UID: " + uidStr) } cfg.AdminUIDs[uid] = struct{}{} } cfg.WatchedInterface = "eth0" if iface := os.Getenv("TG_WATCHED_INTERFACE"); iface != "" { cfg.WatchedInterface = iface } cfg.MonthlyTrafficLimitGiB = 1000 if trafficLimitStr := os.Getenv("TG_MONTHLY_TRAFFIC_LIMIT_GIB"); trafficLimitStr != "" { var err error if cfg.MonthlyTrafficLimitGiB, err = strconv.Atoi(trafficLimitStr); err != nil { return errors.New("invalid traffic limit: " + trafficLimitStr) } } config = &cfg return nil }