@modelzen/feishu-codex-bridge 0.6.0 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +139 -5
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -829,9 +829,9 @@ var init_cards = __esm({
|
|
|
829
829
|
// src/card/managed.ts
|
|
830
830
|
function stampRenderToken(card2) {
|
|
831
831
|
const token = (++renderToken).toString(36);
|
|
832
|
-
const
|
|
832
|
+
const visit2 = (node) => {
|
|
833
833
|
if (Array.isArray(node)) {
|
|
834
|
-
node.forEach(
|
|
834
|
+
node.forEach(visit2);
|
|
835
835
|
return;
|
|
836
836
|
}
|
|
837
837
|
if (!node || typeof node !== "object") return;
|
|
@@ -845,9 +845,9 @@ function stampRenderToken(card2) {
|
|
|
845
845
|
}
|
|
846
846
|
}
|
|
847
847
|
}
|
|
848
|
-
for (const k2 of Object.keys(obj))
|
|
848
|
+
for (const k2 of Object.keys(obj)) visit2(obj[k2]);
|
|
849
849
|
};
|
|
850
|
-
|
|
850
|
+
visit2(card2);
|
|
851
851
|
}
|
|
852
852
|
function isCardIdNotReady(err) {
|
|
853
853
|
const data = err?.response?.data;
|
|
@@ -5953,6 +5953,7 @@ function buildDoctorCard(i) {
|
|
|
5953
5953
|
`- Codex\uFF1A${i.codexOk ? `\u2705 \u53EF\u7528${i.codexVer ? `\uFF08${i.codexVer}\uFF09` : ""}` : "\u274C \u4E0D\u53EF\u7528\uFF08\u68C0\u67E5 CODEX_BIN / PATH\uFF09"}`
|
|
5954
5954
|
),
|
|
5955
5955
|
md(`- \u98DE\u4E66\u957F\u8FDE\u63A5\uFF1A${connLabel(i.conn)}`),
|
|
5956
|
+
md(`- \u673A\u5668\u4EBA open_id\uFF1A${i.botOpenId ? `\`${i.botOpenId}\`` : "\u26A0\uFE0F \u672A\u80FD\u83B7\u53D6\uFF08\u51ED\u636E\u5931\u6548\u6216\u7F51\u7EDC\u4E0D\u901A\uFF09"}`),
|
|
5956
5957
|
...scopeDiagnosis(i),
|
|
5957
5958
|
...eventSubscriptionDiagnosis(i),
|
|
5958
5959
|
note(`bridge v${i.bridgeVer}\u3000\xB7\u3000Node ${i.node}\u3000\xB7\u3000${i.platform}`),
|
|
@@ -9741,6 +9742,80 @@ async function handleDmConsole(channel, cfg, msg) {
|
|
|
9741
9742
|
});
|
|
9742
9743
|
}
|
|
9743
9744
|
|
|
9745
|
+
// src/bot/card-content.ts
|
|
9746
|
+
init_logger();
|
|
9747
|
+
function isDegradedCardContent(content) {
|
|
9748
|
+
const t = content.trim();
|
|
9749
|
+
if (t === "" || t === "[interactive card]") return true;
|
|
9750
|
+
return /请升级至最新版本客户端|请使用新版本.*查看|client to view|upgrade .*client/i.test(t);
|
|
9751
|
+
}
|
|
9752
|
+
function parseRawCardWrapper(bodyContent) {
|
|
9753
|
+
try {
|
|
9754
|
+
const parsed = JSON.parse(bodyContent);
|
|
9755
|
+
if (typeof parsed.json_card === "string") return JSON.parse(parsed.json_card);
|
|
9756
|
+
return parsed;
|
|
9757
|
+
} catch {
|
|
9758
|
+
return void 0;
|
|
9759
|
+
}
|
|
9760
|
+
}
|
|
9761
|
+
function extractRawCardText(jsonCard) {
|
|
9762
|
+
const out = [];
|
|
9763
|
+
visit(jsonCard, out);
|
|
9764
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9765
|
+
const lines = [];
|
|
9766
|
+
for (const piece of out) {
|
|
9767
|
+
const key = piece.trim();
|
|
9768
|
+
if (!key || seen.has(key)) continue;
|
|
9769
|
+
seen.add(key);
|
|
9770
|
+
lines.push(key);
|
|
9771
|
+
}
|
|
9772
|
+
return lines.join("\n");
|
|
9773
|
+
}
|
|
9774
|
+
function visit(node, out) {
|
|
9775
|
+
if (node == null) return;
|
|
9776
|
+
if (Array.isArray(node)) {
|
|
9777
|
+
for (const child of node) visit(child, out);
|
|
9778
|
+
return;
|
|
9779
|
+
}
|
|
9780
|
+
if (typeof node !== "object") return;
|
|
9781
|
+
const obj = node;
|
|
9782
|
+
if (obj.header) visit(obj.header, out);
|
|
9783
|
+
if (obj.body) visit(obj.body, out);
|
|
9784
|
+
const prop = obj.property;
|
|
9785
|
+
if (!prop) return;
|
|
9786
|
+
if (typeof prop.content === "string" && prop.content.trim()) {
|
|
9787
|
+
const url = prop.url?.url;
|
|
9788
|
+
out.push(url ? `[${prop.content.trim()}](${url})` : prop.content);
|
|
9789
|
+
}
|
|
9790
|
+
const i18n = prop.i18nElements;
|
|
9791
|
+
if (i18n && typeof i18n === "object") {
|
|
9792
|
+
visit(i18n.zh_cn ?? i18n.zh_hk ?? i18n.zh_tw ?? i18n.en_us ?? Object.values(i18n)[0], out);
|
|
9793
|
+
}
|
|
9794
|
+
visit(prop.title, out);
|
|
9795
|
+
visit(prop.text, out);
|
|
9796
|
+
visit(prop.elements, out);
|
|
9797
|
+
visit(prop.columns, out);
|
|
9798
|
+
visit(prop.actions, out);
|
|
9799
|
+
}
|
|
9800
|
+
async function fetchInteractiveCardText(channel, messageId) {
|
|
9801
|
+
let body;
|
|
9802
|
+
try {
|
|
9803
|
+
const res = await channel.rawClient.im.v1.message.get({
|
|
9804
|
+
path: { message_id: messageId },
|
|
9805
|
+
params: { card_msg_content_type: "raw_card_content" }
|
|
9806
|
+
});
|
|
9807
|
+
body = res.data?.items?.[0]?.body?.content;
|
|
9808
|
+
} catch (err) {
|
|
9809
|
+
log.warn("intake", "card-content-fetch-failed", { messageId, err: String(err) });
|
|
9810
|
+
return void 0;
|
|
9811
|
+
}
|
|
9812
|
+
if (!body) return void 0;
|
|
9813
|
+
const card2 = parseRawCardWrapper(body);
|
|
9814
|
+
if (card2 == null) return void 0;
|
|
9815
|
+
const text = extractRawCardText(card2);
|
|
9816
|
+
return text.trim() ? text : void 0;
|
|
9817
|
+
}
|
|
9818
|
+
|
|
9744
9819
|
// src/bot/media.ts
|
|
9745
9820
|
init_paths();
|
|
9746
9821
|
init_logger();
|
|
@@ -10061,7 +10136,7 @@ function extractMessageText(msgType, content, mentions) {
|
|
|
10061
10136
|
case "sticker":
|
|
10062
10137
|
return "[\u8868\u60C5]";
|
|
10063
10138
|
case "interactive":
|
|
10064
|
-
return "[\u5361\u7247\u6D88\u606F]";
|
|
10139
|
+
return extractCardText(parsed) || "[\u5361\u7247\u6D88\u606F]";
|
|
10065
10140
|
case "share_chat":
|
|
10066
10141
|
return "[\u5206\u4EAB\u7FA4\u540D\u7247]";
|
|
10067
10142
|
case "share_user":
|
|
@@ -10123,6 +10198,55 @@ function nodeToText(node) {
|
|
|
10123
10198
|
return typeof n.text === "string" ? n.text : "";
|
|
10124
10199
|
}
|
|
10125
10200
|
}
|
|
10201
|
+
var CARD_UPGRADE_HINT = "\u8BF7\u5347\u7EA7\u81F3\u6700\u65B0\u7248\u672C\u5BA2\u6237\u7AEF";
|
|
10202
|
+
function extractCardText(parsed) {
|
|
10203
|
+
if (!parsed || typeof parsed !== "object") return "";
|
|
10204
|
+
const obj = parsed;
|
|
10205
|
+
const parts = [];
|
|
10206
|
+
const title = textValue(obj.title);
|
|
10207
|
+
if (title.trim()) parts.push(title.trim());
|
|
10208
|
+
if (Array.isArray(obj.elements)) {
|
|
10209
|
+
for (const line of obj.elements) {
|
|
10210
|
+
const nodes = Array.isArray(line) ? line : [line];
|
|
10211
|
+
const lineText = nodes.map(cardNodeToText).join("").trim();
|
|
10212
|
+
if (lineText && !lineText.includes(CARD_UPGRADE_HINT)) parts.push(lineText);
|
|
10213
|
+
}
|
|
10214
|
+
}
|
|
10215
|
+
return parts.join("\n").trim();
|
|
10216
|
+
}
|
|
10217
|
+
function textValue(t) {
|
|
10218
|
+
if (typeof t === "string") return t;
|
|
10219
|
+
if (t && typeof t === "object") {
|
|
10220
|
+
const c = t.content;
|
|
10221
|
+
if (typeof c === "string") return c;
|
|
10222
|
+
}
|
|
10223
|
+
return "";
|
|
10224
|
+
}
|
|
10225
|
+
function cardNodeToText(node) {
|
|
10226
|
+
if (typeof node === "string") return node;
|
|
10227
|
+
if (!node || typeof node !== "object") return "";
|
|
10228
|
+
const n = node;
|
|
10229
|
+
switch (n.tag) {
|
|
10230
|
+
case "text":
|
|
10231
|
+
return textValue(n.text);
|
|
10232
|
+
case "a":
|
|
10233
|
+
return textValue(n.text) || (typeof n.href === "string" ? n.href : "");
|
|
10234
|
+
case "at": {
|
|
10235
|
+
const name = typeof n.user_name === "string" ? n.user_name : "";
|
|
10236
|
+
return name ? `@${name}` : "@\u67D0\u4EBA";
|
|
10237
|
+
}
|
|
10238
|
+
case "note":
|
|
10239
|
+
return Array.isArray(n.elements) ? n.elements.map(cardNodeToText).join("") : "";
|
|
10240
|
+
case "button": {
|
|
10241
|
+
const label = textValue(n.text);
|
|
10242
|
+
return label ? `[\u6309\u94AE\uFF1A${label}]` : "";
|
|
10243
|
+
}
|
|
10244
|
+
case "img":
|
|
10245
|
+
return "";
|
|
10246
|
+
default:
|
|
10247
|
+
return textValue(n.text);
|
|
10248
|
+
}
|
|
10249
|
+
}
|
|
10126
10250
|
function replaceMentions(text, mentions) {
|
|
10127
10251
|
if (!text || !mentions?.length) return text;
|
|
10128
10252
|
let out = text;
|
|
@@ -10768,6 +10892,13 @@ function createOrchestrator(channel, cfg, fallbackCwd, cliBridge) {
|
|
|
10768
10892
|
}
|
|
10769
10893
|
return;
|
|
10770
10894
|
}
|
|
10895
|
+
if (msg.rawContentType === "interactive" && isDegradedCardContent(msg.content)) {
|
|
10896
|
+
const full = await fetchInteractiveCardText(channel, msg.messageId);
|
|
10897
|
+
if (full) {
|
|
10898
|
+
log.info("intake", "card-content-enriched", { msgId: msg.messageId, len: full.length });
|
|
10899
|
+
msg.content = full;
|
|
10900
|
+
}
|
|
10901
|
+
}
|
|
10771
10902
|
const text = msg.content.trim();
|
|
10772
10903
|
const cmd = parseCommand(text);
|
|
10773
10904
|
const goalObjective = parseGoalTrigger(text);
|
|
@@ -11590,6 +11721,9 @@ function createOrchestrator(channel, cfg, fallbackCwd, cliBridge) {
|
|
|
11590
11721
|
codexOk: codexProbe.ok,
|
|
11591
11722
|
codexVer: codexProbe.version,
|
|
11592
11723
|
conn: channel.getConnectionStatus?.()?.state ?? "unknown",
|
|
11724
|
+
// 复用上面 validateAppCredentials 的返回(bot/v3/info),不额外发请求;
|
|
11725
|
+
// scopeCheck 没换成 token → undefined,卡片降级显示「未能获取」。
|
|
11726
|
+
botOpenId: scopeCheck?.botOpenId,
|
|
11593
11727
|
bridgeVer: bridgeVersion(),
|
|
11594
11728
|
node: process.version,
|
|
11595
11729
|
platform: `${process.platform}-${process.arch}`,
|