diff --git a/packages/cli/src/shared/agent-setup.ts b/packages/cli/src/shared/agent-setup.ts index 8881c0cc..b1fd59fa 100644 --- a/packages/cli/src/shared/agent-setup.ts +++ b/packages/cli/src/shared/agent-setup.ts @@ -9,7 +9,7 @@ import { join } from "node:path"; import { getTmpDir } from "./paths"; import { asyncTryCatch, asyncTryCatchIf, isOperationalError, tryCatchIf } from "./result.js"; import { getErrorMessage } from "./type-guards"; -import { Err, jsonEscape, logError, logInfo, logStep, logWarn, Ok, prompt, shellQuote, withRetry } from "./ui"; +import { Err, jsonEscape, logError, logInfo, logStep, logWarn, Ok, shellQuote, withRetry } from "./ui"; /** * Wrap an SSH-based async operation into a Result for use with withRetry. @@ -393,39 +393,8 @@ async function setupOpenclawConfig( logWarn("Gateway token re-assertion failed (non-fatal) — dashboard may show Unauthorized"); } - // Telegram channel setup — check env var first, then prompt interactively - if (enabledSteps?.has("telegram")) { - logStep("Setting up Telegram..."); - const envToken = process.env.TELEGRAM_BOT_TOKEN; - if (!envToken) { - logInfo("To get a bot token:"); - logInfo(" 1. Open Telegram and search for @BotFather"); - logInfo(" 2. Send /newbot and follow the prompts"); - logInfo(" 3. Copy the token (looks like 123456:ABC-DEF...)"); - logInfo(" Press Enter to skip if you don't have one yet."); - } - const trimmedToken = envToken?.trim() || (await prompt("Telegram bot token: ")).trim(); - - if (trimmedToken) { - const escapedBotToken = shellQuote(trimmedToken); - const telegramResult = await asyncTryCatchIf(isOperationalError, () => - runner.runServer( - "export PATH=$HOME/.npm-global/bin:$HOME/.bun/bin:$HOME/.local/bin:$PATH; " + - `openclaw config set channels.telegram.botToken ${escapedBotToken}`, - ), - ); - if (telegramResult.ok) { - logInfo("Telegram bot token configured"); - } else { - logWarn("Telegram config failed — set it up via the web dashboard after launch"); - } - } else { - logInfo("No token entered — set up Telegram via the web dashboard after launch"); - } - } - - // WhatsApp — QR code scanning happens interactively in orchestrate.ts - // after the gateway starts and tunnel is set up. No config needed here. + // Channel configuration (Telegram token, WhatsApp QR) happens in orchestrate.ts + // AFTER the gateway starts — openclaw channels commands need a running gateway. // Write USER.md bootstrap file — guides users to the web dashboard for // visual tasks like WhatsApp QR code scanning that don't work in the TUI. diff --git a/packages/cli/src/shared/orchestrate.ts b/packages/cli/src/shared/orchestrate.ts index 079600b6..239ccbe4 100644 --- a/packages/cli/src/shared/orchestrate.ts +++ b/packages/cli/src/shared/orchestrate.ts @@ -25,6 +25,8 @@ import { logWarn, openBrowser, prepareStdinForHandoff, + prompt, + shellQuote, validateModelId, withRetry, } from "./ui"; @@ -291,15 +293,42 @@ export async function runOrchestration( } } - // 11c. Interactive channel login (WhatsApp QR scan, Telegram bot link) - // Runs before the TUI so users can link messaging channels during setup. + // 11c. Channel setup (runs after gateway is up so openclaw commands work) + const ocPath = "export PATH=$HOME/.npm-global/bin:$HOME/.bun/bin:$HOME/.local/bin:$PATH"; + + if (enabledSteps?.has("telegram")) { + logStep("Setting up Telegram..."); + const envToken = process.env.TELEGRAM_BOT_TOKEN; + if (!envToken) { + logInfo("To get a bot token:"); + logInfo(" 1. Open Telegram and search for @BotFather"); + logInfo(" 2. Send /newbot and follow the prompts"); + logInfo(" 3. Copy the token (looks like 123456:ABC-DEF...)"); + logInfo(" Press Enter to skip if you don't have one yet."); + } + const trimmedToken = envToken?.trim() || (await prompt("Telegram bot token: ")).trim(); + if (trimmedToken) { + const escaped = shellQuote(trimmedToken); + const result = await asyncTryCatchIf(isOperationalError, () => + cloud.runner.runServer( + `source ~/.spawnrc 2>/dev/null; ${ocPath}; openclaw channels add --channel telegram --token ${escaped}`, + ), + ); + if (result.ok) { + logInfo("Telegram channel added"); + } else { + logWarn("Telegram setup failed — configure it via the web dashboard after launch"); + } + } else { + logInfo("No token entered — set up Telegram via the web dashboard after launch"); + } + } + if (enabledSteps?.has("whatsapp")) { logStep("Linking WhatsApp — scan the QR code with your phone..."); logInfo("Open WhatsApp > Settings > Linked Devices > Link a Device"); process.stderr.write("\n"); - const whatsappCmd = - "source ~/.spawnrc 2>/dev/null; export PATH=$HOME/.npm-global/bin:$HOME/.bun/bin:$HOME/.local/bin:$PATH; " + - "openclaw channels login --channel whatsapp"; + const whatsappCmd = `source ~/.spawnrc 2>/dev/null; ${ocPath}; openclaw channels login --channel whatsapp`; prepareStdinForHandoff(); await cloud.interactiveSession(whatsappCmd); }