Initial commit: ROA2WEB - FastAPI + Vue.js + Telegram Bot
Modern ERP Reports Application with microservices architecture Tech Stack: - Backend: FastAPI + python-oracledb (Oracle DB integration) - Frontend: Vue.js 3 + PrimeVue + Vite - Telegram Bot: python-telegram-bot + SQLite - Infrastructure: Shared database pool, JWT authentication, SSH tunnel Features: - FastAPI backend with async Oracle connection pool - Vue.js 3 responsive frontend with PrimeVue components - Telegram bot alternative interface - Microservices architecture with shared components - Complete deployment support (Linux Docker + Windows IIS) - Comprehensive testing (Playwright E2E + pytest) Repository Structure: - reports-app/ - Main application (backend, frontend, telegram-bot) - shared/ - Shared components (database pool, auth, utils) - deployment/ - Deployment scripts (Linux & Windows) - docs/ - Project documentation - security/ - Security scanning and git hooks
This commit is contained in:
633
deployment/windows/scripts/Install-TelegramBot.ps1
Normal file
633
deployment/windows/scripts/Install-TelegramBot.ps1
Normal file
@@ -0,0 +1,633 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
ROA2WEB Telegram Bot - Installation Script for Windows Server
|
||||
|
||||
.DESCRIPTION
|
||||
This script performs complete installation of ROA2WEB Telegram Bot on Windows Server:
|
||||
- Checks prerequisites (Admin rights, Python)
|
||||
- Installs NSSM (service manager) if needed
|
||||
- Creates directory structure
|
||||
- Installs Python dependencies
|
||||
- Creates Windows Service for Telegram bot
|
||||
- Configures internal API
|
||||
- Starts service
|
||||
|
||||
.PARAMETER InstallPath
|
||||
Installation path (default: C:\inetpub\wwwroot\roa2web\telegram-bot)
|
||||
|
||||
.PARAMETER ServicePort
|
||||
Internal API service port (default: 8002)
|
||||
|
||||
.PARAMETER SourcePath
|
||||
Source path for deployment package (auto-detected if run from scripts/ directory)
|
||||
|
||||
.PARAMETER SkipPython
|
||||
Skip Python installation check (use existing Python)
|
||||
|
||||
.EXAMPLE
|
||||
.\Install-TelegramBot.ps1
|
||||
Standard installation with defaults (auto-detects source from scripts/ directory)
|
||||
|
||||
.EXAMPLE
|
||||
.\Install-TelegramBot.ps1 -InstallPath "D:\Apps\roa2web\telegram-bot" -ServicePort 8003
|
||||
Custom installation path and port
|
||||
|
||||
.EXAMPLE
|
||||
.\Install-TelegramBot.ps1 -SourcePath "C:\Deploy\telegram-bot"
|
||||
Install from specific source path
|
||||
|
||||
.NOTES
|
||||
Author: ROA2WEB Team
|
||||
Requires: PowerShell 5.1+, Administrator privileges, Python 3.11+
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$InstallPath = "C:\inetpub\wwwroot\roa2web\telegram-bot",
|
||||
[int]$ServicePort = 8002,
|
||||
[string]$SourcePath = "",
|
||||
[switch]$SkipPython
|
||||
)
|
||||
|
||||
# Strict error handling
|
||||
$ErrorActionPreference = "Stop"
|
||||
$ProgressPreference = "SilentlyContinue"
|
||||
|
||||
# =============================================================================
|
||||
# CONFIGURATION
|
||||
# =============================================================================
|
||||
|
||||
# Auto-detect source path: if running from scripts/ subdirectory, use parent
|
||||
$detectedSourcePath = if ($SourcePath) {
|
||||
$SourcePath
|
||||
} elseif ((Split-Path $PSScriptRoot -Leaf) -eq "scripts") {
|
||||
Split-Path $PSScriptRoot -Parent
|
||||
} else {
|
||||
$PSScriptRoot
|
||||
}
|
||||
|
||||
$script:Config = @{
|
||||
AppName = "ROA2WEB-TelegramBot"
|
||||
ServiceName = "ROA2WEB-TelegramBot"
|
||||
ServiceDisplayName = "ROA2WEB Telegram Bot Service"
|
||||
ServiceDescription = "Telegram bot frontend for ROA2WEB with Claude Agent SDK"
|
||||
InstallPath = $InstallPath
|
||||
DataPath = Join-Path $InstallPath "data"
|
||||
LogsPath = Join-Path $InstallPath "logs"
|
||||
TempPath = Join-Path $InstallPath "temp"
|
||||
BackupPath = Join-Path $InstallPath "backups"
|
||||
ServicePort = $ServicePort
|
||||
SourcePath = $detectedSourcePath
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# HELPER FUNCTIONS
|
||||
# =============================================================================
|
||||
|
||||
function Write-Step {
|
||||
param([string]$Message)
|
||||
Write-Host "`n[*] $Message" -ForegroundColor Cyan
|
||||
}
|
||||
|
||||
function Write-Success {
|
||||
param([string]$Message)
|
||||
Write-Host " [OK] $Message" -ForegroundColor Green
|
||||
}
|
||||
|
||||
function Write-Error {
|
||||
param([string]$Message)
|
||||
Write-Host " [ERROR] $Message" -ForegroundColor Red
|
||||
}
|
||||
|
||||
function Write-Warning {
|
||||
param([string]$Message)
|
||||
Write-Host " [WARN] $Message" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
function Test-Administrator {
|
||||
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
|
||||
$principal = [Security.Principal.WindowsPrincipal]$identity
|
||||
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||
}
|
||||
|
||||
function Test-CommandExists {
|
||||
param([string]$Command)
|
||||
try {
|
||||
if (Get-Command $Command -ErrorAction Stop) {
|
||||
return $true
|
||||
}
|
||||
} catch {
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function Test-PythonInstallation {
|
||||
Write-Step "Checking Python installation..."
|
||||
|
||||
if ($SkipPython) {
|
||||
Write-Warning "Skipping Python check (as requested)"
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
$pythonCmd = Get-Command python -ErrorAction Stop
|
||||
$pythonVersionOutput = & python --version 2>&1
|
||||
if ($pythonVersionOutput -match "Python (\d+\.\d+\.\d+)") {
|
||||
$installedVersion = $matches[1]
|
||||
$versionParts = $installedVersion -split '\.'
|
||||
$major = [int]$versionParts[0]
|
||||
$minor = [int]$versionParts[1]
|
||||
|
||||
if ($major -ge 3 -and $minor -ge 11) {
|
||||
Write-Success "Python $installedVersion found at $($pythonCmd.Source)"
|
||||
return
|
||||
} else {
|
||||
throw "Python 3.11+ required, found $installedVersion"
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Write-Error "Python 3.11+ not found. Please install Python first."
|
||||
Write-Host " Download from: https://www.python.org/downloads/" -ForegroundColor Yellow
|
||||
throw "Python not installed"
|
||||
}
|
||||
}
|
||||
|
||||
function Copy-ApplicationFiles {
|
||||
Write-Step "Copying application files from deployment package..."
|
||||
|
||||
$sourceApp = Join-Path $Config.SourcePath "app"
|
||||
$sourceReq = Join-Path $Config.SourcePath "requirements.txt"
|
||||
$sourceScripts = Join-Path $Config.SourcePath "scripts"
|
||||
|
||||
# Validate source files exist
|
||||
if (-not (Test-Path $sourceApp)) {
|
||||
Write-Warning "Source app directory not found: $sourceApp"
|
||||
Write-Warning "You may need to copy application files manually"
|
||||
return $false
|
||||
}
|
||||
|
||||
if (-not (Test-Path $sourceReq)) {
|
||||
Write-Warning "Source requirements.txt not found: $sourceReq"
|
||||
Write-Warning "You may need to copy requirements.txt manually"
|
||||
return $false
|
||||
}
|
||||
|
||||
try {
|
||||
# Copy app directory
|
||||
$destApp = Join-Path $Config.InstallPath "app"
|
||||
if (Test-Path $destApp) {
|
||||
Write-Warning "App directory already exists, removing..."
|
||||
Remove-Item -Path $destApp -Recurse -Force
|
||||
}
|
||||
|
||||
Copy-Item -Path $sourceApp -Destination $destApp -Recurse -Force
|
||||
Write-Success "Application files copied"
|
||||
|
||||
# Copy requirements.txt
|
||||
$destReq = Join-Path $Config.InstallPath "requirements.txt"
|
||||
Copy-Item -Path $sourceReq -Destination $destReq -Force
|
||||
Write-Success "requirements.txt copied"
|
||||
|
||||
# Copy .env.example if exists (but don't overwrite .env)
|
||||
$sourceEnvExample = Join-Path $Config.SourcePath ".env.example"
|
||||
if (Test-Path $sourceEnvExample) {
|
||||
$destEnvExample = Join-Path $Config.InstallPath ".env.example"
|
||||
Copy-Item -Path $sourceEnvExample -Destination $destEnvExample -Force
|
||||
Write-Success ".env.example copied"
|
||||
}
|
||||
|
||||
# Copy management scripts (but exclude installation/deployment scripts)
|
||||
if (Test-Path $sourceScripts) {
|
||||
$destScripts = Join-Path $Config.InstallPath "scripts"
|
||||
if (-not (Test-Path $destScripts)) {
|
||||
New-Item -ItemType Directory -Path $destScripts -Force | Out-Null
|
||||
}
|
||||
|
||||
# List of management scripts to copy
|
||||
$managementScripts = @(
|
||||
"Start-TelegramBot.ps1",
|
||||
"Stop-TelegramBot.ps1",
|
||||
"Restart-TelegramBot.ps1",
|
||||
"Backup-TelegramDB.ps1",
|
||||
"Setup-DailyBackup.ps1",
|
||||
"Setup-ClaudeAuth.ps1"
|
||||
)
|
||||
|
||||
$copiedScriptsCount = 0
|
||||
foreach ($script in $managementScripts) {
|
||||
$sourcePath = Join-Path $sourceScripts $script
|
||||
if (Test-Path $sourcePath) {
|
||||
$destPath = Join-Path $destScripts $script
|
||||
Copy-Item -Path $sourcePath -Destination $destPath -Force
|
||||
$copiedScriptsCount++
|
||||
}
|
||||
}
|
||||
|
||||
if ($copiedScriptsCount -gt 0) {
|
||||
Write-Success "Copied $copiedScriptsCount management scripts to scripts/ directory"
|
||||
} else {
|
||||
Write-Warning "No management scripts found to copy"
|
||||
}
|
||||
} else {
|
||||
Write-Warning "Source scripts directory not found: $sourceScripts"
|
||||
}
|
||||
|
||||
return $true
|
||||
} catch {
|
||||
Write-Error "Failed to copy application files: $_"
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function Install-NSSM {
|
||||
Write-Step "Installing NSSM (service manager)..."
|
||||
|
||||
if (Test-Path "C:\nssm\nssm.exe") {
|
||||
Write-Success "NSSM already installed"
|
||||
return
|
||||
}
|
||||
|
||||
# Check if Chocolatey is available
|
||||
if (Test-CommandExists "choco") {
|
||||
try {
|
||||
choco install nssm -y
|
||||
Write-Success "NSSM installed via Chocolatey"
|
||||
return
|
||||
} catch {
|
||||
Write-Warning "Chocolatey installation failed, trying direct download..."
|
||||
}
|
||||
}
|
||||
|
||||
# Direct download as fallback
|
||||
try {
|
||||
$nssmUrl = "https://nssm.cc/release/nssm-2.24.zip"
|
||||
$nssmZip = "$env:TEMP\nssm.zip"
|
||||
$nssmExtract = "$env:TEMP\nssm"
|
||||
|
||||
Write-Step "Downloading NSSM..."
|
||||
Invoke-WebRequest -Uri $nssmUrl -OutFile $nssmZip
|
||||
|
||||
Write-Step "Extracting NSSM..."
|
||||
Expand-Archive -Path $nssmZip -DestinationPath $nssmExtract -Force
|
||||
|
||||
# Copy nssm.exe to C:\nssm
|
||||
New-Item -ItemType Directory -Path "C:\nssm" -Force | Out-Null
|
||||
Copy-Item -Path "$nssmExtract\nssm-2.24\win64\nssm.exe" -Destination "C:\nssm\nssm.exe" -Force
|
||||
|
||||
# Add to PATH
|
||||
$currentPath = [Environment]::GetEnvironmentVariable("Path", "Machine")
|
||||
if ($currentPath -notlike "*C:\nssm*") {
|
||||
[Environment]::SetEnvironmentVariable("Path", "$currentPath;C:\nssm", "Machine")
|
||||
$env:Path += ";C:\nssm"
|
||||
}
|
||||
|
||||
# Cleanup
|
||||
Remove-Item $nssmZip -Force
|
||||
Remove-Item $nssmExtract -Recurse -Force
|
||||
|
||||
Write-Success "NSSM installed successfully"
|
||||
} catch {
|
||||
throw "Failed to install NSSM: $_"
|
||||
}
|
||||
}
|
||||
|
||||
function New-DirectoryStructure {
|
||||
Write-Step "Creating directory structure..."
|
||||
|
||||
$directories = @(
|
||||
$Config.InstallPath,
|
||||
(Join-Path $Config.InstallPath "app"),
|
||||
$Config.DataPath,
|
||||
$Config.LogsPath,
|
||||
$Config.TempPath,
|
||||
$Config.BackupPath
|
||||
)
|
||||
|
||||
foreach ($dir in $directories) {
|
||||
if (-not (Test-Path $dir)) {
|
||||
New-Item -ItemType Directory -Path $dir -Force | Out-Null
|
||||
Write-Success "Created: $dir"
|
||||
} else {
|
||||
Write-Success "Already exists: $dir"
|
||||
}
|
||||
}
|
||||
|
||||
# Set permissions (service needs full access to data, logs, backups)
|
||||
try {
|
||||
$acl = Get-Acl $Config.InstallPath
|
||||
|
||||
# Grant SYSTEM full control
|
||||
$systemRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
|
||||
"SYSTEM", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow"
|
||||
)
|
||||
$acl.SetAccessRule($systemRule)
|
||||
|
||||
# Grant Administrators full control
|
||||
$adminRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
|
||||
"Administrators", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow"
|
||||
)
|
||||
$acl.SetAccessRule($adminRule)
|
||||
|
||||
Set-Acl -Path $Config.InstallPath -AclObject $acl
|
||||
Write-Success "Permissions set for SYSTEM and Administrators"
|
||||
} catch {
|
||||
Write-Warning "Could not set permissions: $_"
|
||||
}
|
||||
}
|
||||
|
||||
function Install-PythonDependencies {
|
||||
Write-Step "Installing Python dependencies..."
|
||||
|
||||
$requirementsPath = Join-Path $Config.InstallPath "requirements.txt"
|
||||
|
||||
if (-not (Test-Path $requirementsPath)) {
|
||||
Write-Warning "requirements.txt not found at $requirementsPath"
|
||||
Write-Warning "Please copy application files first, then run: pip install -r requirements.txt"
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
# Create virtual environment
|
||||
$venvPath = Join-Path $Config.InstallPath "venv"
|
||||
|
||||
if (-not (Test-Path $venvPath)) {
|
||||
Write-Step "Creating virtual environment..."
|
||||
& python -m venv $venvPath
|
||||
Write-Success "Virtual environment created"
|
||||
} else {
|
||||
Write-Success "Virtual environment already exists"
|
||||
}
|
||||
|
||||
# Activate and install dependencies
|
||||
$pipPath = Join-Path $venvPath "Scripts\pip.exe"
|
||||
$pythonPath = Join-Path $venvPath "Scripts\python.exe"
|
||||
|
||||
Write-Step "Upgrading pip..."
|
||||
& $pythonPath -m pip install --upgrade pip
|
||||
|
||||
Write-Step "Installing dependencies..."
|
||||
& $pipPath install -r $requirementsPath
|
||||
|
||||
Write-Success "Python dependencies installed successfully"
|
||||
} catch {
|
||||
throw "Failed to install Python dependencies: $_"
|
||||
}
|
||||
}
|
||||
|
||||
function New-WindowsService {
|
||||
Write-Step "Creating Windows Service for Telegram bot..."
|
||||
|
||||
# Check if service already exists
|
||||
$oldErrorAction = $ErrorActionPreference
|
||||
$ErrorActionPreference = "SilentlyContinue"
|
||||
|
||||
$nssmOutput = & nssm status $Config.ServiceName 2>&1
|
||||
$serviceExists = $LASTEXITCODE -eq 0
|
||||
|
||||
$ErrorActionPreference = $oldErrorAction
|
||||
|
||||
if ($serviceExists) {
|
||||
Write-Warning "Service already exists, stopping and removing..."
|
||||
& nssm stop $Config.ServiceName 2>&1 | Out-Null
|
||||
Start-Sleep -Seconds 2
|
||||
& nssm remove $Config.ServiceName confirm 2>&1 | Out-Null
|
||||
Start-Sleep -Seconds 2
|
||||
Write-Success "Existing service removed"
|
||||
}
|
||||
|
||||
# Get Python path from virtual environment
|
||||
$venvPath = Join-Path $Config.InstallPath "venv"
|
||||
$pythonPath = Join-Path $venvPath "Scripts\python.exe"
|
||||
|
||||
if (-not (Test-Path $pythonPath)) {
|
||||
throw "Virtual environment not found. Please run Install-PythonDependencies first."
|
||||
}
|
||||
|
||||
$appModule = "-m"
|
||||
$appMain = "app.main"
|
||||
|
||||
# NSSM service creation
|
||||
try {
|
||||
# Install service
|
||||
& nssm install $Config.ServiceName $pythonPath $appModule $appMain
|
||||
|
||||
# Set service configuration
|
||||
& nssm set $Config.ServiceName DisplayName $Config.ServiceDisplayName
|
||||
& nssm set $Config.ServiceName Description $Config.ServiceDescription
|
||||
& nssm set $Config.ServiceName Start SERVICE_AUTO_START
|
||||
& nssm set $Config.ServiceName AppDirectory $Config.InstallPath
|
||||
|
||||
# Set environment variables
|
||||
$envFile = Join-Path $Config.InstallPath ".env"
|
||||
if (Test-Path $envFile) {
|
||||
& nssm set $Config.ServiceName AppEnvironmentExtra "PYTHONPATH=$($Config.InstallPath)"
|
||||
Write-Success ".env file will be loaded by application"
|
||||
} else {
|
||||
Write-Warning ".env file not found - create it before starting service"
|
||||
}
|
||||
|
||||
# Set logging
|
||||
$stdoutLog = Join-Path $Config.LogsPath "stdout.log"
|
||||
$stderrLog = Join-Path $Config.LogsPath "stderr.log"
|
||||
& nssm set $Config.ServiceName AppStdout $stdoutLog
|
||||
& nssm set $Config.ServiceName AppStderr $stderrLog
|
||||
& nssm set $Config.ServiceName AppStdoutCreationDisposition 4
|
||||
& nssm set $Config.ServiceName AppStderrCreationDisposition 4
|
||||
|
||||
# Set restart policy (important for bot reliability)
|
||||
& nssm set $Config.ServiceName AppExit Default Restart
|
||||
& nssm set $Config.ServiceName AppRestartDelay 5000
|
||||
& nssm set $Config.ServiceName AppThrottle 10000
|
||||
|
||||
Write-Success "Windows Service created successfully"
|
||||
} catch {
|
||||
throw "Failed to create Windows Service: $_"
|
||||
}
|
||||
}
|
||||
|
||||
function New-ConfigurationFile {
|
||||
Write-Step "Creating configuration template..."
|
||||
|
||||
$envExample = Join-Path $Config.InstallPath ".env.example"
|
||||
$envFile = Join-Path $Config.InstallPath ".env"
|
||||
|
||||
# Create .env.example template
|
||||
$envTemplate = @"
|
||||
# ROA2WEB Telegram Bot - Production Configuration
|
||||
|
||||
# Telegram Bot Configuration
|
||||
TELEGRAM_BOT_TOKEN=your_production_bot_token_here
|
||||
|
||||
# Claude Authentication Configuration
|
||||
# =====================================
|
||||
# Two authentication methods are supported:
|
||||
#
|
||||
# Method 1: Claude Pro/Max Subscription (RECOMMENDED)
|
||||
# - Leave CLAUDE_API_KEY empty or remove the line
|
||||
# - Run: scripts\Setup-ClaudeAuth.ps1
|
||||
# - Authenticate via browser with your Claude Pro/Max account
|
||||
# - No additional costs!
|
||||
#
|
||||
# Method 2: Claude API Key (Alternative)
|
||||
# - Get API key from: https://console.anthropic.com/settings/keys
|
||||
# - Set CLAUDE_API_KEY below
|
||||
# - This will take precedence over browser login
|
||||
# - Usage-based billing applies
|
||||
#
|
||||
# Leave empty to use Claude Pro/Max subscription:
|
||||
CLAUDE_API_KEY=
|
||||
|
||||
# Backend API Configuration
|
||||
BACKEND_URL=http://localhost:8000
|
||||
BACKEND_TIMEOUT=30
|
||||
|
||||
# SQLite Database Configuration
|
||||
SQLITE_DB_PATH=$($Config.DataPath -replace '\\', '\\')\telegram_bot.db
|
||||
|
||||
# Internal API Configuration (for backend callbacks)
|
||||
INTERNAL_API_HOST=127.0.0.1
|
||||
INTERNAL_API_PORT=$($Config.ServicePort)
|
||||
|
||||
# Logging Configuration
|
||||
LOG_LEVEL=INFO
|
||||
LOG_FILE=$($Config.LogsPath -replace '\\', '\\')\bot.log
|
||||
|
||||
# Environment
|
||||
ENVIRONMENT=production
|
||||
|
||||
# Authentication Configuration
|
||||
AUTH_CODE_EXPIRY_MINUTES=15
|
||||
JWT_REFRESH_THRESHOLD_MINUTES=5
|
||||
|
||||
# Session Configuration
|
||||
SESSION_TIMEOUT_MINUTES=60
|
||||
MAX_CONVERSATION_HISTORY=20
|
||||
"@
|
||||
|
||||
# Write .env.example
|
||||
Set-Content -Path $envExample -Value $envTemplate -Encoding UTF8
|
||||
Write-Success "Created .env.example template"
|
||||
|
||||
# Copy to .env if it doesn't exist
|
||||
if (-not (Test-Path $envFile)) {
|
||||
Copy-Item -Path $envExample -Destination $envFile
|
||||
Write-Warning "Created .env file - PLEASE UPDATE WITH PRODUCTION VALUES"
|
||||
Write-Host " Edit: $envFile" -ForegroundColor Yellow
|
||||
} else {
|
||||
Write-Success ".env file already exists (not overwriting)"
|
||||
}
|
||||
}
|
||||
|
||||
function Test-ServiceHealth {
|
||||
Write-Step "Testing service health..."
|
||||
|
||||
Start-Sleep -Seconds 5
|
||||
|
||||
try {
|
||||
$response = Invoke-WebRequest -Uri "http://localhost:$($Config.ServicePort)/internal/health" -UseBasicParsing -TimeoutSec 10
|
||||
if ($response.StatusCode -eq 200) {
|
||||
$content = $response.Content | ConvertFrom-Json
|
||||
Write-Success "Health check passed: $($content.status)"
|
||||
return $true
|
||||
}
|
||||
} catch {
|
||||
Write-Warning "Health check failed (service may need configuration): $_"
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function Show-Summary {
|
||||
Write-Host "`n" + ("=" * 80) -ForegroundColor Cyan
|
||||
Write-Host " ROA2WEB TELEGRAM BOT INSTALLATION COMPLETED" -ForegroundColor Green
|
||||
Write-Host ("=" * 80) -ForegroundColor Cyan
|
||||
|
||||
Write-Host "`nInstallation Details:" -ForegroundColor Yellow
|
||||
Write-Host " Source Path: $($Config.SourcePath)"
|
||||
Write-Host " Install Path: $($Config.InstallPath)"
|
||||
Write-Host " Scripts Path: $($Config.InstallPath)\scripts\"
|
||||
Write-Host " Data Path: $($Config.DataPath)"
|
||||
Write-Host " Logs Path: $($Config.LogsPath)"
|
||||
Write-Host " Backup Path: $($Config.BackupPath)"
|
||||
Write-Host " Service Name: $($Config.ServiceName)"
|
||||
Write-Host " Internal API Port: $($Config.ServicePort)"
|
||||
|
||||
Write-Host "`nService Endpoints:" -ForegroundColor Yellow
|
||||
Write-Host " Health Check: http://localhost:$($Config.ServicePort)/internal/health"
|
||||
Write-Host " Stats: http://localhost:$($Config.ServicePort)/internal/stats"
|
||||
|
||||
Write-Host "`nNext Steps:" -ForegroundColor Yellow
|
||||
Write-Host " 1. Edit configuration: $($Config.InstallPath)\.env"
|
||||
Write-Host " - Set TELEGRAM_BOT_TOKEN (from @BotFather)"
|
||||
Write-Host " - Set CLAUDE_API_KEY (from Anthropic console)"
|
||||
Write-Host " - Verify BACKEND_URL=http://localhost:8000"
|
||||
Write-Host " 2. Navigate to scripts: cd $($Config.InstallPath)\scripts"
|
||||
Write-Host " 3. Start service: .\Start-TelegramBot.ps1"
|
||||
Write-Host " 4. Check logs: Get-Content $($Config.LogsPath)\stdout.log -Tail 50"
|
||||
|
||||
Write-Host "`nManagement Scripts Location:" -ForegroundColor Yellow
|
||||
Write-Host " $($Config.InstallPath)\scripts\"
|
||||
|
||||
Write-Host "`nManagement Commands:" -ForegroundColor Yellow
|
||||
Write-Host " cd $($Config.InstallPath)\scripts"
|
||||
Write-Host " .\Start-TelegramBot.ps1 # Start service"
|
||||
Write-Host " .\Stop-TelegramBot.ps1 # Stop service"
|
||||
Write-Host " .\Restart-TelegramBot.ps1 # Restart service"
|
||||
Write-Host " .\Backup-TelegramDB.ps1 # Backup database"
|
||||
Write-Host " .\Setup-DailyBackup.ps1 # Setup automated daily backups"
|
||||
|
||||
Write-Host "`n" + ("=" * 80) -ForegroundColor Cyan
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# MAIN INSTALLATION FLOW
|
||||
# =============================================================================
|
||||
|
||||
function Main {
|
||||
Write-Host @"
|
||||
|
||||
====================================================================
|
||||
ROA2WEB Telegram Bot - Windows Server Installation Script
|
||||
Telegram Bot Frontend with Claude Agent SDK
|
||||
====================================================================
|
||||
|
||||
"@ -ForegroundColor Cyan
|
||||
|
||||
# Check prerequisites
|
||||
Write-Step "Checking prerequisites..."
|
||||
|
||||
if (-not (Test-Administrator)) {
|
||||
Write-Error "This script must be run as Administrator"
|
||||
Write-Host " Right-click PowerShell and select 'Run as Administrator'" -ForegroundColor Yellow
|
||||
exit 1
|
||||
}
|
||||
Write-Success "Running as Administrator"
|
||||
|
||||
try {
|
||||
# Installation steps
|
||||
Test-PythonInstallation
|
||||
Install-NSSM
|
||||
New-DirectoryStructure
|
||||
|
||||
# Copy application files from deployment package
|
||||
$filesCopied = Copy-ApplicationFiles
|
||||
if (-not $filesCopied) {
|
||||
throw "Failed to copy application files. Please ensure you're running this script from the deployment package directory."
|
||||
}
|
||||
|
||||
Install-PythonDependencies
|
||||
New-ConfigurationFile
|
||||
New-WindowsService
|
||||
Show-Summary
|
||||
|
||||
Write-Host "`nInstallation completed successfully!" -ForegroundColor Green
|
||||
Write-Host "IMPORTANT: Configure .env file before starting service" -ForegroundColor Yellow
|
||||
|
||||
} catch {
|
||||
Write-Host "`n[FATAL ERROR] Installation failed: $_" -ForegroundColor Red
|
||||
Write-Host $_.ScriptStackTrace -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
# Run main installation
|
||||
Main
|
||||
Reference in New Issue
Block a user