package config import ( "os" "strconv" "strings" ) // Config holds all application configuration type Config struct { Debug bool Hostname string Port string LogLevel string SecretKey string DatabasePath string TelegramConfig TelegramConfig SentryConfig SentryConfig } // TelegramConfig holds Telegram platform configuration type TelegramConfig struct { Token string } // SentryConfig holds Sentry observability configuration type SentryConfig struct { DSN string Environment string Release string TracesSampleRate float64 EnableLogs bool } // Load loads configuration from environment variables func Load() (*Config, error) { config := &Config{ Debug: getEnv("DEBUG", "n") == "y", Hostname: getEnv("BUTTERROBOT_HOSTNAME", "butterrobot-dev.int.fmartingr.network"), Port: getEnv("PORT", "8080"), LogLevel: getEnv("LOG_LEVEL", "ERROR"), SecretKey: getEnv("SECRET_KEY", "1234"), DatabasePath: getEnv("DATABASE_PATH", "butterrobot.db"), TelegramConfig: TelegramConfig{ Token: getEnv("TELEGRAM_TOKEN", ""), }, SentryConfig: SentryConfig{ DSN: getEnv("SENTRY_DSN", ""), Environment: getEnv("SENTRY_ENVIRONMENT", "production"), Release: getEnv("SENTRY_RELEASE", ""), TracesSampleRate: getEnvFloat("SENTRY_TRACES_SAMPLE_RATE", 0), EnableLogs: getEnv("SENTRY_ENABLE_LOGS", "n") == "y", }, } return config, nil } // Secrets returns configured credentials that must never appear in logs or // error reports. Platform credentials travel inside webhook paths and API URLs, // so error reporting has to know which values to redact. func (c *Config) Secrets() []string { var secrets []string for _, secret := range []string{c.TelegramConfig.Token, c.SecretKey} { if secret != "" { secrets = append(secrets, secret) } } return secrets } // getEnv retrieves an environment variable value or returns a default value func getEnv(key, defaultValue string) string { value := os.Getenv(key) if strings.TrimSpace(value) == "" { return defaultValue } return value } // getEnvFloat retrieves an environment variable as a float or returns a default value func getEnvFloat(key string, defaultValue float64) float64 { value, err := strconv.ParseFloat(getEnv(key, ""), 64) if err != nil { return defaultValue } return value }