From 1f90a40972ca570ad8f951e4dbd471bfdc9b60d6 Mon Sep 17 00:00:00 2001 From: paisley <8197966+su8su@users.noreply.github.com> Date: Wed, 11 Mar 2026 21:39:14 +0800 Subject: [PATCH] fix(feishu): resolve feishu connect failures by fixing config mismatch and channel collision (#423) --- electron/utils/channel-config.ts | 9 ++++---- electron/utils/openclaw-auth.ts | 36 ++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/electron/utils/channel-config.ts b/electron/utils/channel-config.ts index b7c79c617..4815a24bf 100644 --- a/electron/utils/channel-config.ts +++ b/electron/utils/channel-config.ts @@ -103,7 +103,6 @@ function ensurePluginAllowlist(currentConfig: OpenClawConfig, channelType: strin allow: [FEISHU_PLUGIN_ID], enabled: true, entries: { - feishu: { enabled: false }, [FEISHU_PLUGIN_ID]: { enabled: true } } }; @@ -122,10 +121,10 @@ function ensurePluginAllowlist(currentConfig: OpenClawConfig, channelType: strin if (!currentConfig.plugins.entries) { currentConfig.plugins.entries = {}; } - if (!currentConfig.plugins.entries['feishu']) { - currentConfig.plugins.entries['feishu'] = {}; - } - currentConfig.plugins.entries['feishu'].enabled = false; + // Remove legacy 'feishu' entry — the official plugin registers its + // channel AS 'feishu' via openclaw.plugin.json, so an explicit + // entries.feishu.enabled=false would block the official plugin's channel. + delete currentConfig.plugins.entries['feishu']; if (!currentConfig.plugins.entries[FEISHU_PLUGIN_ID]) { currentConfig.plugins.entries[FEISHU_PLUGIN_ID] = {}; diff --git a/electron/utils/openclaw-auth.ts b/electron/utils/openclaw-auth.ts index 34ebbe43b..0e90759cf 100644 --- a/electron/utils/openclaw-auth.ts +++ b/electron/utils/openclaw-auth.ts @@ -1001,6 +1001,42 @@ export async function sanitizeOpenClawConfig(): Promise { console.log('[sanitize] Enforced tools.profile="full" and tools.sessions.visibility="all" for OpenClaw 3.8+'); } + // ── plugins.entries.feishu cleanup ────────────────────────────── + // The official feishu plugin registers its channel AS 'feishu' via + // openclaw.plugin.json. An explicit entries.feishu.enabled=false + // (set by older ClawX to disable the legacy built-in) blocks the + // official plugin's channel from starting. Delete it. + if (typeof plugins === 'object' && !Array.isArray(plugins)) { + const pluginsObj = plugins as Record; + const pEntries = pluginsObj.entries as Record> | undefined; + if (pEntries?.feishu) { + console.log('[sanitize] Removing stale plugins.entries.feishu that blocks the official feishu plugin channel'); + delete pEntries.feishu; + modified = true; + } + } + + // ── channels.feishu migration ────────────────────────────────── + // The official feishu plugin reads the default account's credentials from + // the top level of `channels.feishu` (appId, appSecret), but ClawX + // historically stored them only under `channels.feishu.accounts.default`. + // Mirror the default account credentials at the top level so the plugin + // can discover them. + const feishuSection = (config.channels as Record> | undefined)?.feishu; + if (feishuSection) { + const feishuAccounts = feishuSection.accounts as Record> | undefined; + const defaultAccount = feishuAccounts?.default; + if (defaultAccount?.appId && defaultAccount?.appSecret && !feishuSection.appId) { + for (const [key, value] of Object.entries(defaultAccount)) { + if (key !== 'enabled' && !(key in feishuSection)) { + feishuSection[key] = value; + } + } + modified = true; + console.log('[sanitize] Mirrored feishu default account credentials to top-level channels.feishu'); + } + } + if (modified) { await writeOpenClawJson(config); console.log('[sanitize] openclaw.json sanitized successfully');