# Claudible Installer for OpenClaw (Windows PowerShell 5.1+) # Configures OpenClaw Telegram AI bot to use Claudible # Compatible with Windows 10/11 (PowerShell 5.1) and PowerShell 7+ $ErrorActionPreference = "Stop" # Configuration (auto-populated by server) $ENDPOINT_URL = "https://claudible.io" $API_KEY = 'YOUR_KEY' $HAIKU_MODEL = "claude-haiku-4.5" $OPUS_MODEL = "claude-opus-4.6" $SONNET_MODEL = "claude-sonnet-4.6" $TELEGRAM_BOT_TOKEN = "" $TELEGRAM_USER_ID = "" Write-Host "================================" -ForegroundColor Blue Write-Host " OpenClaw Configuration" -ForegroundColor Blue Write-Host "================================" -ForegroundColor Blue Write-Host "" # Validate server-injected configuration if ($ENDPOINT_URL -eq "__" + "ENDPOINT_URL__" -or [string]::IsNullOrEmpty($ENDPOINT_URL)) { Write-Host "Error: Endpoint URL not configured" -ForegroundColor Red exit 1 } if ($API_KEY -eq "__" + "API_KEY__" -or [string]::IsNullOrEmpty($API_KEY)) { Write-Host "Error: API key not configured" -ForegroundColor Red exit 1 } # Mask API key for display $MASKED_KEY = $API_KEY.Substring(0, [Math]::Min(10, $API_KEY.Length)) Write-Host "Endpoint URL: " -NoNewline Write-Host "$ENDPOINT_URL" -ForegroundColor Green Write-Host "API Key: " -NoNewline Write-Host "$MASKED_KEY..." -ForegroundColor Green Write-Host "" # Prompt for Telegram Bot Token if not provided if ($TELEGRAM_BOT_TOKEN -eq "__" + "TELEGRAM_BOT_TOKEN__" -or [string]::IsNullOrEmpty($TELEGRAM_BOT_TOKEN)) { if (-not [Environment]::UserInteractive) { Write-Host "Error: No interactive session available." -ForegroundColor Red Write-Host "" Write-Host "Please pass bot token and user ID via URL query parameters:" -ForegroundColor Yellow Write-Host " irm `"$ENDPOINT_URL/openclaw-install.ps1?key=YOUR_KEY&bot=BOT_TOKEN&uid=USER_ID`" | iex" -ForegroundColor Blue exit 1 } while ($true) { $TELEGRAM_BOT_TOKEN = Read-Host "Enter Telegram Bot Token (from @BotFather)" if ([string]::IsNullOrWhiteSpace($TELEGRAM_BOT_TOKEN)) { Write-Host " Bot token cannot be empty." -ForegroundColor Red continue } if ($TELEGRAM_BOT_TOKEN -match '^[0-9]+:[A-Za-z0-9_-]+$') { break } else { Write-Host " Invalid format. Expected: 123456789:ABCDefGhIjK..." -ForegroundColor Red } } } # Prompt for Telegram User ID if not provided if ($TELEGRAM_USER_ID -eq "__" + "TELEGRAM_USER_ID__" -or [string]::IsNullOrEmpty($TELEGRAM_USER_ID)) { if (-not [Environment]::UserInteractive) { Write-Host "Error: No interactive session available." -ForegroundColor Red Write-Host "" Write-Host "Please pass user ID via URL query parameters:" -ForegroundColor Yellow Write-Host " irm `"$ENDPOINT_URL/openclaw-install.ps1?key=YOUR_KEY&bot=BOT_TOKEN&uid=USER_ID`" | iex" -ForegroundColor Blue exit 1 } while ($true) { $TELEGRAM_USER_ID = Read-Host "Enter Telegram User ID (numeric)" if ([string]::IsNullOrWhiteSpace($TELEGRAM_USER_ID)) { Write-Host " User ID cannot be empty." -ForegroundColor Red continue } if ($TELEGRAM_USER_ID -match '^[0-9]+$') { break } else { Write-Host " Invalid format. User ID must be numeric (e.g., 123456789)." -ForegroundColor Red } } } Write-Host "" $MASKED_BOT = if ($TELEGRAM_BOT_TOKEN.Length -gt 12) { $TELEGRAM_BOT_TOKEN.Substring(0, 8) + "..." + $TELEGRAM_BOT_TOKEN.Substring($TELEGRAM_BOT_TOKEN.Length - 4) } else { $TELEGRAM_BOT_TOKEN.Substring(0, [Math]::Min(4, $TELEGRAM_BOT_TOKEN.Length)) + "..." } Write-Host "Bot Token: " -NoNewline Write-Host "$MASKED_BOT" -ForegroundColor Green Write-Host "User ID: " -NoNewline Write-Host "$TELEGRAM_USER_ID" -ForegroundColor Green Write-Host "" # Define paths $configDir = Join-Path $env:USERPROFILE ".openclaw" $configPath = Join-Path $configDir "config.json" # Try to read existing gateway token, generate new if not found $GATEWAY_TOKEN = "" if (Test-Path $configPath) { try { $existingConfig = Get-Content $configPath -Raw | ConvertFrom-Json if ($existingConfig.gateway.auth.token) { $GATEWAY_TOKEN = $existingConfig.gateway.auth.token } } catch { # Ignore parse errors, will generate new token } } if (-not $GATEWAY_TOKEN) { $rngBytes = New-Object byte[] 16 $rng = [System.Security.Cryptography.RandomNumberGenerator]::Create() $rng.GetBytes($rngBytes) $GATEWAY_TOKEN = ($rngBytes | ForEach-Object { $_.ToString("x2") }) -join "" $rng.Dispose() } # Create config directory if (-not (Test-Path $configDir)) { New-Item -ItemType Directory -Path $configDir -Force | Out-Null } # Backup existing config if (Test-Path $configPath) { $backupPath = "$configPath.backup.$(Get-Date -Format 'yyyyMMddHHmmss')" Copy-Item $configPath $backupPath Write-Host "Backed up existing config: $backupPath" -ForegroundColor Yellow } # Build base URL with /v1 $BASE_API_URL = "$ENDPOINT_URL/v1" # Build config object Write-Host "Generating config..." -ForegroundColor Blue $config = @{ env = @{ TELEGRAM_BOT_TOKEN = $TELEGRAM_BOT_TOKEN } models = @{ providers = @{ claudible = @{ baseUrl = $BASE_API_URL apiKey = $API_KEY api = "openai-completions" models = @( @{ id = $SONNET_MODEL name = "Claude Sonnet 4.6" api = "openai-completions" reasoning = $false input = @("text", "image") cost = @{ input = 0; output = 0; cacheRead = 0; cacheWrite = 0 } contextWindow = 200000 maxTokens = 16384 } @{ id = $OPUS_MODEL name = "Claude Opus 4.6" api = "openai-completions" reasoning = $false input = @("text", "image") cost = @{ input = 0; output = 0; cacheRead = 0; cacheWrite = 0 } contextWindow = 200000 maxTokens = 16384 } @{ id = $HAIKU_MODEL name = "Claude Haiku 4.5" api = "openai-completions" reasoning = $false input = @("text", "image") cost = @{ input = 0; output = 0; cacheRead = 0; cacheWrite = 0 } contextWindow = 200000 maxTokens = 16384 } ) } } } agents = @{ defaults = @{ model = @{ primary = "claudible/$OPUS_MODEL" } maxConcurrent = 4 subagents = @{ maxConcurrent = 8 } } } messages = @{ ackReactionScope = "group-mentions" } commands = @{ native = "auto" nativeSkills = "auto" } channels = @{ telegram = @{ enabled = $true dmPolicy = "pairing" allowFrom = @($TELEGRAM_USER_ID) groupPolicy = "allowlist" streamMode = "block" } } gateway = @{ port = 18789 mode = "local" bind = "loopback" auth = @{ mode = "token" token = $GATEWAY_TOKEN } tailscale = @{ mode = "off" resetOnExit = $false } } plugins = @{ entries = @{ telegram = @{ enabled = $true } } } } # Convert to JSON and write (UTF-8 without BOM) $jsonContent = $config | ConvertTo-Json -Depth 10 [System.IO.File]::WriteAllText($configPath, $jsonContent, [System.Text.UTF8Encoding]::new($false)) # Restrict file permissions to current user only $acl = Get-Acl $configPath $acl.SetAccessRuleProtection($true, $false) $acl.Access | ForEach-Object { $acl.RemoveAccessRule($_) } | Out-Null $rule = New-Object System.Security.AccessControl.FileSystemAccessRule( [System.Security.Principal.WindowsIdentity]::GetCurrent().Name, "FullControl", "Allow") $acl.AddAccessRule($rule) Set-Acl $configPath $acl Write-Host " " -NoNewline Write-Host "OK" -ForegroundColor Green -NoNewline Write-Host " Created $configPath" Write-Host "" Write-Host "================================" -ForegroundColor Green Write-Host " Configuration Complete!" -ForegroundColor Green Write-Host "================================" -ForegroundColor Green Write-Host "" Write-Host "OpenClaw is configured to use Claudible:" Write-Host " Config: " -NoNewline Write-Host "$configPath" -ForegroundColor Blue Write-Host " Endpoint: " -NoNewline Write-Host "$BASE_API_URL" -ForegroundColor Blue Write-Host " API Key: " -NoNewline Write-Host "$MASKED_KEY..." -ForegroundColor Blue Write-Host " Bot: " -NoNewline Write-Host "$MASKED_BOT" -ForegroundColor Blue Write-Host " User ID: " -NoNewline Write-Host "$TELEGRAM_USER_ID" -ForegroundColor Blue Write-Host "" # Auto-restart gateway if (Get-Command openclaw -ErrorAction SilentlyContinue) { Write-Host "Restarting gateway..." -ForegroundColor Blue try { openclaw gateway restart 2>$null Write-Host " Gateway restarted successfully" -ForegroundColor Green } catch { Write-Host " Gateway restart failed. You may need to restart manually:" -ForegroundColor Yellow Write-Host " openclaw gateway restart" -ForegroundColor Blue } } else { Write-Host "Note: openclaw not found on PATH. Please restart the gateway manually:" -ForegroundColor Yellow Write-Host " openclaw gateway restart" -ForegroundColor Blue } Write-Host "" Write-Host "Next steps:" -ForegroundColor Yellow Write-Host " 1. Open Telegram and send a message to your bot" Write-Host "" Write-Host " Documentation: " -NoNewline Write-Host "$ENDPOINT_URL/docs/openclaw" -ForegroundColor Blue Write-Host ""