Files
Pastel/internal/config/config.go
prosolis b8a0fd5f35 Rewrite Pastel from Python to Go with watchlist feature
Full rewrite of the gaming deals Matrix bot in Go for better performance
and a single static binary. Includes all original functionality (CheapShark,
ITAD, Epic free games, multi-currency pricing, dedup, preflight checks,
presence heartbeat) plus a new watchlist feature where users can DM the bot
to watch for specific game deals with 180-day auto-expiry.

New: systemd service file, DB migration script for Python-to-Go transition.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 20:56:15 -07:00

116 lines
2.4 KiB
Go

package config
import (
"fmt"
"os"
"strconv"
"strings"
"github.com/joho/godotenv"
)
type Config struct {
MatrixHomeserverURL string
MatrixBotUserID string
MatrixBotAccessToken string
MatrixDealsRoomID string
ITADAPIKey string
DealSources []string
MinDealRating float64
MinDiscountPercent int
MaxPriceUSD float64
SendIntroMessage bool
DatabasePath string
}
func Load() (*Config, error) {
// Load .env file if present (ignore error if missing)
_ = godotenv.Load()
c := &Config{}
var err error
c.MatrixHomeserverURL, err = require("MATRIX_HOMESERVER_URL")
if err != nil {
return nil, err
}
c.MatrixBotUserID, err = require("MATRIX_BOT_USER_ID")
if err != nil {
return nil, err
}
c.MatrixBotAccessToken, err = require("MATRIX_BOT_ACCESS_TOKEN")
if err != nil {
return nil, err
}
c.MatrixDealsRoomID, err = require("MATRIX_DEALS_ROOM_ID")
if err != nil {
return nil, err
}
c.ITADAPIKey = os.Getenv("ITAD_API_KEY")
rawSources := os.Getenv("DEAL_SOURCES")
if rawSources == "" {
rawSources = "cheapshark"
}
for _, s := range strings.Split(rawSources, ",") {
s = strings.TrimSpace(strings.ToLower(s))
if s != "" {
c.DealSources = append(c.DealSources, s)
}
}
c.MinDealRating = envFloat("MIN_DEAL_RATING", 8.0)
c.MinDiscountPercent = envInt("MIN_DISCOUNT_PERCENT", 50)
c.MaxPriceUSD = envFloat("MAX_PRICE_USD", 20)
c.DatabasePath = envStr("DATABASE_PATH", "deals.db")
intro := strings.ToLower(os.Getenv("SEND_INTRO_MESSAGE"))
c.SendIntroMessage = intro == "true" || intro == "1" || intro == "yes"
return c, nil
}
// HasSource checks if a deal source is enabled.
func (c *Config) HasSource(name string) bool {
for _, s := range c.DealSources {
if s == name {
return true
}
}
return false
}
func require(key string) (string, error) {
v := os.Getenv(key)
if v == "" {
return "", fmt.Errorf("required environment variable %s is not set", key)
}
return v, nil
}
func envStr(key, def string) string {
if v := os.Getenv(key); v != "" {
return v
}
return def
}
func envFloat(key string, def float64) float64 {
if v := os.Getenv(key); v != "" {
if f, err := strconv.ParseFloat(v, 64); err == nil {
return f
}
}
return def
}
func envInt(key string, def int) int {
if v := os.Getenv(key); v != "" {
if i, err := strconv.Atoi(v); err == nil {
return i
}
}
return def
}