Files
tgvpn/internal/config/config.go
T
tgvpn cbb2133991 Add /config trial VPN generation for users (1 day default)
Users get Remnawave subscription via /config or inline button; TRIAL_USER_DAYS and panel lookup by Telegram ID.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 01:29:55 +03:00

113 lines
3.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package config
import (
"fmt"
"os"
"strconv"
"strings"
)
// См. официальную схему env: https://docs.rw/docs/install/subscription-page/bundled
// REMNAWAVE_PANEL_URL + REMNAWAVE_API_TOKEN (+ опционально CADDY_AUTH_API_TOKEN)
type Config struct {
BotToken string
BotDebug bool
TelegramAdminID int64
RemnawaveName string
RemnawavePanelURL string
RemnawaveAPIToken string
CaddyAuthAPIToken string
RemnawaveSubscription string
DatabaseURL string
DefaultUserDays int
TrialUserDays int
DefaultExternalSquadUUID string
DefaultInternalSquadUUIDs []string
}
func Load() (*Config, error) {
token := strings.TrimSpace(os.Getenv("BOT_TOKEN"))
if token == "" {
return nil, fmt.Errorf("BOT_TOKEN не задан")
}
adminID, err := strconv.ParseInt(strings.TrimSpace(os.Getenv("TELEGRAM_ADMIN_ID")), 10, 64)
if err != nil || adminID <= 0 {
return nil, fmt.Errorf("TELEGRAM_ADMIN_ID не задан или неверный")
}
panelURL := strings.TrimRight(strings.TrimSpace(os.Getenv("REMNAWAVE_PANEL_URL")), "/")
if panelURL == "" {
return nil, fmt.Errorf("REMNAWAVE_PANEL_URL не задан (URL панели, см. https://docs.rw/docs/install/subscription-page/bundled)")
}
if !strings.HasPrefix(panelURL, "http://") && !strings.HasPrefix(panelURL, "https://") {
return nil, fmt.Errorf("REMNAWAVE_PANEL_URL должен быть с http:// или https:// (как в документации Remnawave)")
}
apiToken := strings.TrimSpace(os.Getenv("REMNAWAVE_API_TOKEN"))
if apiToken == "" {
return nil, fmt.Errorf("REMNAWAVE_API_TOKEN не задан (Remnawave Settings → API Tokens)")
}
name := strings.TrimSpace(os.Getenv("REMNAWAVE_PANEL_NAME"))
if name == "" {
name = "Панель 1"
}
caddy := strings.TrimSpace(os.Getenv("CADDY_AUTH_API_TOKEN"))
if caddy == "" {
caddy = strings.TrimSpace(os.Getenv("REMNAWAVE_CADDY_TOKEN")) // устаревшее имя
}
subURL := strings.TrimRight(strings.TrimSpace(os.Getenv("REMNAWAVE_SUBSCRIPTION_URL")), "/")
if subURL != "" && !strings.HasPrefix(subURL, "http://") && !strings.HasPrefix(subURL, "https://") {
return nil, fmt.Errorf("REMNAWAVE_SUBSCRIPTION_URL должен начинаться с http:// или https://")
}
dbURL := strings.TrimSpace(os.Getenv("DATABASE_URL"))
if dbURL == "" {
return nil, fmt.Errorf("DATABASE_URL не задан")
}
days := 1
if v := strings.TrimSpace(os.Getenv("DEFAULT_USER_DAYS")); v != "" {
if d, err := strconv.Atoi(v); err == nil && d > 0 {
days = d
}
}
trialDays := days
if v := strings.TrimSpace(os.Getenv("TRIAL_USER_DAYS")); v != "" {
if d, err := strconv.Atoi(v); err == nil && d > 0 {
trialDays = d
}
}
var internalSquads []string
if v := strings.TrimSpace(os.Getenv("DEFAULT_INTERNAL_SQUAD_UUIDS")); v != "" {
for _, part := range strings.Split(v, ",") {
part = strings.TrimSpace(part)
if part != "" {
internalSquads = append(internalSquads, part)
}
}
}
return &Config{
BotToken: token,
BotDebug: strings.EqualFold(strings.TrimSpace(os.Getenv("BOT_DEBUG")), "true"),
TelegramAdminID: adminID,
RemnawaveName: name,
RemnawavePanelURL: panelURL,
RemnawaveAPIToken: apiToken,
CaddyAuthAPIToken: caddy,
RemnawaveSubscription: subURL,
DatabaseURL: dbURL,
DefaultUserDays: days,
TrialUserDays: trialDays,
DefaultExternalSquadUUID: strings.TrimSpace(os.Getenv("DEFAULT_EXTERNAL_SQUAD_UUID")),
DefaultInternalSquadUUIDs: internalSquads,
}, nil
}