From 4fab64e877468b07d1d7c207f294047bb03e6ecd Mon Sep 17 00:00:00 2001 From: hfshfg <38004547@qq.com> Date: Wed, 17 Jun 2026 19:33:25 +0800 Subject: [PATCH] =?UTF-8?q?fix(wechat):=20=E4=BE=BF=E6=90=BA=E5=8C=85?= =?UTF-8?q?=E6=89=93=E5=8C=85=E5=BE=AE=E4=BF=A1=E6=8F=92=E4=BB=B6=20+=20?= =?UTF-8?q?=E4=BF=AE=E8=BF=9E=E6=8E=A5=E6=88=90=E5=8A=9F=E5=8D=B4=E6=8A=A5?= =?UTF-8?q?=E3=80=8C=E6=8F=92=E4=BB=B6=E6=9C=AA=E5=AE=89=E8=A3=85=E3=80=8D?= =?UTF-8?q?=E7=9A=84=E7=9F=9B=E7=9B=BE=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因:微信插件 @tencent-weixin/openclaw-weixin 是独立 npm 包,但 setup/CI 从没装过它,portable/app/ 又被 gitignore —— 发布包 app/extensions/ 是空的, 客户扫码连上后 config-server 找不到插件源,报「插件未安装」。 - release.yml: 装 @tencent-weixin/openclaw-weixin@latest 到 app/extensions/ (npm 包自带 dist/index.js 无需 build;显式把 qrcode-terminal 放进插件 node_modules 以满足 server.js:52 的硬要求) - config-server/public/index.html: 去掉「连接成功」却又「插件未安装」的自相 矛盾提示。后端已自动装插件+写好 openclaw.json+存账号,只需重启即可, 不再暴露 pluginInstalled 内部状态吓客户,改为清晰的「重启 U-Claw 即可用」 - config-server/server.js: 插件 copy 失败时容错(不抛错中断 confirmed 流程) Co-Authored-By: Claude Opus 4.8 --- .github/workflows/release.yml | 26 ++++++++++++++++++++++++ portable/config-server/public/index.html | 10 ++++++--- portable/config-server/server.js | 12 ++++++++--- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1895b30..9f3d5a3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -110,6 +110,32 @@ jobs: done fi + # 6b) Install WeChat (Weixin) plugin into app/extensions/openclaw-weixin + # 官方 npm 包 @tencent-weixin/openclaw-weixin 自带 dist/index.js(发布时已编译,无需 build)。 + # config-server/server.js 把 app/extensions/openclaw-weixin 当作插件源,扫码登录后整目录 + # copy 到 ~/.openclaw/extensions/。它硬要求插件目录内 node_modules/qrcode-terminal 存在 + # (server.js:52),而 npm 会把该依赖提升到顶层,故下面显式 copy 进插件的 node_modules。 + wx_tmp="$(mktemp -d)" + ( + cd "$wx_tmp" + echo '{"name":"wx-tmp","version":"1.0.0","private":true}' > package.json + npm install @tencent-weixin/openclaw-weixin@latest \ + --registry="$mirror_npm" --no-audit --no-fund + ) + wx_pkg="$wx_tmp/node_modules/@tencent-weixin/openclaw-weixin" + if [ -f "$wx_pkg/dist/index.js" ] && [ -f "$wx_pkg/openclaw.plugin.json" ]; then + wx_dest="$app_dir/extensions/openclaw-weixin" + mkdir -p "$wx_dest" + cp -R "$wx_pkg/." "$wx_dest/" + # 把 qrcode-terminal(被 npm 提升到顶层)放进插件自己的 node_modules + mkdir -p "$wx_dest/node_modules" + cp -R "$wx_tmp/node_modules/qrcode-terminal" "$wx_dest/node_modules/qrcode-terminal" + echo "WeChat plugin installed: $(du -sm "$wx_dest" | cut -f1) MB" + else + echo "WARN: WeChat plugin install failed, skipping (dist/index.js or openclaw.plugin.json missing)" + fi + rm -rf "$wx_tmp" + # 7) Belt-and-suspenders: even though we don't pre-install bundled # deps, openclaw's own dependencies might still pull large native # binaries. Prune known offenders just in case. diff --git a/portable/config-server/public/index.html b/portable/config-server/public/index.html index a38a217..5022a39 100644 --- a/portable/config-server/public/index.html +++ b/portable/config-server/public/index.html @@ -628,10 +628,14 @@ async function pollWeChatStatus() { if (data.status === 'confirmed') { wechatPolling = false; qrDiv.innerHTML = '
'; - statusDiv.innerHTML = '微信连接成功!
账号: ' + - (data.accountId || '') + (data.pluginInstalled ? '' : '
⚠️ 插件未安装,请重启 Gateway') + '
需重启 Gateway 生效
'; + // 后端已自动装好插件 + 写好 openclaw.json + 存好账号,剩下只需重启 Gateway 加载插件。 + // 不再暴露 pluginInstalled 内部状态——它即使为 false,配置也已写好,下次启动必加载, + // 显示「插件未安装」只会和「连接成功」自相矛盾、吓到客户。 + statusDiv.innerHTML = '✅ 微信连接成功!' + + '
账号 ' + (data.accountId || '') + ' 已绑定' + + '
最后一步:重启 U-Claw(关闭后重新打开)即可在微信里使用'; statusDiv.style.color = '#4caf50'; - showToast('微信连接成功!'); + showToast('微信连接成功!重启 U-Claw 后生效'); return; } diff --git a/portable/config-server/server.js b/portable/config-server/server.js index 6cc7686..ac130aa 100644 --- a/portable/config-server/server.js +++ b/portable/config-server/server.js @@ -197,9 +197,15 @@ function ensureWeChatPluginInstalled() { return { installed: true }; } // Copy from USB to ~/.openclaw/extensions/ - const extDir = path.join(OPENCLAW_DIR, 'extensions'); - fs.mkdirSync(extDir, { recursive: true }); - copyDirSync(USB_PLUGIN_DIR, INSTALLED_PLUGIN_DIR); + // 容错:copy 失败不抛错中断整个 confirmed 流程(账号保存 + openclaw.json 已/将写好)。 + try { + const extDir = path.join(OPENCLAW_DIR, 'extensions'); + fs.mkdirSync(extDir, { recursive: true }); + copyDirSync(USB_PLUGIN_DIR, INSTALLED_PLUGIN_DIR); + } catch (e) { + console.error('WeChat plugin copy failed:', e.message); + return { installed: false, warning: e.message }; + } return { installed: fs.existsSync(path.join(INSTALLED_PLUGIN_DIR, 'openclaw.plugin.json')) }; }