From 7fe53993aaef9a87aaab083edf8893bbdb953f94 Mon Sep 17 00:00:00 2001 From: 3252a8 <3252a8@proton.me> Date: Thu, 21 May 2026 11:26:59 +0300 Subject: [PATCH] docs: update docs and minimize env.example --- .env.example | 362 +++---------------------------------- README.md | 22 ++- docs/admin.md | 16 +- docs/configuration.md | 318 ++++++++------------------------ docs/deployment.md | 2 +- docs/env-vars.md | 408 ++++++++++++++++++++++++++++++++++++++++++ docs/support.md | 82 +++++++++ docs/webapp.md | 9 +- 8 files changed, 628 insertions(+), 591 deletions(-) create mode 100644 docs/env-vars.md create mode 100644 docs/support.md diff --git a/.env.example b/.env.example index cde0a82..c99ed41 100644 --- a/.env.example +++ b/.env.example @@ -1,345 +1,33 @@ -# Telegram Bot Token and Admin IDs -BOT_TOKEN=your_bot_token_here # Telegram bot token -ADMIN_IDS=comma_separated_admin_ids # Your telegram ID +# Minimal bootstrap env. +# Most product settings are configured later in Web App admin: +# Admin -> System -> Settings, Admin -> System -> Tariffs, Admin -> Appearance. +# Full reference: docs/env-vars.md -# PostgreSQL Database Connection Settings -POSTGRES_USER= # Required: database user name -POSTGRES_PASSWORD= # Required: database password -POSTGRES_HOST=remnawave-minishop-db # Database container name -POSTGRES_PORT=5432 # Port -POSTGRES_DB=postgres # Database name -DB_POOL_SIZE=20 # SQLAlchemy async pool size per backend/worker process -DB_MAX_OVERFLOW=10 # Extra transient DB connections above pool size -DB_POOL_TIMEOUT_SECONDS=30 # Seconds to wait for a DB pool connection -DB_POOL_RECYCLE_SECONDS=1800 # Recycle DB connections to avoid stale sockets - -REDIS_URL=redis://redis:6379/0 # Shared Redis for FSM, rate limits, cache, locks and queues -REDIS_KEY_PREFIX=remnawave-tg-shop # Prefix for Redis keys -WEBAPP_ME_CACHE_TTL_SECONDS=15 # Short TTL for /api/me payload cache -WEBAPP_DEVICES_CACHE_TTL_SECONDS=5 # Short TTL for /api/devices payload cache -PANEL_USER_CACHE_TTL_SECONDS=5 # Short TTL for Remnawave /users/{uuid} cache -PANEL_DEVICES_CACHE_TTL_SECONDS=5 # Short TTL for Remnawave user devices cache -PANEL_ALL_USERS_CACHE_TTL_SECONDS=5 # Short TTL for concurrent Remnawave full user scans -PANEL_ALL_USERS_PAGE_SIZE=1000 # Remnawave /users page size with fallback to 100 -ADMIN_PANEL_STATS_CACHE_TTL_SECONDS=15 # Short TTL for admin panel stats fetched from Remnawave -ADMIN_DB_STATS_CACHE_TTL_SECONDS=5 # Short TTL for expensive admin dashboard DB aggregates -ADMIN_USERS_LIST_CACHE_TTL_SECONDS=3 # Short TTL for admin users list queries -PROFILE_SYNC_CACHE_TTL_SECONDS=900 # Minimum seconds between Telegram profile sync checks per user -PANEL_SYNC_LIFETIME_TRAFFIC_MIN_INTERVAL_SECONDS=3600 # Min seconds between local lifetime traffic writes per user -PANEL_SYNC_LIFETIME_TRAFFIC_MIN_DELTA_BYTES=104857600 # Write lifetime traffic sooner when delta is at least this many bytes -WEBAPP_RATE_LIMIT_TTL_SECONDS=60 # Redis rate-limit window -WEBAPP_RATE_LIMIT_MAX_REQUESTS=30 # Requests per window/action/user/IP -WEBHOOK_QUEUE_NAME=webhook-events # Redis queue for heavy webhook processing -WEBHOOK_QUEUE_CONCURRENCY=4 # Worker webhook consumers -WORKER_PANEL_SYNC_INTERVAL_SECONDS=900 # Worker panel sync interval -TARIFF_WORKER_LOCK_TTL_SECONDS=240 # Redis lock TTL for tariff tick -TARIFF_WORKER_TICK_SECONDS=300 # Tariff worker tick interval -TARIFF_WORKER_BULK_PANEL_FETCH_THRESHOLD=50 # Active subs threshold to bulk-fetch panel users - -# Localization and Display -DEFAULT_LANGUAGE="ru" # or "en" -DEFAULT_CURRENCY_SYMBOL="RUB" # e.g., RUB, USD, EUR - -# External Links -SUPPORT_LINK=https://t.me/your_support_link # Link to the support chat -SERVER_STATUS_URL=https://status.yourdomain.tld/status/your_service # Link to the server status page -TERMS_OF_SERVICE_URL=https://example.com/tos # Link to the terms of service -PRIVACY_POLICY_URL=https://example.com/privacy # Link to the privacy policy -USER_AGREEMENT_URL=https://example.com/user-agreement # Link to the user agreement -SUBSCRIPTION_MINI_APP_URL= # Public URL of the subscription Mini App, e.g. https://app.yourdomain.tld/ -START_COMMAND_DESCRIPTION= # Description of the /start command -DISABLE_WELCOME_MESSAGE= # Disable the welcome message -MY_DEVICES_SECTION_ENABLED=False # Enable the My Devices section in the subscription menu -USER_HWID_DEVICE_LIMIT=0 # Default HWID/device limit for panel users (0 = unlimited) - -# Required channel subscription -REQUIRED_CHANNEL_ID= # Telegram channel ID (e.g. -1001234567890) the user must join -REQUIRED_CHANNEL_LINK=https://t.me/your_channel # Optional: public link/invite button text opens - -# Webhook Base URL (used for Telegram and payment providers) +# Required before first start +BOT_TOKEN=your_bot_token_here +ADMIN_IDS=123456789 WEBHOOK_BASE_URL=https://webhooks.yourdomain.tld -TRUSTED_PROXIES=127.0.0.1,::1 # Reverse proxies trusted for X-Forwarded-For -# Subscription Mini App (same container, separate port) -WEBAPP_ENABLED=True # Run Mini App HTTP server -WEBAPP_SERVER_HOST=0.0.0.0 # Internal listen host -WEBAPP_SERVER_PORT=8081 # Internal/published Mini App port -WEBAPP_TITLE="/minishop" # Mini App title -WEBAPP_THEMES_DIR=data/themes # Folder with theme subfolders: /theme.json and optional CSS/assets -WEBAPP_DEFAULT_THEME= # Optional: override descriptor default theme key (e.g. light) -WEBAPP_SESSION_SECRET= # Optional: HMAC secret for webapp sessions; generated if empty -WEBHOOK_SECRET_TOKEN= # Optional: Telegram webhook secret token; generated if empty -WEBAPP_SESSION_TTL_SECONDS=86400 # Web App session lifetime (24h) -WEBAPP_AUTH_MAX_AGE_SECONDS=86400 # Max Telegram initData age -WEBAPP_LOGIN_TOKEN_TTL_SECONDS=600 # External browser login link lifetime -TELEGRAM_OAUTH_CLIENT_ID= # Telegram Web Login Client ID from BotFather; defaults to bot ID from BOT_TOKEN -TELEGRAM_OAUTH_CLIENT_SECRET= # Optional Telegram Web Login Client Secret; reserved for full OIDC code flow -TELEGRAM_OAUTH_REQUEST_ACCESS=write # Optional comma-separated permissions: write,phone; empty = OpenID profile only +# PostgreSQL used by Docker Compose and backend +POSTGRES_USER=remnawave_minishop +POSTGRES_PASSWORD=change_me +POSTGRES_DB=remnawave_minishop -# Email login and account linking via SMTP (Brevo SMTP relay defaults) -SMTP_HOST=smtp-relay.brevo.com # SMTP server -SMTP_PORT=587 # Brevo recommends 587 with STARTTLS -SMTP_FALLBACK_PORTS=2525,465 # Tried after SMTP_PORT; 465 uses SSL automatically -SMTP_TIMEOUT_SECONDS=30 # Per SMTP connection/send attempt timeout -SMTP_USERNAME= # Brevo SMTP login -SMTP_PASSWORD= # Brevo SMTP key/password -SMTP_FROM_EMAIL= # Verified sender email -SMTP_FROM_NAME= # Optional sender name -SMTP_STARTTLS=True # Use STARTTLS on SMTP_PORT -SMTP_USE_SSL=False # Use SSL wrapper, usually only for port 465 -EMAIL_CODE_TTL_SECONDS=600 # Email verification code lifetime -EMAIL_CODE_RESEND_SECONDS=60 # Minimum delay between code sends -EMAIL_CODE_MAX_ATTEMPTS=5 # Max attempts per code -BRUTE_FORCE_MAX_FAILURES=5 # Max failed code attempts in the throttle window -BRUTE_FORCE_WINDOW_SECONDS=900 # Rolling window used to count failures -BRUTE_FORCE_LOCK_SECONDS=1800 # Temporary lockout duration after too many failures +# Strongly recommended stable secrets. +# Generate with: openssl rand -hex 32 +WEBAPP_SESSION_SECRET= +WEBHOOK_SECRET_TOKEN= -# Payment Method Toggles -YOOKASSA_ENABLED=True # Turn on YOOKASSA -FREEKASSA_ENABLED=True # Turn on FreeKassa -STARS_ENABLED=True # Turn on STARS -CRYPTOPAY_ENABLED=True # Turn on CRYPTOPAY -PLATEGA_ENABLED=False # Turn on PLATEGA -SEVERPAY_ENABLED=False # Turn on SeverPay -WATA_ENABLED=False # Turn on Wata -HELEKET_ENABLED=False # Turn on Heleket (crypto payments) -# Order of payment methods (top to bottom). Supported: severpay, wata, freekassa, platega, yookassa, stars, cryptopay, heleket -PAYMENT_METHODS_ORDER=severpay,wata,yookassa,cryptopay,freekassa,platega,stars,heleket -SUBSCRIPTION_PURCHASE_DESCRIPTION_ENABLED=True # Show subscription description before choosing a purchase/renewal period -SUBSCRIPTION_PURCHASE_DESCRIPTION_RU=Покупая или продлевая подписку, вы получаете доступ к VPN/прокси-сервису, который помогает защищать ваше соединение и поддерживать стабильный доступ к сети. -SUBSCRIPTION_PURCHASE_DESCRIPTION_EN=By buying or renewing a subscription, you get access to a VPN/proxy service that helps protect your connection and keep your access stable. +# Recommended baseline values. +# Remnawave access stays in .env, but can be overridden from the Web App admin. +SUBSCRIPTION_MINI_APP_URL=https://app.yourdomain.tld/ +PANEL_API_URL=https://panel.yourdomain.tld/api +PANEL_API_KEY= +PANEL_WEBHOOK_SECRET= -# Payment button presentation overrides (all optional; empty = provider defaults) -# Text supports per-language overrides: *_LABEL_RU and *_LABEL_EN. Legacy *_LABEL applies to all languages if per-language values are empty. -# Available WebApp icons are exported from frontend/src/lib/components/ui/icons.js, e.g. CreditCard, Smartphone, Bitcoin, Sparkles. -PAYMENT_YOOKASSA_WEBAPP_LABEL_RU= # WebApp payment button text for YooKassa (Russian) -PAYMENT_YOOKASSA_WEBAPP_LABEL_EN= # WebApp payment button text for YooKassa (English) -PAYMENT_YOOKASSA_WEBAPP_ICON=CreditCard # WebApp payment button icon for YooKassa -PAYMENT_YOOKASSA_TELEGRAM_LABEL_RU= # Telegram bot payment button text for YooKassa (Russian) -PAYMENT_YOOKASSA_TELEGRAM_LABEL_EN= # Telegram bot payment button text for YooKassa (English) -PAYMENT_YOOKASSA_TELEGRAM_EMOJI= # Telegram bot payment button emoji for YooKassa -PAYMENT_FREEKASSA_WEBAPP_LABEL_RU= # WebApp payment button text for FreeKassa (Russian) -PAYMENT_FREEKASSA_WEBAPP_LABEL_EN= # WebApp payment button text for FreeKassa (English) -PAYMENT_FREEKASSA_WEBAPP_ICON=Smartphone # WebApp payment button icon for FreeKassa -PAYMENT_FREEKASSA_TELEGRAM_LABEL_RU= # Telegram bot payment button text for FreeKassa (Russian) -PAYMENT_FREEKASSA_TELEGRAM_LABEL_EN= # Telegram bot payment button text for FreeKassa (English) -PAYMENT_FREEKASSA_TELEGRAM_EMOJI= # Telegram bot payment button emoji for FreeKassa -PAYMENT_PLATEGA_SBP_WEBAPP_LABEL_RU= # WebApp payment button text for Platega SBP (Russian) -PAYMENT_PLATEGA_SBP_WEBAPP_LABEL_EN= # WebApp payment button text for Platega SBP (English) -PAYMENT_PLATEGA_SBP_WEBAPP_ICON=CreditCard # WebApp payment button icon for Platega SBP -PAYMENT_PLATEGA_SBP_TELEGRAM_LABEL_RU= # Telegram bot payment button text for Platega SBP (Russian) -PAYMENT_PLATEGA_SBP_TELEGRAM_LABEL_EN= # Telegram bot payment button text for Platega SBP (English) -PAYMENT_PLATEGA_SBP_TELEGRAM_EMOJI= # Telegram bot payment button emoji for Platega SBP -PAYMENT_PLATEGA_CRYPTO_WEBAPP_LABEL_RU= # WebApp payment button text for Platega crypto (Russian) -PAYMENT_PLATEGA_CRYPTO_WEBAPP_LABEL_EN= # WebApp payment button text for Platega crypto (English) -PAYMENT_PLATEGA_CRYPTO_WEBAPP_ICON=Bitcoin # WebApp payment button icon for Platega crypto -PAYMENT_PLATEGA_CRYPTO_TELEGRAM_LABEL_RU= # Telegram bot payment button text for Platega crypto (Russian) -PAYMENT_PLATEGA_CRYPTO_TELEGRAM_LABEL_EN= # Telegram bot payment button text for Platega crypto (English) -PAYMENT_PLATEGA_CRYPTO_TELEGRAM_EMOJI= # Telegram bot payment button emoji for Platega crypto -PAYMENT_SEVERPAY_WEBAPP_LABEL_RU= # WebApp payment button text for SeverPay (Russian) -PAYMENT_SEVERPAY_WEBAPP_LABEL_EN= # WebApp payment button text for SeverPay (English) -PAYMENT_SEVERPAY_WEBAPP_ICON=CreditCard # WebApp payment button icon for SeverPay -PAYMENT_SEVERPAY_TELEGRAM_LABEL_RU= # Telegram bot payment button text for SeverPay (Russian) -PAYMENT_SEVERPAY_TELEGRAM_LABEL_EN= # Telegram bot payment button text for SeverPay (English) -PAYMENT_SEVERPAY_TELEGRAM_EMOJI= # Telegram bot payment button emoji for SeverPay -PAYMENT_WATA_WEBAPP_LABEL_RU= # WebApp payment button text for Wata (Russian) -PAYMENT_WATA_WEBAPP_LABEL_EN= # WebApp payment button text for Wata (English) -PAYMENT_WATA_WEBAPP_ICON=WalletCards # WebApp payment button icon for Wata -PAYMENT_WATA_TELEGRAM_LABEL_RU= # Telegram bot payment button text for Wata (Russian) -PAYMENT_WATA_TELEGRAM_LABEL_EN= # Telegram bot payment button text for Wata (English) -PAYMENT_WATA_TELEGRAM_EMOJI= # Telegram bot payment button emoji for Wata -PAYMENT_STARS_WEBAPP_LABEL_RU= # WebApp payment button text for Telegram Stars (Russian) -PAYMENT_STARS_WEBAPP_LABEL_EN= # WebApp payment button text for Telegram Stars (English) -PAYMENT_STARS_WEBAPP_ICON=Sparkles # WebApp payment button icon for Telegram Stars -PAYMENT_STARS_TELEGRAM_LABEL_RU= # Telegram bot payment button text for Telegram Stars (Russian) -PAYMENT_STARS_TELEGRAM_LABEL_EN= # Telegram bot payment button text for Telegram Stars (English) -PAYMENT_STARS_TELEGRAM_EMOJI= # Telegram bot payment button emoji for Telegram Stars -PAYMENT_CRYPTOPAY_WEBAPP_LABEL_RU= # WebApp payment button text for CryptoPay (Russian) -PAYMENT_CRYPTOPAY_WEBAPP_LABEL_EN= # WebApp payment button text for CryptoPay (English) -PAYMENT_CRYPTOPAY_WEBAPP_ICON=Bitcoin # WebApp payment button icon for CryptoPay -PAYMENT_CRYPTOPAY_TELEGRAM_LABEL_RU= # Telegram bot payment button text for CryptoPay (Russian) -PAYMENT_CRYPTOPAY_TELEGRAM_LABEL_EN= # Telegram bot payment button text for CryptoPay (English) -PAYMENT_CRYPTOPAY_TELEGRAM_EMOJI= # Telegram bot payment button emoji for CryptoPay -PAYMENT_HELEKET_WEBAPP_LABEL_RU= # WebApp payment button text for Heleket (Russian) -PAYMENT_HELEKET_WEBAPP_LABEL_EN= # WebApp payment button text for Heleket (English) -PAYMENT_HELEKET_WEBAPP_ICON=Bitcoin # WebApp payment button icon for Heleket -PAYMENT_HELEKET_TELEGRAM_LABEL_RU= # Telegram bot payment button text for Heleket (Russian) -PAYMENT_HELEKET_TELEGRAM_LABEL_EN= # Telegram bot payment button text for Heleket (English) -PAYMENT_HELEKET_TELEGRAM_EMOJI= # Telegram bot payment button emoji for Heleket - -# YooKassa Payment Gateway Configuration -YOOKASSA_SHOP_ID=your_shop_id # Your store ID in YooKassa -YOOKASSA_SECRET_KEY=your_secret_key # Your secret key for YooKassa -YOOKASSA_RETURN_URL=https://t.me/your_bot # URL to which the user will be returned after payment -YOOKASSA_DEFAULT_RECEIPT_EMAIL=your_email@example.com # Default email for sending receipts -YOOKASSA_VAT_CODE=1 # VAT code -YOOKASSA_AUTOPAYMENTS_ENABLED=False # Auto-renew toggle -YOOKASSA_AUTOPAYMENTS_REQUIRE_CARD_BINDING=True # Force automatic card binding when autopay is enabled (set to False to show the save-card checkbox) - -# Nalogo (self-employed receipts) -NALOGO_INN=your_inn # INN for nalog.ru -NALOGO_PASSWORD=your_nalogo_password # Password for nalog.ru -NALOGO_RECEIPT_NAME_SUBSCRIPTION=subscription {months} months # Receipt name for time-based subscriptions ({months} = duration) -NALOGO_RECEIPT_NAME_TRAFFIC=traffic package {gb} GB # Receipt name for traffic packages ({gb} = traffic amount) - -# FreeKassa Payment Gateway Configuration -FREEKASSA_MERCHANT_ID=your_shop_id # Your shop ID in FreeKassa -FREEKASSA_API_KEY=your_api_key # API key for REST requests -FREEKASSA_SECOND_SECRET=your_second_secret # Secret word #2 (used to verify notifications) -FREEKASSA_PAYMENT_IP= # Public IP address reported to FreeKassa -FREEKASSA_PAYMENT_METHOD_ID=44 # Payment method ID, you can get it from https://merchant.freekassa.net/settings/currencies -FREEKASSA_TRUSTED_IPS=168.119.157.136,168.119.60.227,178.154.197.79,51.250.54.238 # FreeKassa webhook source IP allowlist - -# CryptoBot Payment Gateway Configuration -CRYPTOPAY_TOKEN= # API token for CryptoPay -CRYPTOPAY_NETWORK=mainnet # Network (mainnet or testnet) -CRYPTOPAY_CURRENCY_TYPE=fiat # Currency type (fiat or crypto) -CRYPTOPAY_ASSET=RUB # Asset, e.g., RUB, BTC, USDT - -# Platega Payment Gateway Configuration -PLATEGA_BASE_URL=https://app.platega.io # Base API URL -PLATEGA_MERCHANT_ID= # Your MerchantId from Platega -PLATEGA_SECRET= # API secret from Platega -PLATEGA_PAYMENT_METHOD=2 # Legacy method ID; fallback for the SBP button when PLATEGA_SBP_METHOD stays default -PLATEGA_SBP_ENABLED=False # Show a separate "Pay via SBP" Platega button -PLATEGA_CRYPTO_ENABLED=False # Show a separate "Pay with crypto" Platega button -PLATEGA_SBP_METHOD=2 # Platega method ID for SBP QR (default 2) -PLATEGA_CRYPTO_METHOD=13 # Platega method ID for crypto (default 13) -PLATEGA_RETURN_URL= # Optional: redirect after successful payment (defaults to bot link) -PLATEGA_FAILED_URL= # Optional: redirect after failed/cancelled payment (defaults to return URL) - -# SeverPay Payment Gateway Configuration -SEVERPAY_BASE_URL=https://severpay.io/api/merchant # Base API URL -SEVERPAY_MID= # Your MID from SeverPay -SEVERPAY_TOKEN= # API token/secret for signing requests -SEVERPAY_RETURN_URL= # Optional: redirect URL after payment (defaults to bot link) -SEVERPAY_LIFETIME_MINUTES= # Optional: payment link lifetime in minutes (30-4320, leave empty for default) - -# Wata Payment Gateway Configuration -WATA_BASE_URL=https://api.wata.pro/api/h2h # Base API URL (use https://api-sandbox.wata.pro/api/h2h for sandbox) -WATA_API_TOKEN= # Bearer token from Wata terminal settings -WATA_RETURN_URL= # Optional: redirect after successful payment (defaults to bot link) -WATA_FAILED_URL= # Optional: redirect after failed payment (defaults to return URL) -WATA_PAYMENT_LINK_TTL_DAYS=3 # Payment link lifetime in days (1-30) -WATA_WEBHOOK_VERIFY_SIGNATURE=True # Verify X-Signature with Wata RSA public key -WATA_PUBLIC_KEY= # Optional: cached public key; leave empty to fetch from Wata -WATA_TRUSTED_IPS=62.84.126.140,51.250.106.150 # Wata webhook source IP allowlist - -# Heleket Payment Gateway Configuration (https://doc.heleket.com) -HELEKET_BASE_URL=https://api.heleket.com # Base API URL -HELEKET_MERCHANT_ID= # Your merchant UUID from Heleket dashboard -HELEKET_API_KEY= # Payment API key from Heleket dashboard -HELEKET_CURRENCY=RUB # Invoice currency (fiat or crypto code, e.g. RUB, USD, USDT) -HELEKET_TO_CURRENCY= # Optional: target cryptocurrency for conversion (e.g. USDT) -HELEKET_NETWORK= # Optional: blockchain network code (e.g. tron, bsc, eth) -HELEKET_RETURN_URL= # Optional: redirect after invoice expires/cancel (defaults to bot link) -HELEKET_SUCCESS_URL= # Optional: redirect after successful payment (defaults to return URL) -HELEKET_LIFETIME_SECONDS=3600 # Invoice lifetime in seconds (300-43200) -HELEKET_VERIFY_WEBHOOK_SIGNATURE=True # Verify md5 signature on incoming webhook -HELEKET_TRUSTED_IPS=31.133.220.8 # Heleket webhook source IP allowlist - -# Subscription Options. Specify cost parameters or payment links here. -1_MONTH_ENABLED=True -RUB_PRICE_1_MONTH=150 -STARS_PRICE_1_MONTH=0 - -3_MONTHS_ENABLED=True -RUB_PRICE_3_MONTHS=300 -STARS_PRICE_3_MONTHS=0 - -6_MONTHS_ENABLED=True -RUB_PRICE_6_MONTHS=500 -STARS_PRICE_6_MONTHS=0 - -12_MONTHS_ENABLED=True -RUB_PRICE_12_MONTHS=900 -STARS_PRICE_12_MONTHS=0 - -# Traffic Packages (enables traffic sale mode when set) -TRAFFIC_PACKAGES=10:199,50:799 # Format: ":", comma-separated -STARS_TRAFFIC_PACKAGES=10:2500 # Optional: traffic packages priced in Stars -TARIFFS_CONFIG_PATH=data/tariffs.json # Optional Tariffs 2.0 JSON config. If missing, legacy .env pricing is used. -TARIFF_TRAFFIC_WARNING_LEVELS=85,90,95 # Tariffs 2.0 traffic warning levels, percent used - -# Subscription Notifications -SUBSCRIPTION_NOTIFICATIONS_ENABLED=True # Enable subscription -SUBSCRIPTION_NOTIFY_ON_EXPIRE=True # Notify on subscription -SUBSCRIPTION_NOTIFY_AFTER_EXPIRE=True # Notify after -SUBSCRIPTION_NOTIFY_DAYS_BEFORE=3 # Days before expiration to notify - - -REFERRAL_ONE_BONUS_PER_REFEREE=False # Give a bonus only once per referee -REFERRAL_WELCOME_BONUS_DAYS=3 # Welcome bonus for newly registered user from referral link -LEGACY_REFS=true # Allow ref_ links. Leave unset/true unless you want to disable old links -# Referral Bonus Days -# Bonus for the inviting user -REFERRAL_BONUS_DAYS_1_MONTH=3 -REFERRAL_BONUS_DAYS_3_MONTHS=7 -REFERRAL_BONUS_DAYS_6_MONTHS=15 -REFERRAL_BONUS_DAYS_12_MONTHS=30 -# Invited User Bonus -REFEREE_BONUS_DAYS_1_MONTH=1 -REFEREE_BONUS_DAYS_3_MONTHS=3 -REFEREE_BONUS_DAYS_6_MONTHS=7 -REFEREE_BONUS_DAYS_12_MONTHS=15 - -# Panel API Configuration -PANEL_API_URL=http://your_panel_api_url/api # URL of the panel API -PANEL_API_KEY=your_panel_api_key # Panel API key -PANEL_WEBHOOK_SECRET= # secret used to verify panel webhook signatures - -# User traffic limits (applied for all users) -# 0 means unlimited -USER_TRAFFIC_LIMIT_GB=0 # Traffic limit for users (0 unlimited) -USER_TRAFFIC_STRATEGY="NO_RESET" # Traffic reset strategy (NO_RESET, WEEK, MONTH) - -# Default Internal Squads for Users (Optional, comma-separated UUIDs) -USER_SQUAD_UUIDS=uuid1,uuid2,uuid3 -# Default External Squad for Users (Optional, single UUID) -USER_EXTERNAL_SQUAD_UUID= # Optional: UUID from Remnawave External Squads to auto-link new panel users - -# Trial Settings -TRIAL_ENABLED=True # Enable the trial period -TRIAL_DURATION_DAYS=5 # Duration of the trial period in days -TRIAL_TRAFFIC_LIMIT_GB=0 # Traffic limit for the trial period (0 = unlimited) -TRIAL_TRAFFIC_STRATEGY="NO_RESET" # Traffic reset strategy for the trial period (NO_RESET, WEEK, MONTH) - -# Connection link handling (happ crypt4) -CRYPT4_ENABLED=False # Enable happ crypt4 encryption for subscription URLs -CRYPT4_REDIRECT_URL= # Base redirect to wrap the connect button, e.g. https://redir.example.com?url= -CRYPT4_LINK_CACHE_TTL_SECONDS=3600 # Cache encrypted happ links by raw subscription URL - -# Web Server Settings (for handling webhooks) -WEB_SERVER_HOST="0.0.0.0" +# Optional host ports for local Compose publication. WEB_SERVER_PORT=8080 +FRONTEND_PORT=8082 -# Admin Panel Log Pagination -LOGS_PAGE_SIZE=10 # Number of events in the log -LOG_LEVEL=INFO # Global log level (DEBUG, INFO, WARNING, ERROR, CRITICAL) - -# Admin Logging Configuration -LOG_CHAT_ID=-1001234567890 # Telegram chat/group ID for admin notifications -LOG_THREAD_ID= # Optional: Thread ID for supergroup messages -LOG_SUPPORT_THREAD_ID= # Optional: Thread ID for support ticket messages -LOG_NEW_USERS=True # Log new user registrations -LOG_PAYMENTS=True # Log payments -LOG_SUPPORT=True # Log support tickets and replies -LOG_PROMO_ACTIVATIONS=True # Log promo code activations -LOG_TRIAL_ACTIVATIONS=True # Log trial activations -LOG_SUSPICIOUS_ACTIVITY=True # Log suspicious activity -LOG_ADMIN_ACTIONS=True # Log actions from users listed in ADMIN_IDS - -# Support tickets -SUPPORT_TICKETS_ENABLED=True # Enable support tickets in the Mini App -SUPPORT_ADMIN_EMAIL_NOTIFICATIONS_ENABLED=False # Send support ticket emails to admins with email addresses -SUPPORT_TICKET_MAX_BODY_LENGTH=4000 # Max message length -SUPPORT_TICKET_MAX_SUBJECT_LENGTH=160 # Max subject length -SUPPORT_TICKET_RATE_LIMIT_PER_HOUR=5 # New tickets per user per hour -SUPPORT_ADMIN_NOTIFICATION_COOLDOWN_SECONDS=300 # Min seconds between admin Telegram/log notifications per unread ticket -SUPPORT_ADMIN_EMAIL_COOLDOWN_SECONDS=1800 # Min seconds between admin email notifications per unread ticket - -# Embedded mode thumbnails. Please don't touch this if you don't know what it is. -INLINE_REFERRAL_THUMBNAIL_URL=https://cdn-icons-png.flaticon.com/512/1077/1077114.png -INLINE_USER_STATS_THUMBNAIL_URL=https://cdn-icons-png.flaticon.com/512/681/681494.png -INLINE_FINANCIAL_STATS_THUMBNAIL_URL=https://cdn-icons-png.flaticon.com/512/2769/2769339.png -INLINE_SYSTEM_STATS_THUMBNAIL_URL=https://cdn-icons-png.flaticon.com/512/2920/2920277.png +# Optional reverse proxy trust list for X-Forwarded-For. +TRUSTED_PROXIES=127.0.0.1,::1 diff --git a/README.md b/README.md index 8c62d8e..96e7d6e 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,8 @@ Remnawave Minishop - Telegram-бот и Web App (Mini App) для продажи - покупка подписок, пакетов трафика, обычная и premium-докупка трафика, докупка устройств по настроенному каталогу тарифов; - Web App / Mini App с входом через Telegram или email; - пробный период, промокоды и реферальная программа; -- оплата через YooKassa, FreeKassa, Platega, SeverPay, Wata, CryptoPay и Telegram Stars; +- оплата через YooKassa, FreeKassa, Platega, SeverPay, Wata, CryptoPay, Heleket и Telegram Stars; +- тикеты поддержки в Web App и внешняя ссылка на поддержку; - раздел "Мои устройства" при включенном `MY_DEVICES_SECTION_ENABLED`. Для администраторов: @@ -23,16 +24,18 @@ Remnawave Minishop - Telegram-бот и Web App (Mini App) для продажи - админ-панель для пользователей из `ADMIN_IDS` (только при входе через Telegram, не для аккаунтов только с email); - статистика пользователей, подписок, платежей и синхронизации с Remnawave; - список пользователей с поиском, фильтрами и колонкой premium-трафика; -- блокировка пользователей, рассылки, промокоды, логи действий и настройка разрешенных параметров приложения поверх `.env`; +- блокировка пользователей, поддержка через тикеты, рассылки, промокоды, логи действий и настройка разрешенных параметров приложения поверх `.env`; - редактор JSON-каталога тарифов с period/traffic-моделями, Internal Squads, premium-сквадами и HWID-пакетами; - ручная синхронизация пользователей и подписок с панелью. ## Документация -- [Настройка окружения](docs/configuration.md) - основные переменные `.env`, платежи, Remnawave, пробный период, SMTP для email-входа и секреты. +- [Настройка окружения](docs/configuration.md) - bootstrap `.env` и рекомендуемая настройка через Web App админку. +- [Переменные `.env`](docs/env-vars.md) - полный справочник всех env-ключей по разделам. - [Тарифы](docs/tariffs.md) - каталог тарифов, period- и traffic-модели, обычные и premium-докупки, premium-сквады, смена тарифа, HWID-лимиты и обработка трафика. - [Админ-панель](docs/admin.md) - права доступа, настройки, редактор тарифов, premium-сквады и сохранение JSON-каталога. - [Web App / Mini App](docs/webapp.md) - отдельный порт, домен, Telegram OAuth, email-вход и реферальные ссылки. +- [Поддержка](docs/support.md) - тикеты в Mini App, входящий список админки, уведомления, лимиты и внешняя ссылка поддержки. - [Темы Web App](docs/webapp-themes.md) - кастомные темы, настройка внешнего вида, логотипы, CSS/ассеты и пайплайн создания новой темы. - [Развертывание](docs/deployment.md) - Docker Compose, reverse proxy, Nginx, Caddy, вебхуки, запуск из образа и обновление версии (`IMAGE_TAG`). - [Миграция с remnawave-tg-shop](docs/migration-to-minishop.md) - перенос данных из прежнего стека. @@ -60,7 +63,7 @@ Remnawave Minishop - Telegram-бот и Web App (Mini App) для продажи - Docker и Docker Compose; - рабочая панель Remnawave версии **`> 2.7.0`** (см. раздел «Совместимость»); - токен Telegram-бота; -- параметры хотя бы одного платежного провайдера. +- публичные домены для webhook и Mini App. ```bash git clone https://github.com/3252a8/remnawave-minishop @@ -76,10 +79,13 @@ docker compose logs -f backend worker frontend - `BOT_TOKEN` - токен Telegram-бота; - `ADMIN_IDS` - Telegram ID администраторов через запятую; - `WEBHOOK_BASE_URL` - публичный URL вебхуков; +- `POSTGRES_USER`, `POSTGRES_PASSWORD`, `POSTGRES_DB` - доступы PostgreSQL; +- `WEBAPP_SESSION_SECRET`, `WEBHOOK_SECRET_TOKEN` - стабильные секреты; +- `SUBSCRIPTION_MINI_APP_URL` - публичный URL Mini App; - `PANEL_API_URL`, `PANEL_API_KEY`, `PANEL_WEBHOOK_SECRET` - доступ к Remnawave; -- `USER_SQUAD_UUIDS` - Internal Squads для пользователей; -- настройки платежного провайдера; -- `SUBSCRIPTION_MINI_APP_URL`, если используется Web App. +- остальные настройки удобнее задать в Web App админке. + +После первого входа в админку настройте тарифы, платежные провайдеры, внешний вид, поддержку и уведомления через UI. Полный справочник env-переменных: [docs/env-vars.md](docs/env-vars.md). Для каталога тарифов используется `TARIFFS_CONFIG_PATH` со значением по умолчанию `data/tariffs.json`. Пример формата лежит в [data/tariffs.example.json](data/tariffs.example.json), подробности - в [docs/tariffs.md](docs/tariffs.md). @@ -113,6 +119,6 @@ GHCR image names for releases: - `ghcr.io/3252a8/remnawave-minishop-worker` - `ghcr.io/3252a8/remnawave-minishop-frontend` -## Поддержка +## Поддержать проект - Crypto: `USDT/Other ERC-20 0xeD506D44aae634fEc0E01C8835744fBedb7B2a44 (Ethereum/Polygon/Gnosis)` diff --git a/docs/admin.md b/docs/admin.md index d9fa153..20182df 100644 --- a/docs/admin.md +++ b/docs/admin.md @@ -6,7 +6,7 @@ - дашборд со статистикой пользователей, платежей и синхронизации с Remnawave; - список пользователей с поиском, фильтрами и колонкой premium-трафика; карточка пользователя с активной подпиской, обычным и premium-трафиком, платежами и действиями (подробнее в разделе «Пользователи» ниже); -- блокировка пользователей, рассылки, промокоды и просмотр логов; +- блокировка пользователей, входящий список тикетов поддержки, рассылки, промокоды и просмотр логов; - ручная синхронизация с Remnawave; - редактор разрешенных настроек приложения из manifest-файла; - раздел **Внешний вид** для логотипа, emoji-логотипа, выбора темы, accent-цвета, масштаба логотипа и предпросмотра тем; @@ -39,16 +39,24 @@ В manifest сейчас входят: -- общие параметры: язык, валюта, ссылки поддержки, документы, обязательный канал и поведение `/start`; +- общие параметры: язык, валюта, ссылки поддержки, документы, обязательный канал, Remnawave-доступы и поведение `/start`; - внешний вид и доступность Web App: название, цвет, логотип, emoji-логотип и `WEBAPP_ENABLED`; - legacy-цены без JSON-каталога: периоды подписки, RUB/Stars цены и пакеты трафика; -- платежные провайдеры: включение методов, порядок кнопок, публичные параметры и секреты YooKassa, FreeKassa, Platega, SeverPay, Wata, CryptoPay и Stars, а также текст и иконки кнопок оплаты; -- пробный период, реферальные бонусы, уведомления, логирование, раздел устройств, лимит устройств и legacy-лимиты трафика. +- платежные провайдеры: включение методов, порядок кнопок, публичные параметры и секреты YooKassa, FreeKassa, Platega, SeverPay, Wata, CryptoPay, Heleket и Stars, а также текст и иконки кнопок оплаты; +- пробный период, реферальные бонусы, уведомления, логирование, поддержка, раздел устройств, лимит устройств и legacy-лимиты трафика. Секретные поля помечены как secret и не должны использоваться для произвольного просмотра старых значений. Настройки, которых нет в manifest, остаются только в `.env` или коде. Для каждого платежного метода в разделе провайдера доступны presentation-настройки `PAYMENT__WEBAPP_LABEL_RU`, `PAYMENT__WEBAPP_LABEL_EN`, `PAYMENT__WEBAPP_ICON`, `PAYMENT__TELEGRAM_LABEL_RU`, `PAYMENT__TELEGRAM_LABEL_EN` и `PAYMENT__TELEGRAM_EMOJI`. Пустое значение возвращает мультиязычный дефолт из модуля платежного провайдера. Иконка Web App выбирается из уже подключённых lucide-иконок (`frontend/src/lib/components/ui/icons.js`) через модалку в админке. +## Поддержка + +Раздел **Коммуникации -> Поддержка** показывает входящий список тикетов из Mini App. В списке доступны фильтры по статусу, приоритету, категории и назначенному администратору, поиск по теме и пользователю, сортировка по обновлению, созданию или важности. + +В карточке тикета администратор видит диалог, пользовательский контекст и действия: ответить пользователю, оставить внутреннюю заметку, изменить статус, приоритет, категорию или исполнителя, закрыть тикет и перейти в карточку пользователя. Внутренние заметки не показываются пользователю. + +Счетчик непрочитанных обращений отображается в навигации админки. Уведомления о новых тикетах и ответах пользователя настраиваются через `LOG_SUPPORT`, `LOG_SUPPORT_THREAD_ID` и параметры `SUPPORT_*`. Подробности: [support.md](support.md). + ## Внешний вид Раздел **Внешний вид** объединяет настройки бренда и темы Web App. Логотип можно загрузить файлом или по HTTPS-ссылке; backend сохраняет файл в `data/webapp-logo/uploads` и подставляет локальный URL. Если включен emoji-логотип, картинка скрывается, а для emoji можно выбрать системный, Twemoji, Noto Color, animated Noto и другие варианты отрисовки. diff --git a/docs/configuration.md b/docs/configuration.md index 0733e6e..0ce80e2 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1,256 +1,94 @@ # Настройка окружения -Конфигурация читается из `.env`. За основу удобно взять `.env.example` и заполнить значения под свою панель, домены и платежные провайдеры. +Проект поддерживает два слоя конфигурации: + +- `.env` - bootstrap, инфраструктура, стабильные секреты и базовые доступы к Remnawave; +- Web App админка - основной рекомендуемый способ менять продуктовые настройки после первого запуска. + +Админка сохраняет overrides в базе данных и применяет их поверх `.env`. Это удобно для платежей, внешнего вида, поддержки, уведомлений, legacy-цен и большинства пользовательских параметров. Тарифы редактируются отдельно в разделе **Система -> Тарифы** и сохраняются в JSON-файл `TARIFFS_CONFIG_PATH`. + +Полный справочник всех переменных вынесен в [env-vars.md](env-vars.md). + +## Минимальный `.env` + +Начните с короткого примера: ```bash cp .env.example .env nano .env ``` -## Основные настройки +Минимально заполните: -| Переменная | Назначение | +| Переменная | Зачем нужна | | --- | --- | | `BOT_TOKEN` | Токен Telegram-бота. | -| `ADMIN_IDS` | Telegram ID администраторов через запятую. | -| `DEFAULT_LANGUAGE` | Язык по умолчанию для пользователей: `ru` или `en`. | -| `DEFAULT_CURRENCY_SYMBOL` | Символ валюты по умолчанию в интерфейсе (например `RUB`, `USD`). | -| `SUPPORT_LINK` | Ссылка на поддержку. | -| `SERVER_STATUS_URL` | Ссылка на страницу статуса сервиса. | -| `TERMS_OF_SERVICE_URL` | Ссылка на условия использования (отдельно от пользовательского соглашения). | -| `PRIVACY_POLICY_URL` | Ссылка на политику конфиденциальности в Web App. | -| `USER_AGREEMENT_URL` | Ссылка на пользовательское соглашение в Web App. | -| `REQUIRED_CHANNEL_ID` | ID канала, на который пользователь должен подписаться перед использованием. | -| `REQUIRED_CHANNEL_LINK` | Ссылка на канал для кнопки проверки подписки. | -| `WEBHOOK_BASE_URL` | Публичный базовый URL для вебхуков (Telegram, платежи, панель). **Обязателен:** без него приложение не запускается. | -| `TRUSTED_PROXIES` | Список IP или CIDR reverse proxy, которым доверяют заголовок `X-Forwarded-For` (через запятую). | -| `START_COMMAND_DESCRIPTION` | Текст описания команды `/start` для меню Telegram (BotFather). | -| `DISABLE_WELCOME_MESSAGE` | Если `true`, приветственное сообщение на `/start` не отправляется. | +| `ADMIN_IDS` | Telegram ID администраторов через запятую; без этого не попасть в Web App админку. | +| `WEBHOOK_BASE_URL` | Публичный URL webhook-домена backend. | +| `POSTGRES_USER`, `POSTGRES_PASSWORD`, `POSTGRES_DB` | Доступы PostgreSQL для Compose и backend. | +| `WEBAPP_SESSION_SECRET` | Стабильный секрет сессий Web App. | +| `WEBHOOK_SECRET_TOKEN` | Стабильный secret token Telegram webhook. | +| `SUBSCRIPTION_MINI_APP_URL` | Публичный URL Mini App, чтобы бот мог открыть личный кабинет. | +| `PANEL_API_URL`, `PANEL_API_KEY`, `PANEL_WEBHOOK_SECRET` | Базовая интеграция с Remnawave. Эти значения стоит хранить в `.env`, но при необходимости их можно переопределить из админки. | -Если используется проверка подписки на канал, добавьте бота администратором в этот канал. После первой успешной проверки пользователь продолжает работу без повторной блокировки действий. - -## Remnawave - -| Переменная | Назначение | -| --- | --- | -| `PANEL_API_URL` | URL API панели Remnawave, например `https://panel.domain.com/api`. | -| `PANEL_API_KEY` | API-ключ панели. | -| `PANEL_WEBHOOK_SECRET` | Секрет для проверки вебхуков Remnawave. | -| `USER_SQUAD_UUIDS` | Internal Squads, в которые добавляются пользователи. | -| `USER_EXTERNAL_SQUAD_UUID` | External Squad для пользователей, если он используется. | -| `USER_TRAFFIC_LIMIT_GB` | Лимит трафика для режима без JSON-каталога тарифов. `0` означает безлимит. | -| `USER_TRAFFIC_STRATEGY` | Стратегия лимита трафика для режима без JSON-каталога тарифов. | -| `USER_HWID_DEVICE_LIMIT` | Лимит HWID-устройств для пользователей. `0` означает безлимит. | - -При включенном каталоге тарифов значения `squad_uuids`, `monthly_gb`, `traffic_packages` и `hwid_device_limit` берутся из выбранного тарифа. Подробно это описано в [tariffs.md](tariffs.md). - -## Платежи - -| Переменная | Назначение | -| --- | --- | -| `PAYMENT_METHODS_ORDER` | Порядок кнопок оплаты через запятую: `severpay`, `wata`, `freekassa`, `platega`, `yookassa`, `stars`, `cryptopay`. | -| `SUBSCRIPTION_PURCHASE_DESCRIPTION_ENABLED` | Показывать описание подписки перед выбором срока покупки или продления в Telegram и Web App. | -| `SUBSCRIPTION_PURCHASE_DESCRIPTION_RU` / `SUBSCRIPTION_PURCHASE_DESCRIPTION_EN` | Текст описания подписки для русской и английской локалей; эти же значения можно переопределить в админке. | -| `PAYMENT__WEBAPP_LABEL_RU` / `PAYMENT__WEBAPP_LABEL_EN` / `PAYMENT__WEBAPP_ICON` | Необязательная мультиязычная кастомизация текста и lucide-иконки кнопки оплаты в Web App. | -| `PAYMENT__TELEGRAM_LABEL_RU` / `PAYMENT__TELEGRAM_LABEL_EN` / `PAYMENT__TELEGRAM_EMOJI` | Необязательная мультиязычная кастомизация текста и эмодзи кнопки оплаты в Telegram-боте. | -| `YOOKASSA_ENABLED` | Включает YooKassa. | -| `YOOKASSA_SHOP_ID` / `YOOKASSA_SECRET_KEY` | Данные магазина YooKassa. | -| `YOOKASSA_RETURN_URL` | URL возврата пользователя после оплаты. | -| `YOOKASSA_DEFAULT_RECEIPT_EMAIL` | Email по умолчанию для чеков YooKassa. | -| `YOOKASSA_VAT_CODE` | Код НДС для чеков. | -| `YOOKASSA_AUTOPAYMENTS_ENABLED` | Включает автопродление через сохраненные способы оплаты YooKassa. | -| `YOOKASSA_AUTOPAYMENTS_REQUIRE_CARD_BINDING` | Управляет обязательной привязкой карты при оплате. | -| `FREEKASSA_ENABLED` | Включает FreeKassa. | -| `FREEKASSA_MERCHANT_ID` / `FREEKASSA_API_KEY` / `FREEKASSA_SECOND_SECRET` | Данные FreeKassa и секрет уведомлений. | -| `FREEKASSA_PAYMENT_IP` | Внешний IP сервера для запроса оплаты FreeKassa. | -| `FREEKASSA_PAYMENT_METHOD_ID` | ID метода оплаты FreeKassa. | -| `FREEKASSA_TRUSTED_IPS` | Список IP источников вебхуков FreeKassa (через запятую). | -| `PLATEGA_ENABLED` | Включает Platega. | -| `PLATEGA_BASE_URL` | Базовый URL API Platega. | -| `PLATEGA_MERCHANT_ID` / `PLATEGA_SECRET` | Данные Platega. | -| `PLATEGA_PAYMENT_METHOD` | Общий ID метода в API Platega; при отдельных кнопках СБП/крипто может использоваться как fallback для метода СБП (см. `PLATEGA_SBP_METHOD`). | -| `PLATEGA_SBP_ENABLED` / `PLATEGA_CRYPTO_ENABLED` | Отдельные кнопки «СБП» и «крипто» в Platega. | -| `PLATEGA_SBP_METHOD` / `PLATEGA_CRYPTO_METHOD` | ID методов Platega для СБП и крипто. | -| `PLATEGA_RETURN_URL` / `PLATEGA_FAILED_URL` | URL возврата после оплаты или ошибки. | -| `SEVERPAY_ENABLED` | Включает SeverPay. | -| `SEVERPAY_MID` / `SEVERPAY_TOKEN` | Данные SeverPay. | -| `SEVERPAY_BASE_URL` | Базовый URL API SeverPay. | -| `SEVERPAY_RETURN_URL` | URL возврата после оплаты. | -| `SEVERPAY_LIFETIME_MINUTES` | Время жизни платежной ссылки. | -| `WATA_ENABLED` | Включает Wata. | -| `WATA_API_TOKEN` | Bearer-токен терминала Wata. | -| `WATA_BASE_URL` | Базовый URL API Wata (`https://api.wata.pro/api/h2h`, для песочницы `https://api-sandbox.wata.pro/api/h2h`). | -| `WATA_RETURN_URL` / `WATA_FAILED_URL` | URL возврата после успешной или неуспешной оплаты. | -| `WATA_PAYMENT_LINK_TTL_DAYS` | Время жизни платежной ссылки в днях, от 1 до 30. | -| `WATA_WEBHOOK_VERIFY_SIGNATURE` | Проверять `X-Signature` вебхука через RSA/SHA512. | -| `WATA_PUBLIC_KEY` | Необязательный публичный ключ Wata для проверки вебхуков; если пусто, backend загрузит его из API. | -| `WATA_TRUSTED_IPS` | IP-адреса Wata, с которых принимаются вебхуки. | -| `CRYPTOPAY_ENABLED` | Включает CryptoPay. | -| `CRYPTOPAY_TOKEN` | Токен CryptoPay App. | -| `CRYPTOPAY_NETWORK` | Сеть: `mainnet` или `testnet`. | -| `CRYPTOPAY_CURRENCY_TYPE` | Тип валюты: `fiat` или `crypto`. | -| `CRYPTOPAY_ASSET` | Актив (например `RUB`, `USDT`). | -| `STARS_ENABLED` | Включает Telegram Stars. | - -Вебхуки платежных систем должны проксироваться на порт `WEB_SERVER_PORT`. Примеры маршрутов есть в [deployment.md](deployment.md). - -## Тарифы - -| Переменная | Назначение | -| --- | --- | -| `TARIFFS_CONFIG_PATH` | Путь к JSON-каталогу тарифов. По умолчанию `data/tariffs.json`. | -| `TARIFF_TRAFFIC_WARNING_LEVELS` | Проценты предупреждений по трафику, например `85,90,95`. | -| `RUB_PRICE_1_MONTH`, `RUB_PRICE_3_MONTHS`, `RUB_PRICE_6_MONTHS`, `RUB_PRICE_12_MONTHS` | Цены подписок в рублях для режима без JSON-каталога. | -| `STARS_PRICE_1_MONTH`, `STARS_PRICE_3_MONTHS`, `STARS_PRICE_6_MONTHS`, `STARS_PRICE_12_MONTHS` | Цены подписок в Telegram Stars для режима без JSON-каталога. | -| `1_MONTH_ENABLED`, `3_MONTHS_ENABLED`, `6_MONTHS_ENABLED`, `12_MONTHS_ENABLED` | Доступность периодов подписки для режима без JSON-каталога. | -| `TRAFFIC_PACKAGES` | Пакеты трафика в рублях для режима без JSON-каталога, например `10:199,50:799`. | -| `STARS_TRAFFIC_PACKAGES` | Пакеты трафика в Telegram Stars для режима без JSON-каталога. | - -Если файл из `TARIFFS_CONFIG_PATH` существует, бот использует каталог тарифов. Если файла нет, применяется конфигурация из переменных `.env`. - -В штатном `docker-compose.yml` данные хранятся в named volumes. Если для локальной разработки включён bind mount `./data:/app/data`, админка сможет сохранять `data/tariffs.json`, каталог тем (`data/themes`), кеш логотипа Web App (`data/webapp-logo`) и animated emoji (`data/webapp-emoji`) прямо в рабочую копию. Если bind mount включён на Ubuntu-сервере, создайте подкаталоги и отдайте `data` UID `10001`, под которым работает приложение внутри контейнера: - -```bash -mkdir -p data/themes data/webapp-logo data/webapp-emoji -chown -R 10001:10001 data -chmod -R u+rwX data -``` - -После изменения compose-файла или прав пересоздайте контейнер: - -```bash -docker compose up -d --build --force-recreate -``` - -Переопределения из веб-админки сохраняются в БД и применяются поверх `.env` без перезапуска. Для платежных методов кнопка отображается только если соответствующий `*_ENABLED=true` и сервис настроен. - -Редактор тарифов в админке сохраняет не override в БД, а сам JSON-файл `TARIFFS_CONFIG_PATH`. Редактор настроек админки, наоборот, работает через allowlist из `backend/bot/app/web/admin_settings_manifest.py` и сохраняет overrides в БД. Через него можно менять только заявленные в manifest параметры приложения; остальные параметры остаются в `.env`. Подробнее: [admin.md](admin.md). - -## Web App и email-вход - -| Переменная | Назначение | -| --- | --- | -| `WEBAPP_ENABLED` | Включает Web App в том же контейнере. | -| `WEBAPP_SERVER_HOST` / `WEBAPP_SERVER_PORT` | Внутренний aiohttp server для WebApp API/auth/theme assets. По умолчанию порт `8081`; статический frontend отдается отдельным nginx image. | -| `SUBSCRIPTION_MINI_APP_URL` | Публичный URL Web App. | -| `WEBAPP_TITLE` | Заголовок Web App. | -| `WEBAPP_THEMES_DIR` | Каталог тем Web App. По умолчанию `data/themes`; внутри ожидаются папки `/theme.json` и опциональные CSS/ассеты. | -| `WEBAPP_DEFAULT_THEME` | Опциональный override темы по ключу, например `light` или `neon`. Если пусто, используется `default` из дескрипторов тем. | -| `WEBAPP_SESSION_SECRET` | HMAC-секрет сессий Web App. | -| `WEBHOOK_SECRET_TOKEN` | Секретный токен, с которым Telegram шлёт обновления на вебхук. | -| `WEBAPP_SESSION_TTL_SECONDS` | Время жизни сессии Web App. | -| `WEBAPP_AUTH_MAX_AGE_SECONDS` | Максимальный возраст `initData` Telegram Mini App. | -| `WEBAPP_LOGIN_TOKEN_TTL_SECONDS` | Время жизни ссылки «войти с другого устройства» / внешнего логина. | -| `TELEGRAM_OAUTH_CLIENT_ID` / `TELEGRAM_OAUTH_CLIENT_SECRET` | Данные Telegram OAuth / OpenID Connect из BotFather. | -| `TELEGRAM_OAUTH_REQUEST_ACCESS` | Дополнительные разрешения Telegram Login, например `write`. | -| `SMTP_HOST`, `SMTP_PORT`, `SMTP_FALLBACK_PORTS` | SMTP-подключение для email-кодов; резервные порты перебираются при ошибке основного. | -| `SMTP_TIMEOUT_SECONDS` | Таймаут одной попытки подключения и отправки. | -| `SMTP_STARTTLS` / `SMTP_USE_SSL` | STARTTLS на обычном порту (например 587) и SSL-обёртка (часто порт 465). | -| `SMTP_USERNAME` / `SMTP_PASSWORD` | Логин и пароль или SMTP key. | -| `SMTP_FROM_EMAIL` / `SMTP_FROM_NAME` | Отправитель писем с кодом; адрес из `SMTP_FROM_EMAIL` должен быть разрешён у провайдера. | -| `EMAIL_CODE_TTL_SECONDS` | Срок действия email-кода. | -| `EMAIL_CODE_RESEND_SECONDS` | Пауза перед повторной отправкой кода. | -| `EMAIL_CODE_MAX_ATTEMPTS` | Максимум попыток ввода одного кода. | -| `BRUTE_FORCE_MAX_FAILURES` | Количество неудачных попыток до временной блокировки. | -| `BRUTE_FORCE_WINDOW_SECONDS` | Окно учета неудачных попыток. | -| `BRUTE_FORCE_LOCK_SECONDS` | Длительность временной блокировки. | -| `MY_DEVICES_SECTION_ENABLED` | Показывает раздел "Мои устройства" и включает API устройств. | - -Логотип, emoji-логотип, основной accent-цвет и тема редактируются в разделе **Админка -> Внешний вид** и сохраняются как overrides в базе. Переменные `WEBAPP_PRIMARY_COLOR`, `WEBAPP_LOGO_URL`, `WEBAPP_LOGO_USE_EMOJI`, `WEBAPP_LOGO_EMOJI` и `WEBAPP_LOGO_EMOJI_FONT` в `.env` считаются устаревшими для первичной настройки и игнорируются при загрузке env. Настройка домена, BotFather и callback URL описана в [webapp.md](webapp.md), а создание кастомных тем - в [webapp-themes.md](webapp-themes.md). - -### SMTP и вход по email - -Вход по email в Web App включается только если заполнены все обязательные поля SMTP: **`SMTP_HOST`**, **`SMTP_PORT`**, **`SMTP_USERNAME`**, **`SMTP_PASSWORD`**, **`SMTP_FROM_EMAIL`**. Имя отправителя **`SMTP_FROM_NAME`** необязательно. Пока конфигурация неполная, интерфейс входа по email не показывается. - -Рекомендуемый типичный вариант — **порт 587** с **STARTTLS** (`SMTP_STARTTLS=True`, `SMTP_USE_SSL=False`), как в примере для Brevo в `.env.example`. Для **порта 465** обычно используют обёртку SSL: выставьте `SMTP_USE_SSL=True` и при необходимости `SMTP_STARTTLS=False`; приложение также считает порт 465 SSL-режимом автоматически при отправке. - -Если основной порт недоступен, перебираются порты из **`SMTP_FALLBACK_PORTS`** (список через запятую, после `SMTP_PORT`). Таймаут одной попытки подключения и отправки задаёт **`SMTP_TIMEOUT_SECONDS`**. - -Порядок действий при подключении нового SMTP: - -1. В панели почтового провайдера создайте SMTP-доступ и подтвердите адрес отправителя (**from**), совпадающий с `SMTP_FROM_EMAIL`. -2. Перенесите хост, порт, логин и пароль (или API-ключ SMTP) в `.env`. -3. Перезапустите контейнер приложения, чтобы подхватить переменные. -4. Проверьте вход: на странице Web App запросите код на почту; при ошибках смотрите логи контейнера. - -Для ограничений по частоте отправки кодов см. `EMAIL_CODE_*` и `BRUTE_FORCE_*` в таблице выше. - -## Пробный период - -| Переменная | Назначение | -| --- | --- | -| `TRIAL_ENABLED` | Включает пробный период. | -| `TRIAL_DURATION_DAYS` | Длительность пробного периода в днях. | -| `TRIAL_TRAFFIC_LIMIT_GB` | Лимит трафика пробного периода. `0` означает безлимит. | -| `TRIAL_TRAFFIC_STRATEGY` | Стратегия лимита трафика пробного периода. | - -## Реферальная программа - -| Переменная | Назначение | -| --- | --- | -| `REFERRAL_WELCOME_BONUS_DAYS` | Бонус пользователю, который пришел по реферальной ссылке. | -| `REFERRAL_ONE_BONUS_PER_REFEREE` | Ограничивает бонусы одним успешным платежом приглашенного пользователя. | -| `REFERRAL_BONUS_DAYS_*` | Бонусные дни пригласившему по периодам подписки. | -| `REFEREE_BONUS_DAYS_*` | Бонусные дни приглашенному по периодам подписки. | -| `LEGACY_REFS` | Разрешает ссылки формата `ref_`. | - -В режиме продажи трафика без JSON-каталога бонусы по периодам не отображаются, потому что покупка не привязана к сроку подписки. - -## Уведомления о подписке - -| Переменная | Назначение | -| --- | --- | -| `SUBSCRIPTION_NOTIFICATIONS_ENABLED` | Включает напоминания о подписке в Telegram. | -| `SUBSCRIPTION_NOTIFY_ON_EXPIRE` | Уведомлять в день окончания. | -| `SUBSCRIPTION_NOTIFY_AFTER_EXPIRE` | Уведомлять после окончания. | -| `SUBSCRIPTION_NOTIFY_DAYS_BEFORE` | За сколько дней до окончания напоминать. | - -## Чеки самозанятого (LKNPD) - -Интеграция с API lknpd.nalog.ru использует переменные с префиксом **`NALOGO_`**: - -| Переменная | Назначение | -| --- | --- | -| `NALOGO_INN` | ИНН самозанятого. | -| `NALOGO_PASSWORD` | Пароль для LKNPD / «Мой налог». | -| `NALOGO_API_URL` | Базовый URL API (по умолчанию `https://lknpd.nalog.ru/api`). | -| `NALOGO_RECEIPT_NAME_SUBSCRIPTION` | Название позиции чека для подписки; в тексте можно использовать `{months}`. | -| `NALOGO_RECEIPT_NAME_TRAFFIC` | Название для пакета трафика; плейсхолдер `{gb}`. | - -Нужны **оба** поля `NALOGO_INN` и `NALOGO_PASSWORD`; иначе отправка чеков отключается (в логах будет предупреждение). - -## Happ crypt4 для ссылок подключения - -| Переменная | Назначение | -| --- | --- | -| `CRYPT4_ENABLED` | Включить шифрование ссылок happ crypt4. | -| `CRYPT4_REDIRECT_URL` | Базовый URL редиректа для кнопки подключения (обёртка с query, например `?url=`). | - -## Логирование и уведомления в Telegram - -| Переменная | Назначение | -| --- | --- | -| `LOG_LEVEL` | Уровень логов: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`. | -| `LOGS_PAGE_SIZE` | Размер страницы журнала в админке. | -| `LOG_CHAT_ID` | ID чата или группы для служебных уведомлений. | -| `LOG_THREAD_ID` | ID топика в супергруппе (опционально). | -| `LOG_NEW_USERS` | Уведомлять о новых регистрациях. | -| `LOG_PAYMENTS` | Уведомлять об успешных платежах. | -| `LOG_PROMO_ACTIVATIONS` | Уведомлять об активации промокодов. | -| `LOG_TRIAL_ACTIVATIONS` | Уведомлять об активации пробного периода. | -| `LOG_SUSPICIOUS_ACTIVITY` | Уведомлять о подозрительных попытках. | -| `LOG_ADMIN_ACTIONS` | Писать в журнал админки действия пользователей из `ADMIN_IDS`. | - -Часть этих переключателей доступна для правки через Web App (allowlist в `backend/bot/app/web/admin_settings_manifest.py`), см. [admin.md](admin.md). - -## Миниатюры inline-режима - -Превью для inline-результатов задаются `INLINE_REFERRAL_THUMBNAIL_URL`, `INLINE_USER_STATS_THUMBNAIL_URL`, `INLINE_FINANCIAL_STATS_THUMBNAIL_URL`, `INLINE_SYSTEM_STATS_THUMBNAIL_URL` (значения по умолчанию есть в `.env.example`). - -## Секреты - -`WEBAPP_SESSION_SECRET` и `WEBHOOK_SECRET_TOKEN` могут генерироваться при старте, но для рабочего окружения их лучше задать явно. Иначе после рестарта сессии Web App станут невалидными, а Telegram получит новый `secret_token` для вебхука (старые запросы от API Telegram могут перестать проходить проверку до следующей переустановки вебхука). +`WEBAPP_SESSION_SECRET` и `WEBHOOK_SECRET_TOKEN` можно сгенерировать так: ```bash openssl rand -hex 32 ``` + +Если оставить эти секреты пустыми, приложение сгенерирует их на процесс, но после рестарта Web App-сессии станут невалидными, а Telegram webhook получит новый `secret_token`. + +## Настройка через админку + +После запуска откройте Mini App под аккаунтом, чей Telegram ID указан в `ADMIN_IDS`, и перейдите в админ-панель. + +Рекомендуемый порядок первичной настройки: + +1. **Система -> Настройки -> Remnawave**: проверьте `PANEL_API_URL`, `PANEL_API_KEY`, `PANEL_WEBHOOK_SECRET`, базовые squads. +2. **Система -> Тарифы**: создайте JSON-каталог тарифов, выберите Internal Squads, настройте period/traffic-модели, premium-сквады и HWID-пакеты. +3. **Система -> Настройки -> Платежи**: включите нужные провайдеры и заполните их ключи. +4. **Внешний вид**: настройте название, тему, логотип, favicon и accent. +5. **Система -> Настройки -> Поддержка / Уведомления**: настройте тикеты, лог-чат, email-уведомления и напоминания. +6. **Общие настройки**: заполните ссылки на поддержку, документы, статус сервиса и обязательный канал, если он нужен. + +Изменения из админки пишутся в таблицу `app_setting_overrides`. При сбросе override снова используется значение из `.env` или дефолт из кода. + +## Что оставить только в `.env` + +Не все настройки стоит переносить в базу. В `.env` остаются: + +- токен бота и `ADMIN_IDS`; +- параметры PostgreSQL, Redis, портов и Compose; +- `WEBHOOK_BASE_URL`, потому что Telegram webhook устанавливается при старте; +- стабильные секреты `WEBAPP_SESSION_SECRET` и `WEBHOOK_SECRET_TOKEN`; +- `WEBAPP_THEMES_DIR`, `TARIFFS_CONFIG_PATH` и низкоуровневые TTL/pool/worker-параметры; +- Remnawave-доступы как базовый источник правды, даже если для удобства они доступны в админке. + +## Файловые данные + +В штатном `docker-compose.yml` данные хранятся в named volume `shop-data`. Внутри него лежат тарифы, темы, логотипы и прочие файловые данные приложения. + +Если для локальной разработки включаете bind mount `./data:/app/data`, заранее создайте каталоги и отдайте их пользователю контейнера: + +```bash +mkdir -p data/themes data/webapp-logo data/webapp-emoji data/tariffs +chown -R 10001:10001 data +chmod -R u+rwX data +docker compose up -d --force-recreate backend worker +``` + +Проверить права можно так: + +```bash +docker compose exec backend sh -lc 'id; touch /app/data/themes/test && rm /app/data/themes/test' +``` + +## Дополнительные разделы + +- [env-vars.md](env-vars.md) - полный справочник переменных `.env`. +- [admin.md](admin.md) - как устроены overrides и allowlist настроек. +- [tariffs.md](tariffs.md) - JSON-каталог тарифов и редактор тарифов. +- [webapp.md](webapp.md) - домен Mini App, Telegram OAuth и email-вход. +- [support.md](support.md) - тикеты поддержки и уведомления. +- [deployment.md](deployment.md) - Docker Compose, reverse proxy, Caddy/Nginx и обновления. diff --git a/docs/deployment.md b/docs/deployment.md index 246b45a..72f345d 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -1,7 +1,7 @@ # Развертывание Документ описывает продакшен-запуск после разделения проекта на `backend`, `frontend` и `worker`. -Перед стартом заполните `.env` по [configuration.md](configuration.md). +Перед стартом заполните минимальный `.env` по [configuration.md](configuration.md). Полный справочник переменных лежит в [env-vars.md](env-vars.md); после первого входа большинство продуктовых настроек удобнее менять через Web App админку. ## Быстрый старт diff --git a/docs/env-vars.md b/docs/env-vars.md new file mode 100644 index 0000000..d635712 --- /dev/null +++ b/docs/env-vars.md @@ -0,0 +1,408 @@ +# Переменные окружения + +`.env` нужен прежде всего для bootstrap: токен бота, доступ к базе, публичный webhook URL и стабильные секреты. После первого входа большая часть продуктовых настроек меняется в Web App админке и сохраняется в БД как override поверх `.env`. + +Рекомендуемый порядок: + +1. Заполнить минимальный `.env` по `.env.example`. +2. Запустить стек и войти в Web App под Telegram ID из `ADMIN_IDS`. +3. Настроить Remnawave, платежи, внешний вид, поддержку, уведомления и тарифы через админку. + +## Минимальный bootstrap + +| Переменная | Где менять | Назначение | +| --- | --- | --- | +| `BOT_TOKEN` | Только `.env` | Токен Telegram-бота. | +| `ADMIN_IDS` | Только `.env` | Telegram ID администраторов через запятую. Нужен для первого входа в админку. | +| `WEBHOOK_BASE_URL` | `.env` | Публичный URL backend/webhook-домена. Используется для Telegram, платежных и Remnawave webhook URL. | +| `POSTGRES_USER` | `.env` / Compose | Пользователь PostgreSQL. | +| `POSTGRES_PASSWORD` | `.env` / Compose | Пароль PostgreSQL. | +| `POSTGRES_DB` | `.env` / Compose | Имя базы PostgreSQL. | +| `WEBAPP_SESSION_SECRET` | `.env` | Стабильный HMAC-секрет сессий Web App. Если пустой, генерируется на процесс, но сессии сбросятся после рестарта. | +| `WEBHOOK_SECRET_TOKEN` | `.env` | Секрет Telegram webhook. Если пустой, генерируется на процесс. | + +## Инфраструктура и Compose + +| Переменная | Где менять | Назначение | +| --- | --- | --- | +| `APP_ENV_FILE` | CLI/Compose | Путь к env-файлу вместо `.env`. | +| `IMAGE_TAG` | CLI/Compose | Тег Docker-образов. | +| `FRONTEND_PORT` | `.env` / Compose | Хостовый порт frontend nginx. По умолчанию `8082`. | +| `WEB_SERVER_HOST` | `.env` | Внутренний host backend webhook server. Обычно `0.0.0.0`. | +| `WEB_SERVER_PORT` | `.env` / Compose | Хостовый порт backend webhook server. По умолчанию `8080`. | +| `WEBAPP_SERVER_HOST` | `.env` | Внутренний host Web App API server. Обычно `0.0.0.0`. | +| `WEBAPP_SERVER_PORT` | `.env` | Внутренний порт Web App API server. По умолчанию `8081`. | +| `POSTGRES_HOST` | Compose | Host PostgreSQL. В штатном Compose задается как `postgres`. | +| `POSTGRES_PORT` | `.env` | Порт PostgreSQL. | +| `DB_POOL_SIZE` | `.env` | Размер async SQLAlchemy pool. | +| `DB_MAX_OVERFLOW` | `.env` | Дополнительные transient DB-соединения сверх pool. | +| `DB_POOL_TIMEOUT_SECONDS` | `.env` | Таймаут ожидания соединения из pool. | +| `DB_POOL_RECYCLE_SECONDS` | `.env` | Период recycling DB-соединений. | +| `REDIS_URL` | Compose | Redis для FSM, кеша, rate-limit, очередей и locks. В Compose задается автоматически. | +| `REDIS_KEY_PREFIX` | `.env` | Префикс Redis-ключей. | +| `TRUSTED_PROXIES` | `.env` | IP/CIDR reverse proxy, которым доверяется `X-Forwarded-For`. | +| `HTTP_BIND` / `HTTPS_BIND` | Caddy Compose | Адреса публикации Caddy-варианта. | +| `NEWT_ID` / `NEWT_SECRET` | Dev Compose | Доступы Newt в dev-compose. | + +## Кеши, rate limits и worker + +Обычно эти значения не требуют правки. + +| Переменная | Назначение | +| --- | --- | +| `WEBAPP_ME_CACHE_TTL_SECONDS` | TTL кеша `/api/me`. | +| `WEBAPP_DEVICES_CACHE_TTL_SECONDS` | TTL кеша устройств Web App. | +| `PANEL_USER_CACHE_TTL_SECONDS` | TTL кеша Remnawave `/users/{uuid}`. | +| `PANEL_DEVICES_CACHE_TTL_SECONDS` | TTL кеша устройств пользователя Remnawave. | +| `PANEL_ALL_USERS_CACHE_TTL_SECONDS` | TTL кеша полных сканов пользователей Remnawave. | +| `PANEL_ALL_USERS_PAGE_SIZE` | Размер страницы Remnawave `/users`. | +| `ADMIN_PANEL_STATS_CACHE_TTL_SECONDS` | TTL статистики Remnawave в админке. | +| `ADMIN_DB_STATS_CACHE_TTL_SECONDS` | TTL дорогих DB-агрегатов админки. | +| `ADMIN_USERS_LIST_CACHE_TTL_SECONDS` | TTL списка пользователей админки. | +| `PROFILE_SYNC_CACHE_TTL_SECONDS` | Минимальная пауза между sync Telegram-профиля пользователя. | +| `PANEL_SYNC_LIFETIME_TRAFFIC_MIN_INTERVAL_SECONDS` | Минимальная пауза записи lifetime-трафика. | +| `PANEL_SYNC_LIFETIME_TRAFFIC_MIN_DELTA_BYTES` | Дельта lifetime-трафика для более ранней записи. | +| `WEBAPP_RATE_LIMIT_TTL_SECONDS` | Окно Web App rate limit. | +| `WEBAPP_RATE_LIMIT_MAX_REQUESTS` | Количество запросов в окне rate limit. | +| `WEBHOOK_QUEUE_NAME` | Redis queue для тяжелой обработки webhook. | +| `WEBHOOK_QUEUE_CONCURRENCY` | Количество worker consumers для webhook queue. | +| `WORKER_PANEL_SYNC_INTERVAL_SECONDS` | Интервал фоновой синхронизации с панелью. | +| `TARIFF_WORKER_LOCK_TTL_SECONDS` | TTL Redis lock для tariff worker. | +| `TARIFF_WORKER_TICK_SECONDS` | Интервал tariff worker. | +| `TARIFF_WORKER_BULK_PANEL_FETCH_THRESHOLD` | Порог активных подписок для bulk fetch пользователей панели. | + +## Общие настройки + +Эти поля доступны в админке: **Система -> Настройки**. + +| Переменная | Назначение | +| --- | --- | +| `DEFAULT_LANGUAGE` | Язык по умолчанию: `ru` или `en`. | +| `DEFAULT_CURRENCY_SYMBOL` | Символ/код валюты в интерфейсе. | +| `SUPPORT_LINK` | Внешняя ссылка поддержки. | +| `SERVER_STATUS_URL` | Страница статуса сервиса. | +| `TERMS_OF_SERVICE_URL` | Условия использования. | +| `PRIVACY_POLICY_URL` | Политика конфиденциальности. | +| `USER_AGREEMENT_URL` | Пользовательское соглашение. | +| `REQUIRED_CHANNEL_ID` | ID обязательного Telegram-канала. | +| `REQUIRED_CHANNEL_LINK` | Ссылка на обязательный канал. | +| `START_COMMAND_DESCRIPTION` | Описание `/start` для меню Telegram. | +| `DISABLE_WELCOME_MESSAGE` | Отключить приветствие на `/start`. | + +## Remnawave + +Эти поля стоит держать в `.env` как базовую конфигурацию интеграции с панелью. Они также доступны в админке, чтобы можно было быстро поправить доступы или временно переопределить их без ручного редактирования файла и перезапуска. + +| Переменная | Назначение | +| --- | --- | +| `PANEL_API_URL` | URL API панели, например `https://panel.example.com/api`. | +| `PANEL_API_KEY` | API-ключ панели. | +| `PANEL_WEBHOOK_SECRET` | Секрет проверки Remnawave webhook. | +| `USER_SQUAD_UUIDS` | Internal Squads по умолчанию для legacy-режима без JSON-каталога. | +| `USER_EXTERNAL_SQUAD_UUID` | Необязательный External Squad. | +| `USER_TRAFFIC_LIMIT_GB` | Legacy-лимит трафика пользователя. | +| `USER_TRAFFIC_STRATEGY` | Legacy-стратегия лимита трафика. | +| `USER_HWID_DEVICE_LIMIT` | Legacy-лимит HWID-устройств по умолчанию. | + +## Web App, внешний вид и Telegram Login + +Часть внешнего вида (`WEBAPP_PRIMARY_COLOR`, `WEBAPP_LOGO_*`, `WEBAPP_FAVICON_*`) сохранена для совместимости, но env-значения этих полей игнорируются при загрузке. Настраивайте их в **Админка -> Внешний вид**. + +| Переменная | Где менять | Назначение | +| --- | --- | --- | +| `WEBAPP_ENABLED` | Админка | Включает Web App. | +| `SUBSCRIPTION_MINI_APP_URL` | Админка | Публичный URL Mini App. | +| `WEBAPP_TITLE` | Админка | Заголовок Web App. | +| `WEBAPP_THEMES_DIR` | `.env` | Каталог кастомных тем. | +| `WEBAPP_DEFAULT_THEME` | `.env` / админка | Ключ темы по умолчанию. | +| `WEBAPP_SESSION_TTL_SECONDS` | `.env` | Время жизни Web App-сессии. | +| `WEBAPP_AUTH_MAX_AGE_SECONDS` | `.env` | Максимальный возраст Telegram Mini Apps `initData`. | +| `WEBAPP_LOGIN_TOKEN_TTL_SECONDS` | `.env` | TTL ссылки внешнего логина. | +| `TELEGRAM_OAUTH_CLIENT_ID` | `.env` | Client ID Telegram OAuth / OpenID Connect. Если пусто, берется bot ID из `BOT_TOKEN`. | +| `TELEGRAM_OAUTH_CLIENT_SECRET` | `.env` | Client Secret Telegram OAuth / OpenID Connect. | +| `TELEGRAM_OAUTH_REQUEST_ACCESS` | `.env` | Дополнительные permissions, например `write`. | +| `WEBAPP_PRIMARY_COLOR` | Админка | Устаревшее env-поле, игнорируется. | +| `WEBAPP_LOGO_URL` | Админка | Устаревшее env-поле, игнорируется. | +| `WEBAPP_LOGO_USE_EMOJI` | Админка | Устаревшее env-поле, игнорируется. | +| `WEBAPP_LOGO_EMOJI` | Админка | Устаревшее env-поле, игнорируется. | +| `WEBAPP_LOGO_EMOJI_FONT` | Админка | Устаревшее env-поле, игнорируется. | +| `WEBAPP_FAVICON_USE_CUSTOM` | Админка | Устаревшее env-поле, игнорируется. | +| `WEBAPP_FAVICON_URL` | Админка | Устаревшее env-поле, игнорируется. | +| `WEBAPP_LOGO_FAVICON_URL` | Админка | Устаревшее env-поле, игнорируется. | + +## SMTP и email-вход + +Email-вход появляется только если заполнены `SMTP_HOST`, `SMTP_PORT`, `SMTP_USERNAME`, `SMTP_PASSWORD` и `SMTP_FROM_EMAIL`. + +| Переменная | Назначение | +| --- | --- | +| `SMTP_HOST` | SMTP host. | +| `SMTP_PORT` | Основной SMTP port. | +| `SMTP_FALLBACK_PORTS` | Резервные порты через запятую. | +| `SMTP_TIMEOUT_SECONDS` | Таймаут SMTP-попытки. | +| `SMTP_USERNAME` | SMTP login. | +| `SMTP_PASSWORD` | SMTP password/API key. | +| `SMTP_FROM_EMAIL` | Подтвержденный адрес отправителя. | +| `SMTP_FROM_NAME` | Имя отправителя. | +| `SMTP_STARTTLS` | Использовать STARTTLS. | +| `SMTP_USE_SSL` | Использовать SSL-wrapper. | +| `EMAIL_CODE_TTL_SECONDS` | TTL email-кода. | +| `EMAIL_CODE_RESEND_SECONDS` | Пауза перед повторной отправкой. | +| `EMAIL_CODE_MAX_ATTEMPTS` | Максимум попыток ввода кода. | +| `BRUTE_FORCE_MAX_FAILURES` | Количество ошибок до временной блокировки. | +| `BRUTE_FORCE_WINDOW_SECONDS` | Окно учета ошибок. | +| `BRUTE_FORCE_LOCK_SECONDS` | Длительность блокировки. | + +## Платежи + +Все включатели, секреты и presentation-настройки провайдеров доступны в админке: **Система -> Настройки -> Платежи**. + +| Переменная | Назначение | +| --- | --- | +| `PAYMENT_METHODS_ORDER` | Порядок кнопок оплаты: `severpay,wata,freekassa,platega,yookassa,stars,cryptopay,heleket`. | +| `SUBSCRIPTION_PURCHASE_DESCRIPTION_ENABLED` | Показывать описание подписки перед выбором срока. | +| `SUBSCRIPTION_PURCHASE_DESCRIPTION_RU` / `SUBSCRIPTION_PURCHASE_DESCRIPTION_EN` | Локализованное описание подписки. | +| `PAYMENT__WEBAPP_LABEL_RU` / `PAYMENT__WEBAPP_LABEL_EN` | Текст кнопки провайдера в Web App. | +| `PAYMENT__WEBAPP_ICON` | Lucide-иконка кнопки в Web App. | +| `PAYMENT__TELEGRAM_LABEL_RU` / `PAYMENT__TELEGRAM_LABEL_EN` | Текст кнопки в Telegram. | +| `PAYMENT__TELEGRAM_EMOJI` | Emoji кнопки в Telegram. | +| `STARS_ENABLED` | Включает Telegram Stars. | +| `YOOKASSA_ENABLED` | Включает YooKassa. | +| `FREEKASSA_ENABLED` | Включает FreeKassa. | +| `PLATEGA_ENABLED` | Включает Platega. | +| `PLATEGA_SBP_ENABLED` / `PLATEGA_CRYPTO_ENABLED` | Отдельные кнопки СБП/крипто Platega. | +| `SEVERPAY_ENABLED` | Включает SeverPay. | +| `WATA_ENABLED` | Включает Wata. | +| `CRYPTOPAY_ENABLED` | Включает CryptoPay. | +| `HELEKET_ENABLED` | Включает Heleket. | + +Конкретные presentation-ключи: + +```text +PAYMENT_YOOKASSA_WEBAPP_LABEL_RU +PAYMENT_YOOKASSA_WEBAPP_LABEL_EN +PAYMENT_YOOKASSA_WEBAPP_ICON +PAYMENT_YOOKASSA_TELEGRAM_LABEL_RU +PAYMENT_YOOKASSA_TELEGRAM_LABEL_EN +PAYMENT_YOOKASSA_TELEGRAM_EMOJI +PAYMENT_FREEKASSA_WEBAPP_LABEL_RU +PAYMENT_FREEKASSA_WEBAPP_LABEL_EN +PAYMENT_FREEKASSA_WEBAPP_ICON +PAYMENT_FREEKASSA_TELEGRAM_LABEL_RU +PAYMENT_FREEKASSA_TELEGRAM_LABEL_EN +PAYMENT_FREEKASSA_TELEGRAM_EMOJI +PAYMENT_PLATEGA_SBP_WEBAPP_LABEL_RU +PAYMENT_PLATEGA_SBP_WEBAPP_LABEL_EN +PAYMENT_PLATEGA_SBP_WEBAPP_ICON +PAYMENT_PLATEGA_SBP_TELEGRAM_LABEL_RU +PAYMENT_PLATEGA_SBP_TELEGRAM_LABEL_EN +PAYMENT_PLATEGA_SBP_TELEGRAM_EMOJI +PAYMENT_PLATEGA_CRYPTO_WEBAPP_LABEL_RU +PAYMENT_PLATEGA_CRYPTO_WEBAPP_LABEL_EN +PAYMENT_PLATEGA_CRYPTO_WEBAPP_ICON +PAYMENT_PLATEGA_CRYPTO_TELEGRAM_LABEL_RU +PAYMENT_PLATEGA_CRYPTO_TELEGRAM_LABEL_EN +PAYMENT_PLATEGA_CRYPTO_TELEGRAM_EMOJI +PAYMENT_SEVERPAY_WEBAPP_LABEL_RU +PAYMENT_SEVERPAY_WEBAPP_LABEL_EN +PAYMENT_SEVERPAY_WEBAPP_ICON +PAYMENT_SEVERPAY_TELEGRAM_LABEL_RU +PAYMENT_SEVERPAY_TELEGRAM_LABEL_EN +PAYMENT_SEVERPAY_TELEGRAM_EMOJI +PAYMENT_WATA_WEBAPP_LABEL_RU +PAYMENT_WATA_WEBAPP_LABEL_EN +PAYMENT_WATA_WEBAPP_ICON +PAYMENT_WATA_TELEGRAM_LABEL_RU +PAYMENT_WATA_TELEGRAM_LABEL_EN +PAYMENT_WATA_TELEGRAM_EMOJI +PAYMENT_STARS_WEBAPP_LABEL_RU +PAYMENT_STARS_WEBAPP_LABEL_EN +PAYMENT_STARS_WEBAPP_ICON +PAYMENT_STARS_TELEGRAM_LABEL_RU +PAYMENT_STARS_TELEGRAM_LABEL_EN +PAYMENT_STARS_TELEGRAM_EMOJI +PAYMENT_CRYPTOPAY_WEBAPP_LABEL_RU +PAYMENT_CRYPTOPAY_WEBAPP_LABEL_EN +PAYMENT_CRYPTOPAY_WEBAPP_ICON +PAYMENT_CRYPTOPAY_TELEGRAM_LABEL_RU +PAYMENT_CRYPTOPAY_TELEGRAM_LABEL_EN +PAYMENT_CRYPTOPAY_TELEGRAM_EMOJI +PAYMENT_HELEKET_WEBAPP_LABEL_RU +PAYMENT_HELEKET_WEBAPP_LABEL_EN +PAYMENT_HELEKET_WEBAPP_ICON +PAYMENT_HELEKET_TELEGRAM_LABEL_RU +PAYMENT_HELEKET_TELEGRAM_LABEL_EN +PAYMENT_HELEKET_TELEGRAM_EMOJI +``` + +### YooKassa + +| Переменная | Назначение | +| --- | --- | +| `YOOKASSA_SHOP_ID` | ID магазина. | +| `YOOKASSA_SECRET_KEY` | Secret key. | +| `YOOKASSA_RETURN_URL` | URL возврата после оплаты. | +| `YOOKASSA_DEFAULT_RECEIPT_EMAIL` | Email для чеков по умолчанию. | +| `YOOKASSA_VAT_CODE` | Код НДС. | +| `YOOKASSA_AUTOPAYMENTS_ENABLED` | Автопродление через сохраненные способы оплаты. | +| `YOOKASSA_AUTOPAYMENTS_REQUIRE_CARD_BINDING` | Требовать привязку карты. | + +### FreeKassa + +| Переменная | Назначение | +| --- | --- | +| `FREEKASSA_MERCHANT_ID` | ID магазина. | +| `FREEKASSA_API_KEY` | API key. | +| `FREEKASSA_SECOND_SECRET` | Секрет уведомлений. | +| `FREEKASSA_PAYMENT_IP` | Публичный IP сервера для запроса оплаты. | +| `FREEKASSA_PAYMENT_METHOD_ID` | ID метода оплаты. | +| `FREEKASSA_TRUSTED_IPS` | IP-allowlist webhook-источников. | + +### Platega + +| Переменная | Назначение | +| --- | --- | +| `PLATEGA_BASE_URL` | Базовый URL API. | +| `PLATEGA_MERCHANT_ID` | Merchant ID. | +| `PLATEGA_SECRET` | API secret. | +| `PLATEGA_PAYMENT_METHOD` | Legacy/fallback method ID. | +| `PLATEGA_SBP_METHOD` | Method ID для СБП. | +| `PLATEGA_CRYPTO_METHOD` | Method ID для крипто. | +| `PLATEGA_RETURN_URL` | URL успешного возврата. | +| `PLATEGA_FAILED_URL` | URL неуспешного возврата. | + +### SeverPay + +| Переменная | Назначение | +| --- | --- | +| `SEVERPAY_BASE_URL` | Базовый URL API. | +| `SEVERPAY_MID` | Merchant MID. | +| `SEVERPAY_TOKEN` | API token/secret. | +| `SEVERPAY_RETURN_URL` | URL возврата. | +| `SEVERPAY_LIFETIME_MINUTES` | Время жизни платежной ссылки. | + +### Wata + +| Переменная | Назначение | +| --- | --- | +| `WATA_BASE_URL` | Базовый URL API. | +| `WATA_API_TOKEN` | Bearer token. | +| `WATA_RETURN_URL` | URL успешного возврата. | +| `WATA_FAILED_URL` | URL неуспешного возврата. | +| `WATA_PAYMENT_LINK_TTL_DAYS` | TTL платежной ссылки в днях. | +| `WATA_WEBHOOK_VERIFY_SIGNATURE` | Проверять `X-Signature`. | +| `WATA_PUBLIC_KEY` | Cached public key; если пусто, загружается из API. | +| `WATA_TRUSTED_IPS` | IP-allowlist webhook-источников. | + +### CryptoPay + +| Переменная | Назначение | +| --- | --- | +| `CRYPTOPAY_TOKEN` | API token CryptoPay. | +| `CRYPTOPAY_NETWORK` | `mainnet` или `testnet`. | +| `CRYPTOPAY_CURRENCY_TYPE` | `fiat` или `crypto`. | +| `CRYPTOPAY_ASSET` | Актив, например `RUB`, `USDT`, `BTC`. | + +### Heleket + +| Переменная | Назначение | +| --- | --- | +| `HELEKET_BASE_URL` | Базовый URL API. | +| `HELEKET_MERCHANT_ID` | UUID мерчанта. | +| `HELEKET_API_KEY` | Payment API key. | +| `HELEKET_CURRENCY` | Валюта инвойса. | +| `HELEKET_TO_CURRENCY` | Целевая криптовалюта для конвертации. | +| `HELEKET_NETWORK` | Сеть, например `tron`, `bsc`, `eth`. | +| `HELEKET_RETURN_URL` | URL после отмены/истечения. | +| `HELEKET_SUCCESS_URL` | URL после успешной оплаты. | +| `HELEKET_LIFETIME_SECONDS` | TTL инвойса: 300..43200. | +| `HELEKET_VERIFY_WEBHOOK_SIGNATURE` | Проверять подпись webhook. | +| `HELEKET_TRUSTED_IPS` | IP-allowlist webhook-источников. | + +## Тарифы и legacy-цены + +Рекомендуемый способ настройки тарифов - раздел **Система -> Тарифы** в админке. Он сохраняет JSON в `TARIFFS_CONFIG_PATH`. + +| Переменная | Назначение | +| --- | --- | +| `TARIFFS_CONFIG_PATH` | Путь к JSON-каталогу тарифов. | +| `TARIFF_TRAFFIC_WARNING_LEVELS` | Уровни предупреждений по трафику в процентах. | +| `1_MONTH_ENABLED` | Legacy-доступность периода 1 месяц без JSON-каталога. | +| `3_MONTHS_ENABLED` | Legacy-доступность периода 3 месяца без JSON-каталога. | +| `6_MONTHS_ENABLED` | Legacy-доступность периода 6 месяцев без JSON-каталога. | +| `12_MONTHS_ENABLED` | Legacy-доступность периода 12 месяцев без JSON-каталога. | +| `RUB_PRICE_1_MONTH`, `RUB_PRICE_3_MONTHS`, `RUB_PRICE_6_MONTHS`, `RUB_PRICE_12_MONTHS` | Legacy-цены RUB. | +| `STARS_PRICE_1_MONTH`, `STARS_PRICE_3_MONTHS`, `STARS_PRICE_6_MONTHS`, `STARS_PRICE_12_MONTHS` | Legacy-цены Stars. | +| `TRAFFIC_PACKAGES` | Legacy-пакеты трафика RUB, формат `10:199,50:799`. | +| `STARS_TRAFFIC_PACKAGES` | Legacy-пакеты трафика Stars. | + +## Trial, referral и уведомления + +Эти настройки доступны в админке. + +| Переменная | Назначение | +| --- | --- | +| `TRIAL_ENABLED` | Включает пробный период. | +| `TRIAL_DURATION_DAYS` | Длительность пробного периода. | +| `TRIAL_TRAFFIC_LIMIT_GB` | Лимит трафика пробного периода. | +| `TRIAL_TRAFFIC_STRATEGY` | Стратегия лимита пробного периода. | +| `REFERRAL_ONE_BONUS_PER_REFEREE` | Ограничить бонусы одним успешным платежом приглашенного. | +| `REFERRAL_WELCOME_BONUS_DAYS` | Приветственный бонус пришедшему по реферальной ссылке. | +| `LEGACY_REFS` | Разрешить ссылки `ref_`. | +| `REFERRAL_BONUS_DAYS_1_MONTH`, `REFERRAL_BONUS_DAYS_3_MONTHS`, `REFERRAL_BONUS_DAYS_6_MONTHS`, `REFERRAL_BONUS_DAYS_12_MONTHS` | Legacy-бонусы пригласившему. | +| `REFEREE_BONUS_DAYS_1_MONTH`, `REFEREE_BONUS_DAYS_3_MONTHS`, `REFEREE_BONUS_DAYS_6_MONTHS`, `REFEREE_BONUS_DAYS_12_MONTHS` | Legacy-бонусы приглашенному. | +| `SUBSCRIPTION_NOTIFICATIONS_ENABLED` | Включает напоминания о подписке. | +| `SUBSCRIPTION_NOTIFY_ON_EXPIRE` | Уведомлять в день окончания. | +| `SUBSCRIPTION_NOTIFY_AFTER_EXPIRE` | Уведомлять после окончания. | +| `SUBSCRIPTION_NOTIFY_DAYS_BEFORE` | За сколько дней предупреждать. | + +## Поддержка + +Подробный сценарий описан в [support.md](support.md). + +| Переменная | Назначение | +| --- | --- | +| `SUPPORT_TICKETS_ENABLED` | Включает тикеты в Mini App. | +| `SUPPORT_ADMIN_EMAIL_NOTIFICATIONS_ENABLED` | Email-уведомления администраторам. | +| `SUPPORT_TICKET_MAX_BODY_LENGTH` | Максимальная длина сообщения. | +| `SUPPORT_TICKET_MAX_SUBJECT_LENGTH` | Максимальная длина темы. | +| `SUPPORT_TICKET_RATE_LIMIT_PER_HOUR` | Лимит новых тикетов в час. | +| `SUPPORT_ADMIN_NOTIFICATION_COOLDOWN_SECONDS` | Cooldown Telegram/log уведомлений. | +| `SUPPORT_ADMIN_EMAIL_COOLDOWN_SECONDS` | Cooldown email-уведомлений. | + +## Логирование + +Часть настроек доступна в админке. + +| Переменная | Назначение | +| --- | --- | +| `LOG_LEVEL` | `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`. | +| `LOGS_PAGE_SIZE` | Размер страницы логов в админке. | +| `LOG_CHAT_ID` | Telegram chat/group ID для служебных уведомлений. | +| `LOG_THREAD_ID` | Topic/thread ID общего лог-чата. | +| `LOG_SUPPORT_THREAD_ID` | Topic/thread ID поддержки. | +| `LOG_NEW_USERS` | Логировать новые регистрации. | +| `LOG_PAYMENTS` | Логировать платежи. | +| `LOG_SUPPORT` | Логировать тикеты поддержки. | +| `LOG_PROMO_ACTIVATIONS` | Логировать активации промокодов. | +| `LOG_TRIAL_ACTIVATIONS` | Логировать активации trial. | +| `LOG_SUSPICIOUS_ACTIVITY` | Логировать подозрительную активность. | +| `LOG_ADMIN_ACTIONS` | Логировать действия администраторов. | + +## Чеки, ссылки подключения и inline + +| Переменная | Назначение | +| --- | --- | +| `NALOGO_INN` | ИНН самозанятого для LKNPD. | +| `NALOGO_PASSWORD` | Пароль LKNPD / «Мой налог». | +| `NALOGO_API_URL` | Базовый URL LKNPD API. | +| `NALOGO_RECEIPT_NAME_SUBSCRIPTION` | Название позиции чека подписки. | +| `NALOGO_RECEIPT_NAME_TRAFFIC` | Название позиции чека пакета трафика. | +| `CRYPT4_ENABLED` | Включает happ crypt4 для ссылок подключения. | +| `CRYPT4_REDIRECT_URL` | URL-обертка для кнопки подключения. | +| `CRYPT4_LINK_CACHE_TTL_SECONDS` | TTL кеша crypt4-ссылок. | +| `MY_DEVICES_SECTION_ENABLED` | Показывать раздел «Мои устройства». | +| `INLINE_REFERRAL_THUMBNAIL_URL` | Превью inline-результата рефералов. | +| `INLINE_USER_STATS_THUMBNAIL_URL` | Превью inline-результата пользовательской статистики. | +| `INLINE_FINANCIAL_STATS_THUMBNAIL_URL` | Превью inline-результата финансовой статистики. | +| `INLINE_SYSTEM_STATS_THUMBNAIL_URL` | Превью inline-результата системной статистики. | diff --git a/docs/support.md b/docs/support.md new file mode 100644 index 0000000..a57effd --- /dev/null +++ b/docs/support.md @@ -0,0 +1,82 @@ +# Поддержка + +В проекте есть два канала поддержки: + +- внешняя ссылка `SUPPORT_LINK`, которая ведет пользователя в Telegram-чат, канал, форму или любой другой публичный URL; +- встроенные тикеты Web App / Mini App, если включен `SUPPORT_TICKETS_ENABLED`. + +Внешняя ссылка остается простым резервным каналом. Тикеты дают полноценный диалог внутри личного кабинета: пользователь создает обращение, видит историю ответов, получает счетчик непрочитанных сообщений, а администратор отвечает из админ-панели. + +## Пользовательский сценарий + +Раздел **Поддержка** появляется в Web App, когда `SUPPORT_TICKETS_ENABLED=True`. Пользователь может: + +- создать тикет с темой, категорией, приоритетом и первым сообщением; +- выбрать категорию `billing`, `technical`, `account` или `other`; +- выбрать приоритет `normal` или `high`; +- открыть список своих тикетов с фильтром по активным и всем обращениям; +- отвечать в открытом тикете и видеть ответы поддержки; +- перейти по `SUPPORT_LINK`, если нужна внешняя поддержка. + +Заблокированные пользователи не могут создавать тикеты и отвечать в них. Для пользователей показываются только обычные сообщения: внутренние заметки администраторов скрыты. + +## Админский сценарий + +В админ-панели тикеты доступны в разделе **Коммуникации -> Поддержка**. Доступ проверяется так же, как и для остальных `/api/admin/*`: нужна Web App-сессия пользователя, чей Telegram ID указан в `ADMIN_IDS`. + +Администратор может: + +- видеть сводку по открытым, ожидающим ответа, закрытым и непрочитанным тикетам; +- фильтровать обращения по статусу, приоритету, категории и назначенному администратору; +- искать по теме, username, имени и email пользователя; +- сортировать по обновлению, созданию или важности; +- отвечать пользователю, менять статус, категорию, приоритет и исполнителя; +- оставлять внутренние заметки, которые видны только администраторам; +- открыть карточку пользователя и видеть контекст подписки: тариф, статус, остаток времени, обычный и premium-трафик. + +Статусы тикета: `open`, `awaiting_user`, `awaiting_admin`, `resolved`, `closed`. При создании тикет сразу получает статус `awaiting_admin`; ответ пользователя переводит незакрытый тикет в `awaiting_admin`, ответ администратора - в `awaiting_user`. Закрытые статусы считаются `resolved` и `closed`. + +## Уведомления + +Новые тикеты и ответы пользователя могут отправляться в Telegram-уведомления администраторам и в лог-чат. Для отдельного топика поддержки используйте `LOG_SUPPORT_THREAD_ID`; если он пустой, сообщения идут в общий `LOG_THREAD_ID`/чат по настройкам логирования. + +Повторные уведомления по одному непрочитанному тикету ограничиваются cooldown-настройками, чтобы не заспамить админов: + +- `SUPPORT_ADMIN_NOTIFICATION_COOLDOWN_SECONDS` - пауза для Telegram/log уведомлений; +- `SUPPORT_ADMIN_EMAIL_COOLDOWN_SECONDS` - пауза для email-уведомлений. + +Email-уведомления администраторам включаются через `SUPPORT_ADMIN_EMAIL_NOTIFICATIONS_ENABLED=True`. Письма отправляются только администраторам из `ADMIN_IDS`, у которых в базе есть email. Для отправки нужен рабочий SMTP-конфиг, как и для входа по email. + +Ответ администратора и закрытие тикета дополнительно отправляются пользователю в Telegram, если у него есть Telegram-аккаунт, и на email, если он привязан. + +## Настройки + +| Переменная | Назначение | +| --- | --- | +| `SUPPORT_LINK` | Внешняя ссылка поддержки. Показывается в боте и Web App как быстрый способ связаться с командой. | +| `SUPPORT_TICKETS_ENABLED` | Включает раздел тикетов в Mini App и разрешает создание обращений. | +| `SUPPORT_TICKET_MAX_BODY_LENGTH` | Максимальная длина сообщения тикета. | +| `SUPPORT_TICKET_MAX_SUBJECT_LENGTH` | Максимальная длина темы тикета. | +| `SUPPORT_TICKET_RATE_LIMIT_PER_HOUR` | Сколько новых тикетов пользователь может создать за час; `0` отключает лимит. | +| `LOG_SUPPORT` | Включает Telegram/log уведомления по тикетам поддержки. | +| `LOG_SUPPORT_THREAD_ID` | Необязательный ID топика в лог-чате для сообщений поддержки. | +| `SUPPORT_ADMIN_EMAIL_NOTIFICATIONS_ENABLED` | Включает email-уведомления администраторам о новых тикетах и ответах пользователей. | +| `SUPPORT_ADMIN_NOTIFICATION_COOLDOWN_SECONDS` | Минимальная пауза между повторными Telegram/log уведомлениями по одному непрочитанному тикету. | +| `SUPPORT_ADMIN_EMAIL_COOLDOWN_SECONDS` | Минимальная пауза между повторными email-уведомлениями по одному непрочитанному тикету. | + +Все эти параметры описаны в [env-vars.md](env-vars.md). Основной рекомендуемый способ менять их - админка **Система -> Настройки -> Поддержка**; значения применяются как override поверх `.env`. + +## API и хранение + +Пользовательские маршруты: + +- `GET /api/support/tickets` - список тикетов пользователя; +- `POST /api/support/tickets` - создать тикет; +- `GET /api/support/tickets/{id}` - открыть тикет; +- `POST /api/support/tickets/{id}/messages` - отправить ответ; +- `POST /api/support/tickets/{id}/read` - отметить сообщения прочитанными; +- `GET /api/support/unread` - счетчик непрочитанных ответов поддержки. + +Админские маршруты находятся под `/api/admin/support/*`: список, карточка тикета, ответ, изменение статуса/приоритета/категории/исполнителя, отметка прочитанного и статистика. + +Данные хранятся в таблицах `support_tickets` и `support_ticket_messages`; миграция применяется автоматически сервисом `migrate` при `docker compose up -d --build`. diff --git a/docs/webapp.md b/docs/webapp.md index e2193ac..986b700 100644 --- a/docs/webapp.md +++ b/docs/webapp.md @@ -11,10 +11,11 @@ Web App собирается в отдельный `frontend` image и отда - доступные тарифы, способы оплаты и платежный статус; - смену тарифа, обычную докупку трафика и докупку premium-трафика при настроенном каталоге тарифов; - раздел "Мои устройства" при `MY_DEVICES_SECTION_ENABLED=True`; +- раздел "Поддержка" с тикетами и внешней ссылкой `SUPPORT_LINK` при включенном `SUPPORT_TICKETS_ENABLED`; - реферальную ссылку и статистику приглашений; - привязку email и Telegram к одному аккаунту. -Для администраторов из `ADMIN_IDS` Web App также показывает админ-панель: статистику, **пользователей** (поиск, фильтры, premium-трафик), рассылки, промокоды, логи, настройки и редактор тарифов. Подробности: [admin.md](admin.md). +Для администраторов из `ADMIN_IDS` Web App также показывает админ-панель: статистику, **пользователей** (поиск, фильтры, premium-трафик), поддержку, рассылки, промокоды, логи, настройки и редактор тарифов. Подробности: [admin.md](admin.md). ## Настройки `.env` @@ -45,12 +46,18 @@ SMTP_USERNAME= SMTP_PASSWORD= SMTP_FROM_EMAIL=no-reply@domain.com SMTP_FROM_NAME=Remnawave Minishop + +SUPPORT_LINK=https://t.me/your_support_link +SUPPORT_TICKETS_ENABLED=True +SUPPORT_TICKET_RATE_LIMIT_PER_HOUR=5 ``` Внешний вид настраивается в админке: раздел **Внешний вид** управляет логотипом, emoji-логотипом, accent-цветом, выбранной темой и масштабом логотипа. Кастомные темы читаются из `WEBAPP_THEMES_DIR`, а `WEBAPP_DEFAULT_THEME` может принудительно выбрать тему по ключу. Подробный контракт `theme.json`, CSS/asset-роуты и пайплайн создания темы описаны в [webapp-themes.md](webapp-themes.md). Если SMTP-настройки не заполнены, вход по email скрывается. +Тикеты поддержки включаются через `SUPPORT_TICKETS_ENABLED`; внешний резервный контакт задается `SUPPORT_LINK`. Полный сценарий пользователя, админа и уведомлений описан в [support.md](support.md). + ## Telegram-авторизация Внутри Telegram Mini App пользователь авторизуется через Telegram Mini Apps `initData`. При открытии страницы вне Telegram используется Telegram OAuth / OpenID Connect Authorization Code Flow с PKCE, callback `/auth/telegram/callback`, `nonce` и серверной проверкой `id_token` по JWKS Telegram.