fix(portable): 微信扫码重定向/Telegram botToken/Windows 启动端口 (v2.1.11)

- 微信扫码卡死: config-server 跟随 IDC scaned_but_redirect 把后续轮询切到
  redirect_host,刷新二维码时重置 pollBaseUrl(扫码后不再卡住等不到 confirmed)。新增测试。
- Telegram 渠道改用 botToken(顶层 telegram 只认 botToken,旧 token 别名被静默忽略 → 连不上)。
- Windows-Start: 先起 config-server 再探测 gateway 端口,从 runtime.json 读实际
  configServerPort 并按该端口开 Config Center / 传给 wait-gateway(18788 被占也能开)。
- wait-gateway.bat: 用 ping 代替 timeout /t(避开 PATH 上 GNU coreutils timeout 冲突),接受 CONFIG_PORT 参数。
- Windows-Menu: IF 块内 echo 的 () 转义为 ^(^),修 v2.1.10 闪退回归。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
hfshfg
2026-06-24 00:41:20 +08:00
parent 3439db32ad
commit 6ab87c6b67
8 changed files with 177 additions and 34 deletions

View File

@@ -477,12 +477,12 @@ echo Fetching latest version...
for /f "tokens=*" %%v in ('"%NODE_BIN%" -e "const https=require('https');https.get('https://registry.npmmirror.com/openclaw/latest',r=>{let d='';r.on('data',c=>d+=c);r.on('end',()=>{try{console.log(JSON.parse(d).version)}catch(e){console.log('error')}})})" 2^>nul') do set LATEST_VER=%%v
if "!LATEST_VER!"=="" (
echo Could not fetch latest version (network issue?)
echo Could not fetch latest version ^(network issue?^)
pause
goto :menu
)
if "!LATEST_VER!"=="error" (
echo Could not fetch latest version (network issue?)
echo Could not fetch latest version ^(network issue?^)
pause
goto :menu
)
@@ -550,7 +550,7 @@ if !BK_COUNT! gtr 3 (
echo Cleaned !DEL_NUM! old backups.
)
) else (
echo Backups: !BK_COUNT! (no cleanup needed)
echo Backups: !BK_COUNT! ^(no cleanup needed^)
)
REM Clean old logs (>7 days)
@@ -598,7 +598,7 @@ if "%plgchoice%"=="b" (
echo.
echo Common plugins:
echo @icesword760/openclaw-wechat - WeChat
echo @nicepkg/openclaw-plugin-qq - QQ (community)
echo @nicepkg/openclaw-plugin-qq - QQ ^(community^)
echo.
set /p plgname=" Plugin name (empty to cancel): "
if not "!plgname!"=="" (

View File

@@ -107,7 +107,8 @@ for /f "usebackq tokens=1,* delims==" %%a in (`""%NODE_BIN%" "%UCLAW_DIR%lib\res
)
if defined NO_PROXY (
set "no_proxy=%NO_PROXY%"
echo Direct-connect (NO_PROXY): %NO_PROXY%
REM Note: no unescaped parens in echo inside this IF block - cmd treats ) as block-end.
echo Direct-connect via NO_PROXY: %NO_PROXY%
)
REM Async update check (non-blocking, 5s timeout, silent failure)
@@ -134,7 +135,30 @@ if exist "%WECHAT_PLUGIN_SRC%\openclaw.plugin.json" (
)
)
REM Find available port
REM Start Config Server in background
echo Starting Config Center on port 18788...
set "CONFIG_SERVER=%UCLAW_DIR%config-server"
set "RUNTIME_JSON=%STATE_DIR%\runtime.json"
del "%RUNTIME_JSON%" >nul 2>&1
start /B "" "%NODE_BIN%" "%CONFIG_SERVER%\server.js" >nul 2>&1
REM Wait for Config Server with polling instead of a fixed delay.
REM It writes runtime.json with the actual fallback port when ready.
set /a CFG_TRIES=0
:wait_config
if exist "%RUNTIME_JSON%" goto :config_ready
set /a CFG_TRIES+=1
if %CFG_TRIES% geq 20 goto :config_ready
ping -n 1 -w 300 127.0.0.1 >nul 2>&1
goto :wait_config
:config_ready
set "CONFIG_PORT=18788"
if exist "%RUNTIME_JSON%" (
for /f "usebackq tokens=*" %%p in (`powershell -NoProfile -Command "try { (Get-Content -Raw '%RUNTIME_JSON%' | ConvertFrom-Json).configServerPort } catch {}" 2^>nul`) do set "CONFIG_PORT=%%p"
)
echo Config Center port: %CONFIG_PORT%
REM Find available gateway port after Config Center has bound its port.
set PORT=18789
:check_port
netstat -an | findstr ":%PORT% " | findstr "LISTENING" >nul 2>&1
@@ -152,24 +176,6 @@ if %errorlevel%==0 (
echo Starting OpenClaw on port %PORT%...
echo.
REM Start Config Server in background
echo Starting Config Center on port 18788...
set "CONFIG_SERVER=%UCLAW_DIR%config-server"
start /B "" "%NODE_BIN%" "%CONFIG_SERVER%\server.js" >nul 2>&1
REM Wait for Config Server with polling instead of a fixed delay.
REM It is usually ready in under one second. Poll about every 0.3 seconds,
REM up to about 6 seconds, then continue anyway.
set /a CFG_TRIES=0
:wait_config
netstat -an | findstr ":18788 " | findstr "LISTENING" >nul 2>&1
if %errorlevel%==0 goto :config_ready
set /a CFG_TRIES+=1
if %CFG_TRIES% geq 20 goto :config_ready
ping -n 1 -w 300 127.0.0.1 >nul 2>&1
goto :wait_config
:config_ready
REM Do not open Dashboard before the gateway is ready.
REM Slow USB drives may need tens of seconds to stage bundled deps.
REM Open the local startup page now, and always open Config Center too.
@@ -182,11 +188,11 @@ set "LOADING_URL=file:///%LOADING_PATH:\=/%?port=%PORT%&token=uclaw"
start "" "%LOADING_URL%"
echo Opening Config Center...
start "" http://127.0.0.1:18788/
start "" http://127.0.0.1:%CONFIG_PORT%/
REM Fallback watcher: if the startup page cannot poll from file URLs,
REM keep polling and reopen Config Center after the gateway is ready.
start /B "" cmd /c ""%UCLAW_DIR%lib\wait-gateway.bat" %PORT%"
start /B "" cmd /c ""%UCLAW_DIR%lib\wait-gateway.bat" %PORT% %CONFIG_PORT%"
REM Prewarm gateway in the background after it becomes ready.
start /B "" "%NODE_BIN%" "%UCLAW_DIR%lib\prewarm.mjs" %PORT% uclaw >nul 2>&1

View File

@@ -678,7 +678,9 @@ async function saveChannelsAndOpen() {
var channels = {};
var tgToken = document.getElementById('ch-telegram-token').value.trim();
if (tgToken) channels.telegram = { enabled: true, token: tgToken, dmPolicy: 'pairing' };
// OpenClaw 顶层 telegram 渠道只认 botToken旧 token 别名仅在 accounts.<id> 里有效)。
// 之前写成 token 会被静默忽略 → Telegram 接不上。
if (tgToken) channels.telegram = { enabled: true, botToken: tgToken, dmPolicy: 'pairing' };
var qqId = document.getElementById('ch-qqbot-appid').value.trim();
var qqSecret = document.getElementById('ch-qqbot-secret').value.trim();

View File

@@ -246,7 +246,13 @@ async function handleWeChatStatus(sessionKey) {
return { status: 'expired', message: 'Session expired' };
}
const result = await pollWeChatQrStatus(login.apiBaseUrl, login.qrcode);
// 状态轮询用 pollBaseUrlIDC 重定向后会指向新主机);二维码获取/刷新始终用原始
// apiBaseUrl与官方插件一致refresh 回到固定主机,只有 status 轮询跟随重定向)。
const result = await pollWeChatQrStatus(login.pollBaseUrl || login.apiBaseUrl, login.qrcode);
// 微信登录状态流转日志(跳过高频的 wait便于排查"扫码卡死"类问题)。
if (result.status && result.status !== 'wait') {
console.log(`[wechat] status=${result.status}` + (result.redirect_host ? ` redirect_host=${result.redirect_host}` : ''));
}
if (result.status === 'expired') {
// Try to refresh QR code
@@ -261,6 +267,8 @@ async function handleWeChatStatus(sessionKey) {
login.qrcode = refreshed.qrcode;
login.qrcodeUrl = newQr;
login.startedAt = Date.now();
// 新二维码来自原始主机,重置轮询主机,避免拿新码去轮询旧的重定向主机。
login.pollBaseUrl = null;
return { status: 'refreshed', qrcodeUrl: newQr };
}
@@ -302,6 +310,18 @@ async function handleWeChatStatus(sessionKey) {
};
}
// IDC 重定向用户扫码后ilink 服务端可能要求把后续轮询切换到另一个数据中心主机
// (status=scaned_but_redirect + redirect_host)。必须跟着切,否则一直轮询旧主机,
// 扫码后永远等不到 confirmed——表现为「扫了码却卡死不前进」。
// 同款逻辑见官方插件 openclaw-weixin/src/auth/login-qr.ts 的 scaned_but_redirect 分支。
if (result.status === 'scaned_but_redirect') {
if (result.redirect_host) {
login.pollBaseUrl = 'https://' + result.redirect_host;
}
// 对前端按「已扫码」处理:显示提示并继续轮询,下一轮已指向新主机。
return { status: 'scaned' };
}
return { status: result.status };
}

View File

@@ -4,11 +4,13 @@ REM Slow USB drives can need tens of seconds before the gateway listens.
REM
REM Windows-Start opens Config Center immediately, so the ready path only
REM exits quietly. On timeout, reopen Config Center as a recovery hint.
REM Usage (called in background by Windows-Start.bat): wait-gateway.bat PORT
REM Usage (called in background by Windows-Start.bat): wait-gateway.bat PORT CONFIG_PORT
REM Polls every 2 seconds, up to about 5 minutes.
set "PORT=%~1"
if "%PORT%"=="" set "PORT=18789"
set "CONFIG_PORT=%~2"
if "%CONFIG_PORT%"=="" set "CONFIG_PORT=18788"
set /a TRIES=0
:wait_loop
@@ -16,12 +18,15 @@ netstat -an | findstr ":%PORT% " | findstr "LISTENING" >nul 2>&1
if %errorlevel%==0 goto :ready
set /a TRIES+=1
if %TRIES% geq 150 goto :timeout
timeout /t 2 /nobreak >nul
REM Use ping (not "timeout /t") for the ~2s delay: if a GNU coreutils "timeout"
REM is on PATH (Git/MSYS bin), it rejects "/t" and this poll becomes a busy-loop.
REM ping for the delay is PATH-robust and matches Windows-Start.bat's wait loop.
ping -n 3 127.0.0.1 >nul 2>&1
goto :wait_loop
:ready
exit /b 0
:timeout
start "" http://127.0.0.1:18788/
start "" http://127.0.0.1:%CONFIG_PORT%/
exit /b 1