All checks were successful
continuous-integration/drone/push Build is passing
59 lines
2.4 KiB
Go
59 lines
2.4 KiB
Go
package config
|
||
|
||
import (
|
||
"fmt"
|
||
"log"
|
||
"strings"
|
||
|
||
"github.com/caarlos0/env/v10"
|
||
)
|
||
|
||
// Config содержит всю конфигурацию приложения, получаемую из переменных окружения.
|
||
type Config struct {
|
||
TelegramBotToken string `env:"TELEGRAM_BOT_TOKEN,required"`
|
||
TelegramAdminIDsRaw string `env:"TELEGRAM_ADMIN_IDS,required"`
|
||
TelegramCacheChatID int64 `env:"TELEGRAM_CACHE_CHAT_ID,required"`
|
||
YandexMusicToken string `env:"YANDEX_MUSIC_TOKEN"`
|
||
DatabasePath string `env:"DATABASE_PATH" envDefault:"/data/bot.db"`
|
||
LogLevel string `env:"LOG_LEVEL" envDefault:"info"`
|
||
ProcessorWorkers int `env:"PROCESSOR_WORKERS" envDefault:"4"`
|
||
YandexAPIRateLimit int `env:"YANDEX_API_RATE_LIMIT" envDefault:"5"`
|
||
TelegramAPIRateLimit int `env:"TELEGRAM_API_RATE_LIMIT" envDefault:"25"` // Общий лимит в секунду
|
||
TelegramCacheRateLimitPerMinute int `env:"TELEGRAM_CACHE_RATE_LIMIT_PER_MINUTE" envDefault:"20"` // Лимит для кэш-канала в минуту
|
||
TelegramAdminIDs []int64 `env:"-"`
|
||
}
|
||
|
||
// New загружает конфигурацию из переменных окружения и парсит необходимые поля.
|
||
func New() *Config {
|
||
cfg := &Config{}
|
||
if err := env.Parse(cfg); err != nil {
|
||
log.Fatalf("failed to parse config: %+v", err)
|
||
}
|
||
|
||
// Парсим ID администраторов из строки
|
||
if cfg.TelegramAdminIDsRaw != "" {
|
||
ids := strings.Split(cfg.TelegramAdminIDsRaw, ",")
|
||
cfg.TelegramAdminIDs = make([]int64, 0, len(ids))
|
||
for _, idStr := range ids {
|
||
var id int64
|
||
if _, err := Sscanf(strings.TrimSpace(idStr), "%d", &id); err == nil {
|
||
cfg.TelegramAdminIDs = append(cfg.TelegramAdminIDs, id)
|
||
} else {
|
||
log.Printf("warning: could not parse admin ID: %s", idStr)
|
||
}
|
||
}
|
||
}
|
||
|
||
if len(cfg.TelegramAdminIDs) == 0 {
|
||
log.Fatalf("no valid admin IDs provided in TELEGRAM_ADMIN_IDS")
|
||
}
|
||
|
||
return cfg
|
||
}
|
||
|
||
// Sscanf - простая реализация для парсинга, чтобы избежать лишних зависимостей.
|
||
// В стандартной библиотеке fmt.Sscanf требует, чтобы вся строка была разобрана.
|
||
func Sscanf(str, format string, a ...interface{}) (int, error) {
|
||
return fmt.Sscanf(str, format, a...)
|
||
}
|