@openclaw/feishu 2026.8.2 → 2026.9.1
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/api.js +119 -171
- package/dist/{channel-BtM7n79m.js → channel-DSYCNah8.js} +9 -159
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-DmCiCQJE.js → channel.runtime-EfDl2Q8q.js} +14 -18
- package/dist/{chat-Cbr7P_JH.js → chat-CxXaPTuO.js} +2 -2
- package/dist/{client-vJJyfkxI.js → client-DMbIL3UH.js} +1 -5
- package/dist/{monitor-BVYpA9SO.js → monitor-DoMmOfaD.js} +2 -2
- package/dist/{monitor.account-CuOAmGJf.js → monitor.account-WFdlCDhR.js} +165 -177
- package/dist/{probe-Cs1s-qSS.js → probe-D_SatdZl.js} +1 -1
- package/dist/{reply-delivery-result-BIIeISPG.js → reply-delivery-result-CEFTDA3f.js} +183 -81
- package/dist/setup-api.js +1 -1
- package/dist/{subagent-hooks-BnO3ALWB.js → subagent-hooks-Buadpie_.js} +2 -5
- package/dist/subagent-hooks-api.js +1 -1
- package/dist/{targets-BUjQ1TcA.js → targets-BTQCYRZQ.js} +4 -4
- package/package.json +5 -4
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { a as resolveDefaultFeishuAccountId, i as listFeishuAccountIds, o as resolveFeishuAccount, r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount } from "./accounts-RwSyseKr.js";
|
|
2
|
-
import { i as resolveReceiveIdType, r as normalizeFeishuTarget, t as detectIdType } from "./targets-
|
|
2
|
+
import { i as resolveReceiveIdType, r as normalizeFeishuTarget, t as detectIdType } from "./targets-BTQCYRZQ.js";
|
|
3
3
|
import { o as normalizeFeishuExternalKey } from "./doctor-contract-CQAuBotF.js";
|
|
4
|
-
import { r as createFeishuClient } from "./client-
|
|
4
|
+
import { r as createFeishuClient } from "./client-DMbIL3UH.js";
|
|
5
5
|
import { t as getFeishuRuntime } from "./runtime-C5JxBWZp.js";
|
|
6
6
|
import { normalizeAccountId, normalizeOptionalAccountId, resolveMergedAccountConfig } from "openclaw/plugin-sdk/account-resolution";
|
|
7
7
|
import { compileAllowlist, resolveAllowlistMatchByCandidates } from "openclaw/plugin-sdk/allow-from";
|
|
8
8
|
import { ToolAuthorizationError } from "openclaw/plugin-sdk/channel-actions";
|
|
9
9
|
import { createMessageReceiptFromOutboundResults } from "openclaw/plugin-sdk/channel-outbound";
|
|
10
10
|
import { PlatformMessageNotDispatchedError, formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
11
|
-
import { legacyInteractiveReplyToPresentation, normalizeLegacyInteractiveReply, normalizeMessagePresentation, renderMessagePresentationChartFallbackText, renderMessagePresentationFallbackText, renderMessagePresentationTableFallbackText } from "openclaw/plugin-sdk/interactive-runtime";
|
|
11
|
+
import { legacyInteractiveReplyToPresentation, normalizeLegacyInteractiveReply, normalizeMessagePresentation, renderMessagePresentationChartFallbackText, renderMessagePresentationFallbackText, renderMessagePresentationTableFallbackText, renderPresentationForDelivery, resolveLegacyInteractiveTextFallback } from "openclaw/plugin-sdk/interactive-runtime";
|
|
12
12
|
import { parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
13
13
|
import { isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringEntries, readStringValue } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
14
14
|
import { convertMarkdownTables } from "openclaw/plugin-sdk/text-chunking";
|
|
@@ -1423,38 +1423,19 @@ function resolveAmbientCommentTarget(context) {
|
|
|
1423
1423
|
if (deliveryContext?.channel && deliveryContext.channel !== "feishu") return null;
|
|
1424
1424
|
return parseFeishuCommentTarget(deliveryContext?.to);
|
|
1425
1425
|
}
|
|
1426
|
-
function
|
|
1426
|
+
function resolveDriveCommentParams(params, context, action) {
|
|
1427
1427
|
const ambient = resolveAmbientCommentTarget(context);
|
|
1428
|
-
|
|
1429
|
-
|
|
1428
|
+
let resolved = params;
|
|
1429
|
+
if (ambient && (action !== "add_comment" || ambient.fileType === "doc" || ambient.fileType === "docx")) resolved = {
|
|
1430
1430
|
...params,
|
|
1431
1431
|
file_token: params.file_token?.trim() || ambient.fileToken,
|
|
1432
1432
|
file_type: params.file_type ?? ambient.fileType,
|
|
1433
|
-
comment_id: params.comment_id?.trim() || ambient.commentId
|
|
1434
|
-
};
|
|
1435
|
-
}
|
|
1436
|
-
function applyAddCommentAmbientDefaults(params, context) {
|
|
1437
|
-
const ambient = resolveAmbientCommentTarget(context);
|
|
1438
|
-
if (!ambient || ambient.fileType !== "doc" && ambient.fileType !== "docx") return params;
|
|
1439
|
-
return {
|
|
1440
|
-
...params,
|
|
1441
|
-
file_token: params.file_token?.trim() || ambient.fileToken,
|
|
1442
|
-
file_type: params.file_type ?? ambient.fileType
|
|
1433
|
+
...action !== "add_comment" && { comment_id: params.comment_id?.trim() || ambient.commentId }
|
|
1443
1434
|
};
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
const fileType = params.file_type ?? "docx";
|
|
1447
|
-
if (!params.file_type) console.info(`[feishu_drive] add_comment missing file_type; defaulting to docx file_token=${params.file_token ?? "unknown"}`);
|
|
1435
|
+
const fileType = resolved.file_type ?? "docx";
|
|
1436
|
+
if (!resolved.file_type) console.info(`[feishu_drive] ${action} missing file_type; defaulting to docx file_token=${resolved.file_token ?? "unknown"}`);
|
|
1448
1437
|
return {
|
|
1449
|
-
...
|
|
1450
|
-
file_type: fileType
|
|
1451
|
-
};
|
|
1452
|
-
}
|
|
1453
|
-
function applyCommentFileTypeDefault(params, action) {
|
|
1454
|
-
const fileType = params.file_type ?? "docx";
|
|
1455
|
-
if (!params.file_type) console.info(`[feishu_drive] ${action} missing file_type; defaulting to docx file_token=${params.file_token ?? "unknown"}`);
|
|
1456
|
-
return {
|
|
1457
|
-
...params,
|
|
1438
|
+
...resolved,
|
|
1458
1439
|
file_type: fileType
|
|
1459
1440
|
};
|
|
1460
1441
|
}
|
|
@@ -1598,28 +1579,13 @@ async function deleteFile(client, fileToken, type) {
|
|
|
1598
1579
|
task_id: res.data?.task_id
|
|
1599
1580
|
};
|
|
1600
1581
|
}
|
|
1601
|
-
async function
|
|
1602
|
-
const
|
|
1603
|
-
|
|
1604
|
-
method: "GET",
|
|
1605
|
-
url: `/open-apis/drive/v1/files/${encodeURIComponent(params.file_token)}/comments` + encodeQuery({
|
|
1606
|
-
file_type: params.file_type,
|
|
1607
|
-
page_size: normalizeCommentPageSize(params.page_size),
|
|
1608
|
-
page_token: params.page_token,
|
|
1609
|
-
user_id_type: "open_id"
|
|
1610
|
-
})
|
|
1611
|
-
}));
|
|
1612
|
-
return {
|
|
1613
|
-
has_more: response.data?.has_more ?? false,
|
|
1614
|
-
page_token: response.data?.page_token,
|
|
1615
|
-
comments: (response.data?.items ?? []).map(normalizeCommentCard)
|
|
1616
|
-
};
|
|
1617
|
-
}
|
|
1618
|
-
async function listCommentReplies(client, params) {
|
|
1582
|
+
async function listDriveCommentPage(client, params) {
|
|
1583
|
+
const filePath = `/open-apis/drive/v1/files/${encodeURIComponent(params.file_token)}/comments`;
|
|
1584
|
+
const isReplies = params.action === "list_comment_replies";
|
|
1619
1585
|
const response = assertDriveApiSuccess(await requestDriveApi({
|
|
1620
1586
|
client,
|
|
1621
1587
|
method: "GET",
|
|
1622
|
-
url:
|
|
1588
|
+
url: (isReplies ? `${filePath}/${encodeURIComponent(params.comment_id)}/replies` : filePath) + encodeQuery({
|
|
1623
1589
|
file_type: params.file_type,
|
|
1624
1590
|
page_size: normalizeCommentPageSize(params.page_size),
|
|
1625
1591
|
page_token: params.page_token,
|
|
@@ -1629,7 +1595,7 @@ async function listCommentReplies(client, params) {
|
|
|
1629
1595
|
return {
|
|
1630
1596
|
has_more: response.data?.has_more ?? false,
|
|
1631
1597
|
page_token: response.data?.page_token,
|
|
1632
|
-
replies: (response.data?.items ?? []).map(normalizeCommentReply)
|
|
1598
|
+
...isReplies ? { replies: (response.data?.items ?? []).map(normalizeCommentReply) } : { comments: (response.data?.items ?? []).map(normalizeCommentCard) }
|
|
1633
1599
|
};
|
|
1634
1600
|
}
|
|
1635
1601
|
async function addComment(client, params) {
|
|
@@ -1773,23 +1739,13 @@ function registerFeishuDriveTools(api) {
|
|
|
1773
1739
|
case "create_folder": return feishuExternalToolResult(await createFolder(client, p.name, p.folder_token));
|
|
1774
1740
|
case "move": return feishuExternalToolResult(await moveFile(client, p.file_token, p.type, p.folder_token));
|
|
1775
1741
|
case "delete": return feishuExternalToolResult(await deleteFile(client, p.file_token, p.type));
|
|
1776
|
-
case "list_comments":
|
|
1777
|
-
case "list_comment_replies": return feishuExternalToolResult(await
|
|
1778
|
-
case "add_comment":
|
|
1779
|
-
const resolved = applyAddCommentDefaults(applyAddCommentAmbientDefaults(p, ctx));
|
|
1780
|
-
try {
|
|
1781
|
-
return feishuExternalToolResult(await addComment(client, resolved));
|
|
1782
|
-
} finally {
|
|
1783
|
-
cleanupAmbientCommentTypingReaction({
|
|
1784
|
-
client: getDriveInternalClient(client),
|
|
1785
|
-
deliveryContext: ctx.deliveryContext
|
|
1786
|
-
});
|
|
1787
|
-
}
|
|
1788
|
-
}
|
|
1742
|
+
case "list_comments":
|
|
1743
|
+
case "list_comment_replies": return feishuExternalToolResult(await listDriveCommentPage(client, resolveDriveCommentParams(p, ctx, p.action)));
|
|
1744
|
+
case "add_comment":
|
|
1789
1745
|
case "reply_comment": {
|
|
1790
|
-
const resolved =
|
|
1746
|
+
const resolved = resolveDriveCommentParams(p, ctx, p.action);
|
|
1791
1747
|
try {
|
|
1792
|
-
return feishuExternalToolResult(await deliverCommentThreadText(client, resolved));
|
|
1748
|
+
return feishuExternalToolResult(await (resolved.action === "add_comment" ? addComment(client, resolved) : deliverCommentThreadText(client, resolved)));
|
|
1793
1749
|
} finally {
|
|
1794
1750
|
cleanupAmbientCommentTypingReaction({
|
|
1795
1751
|
client: getDriveInternalClient(client),
|
|
@@ -1857,6 +1813,11 @@ async function buildFeishuMediaFallbackText(params) {
|
|
|
1857
1813
|
return [params.text?.trim(), attachmentText].filter(Boolean).join("\n\n");
|
|
1858
1814
|
}
|
|
1859
1815
|
//#endregion
|
|
1816
|
+
//#region extensions/feishu/src/api-response.ts
|
|
1817
|
+
function assertFeishuApiSuccess(response, errorPrefix) {
|
|
1818
|
+
if (response.code !== 0) throw new Error(`${errorPrefix}: ${response.msg || `code ${response.code}`}`);
|
|
1819
|
+
}
|
|
1820
|
+
//#endregion
|
|
1860
1821
|
//#region extensions/feishu/src/media-chunk-idle.ts
|
|
1861
1822
|
var FeishuInboundMediaTimeoutError = class extends Error {
|
|
1862
1823
|
constructor(chunkTimeoutMs) {
|
|
@@ -1934,9 +1895,6 @@ function createFeishuSendReceipt(params) {
|
|
|
1934
1895
|
kind: params.kind ?? "unknown"
|
|
1935
1896
|
});
|
|
1936
1897
|
}
|
|
1937
|
-
function assertFeishuMessageApiSuccess(response, errorPrefix) {
|
|
1938
|
-
if (response.code !== 0) throw new Error(`${errorPrefix}: ${response.msg || `code ${response.code}`}`);
|
|
1939
|
-
}
|
|
1940
1898
|
function toFeishuSendResult(response, chatId, kind, errorPrefix = "Feishu send failed", replyToId) {
|
|
1941
1899
|
const messageId = response.data?.message_id?.trim();
|
|
1942
1900
|
if (!messageId) throw createChannelPartialDeliveryError(/* @__PURE__ */ new Error(`${errorPrefix}: no message_id returned`), {
|
|
@@ -2352,7 +2310,7 @@ async function sendFallbackDirect(client, params, errorPrefix) {
|
|
|
2352
2310
|
msg_type: params.msgType
|
|
2353
2311
|
}
|
|
2354
2312
|
}), errorPrefix, { includeNestedErrorLogId: true });
|
|
2355
|
-
|
|
2313
|
+
assertFeishuApiSuccess(response, errorPrefix);
|
|
2356
2314
|
return toFeishuSendResult(response, params.receiveId, resolveFeishuReceiptKind(params.msgType), errorPrefix);
|
|
2357
2315
|
}
|
|
2358
2316
|
async function sendReplyOrFallbackDirect(client, params) {
|
|
@@ -2377,7 +2335,7 @@ async function sendReplyOrFallbackDirect(client, params) {
|
|
|
2377
2335
|
if (replyTargetFallbackError) throw replyTargetFallbackError;
|
|
2378
2336
|
return sendFallbackDirect(client, params.directParams, params.directErrorPrefix);
|
|
2379
2337
|
}
|
|
2380
|
-
|
|
2338
|
+
assertFeishuApiSuccess(response, params.replyErrorPrefix);
|
|
2381
2339
|
return toFeishuSendResult(response, params.directParams.receiveId, resolveFeishuReceiptKind(params.msgType), params.replyErrorPrefix, params.replyToMessageId);
|
|
2382
2340
|
}
|
|
2383
2341
|
function parseFeishuMessageContent(rawContent, msgType, messageId) {
|
|
@@ -2568,11 +2526,10 @@ async function editMessageFeishu(params) {
|
|
|
2568
2526
|
const client = createFeishuClient(account);
|
|
2569
2527
|
if (card) {
|
|
2570
2528
|
const content = JSON.stringify(card);
|
|
2571
|
-
|
|
2529
|
+
assertFeishuApiSuccess(await client.im.message.patch({
|
|
2572
2530
|
path: { message_id: messageId },
|
|
2573
2531
|
data: { content }
|
|
2574
|
-
});
|
|
2575
|
-
if (response.code !== 0) throw new Error(`Feishu message edit failed: ${response.msg || `code ${response.code}`}`);
|
|
2532
|
+
}), "Feishu message edit failed");
|
|
2576
2533
|
return {
|
|
2577
2534
|
messageId,
|
|
2578
2535
|
contentType: "interactive"
|
|
@@ -2584,14 +2541,13 @@ async function editMessageFeishu(params) {
|
|
|
2584
2541
|
});
|
|
2585
2542
|
const content = buildFeishuPostMessageContent({ messageText: materializeFeishuPostMarkdownSoftBreaks(convertMarkdownTables(text, tableMode)) });
|
|
2586
2543
|
assertFeishuPostWithinEnvelope(content, "Feishu message edit");
|
|
2587
|
-
|
|
2544
|
+
assertFeishuApiSuccess(await client.im.message.update({
|
|
2588
2545
|
path: { message_id: messageId },
|
|
2589
2546
|
data: {
|
|
2590
2547
|
msg_type: "post",
|
|
2591
2548
|
content
|
|
2592
2549
|
}
|
|
2593
|
-
});
|
|
2594
|
-
if (response.code !== 0) throw new Error(`Feishu message edit failed: ${response.msg || `code ${response.code}`}`);
|
|
2550
|
+
}), "Feishu message edit failed");
|
|
2595
2551
|
return {
|
|
2596
2552
|
messageId,
|
|
2597
2553
|
contentType: "post"
|
|
@@ -2944,7 +2900,7 @@ async function sendImageFeishu(params) {
|
|
|
2944
2900
|
msg_type: "image"
|
|
2945
2901
|
}
|
|
2946
2902
|
}), "Feishu image send failed", { includeNestedErrorLogId: true });
|
|
2947
|
-
|
|
2903
|
+
assertFeishuApiSuccess(response, "Feishu image send failed");
|
|
2948
2904
|
return toFeishuSendResult(response, receiveId, "media", "Feishu image send failed");
|
|
2949
2905
|
}
|
|
2950
2906
|
/**
|
|
@@ -3273,6 +3229,28 @@ async function sendMediaFeishu(params) {
|
|
|
3273
3229
|
}
|
|
3274
3230
|
//#endregion
|
|
3275
3231
|
//#region extensions/feishu/src/presentation-card.ts
|
|
3232
|
+
const RENDERED_FEISHU_CARD = Symbol("openclaw.renderedFeishuCard");
|
|
3233
|
+
const FEISHU_PRESENTATION_FALLBACK_MARKER = "__openclawPresentationFallback";
|
|
3234
|
+
const FEISHU_PRESENTATION_CAPABILITIES = {
|
|
3235
|
+
supported: true,
|
|
3236
|
+
buttons: true,
|
|
3237
|
+
selects: false,
|
|
3238
|
+
context: true,
|
|
3239
|
+
divider: true,
|
|
3240
|
+
limits: {
|
|
3241
|
+
actions: {
|
|
3242
|
+
maxActions: 20,
|
|
3243
|
+
maxActionsPerRow: 5,
|
|
3244
|
+
maxLabelLength: 40,
|
|
3245
|
+
maxValueBytes: 1024
|
|
3246
|
+
},
|
|
3247
|
+
text: {
|
|
3248
|
+
maxLength: 4e3,
|
|
3249
|
+
encoding: "characters",
|
|
3250
|
+
markdownDialect: "markdown"
|
|
3251
|
+
}
|
|
3252
|
+
}
|
|
3253
|
+
};
|
|
3276
3254
|
const FEISHU_CARD_MAX_BYTES = 30720;
|
|
3277
3255
|
const FEISHU_CARD_MAX_ELEMENTS = 200;
|
|
3278
3256
|
function resolveFeishuRichReply(payload) {
|
|
@@ -3293,12 +3271,11 @@ function buildFeishuPresentationFallback(params) {
|
|
|
3293
3271
|
}
|
|
3294
3272
|
function countFeishuCardElements(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
3295
3273
|
if (Array.isArray(value)) return value.reduce((count, entry) => count + countFeishuCardElements(entry, ancestors), 0);
|
|
3296
|
-
if (!value
|
|
3274
|
+
if (!isRecord(value)) return 0;
|
|
3297
3275
|
if (ancestors.has(value)) return 201;
|
|
3298
3276
|
ancestors.add(value);
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
for (const entry of Object.values(record)) {
|
|
3277
|
+
let count = typeof value.tag === "string" ? 1 : 0;
|
|
3278
|
+
for (const entry of Object.values(value)) {
|
|
3302
3279
|
count += countFeishuCardElements(entry, ancestors);
|
|
3303
3280
|
if (count > FEISHU_CARD_MAX_ELEMENTS) break;
|
|
3304
3281
|
}
|
|
@@ -3438,6 +3415,131 @@ function buildFeishuPresentationCard(params) {
|
|
|
3438
3415
|
body: { elements: buildFeishuPresentationCardElements(params) }
|
|
3439
3416
|
};
|
|
3440
3417
|
}
|
|
3418
|
+
function markRenderedFeishuCard(card) {
|
|
3419
|
+
Object.defineProperty(card, RENDERED_FEISHU_CARD, {
|
|
3420
|
+
value: true,
|
|
3421
|
+
enumerable: false
|
|
3422
|
+
});
|
|
3423
|
+
return card;
|
|
3424
|
+
}
|
|
3425
|
+
function readNativeFeishuCard(payload) {
|
|
3426
|
+
const feishuData = payload.channelData?.feishu;
|
|
3427
|
+
if (!isRecord(feishuData)) return;
|
|
3428
|
+
const card = feishuData.card ?? feishuData.interactiveCard;
|
|
3429
|
+
if (!isRecord(card)) return;
|
|
3430
|
+
const rendered = card;
|
|
3431
|
+
if (rendered[RENDERED_FEISHU_CARD] === true) return rendered;
|
|
3432
|
+
const sanitizedCard = sanitizeNativeFeishuCard(card);
|
|
3433
|
+
return sanitizedCard ? markRenderedFeishuCard(sanitizedCard) : void 0;
|
|
3434
|
+
}
|
|
3435
|
+
function consumeFeishuPresentationFallbackMarker(payload) {
|
|
3436
|
+
const feishuData = isRecord(payload.channelData?.feishu) ? payload.channelData.feishu : void 0;
|
|
3437
|
+
const presentationFallback = feishuData?.[FEISHU_PRESENTATION_FALLBACK_MARKER];
|
|
3438
|
+
if (!isRecord(presentationFallback) || typeof presentationFallback.hasVisibleContent !== "boolean") return { payload };
|
|
3439
|
+
const nextFeishuData = { ...feishuData };
|
|
3440
|
+
delete nextFeishuData[FEISHU_PRESENTATION_FALLBACK_MARKER];
|
|
3441
|
+
const nextChannelData = { ...payload.channelData };
|
|
3442
|
+
if (Object.keys(nextFeishuData).length > 0) nextChannelData.feishu = nextFeishuData;
|
|
3443
|
+
else delete nextChannelData.feishu;
|
|
3444
|
+
return {
|
|
3445
|
+
payload: {
|
|
3446
|
+
...payload,
|
|
3447
|
+
channelData: Object.keys(nextChannelData).length > 0 ? nextChannelData : void 0
|
|
3448
|
+
},
|
|
3449
|
+
presentationFallback: { hasVisibleContent: presentationFallback.hasVisibleContent }
|
|
3450
|
+
};
|
|
3451
|
+
}
|
|
3452
|
+
function buildFeishuPayloadCard(params) {
|
|
3453
|
+
const nativeCard = readNativeFeishuCard(params.payload);
|
|
3454
|
+
const rawText = params.text ?? params.payload.text;
|
|
3455
|
+
const textCard = readNativeFeishuCardJson(rawText);
|
|
3456
|
+
const { interactive, presentation } = resolveFeishuRichReply(params.payload);
|
|
3457
|
+
let card = nativeCard ?? (!presentation ? textCard : void 0);
|
|
3458
|
+
const isNativeCard = card !== void 0;
|
|
3459
|
+
if (!card && presentation) card = buildFeishuPresentationCard({
|
|
3460
|
+
presentation: {
|
|
3461
|
+
...presentation,
|
|
3462
|
+
title: presentation.title ?? resolveFeishuIdentityHeaderTitle(params.identity)
|
|
3463
|
+
},
|
|
3464
|
+
fallbackText: textCard ? void 0 : resolveLegacyInteractiveTextFallback({
|
|
3465
|
+
text: rawText,
|
|
3466
|
+
interactive
|
|
3467
|
+
})
|
|
3468
|
+
});
|
|
3469
|
+
if (!card) return;
|
|
3470
|
+
if (params.mentions?.length) card = {
|
|
3471
|
+
...card,
|
|
3472
|
+
body: {
|
|
3473
|
+
...card.body,
|
|
3474
|
+
elements: [{
|
|
3475
|
+
tag: "markdown",
|
|
3476
|
+
content: buildMentionedCardContent(params.mentions, "").trimEnd()
|
|
3477
|
+
}, ...card.body.elements]
|
|
3478
|
+
}
|
|
3479
|
+
};
|
|
3480
|
+
if (isNativeCard) assertFeishuCardWithinEnvelope(card, "Feishu native card");
|
|
3481
|
+
return isFeishuCardWithinEnvelope(card) ? markRenderedFeishuCard(card) : void 0;
|
|
3482
|
+
}
|
|
3483
|
+
function renderFeishuPresentationPayload({ payload, presentation, sourcePresentation, ctx }) {
|
|
3484
|
+
const card = buildFeishuPayloadCard({
|
|
3485
|
+
payload,
|
|
3486
|
+
text: payload.text,
|
|
3487
|
+
identity: ctx.identity,
|
|
3488
|
+
mentions: ctx.mentions
|
|
3489
|
+
});
|
|
3490
|
+
const isComment = Boolean(parseFeishuCommentTarget(ctx.to));
|
|
3491
|
+
const fallbackPresentation = !card || isComment ? sourcePresentation ?? presentation : presentation;
|
|
3492
|
+
const { fallbackText, fallbackHasCommand } = buildFeishuPresentationFallback({
|
|
3493
|
+
text: readNativeFeishuCardJson(payload.text) ? void 0 : payload.text,
|
|
3494
|
+
presentation: fallbackPresentation,
|
|
3495
|
+
textFormat: isComment ? "plain" : "markdown"
|
|
3496
|
+
});
|
|
3497
|
+
const existingFeishuData = isRecord(payload.channelData?.feishu) ? payload.channelData.feishu : void 0;
|
|
3498
|
+
if (!card) return {
|
|
3499
|
+
...payload,
|
|
3500
|
+
text: fallbackText,
|
|
3501
|
+
channelData: {
|
|
3502
|
+
...payload.channelData,
|
|
3503
|
+
feishu: {
|
|
3504
|
+
...existingFeishuData,
|
|
3505
|
+
[FEISHU_PRESENTATION_FALLBACK_MARKER]: { hasVisibleContent: Boolean(renderFeishuPresentationFallbackText({ presentation: fallbackPresentation }).trim()) },
|
|
3506
|
+
...fallbackHasCommand ? { fallbackHasCommand: true } : {}
|
|
3507
|
+
}
|
|
3508
|
+
}
|
|
3509
|
+
};
|
|
3510
|
+
return {
|
|
3511
|
+
...payload,
|
|
3512
|
+
text: fallbackText,
|
|
3513
|
+
channelData: {
|
|
3514
|
+
...payload.channelData,
|
|
3515
|
+
feishu: {
|
|
3516
|
+
...existingFeishuData,
|
|
3517
|
+
card,
|
|
3518
|
+
...fallbackHasCommand ? { fallbackHasCommand: true } : {}
|
|
3519
|
+
}
|
|
3520
|
+
}
|
|
3521
|
+
};
|
|
3522
|
+
}
|
|
3523
|
+
async function renderFeishuReplyPayload(payload, ctx) {
|
|
3524
|
+
const { presentation } = resolveFeishuRichReply(payload);
|
|
3525
|
+
if (!presentation) return { payload };
|
|
3526
|
+
const { interactive: _interactive, ...withoutInteractive } = await renderPresentationForDelivery({
|
|
3527
|
+
presentationCapabilities: FEISHU_PRESENTATION_CAPABILITIES,
|
|
3528
|
+
renderPresentation: (adapted, sourcePresentation) => renderFeishuPresentationPayload({
|
|
3529
|
+
payload: adapted,
|
|
3530
|
+
presentation: adapted.presentation,
|
|
3531
|
+
sourcePresentation,
|
|
3532
|
+
ctx
|
|
3533
|
+
})
|
|
3534
|
+
}, {
|
|
3535
|
+
...payload,
|
|
3536
|
+
presentation
|
|
3537
|
+
});
|
|
3538
|
+
return {
|
|
3539
|
+
payload: withoutInteractive,
|
|
3540
|
+
card: readNativeFeishuCard(withoutInteractive)
|
|
3541
|
+
};
|
|
3542
|
+
}
|
|
3441
3543
|
//#endregion
|
|
3442
3544
|
//#region extensions/feishu/src/reply-delivery-result.ts
|
|
3443
3545
|
const noVisibleFeishuReplyDelivery = { visibleReplySent: false };
|
|
@@ -3481,4 +3583,4 @@ function createFeishuPartialReplyDeliveryError(cause, result) {
|
|
|
3481
3583
|
});
|
|
3482
3584
|
}
|
|
3483
3585
|
//#endregion
|
|
3484
|
-
export {
|
|
3586
|
+
export { parseCommentContentElements as $, isFeishuBroadcastMention as A, decodeFeishuCardAction as At, deliverCommentThreadText as B, editMessageFeishu as C, resolveFeishuGroupToolPolicy as Ct, sendMessageFeishu as D, FEISHU_CARD_INTERACTION_VERSION as Dt, sendCardFeishu as E, resolveFeishuChatType as Et, createFeishuSendReceipt as F, createFeishuToolClient as G, feishuExternalToolResult as H, assertFeishuApiSuccess as I, cleanupAmbientCommentTypingReaction as J, resolveAnyEnabledFeishuToolsConfig as K, buildFeishuMediaFallbackText as L, isFeishuGroupChatType as M, parseInteractiveCardContent as N, sendStructuredCardFeishu as O, buildFeishuCardActionTextFallback as Ot, parsePostContent as P, formatFeishuApiError as Q, resolveFeishuIdentityEmoji as R, chunkFeishuCardMarkdown as S, resolveFeishuGroupSenderActivationIngressAccess as St, listFeishuThreadMessages as T, normalizeFeishuChatType as Tt, toolExecutionErrorResult as U, registerFeishuDriveTools as V, unknownToolActionResult as W, encodeQuery as X, createCommentTypingReactionLifecycle as Y, extractReplyText as Z, resolveFeishuRichReply as _, hasExplicitFeishuGroupConfig as _t, FEISHU_PRESENTATION_CAPABILITIES as a, resolveFeishuCardTemplate as at, sendStickerFeishu as b, resolveFeishuGroupConfig as bt, buildFeishuPresentationCard as c, materializeFeishuPostMarkdownSoftBreaks as ct, isFeishuCardWithinEnvelope as d, authorizeFeishuChatMemberRead as dt, requestFeishuApi as et, markRenderedFeishuCard as f, canEnumerateAllFeishuGroups as ft, renderFeishuReplyPayload as g, resolveFeishuChatReadPreliminaryAuthorization as gt, renderFeishuPresentationPayload as h, isFeishuGroupReadEnabled as ht, noVisibleFeishuReplyDelivery as i, readNativeFeishuCardJson as it, isMentionForwardRequest as j, extractMentionTargets as k, createFeishuCardInteractionEnvelope as kt, buildFeishuPresentationFallback as l, parseFeishuMarkdown as lt, renderFeishuPresentationFallbackText as m, isFeishuGroupReadAllowed as mt, createFeishuReplyDeliveryResult as n, normalizeCommentFileType as nt, assertFeishuCardWithinEnvelope as o, chunkFeishuMarkdown as ot, readNativeFeishuCard as p, canEnumerateAllFeishuPeers as pt, resolveFeishuToolAccount as q, mergeFeishuReplyDeliveryResults as r, parseFeishuCommentTarget as rt, buildFeishuPayloadCard as s, chunkFeishuPostMarkdown as st, createFeishuPartialReplyDeliveryError as t, buildFeishuCommentTarget as tt, consumeFeishuPresentationFallbackMarker as u, assertFeishuChatReadAllowed as ut, saveMessageResourceFeishu as v, normalizeFeishuAllowEntry as vt, getMessageFeishu as w, resolveFeishuReplyPolicy as wt, shouldSuppressFeishuTextForVoiceMedia as x, resolveFeishuGroupConversationIngressAccess as xt, sendMediaFeishu as y, resolveFeishuDmIngressAccess as yt, resolveFeishuIdentityHeaderTitle as z };
|
package/dist/setup-api.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as feishuSetupAdapter, n as feishuSetupWizard, t as feishuPlugin } from "./channel-
|
|
1
|
+
import { i as feishuSetupAdapter, n as feishuSetupWizard, t as feishuPlugin } from "./channel-DSYCNah8.js";
|
|
2
2
|
export { feishuPlugin, feishuSetupAdapter, feishuSetupWizard };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
|
-
import { r as normalizeFeishuTarget } from "./targets-
|
|
2
|
+
import { a as stripFeishuProviderPrefix, r as normalizeFeishuTarget } from "./targets-BTQCYRZQ.js";
|
|
3
3
|
import { r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-VYgGQ-GX.js";
|
|
4
4
|
import { n as getFeishuThreadBindingManager } from "./thread-bindings-BiL1wGqK.js";
|
|
5
5
|
import { normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
@@ -8,14 +8,11 @@ var subagent_hooks_exports = /* @__PURE__ */ __exportAll({
|
|
|
8
8
|
handleFeishuSubagentDeliveryTarget: () => handleFeishuSubagentDeliveryTarget,
|
|
9
9
|
handleFeishuSubagentEnded: () => handleFeishuSubagentEnded
|
|
10
10
|
});
|
|
11
|
-
function stripProviderPrefix(raw) {
|
|
12
|
-
return raw.replace(/^(feishu|lark):/i, "").trim();
|
|
13
|
-
}
|
|
14
11
|
function resolveFeishuRequesterConversation(params) {
|
|
15
12
|
const manager = getFeishuThreadBindingManager(params.accountId);
|
|
16
13
|
if (!manager) return null;
|
|
17
14
|
const rawTo = params.to?.trim();
|
|
18
|
-
const withoutProviderPrefix = rawTo ?
|
|
15
|
+
const withoutProviderPrefix = rawTo ? stripFeishuProviderPrefix(rawTo) : "";
|
|
19
16
|
const normalizedTarget = rawTo ? normalizeFeishuTarget(rawTo) : null;
|
|
20
17
|
const threadId = params.threadId != null && params.threadId !== "" ? String(params.threadId).trim() : "";
|
|
21
18
|
const isChatTarget = /^(chat|group|channel):/i.test(withoutProviderPrefix);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
2
2
|
//#region extensions/feishu/subagent-hooks-api.ts
|
|
3
|
-
const loadFeishuSubagentHooksModule = createLazyRuntimeModule(() => import("./subagent-hooks-
|
|
3
|
+
const loadFeishuSubagentHooksModule = createLazyRuntimeModule(() => import("./subagent-hooks-Buadpie_.js").then((n) => n.r));
|
|
4
4
|
function registerFeishuSubagentHooks(api) {
|
|
5
5
|
api.on("subagent_delivery_target", async (event) => {
|
|
6
6
|
const { handleFeishuSubagentDeliveryTarget } = await loadFeishuSubagentHooksModule();
|
|
@@ -3,7 +3,7 @@ import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coer
|
|
|
3
3
|
const CHAT_ID_PREFIX = "oc_";
|
|
4
4
|
const OPEN_ID_PREFIX = "ou_";
|
|
5
5
|
const USER_ID_REGEX = /^[a-zA-Z0-9_-]+$/;
|
|
6
|
-
function
|
|
6
|
+
function stripFeishuProviderPrefix(raw) {
|
|
7
7
|
return raw.replace(/^(feishu|lark):/i, "").trim();
|
|
8
8
|
}
|
|
9
9
|
function detectIdType(id) {
|
|
@@ -16,7 +16,7 @@ function detectIdType(id) {
|
|
|
16
16
|
function normalizeFeishuTarget(raw) {
|
|
17
17
|
const trimmed = raw.trim();
|
|
18
18
|
if (!trimmed) return null;
|
|
19
|
-
const withoutProvider =
|
|
19
|
+
const withoutProvider = stripFeishuProviderPrefix(trimmed);
|
|
20
20
|
const lowered = normalizeLowercaseStringOrEmpty(withoutProvider);
|
|
21
21
|
if (lowered.startsWith("chat:")) return withoutProvider.slice(5).trim() || null;
|
|
22
22
|
if (lowered.startsWith("group:")) return withoutProvider.slice(6).trim() || null;
|
|
@@ -37,7 +37,7 @@ function resolveReceiveIdType(id) {
|
|
|
37
37
|
return "user_id";
|
|
38
38
|
}
|
|
39
39
|
function looksLikeFeishuId(raw) {
|
|
40
|
-
const trimmed =
|
|
40
|
+
const trimmed = stripFeishuProviderPrefix(raw.trim());
|
|
41
41
|
if (!trimmed) return false;
|
|
42
42
|
if (/^(chat|group|channel|user|dm|open_id):/i.test(trimmed)) return true;
|
|
43
43
|
if (trimmed.startsWith(CHAT_ID_PREFIX)) return true;
|
|
@@ -45,4 +45,4 @@ function looksLikeFeishuId(raw) {
|
|
|
45
45
|
return false;
|
|
46
46
|
}
|
|
47
47
|
//#endregion
|
|
48
|
-
export { resolveReceiveIdType as i, looksLikeFeishuId as n, normalizeFeishuTarget as r, detectIdType as t };
|
|
48
|
+
export { stripFeishuProviderPrefix as a, resolveReceiveIdType as i, looksLikeFeishuId as n, normalizeFeishuTarget as r, detectIdType as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/feishu",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.9.1",
|
|
4
4
|
"description": "OpenClaw Feishu/Lark channel plugin for chats and workplace tools (community maintained by @m1heng).",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"zod": "4.4.3"
|
|
17
17
|
},
|
|
18
18
|
"peerDependencies": {
|
|
19
|
-
"openclaw": ">=2026.
|
|
19
|
+
"openclaw": ">=2026.9.1"
|
|
20
20
|
},
|
|
21
21
|
"peerDependenciesMeta": {
|
|
22
22
|
"openclaw": {
|
|
@@ -62,10 +62,11 @@
|
|
|
62
62
|
"minHostVersion": ">=2026.5.29"
|
|
63
63
|
},
|
|
64
64
|
"compat": {
|
|
65
|
-
"pluginApi": ">=2026.
|
|
65
|
+
"pluginApi": ">=2026.9.1"
|
|
66
66
|
},
|
|
67
67
|
"build": {
|
|
68
|
-
"
|
|
68
|
+
"bundledDist": false,
|
|
69
|
+
"openclawVersion": "2026.9.1"
|
|
69
70
|
},
|
|
70
71
|
"release": {
|
|
71
72
|
"publishToClawHub": true,
|