### Quick Start with Docker Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/README.md Clone the repository, set up environment variables, and start the bot using Docker Compose. ```bash git clone https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot.git cd remnawave-bedolaga-telegram-bot cp .env.example .env # заполните переменные docker compose up -d ``` -------------------------------- ### Guide Mode for Subscription Display Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/wiki/6.-Режимы-вывода-подписки Sets the bot to display a guide for connection with buttons and links to applications. Ensure app-config.json is correctly mounted in docker-compose.yml for custom application and guide editing. ```env CONNECT_BUTTON_MODE=guide ``` -------------------------------- ### Copy Example .env File Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/wiki/2.-Настройка-бота-.env Before editing, copy the example .env file to create your own configuration file. This ensures all necessary variables are present. ```bash cp .env.example .env ``` -------------------------------- ### Get Account Token API Success Response Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/apple-iap-ios-requirements.md Example of a successful JSON response containing the `app_account_token`. This token must be parsed as a UUID and cached per user. ```json { "app_account_token": "123e4567-e89b-12d3-a456-426614174000" } ``` -------------------------------- ### Start and Stop Apple IAP Transaction Listener Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/apple-iap-ios-requirements.md Initiates a background task to listen for transaction updates from StoreKit. Call `start()` during app startup and `stop()` when the listener is no longer needed. Ensure `checkVerified` is implemented to verify transactions. ```swift final class AppleIAPTransactionObserver { private var updatesTask: Task? func start() { updatesTask = Task.detached(priority: .background) { for await result in Transaction.updates { do { let transaction = try checkVerified(result) await AppleIAPCoordinator.shared.handleUpdatedTransaction(transaction) } catch { // Unverified transaction. Do not deliver or finish. AppleIAPLogger.logUnverifiedTransaction(error) } } } } func stop() { updatesTask?.cancel() updatesTask = nil } } ``` -------------------------------- ### Get User Click Sequences Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/menu_stats_api_usage.md Retrieves the chronological sequence of button clicks for a specific user. Useful for analyzing user navigation paths and interaction patterns. ```python sequences = await MenuLayoutService.get_user_click_sequences(db, user_id=123456789, limit=50) # Возвращает: # [ # {"button_id": "menu_balance", "button_text": "💰 Баланс", "clicked_at": datetime(...)}, # {"button_id": "menu_subscription", "button_text": "📊 Подписка", "clicked_at": datetime(...)}, # ... # ] ``` -------------------------------- ### Docker Compose for Building from Image Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/wiki/4.-docker‐compose.yml This configuration is used when building the bot from a pre-existing Docker image. It sets up PostgreSQL, Redis, and the bot service with specified environment variables, volumes, and network settings. ```yaml services: postgres: image: postgres:15-alpine container_name: remnawave_bot_db restart: unless-stopped environment: POSTGRES_DB: ${POSTGRES_DB:-remnawave_bot} POSTGRES_USER: ${POSTGRES_USER:-remnawave_user} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-secure_password_123} POSTGRES_INITDB_ARGS: "--encoding=UTF8" volumes: - postgres_data:/var/lib/postgresql/data networks: - bot_network healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-remnawave_user} -d ${POSTGRES_DB:-remnawave_bot}"] interval: 30s timeout: 5s retries: 5 start_period: 30s redis: image: redis:7-alpine container_name: remnawave_bot_redis restart: unless-stopped command: redis-server --appendonly yes volumes: - redis_data:/data networks: - bot_network healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 30s timeout: 10s retries: 3 bot: image: fr1ngg/remnawave-bedolaga-telegram-bot:latest container_name: remnawave_bot restart: unless-stopped depends_on: postgres: condition: service_healthy redis: condition: service_healthy env_file: - .env environment: DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-remnawave_user}:${POSTGRES_PASSWORD:-secure_password_123}@postgres:5432/${POSTGRES_DB:-remnawave_bot} REDIS_URL: redis://redis:6379/0 volumes: # Логи - ./logs:/app/logs:rw # Данные приложения (для SQLite в случае переключения) - ./data:/app/data:rw # Конфигурация приложения # - ./app-config.json:/app/app-config.json:ro # Timezone - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro # Логотип для сообщений - ./vpn_logo.png:/app/vpn_logo.png:ro ports: - "${TRIBUTE_WEBHOOK_PORT:-8081}:8081" - "${YOOKASSA_WEBHOOK_PORT:-8082}:8082" networks: - bot_network volumes: postgres_data: redis_data: networks: bot_network: driver: bridge ipam: config: - subnet: 172.20.0.0/16 ``` -------------------------------- ### Get Account Token API Request Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/apple-iap-ios-requirements.md HTTP GET request to retrieve the `app_account_token` from the backend. This token is required before initiating a StoreKit purchase. ```http GET /cabinet/apple-iap/account-token Authorization: Bearer Accept: application/json ``` -------------------------------- ### Docker Compose конфигурация для Nginx Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/miniapp-setup.md Пример конфигурации docker-compose для запуска Nginx в качестве reverse-proxy. Монтирует локальный каталог 'miniapp' внутрь контейнера для обслуживания статических файлов. ```yaml services: nginx: image: nginx:1.25-alpine restart: unless-stopped volumes: - ./miniapp:/miniapp:ro # общий каталог статических файлов - ./deploy/nginx.conf:/etc/nginx/conf.d/default.conf:ro ports: - "80:80" - "443:443" ``` -------------------------------- ### Docker Compose конфигурация для Caddy Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/miniapp-setup.md Пример конфигурации docker-compose для запуска Caddy в качестве reverse-proxy. Монтирует локальный каталог 'miniapp' внутрь контейнера для обслуживания статических файлов. ```yaml services: caddy: image: caddy:2 restart: unless-stopped volumes: - ./miniapp:/miniapp:ro # монтируем локальную папку внутрь контейнера - ./deploy/Caddyfile:/etc/caddy/Caddyfile:ro ports: - "80:80" - "443:443" ``` -------------------------------- ### REMNAWAVE_SECRET_KEY Configuration Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/wiki/8.-Интеграция-со-скриптом-установки-панели-eGames For panels installed by the eGames script, the secret key must be in the format XXXXXXX:DDDDDDDD. This is used for authentication when connecting to the panel externally. ```env # Для панелей установленных скриптом eGames прописывать ключ в формате XXXXXXX:DDDDDDDD - https://panel.example.com/auth/login?XXXXXXX=DDDDDDDD REMNAWAVE_SECRET_KEY=your_secret_key_here ``` -------------------------------- ### Recommended Swift Product Model Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/apple-iap-ios-requirements.md A recommended Swift struct for modeling consumable in-app purchase products. Use this to manage product information within the app. ```swift struct AppleTopUpProduct: Identifiable, Equatable { let id: String // App Store product ID let displayOrder: Int let fallbackTitle: String } ``` -------------------------------- ### Backend Product IDs Configuration Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/apple-iap-ios-requirements.md Defines the mapping between App Store product IDs and the credited balance on the backend. Ensure product IDs in the app exactly match these. ```json { "com.app.client.topup.100": 10000, "com.app.client.topup.300": 30000, "com.app.client.topup.500": 50000 } ``` -------------------------------- ### Swift Pseudocode for Purchase Flow Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/apple-iap-ios-requirements.md This pseudocode outlines the recommended sequence of operations for handling a user's in-app purchase, from authentication to finishing the StoreKit transaction. ```swift func purchaseTopUp(product: Product) async { guard authSession.isAuthenticated else { showLogin() return } let accountToken: UUID do { accountToken = try await appleIAPAPI.fetchAccountToken() } catch { showPurchaseUnavailable(error) return } do { let result = try await product.purchase(options: [ .appAccountToken(accountToken) ]) switch result { case .success(let verificationResult): let transaction = try checkVerified(verificationResult) await deliverAndFinish(transaction) case .pending: showPendingApprovalState() case .userCancelled: return @unknown default: showPurchaseUnavailable(nil) } } catch { showPurchaseFailed(error) } } ``` -------------------------------- ### Get Top Users by Clicks Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/menu_stats_api_usage.md Retrieves a list of users with the highest click counts for a specific button within a given period. Use this to identify your most engaged users. ```python top_users = await MenuLayoutService.get_top_users(db, button_id="menu_balance", limit=10, days=30) # Возвращает: # [ # {"user_id": 123456789, "clicks_count": 50, "last_click_at": datetime(...)}, # ... # ] ``` -------------------------------- ### Edit .env File Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/wiki/2.-Настройка-бота-.env Use a text editor like nano to modify the .env file and set your bot's configuration parameters. This is where you'll input tokens, IDs, and other sensitive information. ```bash nano .env ``` -------------------------------- ### Конфигурация Nginx для мини-приложения Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/miniapp-setup.md Настройка Nginx для обслуживания статических файлов мини-приложения и проксирования запросов к административному API бота. Включает SSL-сертификаты и директивы для обработки запросов. ```nginx server { listen 80; listen 443 ssl http2; server_name miniapp.example.com; ssl_certificate /etc/letsencrypt/live/miniapp.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/miniapp.example.com/privkey.pem; # Статические файлы мини-приложения root /miniapp; index index.html; location = /miniapp/app-config.json { add_header Access-Control-Allow-Origin "*"; try_files $uri =404; } location / { try_files $uri /index.html =404; } # Проксирование запросов к административному API location /miniapp/ { proxy_pass http://127.0.0.1:8080/miniapp/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } # Если нужно проксировать другие эндпоинты API, добавьте аналогичные location-блоки. } ``` -------------------------------- ### Конфигурация Caddy для мини-приложения Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/miniapp-setup.md Настройка Caddy для обслуживания статических файлов мини-приложения и проксирования запросов к административному API бота. Caddy автоматически управляет SSL-сертификатами. ```caddy miniapp.example.com { encode gzip zstd root * /miniapp file_server @config path /app-config.json header @config Access-Control-Allow-Origin "*" reverse_proxy /miniapp/* 127.0.0.1:8080 { header_up Host {host} header_up X-Real-IP {remote_host} } } ``` -------------------------------- ### Клонирование репозитория бота Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/wiki/1.-Установка-бота Клонируйте репозиторий бота с GitHub, чтобы получить локальную копию кода. ```bash git clone https://github.com/Fr1ngg/remnawave-bedolaga-telegram-bot.git ``` -------------------------------- ### Initialize WebSocket Manager in App Component Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/web-admin-integration-guide.md Sets up and connects the WebSocketManager in the main App component. It handles token retrieval, connection establishment, and registers event listeners for various real-time updates. Ensure you have authentication and WebSocket URL configured. ```typescript // App.tsx или main.tsx import { useEffect, useState } from 'react'; import WebSocketManager from './utils/websocket'; import { getApiToken } from './utils/auth'; function App() { const [wsManager, setWsManager] = useState(null); useEffect(() => { const token = getApiToken(); if (!token) { console.warn('No API token found, WebSocket will not connect'); return; } const manager = new WebSocketManager(token); const wsUrl = process.env.REACT_APP_WS_URL || 'ws://localhost:8080/ws'; manager.connect(wsUrl); setWsManager(manager); // Обработка событий manager.on('user.created', (payload) => { console.log('New user created:', payload); // Обновить список пользователей // Показать уведомление }); manager.on('payment.completed', (payload) => { console.log('Payment completed:', payload); // Обновить статистику // Обновить баланс пользователя }); manager.on('ticket.created', (payload) => { console.log('New ticket created:', payload); // Обновить список тикетов // Показать уведомление }); manager.on('ticket.status_changed', (payload) => { console.log('Ticket status changed:', payload); // Обновить статус тикета в списке }); manager.on('ticket.message_added', (payload) => { console.log('New message in ticket:', payload); // Обновить список сообщений в тикете // Показать уведомление о новом сообщении }); return () => { manager.disconnect(); }; }, []); return ( // Ваш компонент приложения ); } ``` -------------------------------- ### Create Webhook Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/web-admin-integration-guide.md Use this cURL command to create a new webhook. Ensure you replace YOUR_TOKEN and your-unique-url with actual values. The event_type specifies which events will trigger this webhook. ```bash curl -X POST http://localhost:8080/webhooks \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Test Webhook", "url": "https://webhook.site/your-unique-url", "event_type": "user.created" }' ``` -------------------------------- ### Docker Compose for Local Build Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/wiki/4.-docker‐compose.yml This configuration is used for local development and builds the bot directly from the Dockerfile. It includes specific settings for Redis memory, locale for PostgreSQL, and environment variables for database connection and timezone. ```yaml services: postgres: image: postgres:15-alpine container_name: remnawave_bot_db restart: unless-stopped environment: POSTGRES_DB: ${POSTGRES_DB:-remnawave_bot} POSTGRES_USER: ${POSTGRES_USER:-remnawave_user} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-secure_password_123} POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C" volumes: - postgres_data:/var/lib/postgresql/data networks: - bot_network healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-remnawave_user} -d ${POSTGRES_DB:-remnawave_bot}"] interval: 30s timeout: 5s retries: 5 start_period: 30s redis: image: redis:7-alpine container_name: remnawave_bot_redis restart: unless-stopped command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru volumes: - redis_data:/data networks: - bot_network healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 30s timeout: 10s retries: 3 bot: build: context: . # путь до папки с Dockerfile dockerfile: Dockerfile container_name: remnawave_bot restart: unless-stopped depends_on: postgres: condition: service_healthy redis: condition: service_healthy env_file: - .env environment: DOCKER_ENV: "true" DATABASE_MODE: "auto" POSTGRES_HOST: "postgres" POSTGRES_PORT: "5432" POSTGRES_DB: "${POSTGRES_DB:-remnawave_bot}" POSTGRES_USER: "${POSTGRES_USER:-remnawave_user}" POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-secure_password_123}" REDIS_URL: "redis://redis:6379/0" TZ: "Europe/Moscow" volumes: # Логи - ./logs:/app/logs:rw # Данные приложения (для SQLite в случае переключения) - ./data:/app/data:rw # Конфигурация приложения # - ./app-config.json:/app/app-config.json:ro # Timezone - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro # Логотип для сообщений - ./vpn_logo.png:/app/vpn_logo.png:ro ports: - "${TRIBUTE_WEBHOOK_PORT:-8081}:8081" - "${YOOKASSA_WEBHOOK_PORT:-8082}:8082" networks: - bot_network healthcheck: test: ["CMD-SHELL", "python -c 'import requests; requests.get(\"http://localhost:8081/health\", timeout=5)' || exit 1"] interval: 60s timeout: 10s retries: 3 start_period: 30s volumes: postgres_data: driver: local redis_data: driver: local networks: bot_network: driver: bridge ipam: config: - subnet: 172.20.0.0/16 gateway: 172.20.0.1 ``` -------------------------------- ### Custom Mini-App URL for Subscription Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/wiki/6.-Режимы-вывода-подписки Configures the bot to open a specified subscription link directly within a mini-application. Set the MINIAPP_CUSTOM_URL environment variable to your custom subscription page domain. ```env MINIAPP_CUSTOM_URL= ``` -------------------------------- ### Recommended Swift Account Token Response Model Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/apple-iap-ios-requirements.md A Swift Decodable model for parsing the backend's `app_account_token` response. Ensure proper error handling for UUID parsing. ```swift struct AppleAccountTokenResponse: Decodable { let appAccountToken: String enum CodingKeys: String, CodingKey { case appAccountToken = "app_account_token" } } ``` -------------------------------- ### Remnawave Bedolaga Bot Configuration Parameters Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/wiki/2.-Настройка-бота-.env This section outlines the various configuration parameters available in the .env file for the Remnawave Bedolaga Bot. It covers Telegram bot settings, database connections, API details, subscription management, and payment gateway integrations. ```dotenv # =============================================== # 🤖 REMNAWAVE BEDOLAGA BOT CONFIGURATION # =============================================== # ===== TELEGRAM BOT ===== BOT_TOKEN= ADMIN_IDS= SUPPORT_USERNAME=@support # Уведомления администраторов ADMIN_NOTIFICATIONS_ENABLED=true ADMIN_NOTIFICATIONS_CHAT_ID=-1001234567890 # Замени на ID твоего канала (-100) - ПРЕФИКС ЗАКРЫТОГО КАНАЛА! ВСТАВИТЬ СВОЙ ID СРАЗУ ПОСЛЕ (-100) БЕЗ ПРОБЕЛОВ! ADMIN_NOTIFICATIONS_TOPIC_ID=123 # Опционально: ID топика # ===== DATABASE CONFIGURATION ===== # Режим базы данных: "auto", "postgresql", "sqlite" DATABASE_MODE=auto # Основной URL (можно оставить пустым для автоматического выбора) DATABASE_URL= # PostgreSQL настройки (для Docker и кастомных установок) POSTGRES_HOST=postgres POSTGRES_PORT=5432 POSTGRES_DB=remnawave_bot POSTGRES_USER=remnawave_user POSTGRES_PASSWORD=secure_password_123 # SQLite настройки (для локального запуска) SQLITE_PATH=./data/bot.db # Redis REDIS_URL=redis://redis:6379/0 # ===== REMNAWAVE API ===== REMNAWAVE_API_URL=https://panel.example.com REMNAWAVE_API_KEY= # Для панелей установленных скриптом eGames прописывать ключ в формате XXXXXXX:DDDDDDDD - https://panel.example.com/auth/login?XXXXXXX=DDDDDDDD REMNAWAVE_SECRET_KEY=your_secret_key_here # ========= ПОДПИСКИ ========= # ===== ТРИАЛ ПОДПИСКА ===== TRIAL_DURATION_DAYS=3 TRIAL_TRAFFIC_LIMIT_GB=10 TRIAL_DEVICE_LIMIT=1 TRIAL_SQUAD_UUID= # ===== ПЛАТНАЯ ПОДПИСКА ===== # Сколько устройств доступно по дефолту при покупке платной подписки DEFAULT_DEVICE_LIMIT=3 # Максимум устройств достопных к покупке (0 = Нет лимита) MAX_DEVICES_LIMIT=15 # Дефолт параметры для подписок выданных через админку DEFAULT_TRAFFIC_LIMIT_GB=100 # ===== ГЛОБАЛЬНЫЙ ПАРАМЕТР ДЛЯ ВСЕХ ПОДПИСОК ===== DEFAULT_TRAFFIC_RESET_STRATEGY=MONTH # ===== НАСТРОЙКИ ТРАФИКА ===== # Режим выбора трафика: # "selectable" - пользователи выбирают пакеты трафика (по умолчанию) # "fixed" - фиксированный лимит трафика для всех подписок TRAFFIC_SELECTION_MODE=selectable # Фиксированный лимит трафика в ГБ (используется только в режиме "fixed") # 0 = безлимит FIXED_TRAFFIC_LIMIT_GB=100 # ===== ПЕРИОДЫ ПОДПИСКИ ===== # Доступные периоды подписки (через запятую) # Возможные значения: 14,30,60,90,180,360 AVAILABLE_SUBSCRIPTION_PERIODS=30,90,180 AVAILABLE_RENEWAL_PERIODS=30,90,180 # ===== ЦЕНЫ (в копейках) ===== BASE_SUBSCRIPTION_PRICE=0 # Цены за периоды PRICE_14_DAYS=7000 PRICE_30_DAYS=9900 PRICE_60_DAYS=25900 PRICE_90_DAYS=36900 PRICE_180_DAYS=69900 PRICE_360_DAYS=109900 # Выводимые пакеты трафика и их цены в копейках TRAFFIC_PACKAGES_CONFIG="5:2000:false,10:3500:false,25:7000:false,50:11000:true,100:15000:true,250:17000:false,500:19000:false,1000:19500:true,0:20000:true" # Цена за дополнительное устройство (DEFAULT_DEVICE_LIMIT идет бесплатно!) PRICE_PER_DEVICE=5000 # ===== РЕФЕРАЛЬНАЯ СИСТЕМА ===== REFERRAL_MINIMUM_TOPUP_KOPEKS=10000 REFERRAL_FIRST_TOPUP_BONUS_KOPEKS=10000 REFERRAL_INVITER_BONUS_KOPEKS=10000 REFERRAL_COMMISSION_PERCENT=25 # Уведомления REFERRAL_NOTIFICATIONS_ENABLED=true REFERRAL_NOTIFICATION_RETRY_ATTEMPTS=3 # ===== АВТОПРОДЛЕНИЕ ===== AUTOPAY_WARNING_DAYS=3,1 DEFAULT_AUTOPAY_DAYS_BEFORE=3 MIN_BALANCE_FOR_AUTOPAY_KOPEKS=10000 # ===== ПЛАТЕЖНЫЕ СИСТЕМЫ ===== # Telegram Stars (работает автоматически) TELEGRAM_STARS_ENABLED=true TELEGRAM_STARS_RATE_RUB=1.3 # Tribute (https://tribute.app) TRIBUTE_ENABLED=false TRIBUTE_API_KEY= TRIBUTE_DONATE_LINK= TRIBUTE_WEBHOOK_PATH=/tribute-webhook TRIBUTE_WEBHOOK_PORT=8081 # YooKassa (https://yookassa.ru) YOOKASSA_ENABLED=false YOOKASSA_SHOP_ID= YOOKASSA_SECRET_KEY= YOOKASSA_RETURN_URL= YOOKASSA_DEFAULT_RECEIPT_EMAIL=receipts@yourdomain.com # Настройки чеков для налоговой YOOKASSA_VAT_CODE=1 # Коды НДС: # 1 - НДС не облагается # 2 - НДС 0% # 3 - НДС 10% # 4 - НДС 20% # 5 - НДС 10/110 # 6 - НДС 20/120 YOOKASSA_PAYMENT_MODE=full_payment # Способы расчета: # full_payment - полная оплата # partial_payment - частичная оплата # advance - аванс # full_prepayment - полная предоплата # partial_prepayment - частичная предоплата # credit - передача в кредит # credit_payment - оплата кредита YOOKASSA_PAYMENT_SUBJECT=service # Предметы расчета: # commodity - товар # excise - подакцизный товар # job - работа # service - услуга # gambling_bet - ставка в азартной игре # gambling_prize - выигрыш в азартной игре # lottery - лотерейный билет # lottery_prize - выигрыш в лотерее # intellectual_activity - результат интеллектуальной деятельности # payment - платеж # agent_commission - агентское вознаграждение # composite - составной предмет расчета # another - другое # Webhook настройки YOOKASSA_WEBHOOK_PATH=/yookassa-webhook YOOKASSA_WEBHOOK_PORT=8082 YOOKASSA_WEBHOOK_SECRET=your_webhook_secret # ===== НАСТРОЙКИ ОПИСАНИЙ ПЛАТЕЖЕЙ ===== # Эти настройки позволяют изменить описания платежей, ``` -------------------------------- ### WebSocket Manager Class Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/web-admin-integration-guide.md Класс для управления WebSocket подключением, включая обработку сообщений, автоматические повторные попытки подключения и управление слушателями событий. Используйте для поддержания real-time связи с сервером. ```typescript class WebSocketManager { private ws: WebSocket | null = null; private reconnectAttempts = 0; private maxReconnectAttempts = 5; private reconnectDelay = 1000; private listeners: Map> = new Map(); private apiToken: string; constructor(apiToken: string) { this.apiToken = apiToken; } connect(url: string): void { if (this.ws?.readyState === WebSocket.OPEN) { console.log('WebSocket already connected'); return; } const wsUrl = `${url}?token=${this.apiToken}`; this.ws = new WebSocket(wsUrl); this.ws.onopen = () => { console.log('WebSocket connected'); this.reconnectAttempts = 0; this.emit('connected', {}); }; this.ws.onmessage = (event) => { try { const data = JSON.parse(event.data); this.handleMessage(data); } catch (error) { console.error('Failed to parse WebSocket message:', error); } }; this.ws.onerror = (error) => { console.error('WebSocket error:', error); this.emit('error', { error }); }; this.ws.onclose = () => { console.log('WebSocket disconnected'); this.emit('disconnected', {}); this.attemptReconnect(url); }; // Ping для keepalive каждые 30 секунд setInterval(() => { if (this.ws?.readyState === WebSocket.OPEN) { this.ws.send(JSON.stringify({ type: 'ping' })); } }, 30000); } private handleMessage(data: any): void { if (data.type === 'pong') { return; // Игнорируем pong } if (data.type === 'connection') { this.emit('connection', data); return; } // Эмитим событие по типу this.emit(data.type, data.payload); } private attemptReconnect(url: string): void { if (this.reconnectAttempts >= this.maxReconnectAttempts) { console.error('Max reconnect attempts reached'); return; } this.reconnectAttempts++; const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1); setTimeout(() => { console.log(`Reconnecting... (attempt ${this.reconnectAttempts})`); this.connect(url); }, delay); } on(event: string, callback: Function): void { if (!this.listeners.has(event)) { this.listeners.set(event, new Set()); } this.listeners.get(event)!.add(callback); } off(event: string, callback: Function): void { const callbacks = this.listeners.get(event); if (callbacks) { callbacks.delete(callback); } } private emit(event: string, data: any): void { const callbacks = this.listeners.get(event); if (callbacks) { callbacks.forEach(callback => { try { callback(data); } catch (error) { console.error(`Error in event listener for ${event}:`, error); } }); } } disconnect(): void { if (this.ws) { this.ws.close(); this.ws = null; } } isConnected(): boolean { return this.ws?.readyState === WebSocket.OPEN; } } export default WebSocketManager; ``` -------------------------------- ### Swift Delivery and Finish Helper Function Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/apple-iap-ios-requirements.md This function handles the delivery of a verified purchase to the backend and the subsequent finishing of the StoreKit transaction. It includes logic for retries and error handling based on backend responses. ```swift func deliverAndFinish(_ transaction: Transaction) async { guard isSupportedTopUpProduct(transaction.productID) else { // Unknown product. Do not deliver and do not finish automatically. recordLocalPurchaseIssue(transaction) return } if let token = transaction.appAccountToken, let expected = try? await appleIAPAPI.cachedOrFetchedAccountToken(), token != expected { // Prevent cross-account delivery. recordLocalPurchaseIssue(transaction) return } persistPendingDelivery(transaction) do { let delivered = try await appleIAPAPI.deliverPurchase( productID: transaction.productID, transactionID: String(transaction.id) ) if delivered { removePendingDelivery(transaction) await transaction.finish() await balanceService.refreshBalance() showTopUpSuccess() } else { scheduleDeliveryRetry(transaction) showDeliveryPending() } } catch { scheduleDeliveryRetry(transaction) showDeliveryPending() } } ``` -------------------------------- ### Swift Models for Purchase Delivery Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/apple-iap-ios-requirements.md Recommended Swift structs for encoding the purchase delivery request and decoding the response. These models help structure the data exchanged with the backend. ```swift struct ApplePurchaseDeliveryRequest: Encodable { let productId: String let transactionId: String enum CodingKeys: String, CodingKey { case productId = "product_id" case transactionId = "transaction_id" } } struct ApplePurchaseDeliveryResponse: Decodable { let success: Bool } ``` -------------------------------- ### Настройка переменных окружения для веб-API Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/miniapp-setup.md Задайте переменные окружения для включения и настройки веб-API бота. Убедитесь, что WEB_API_ALLOWED_ORIGINS содержит домен мини-приложения, а WEB_API_DEFAULT_TOKEN используется для начальной авторизации. ```env WEB_API_ENABLED=true # включает FastAPI WEB_API_HOST=0.0.0.0 WEB_API_PORT=8080 WEB_API_ALLOWED_ORIGINS=https://miniapp.example.com WEB_API_DEFAULT_TOKEN=super-secret-token ``` -------------------------------- ### Проверка доступности административного API Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/miniapp-setup.md Используйте curl для проверки доступности административного API бота по HTTP или HTTPS, используя предоставленный токен. ```bash curl -H "X-API-Key: super-secret-token" https://miniapp.example.com/miniapp/health || \ curl -H "X-API-Key: super-secret-token" http://127.0.0.1:8080/health ``` -------------------------------- ### Создание и настройка директорий Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/wiki/1.-Установка-бота Создайте необходимые директории для логов и данных бота, а также установите соответствующие права доступа и владельца. ```bash mkdir -p ./logs ./data ./data/backups ./data/referral_qr chmod -R 755 ./logs ./data sudo chown -R 1000:1000 ./logs ./data ``` -------------------------------- ### Caddy Webhook Configuration Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/wiki/3.-Настройка-вебхуков Configure Caddy to proxy webhook requests for Tribute, CryptoBot, and YooKassa to their respective backend services. Ensure Caddy and the bot are on the same network for proxying to work. ```caddy your-domain.com { handle /tribute-webhook* { reverse_proxy localhost:8081 } handle /cryptobot-webhook* { reverse_proxy localhost:8081 } handle /yookassa-webhook* { reverse_proxy localhost:8082 } handle /health { reverse_proxy localhost:8081/health } } ``` -------------------------------- ### Selectable Traffic Selection Mode Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/wiki/7.-Режимы-продажи-трафика Set TRAFFIC_SELECTION_MODE to 'selectable' to allow users to choose their traffic packages. Configure available packages and their prices using TRAFFIC_PACKAGES_CONFIG. ```env TRAFFIC_SELECTION_MODE=selectable ``` ```env TRAFFIC_PACKAGES_CONFIG="5:2000:false,10:3500:false,25:7000:false,50:11000:true,100:15000:true,250:0:true,500:19000:false,1000:19500:true,0:20000:true" ``` -------------------------------- ### POST Request to Deliver Purchase Source: https://github.com/bedolaga-dev/remnawave-bedolaga-telegram-bot/blob/main/docs/apple-iap-ios-requirements.md This is the HTTP POST request structure for delivering a purchase to the backend after local verification. Ensure the Authorization header and Content-Type are correctly set. ```http POST /cabinet/apple-purchase Authorization: Bearer Content-Type: application/json Accept: application/json ```