@openclaw/feishu 2026.7.2-beta.7 → 2026.8.1-beta.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/accounts-CCCdMen2.js +203 -0
- package/dist/api.js +52 -51
- package/dist/{channel-CScE82zY.js → channel-Dzb5jv3i.js} +53 -30
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-B21e1E0r.js → channel.runtime-CoPaHQQ6.js} +181 -142
- package/dist/{client-Dcbs6vml.js → client-Hp7uo_cl.js} +27 -16
- package/dist/contract-api.js +2 -2
- package/dist/{conversation-id-BeJL-wq7.js → conversation-id-VYgGQ-GX.js} +11 -15
- package/dist/doctor-contract-api.js +1 -1
- package/dist/doctor-contract-bEQXIXyP.js +158 -0
- package/dist/{drive-hSi_Utp0.js → drive-B0JkoiRj.js} +318 -41
- package/dist/{media-CEUraFOR.js → media-BjSy8fiy.js} +298 -182
- package/dist/{monitor-DngbaA6a.js → monitor-CeHCfROt.js} +3 -3
- package/dist/{monitor.account-BnTWCw55.js → monitor.account-DwdqexLU.js} +237 -158
- package/dist/{monitor.startup-CqH2tiJq.js → monitor.startup-BGErejNH.js} +1 -1
- package/dist/{probe-p3POS2RN.js → probe-DVpy58s0.js} +2 -2
- package/dist/security-audit-D6Fz2h6p.js +23 -0
- package/dist/{send-result-B9_BpUPx.js → send-result-DEAycmOk.js} +18 -9
- package/dist/session-binding-contract-api.js +1 -1
- package/dist/{session-conversation-BksWrfzm.js → session-conversation-DFCIvQK-.js} +1 -1
- package/dist/session-key-api.js +1 -1
- package/dist/setup-api.js +1 -1
- package/dist/{subagent-hooks-Cx1cX7rW.js → subagent-hooks-B867acTt.js} +2 -2
- package/dist/subagent-hooks-api.js +1 -1
- package/dist/{thread-bindings-N3wkgkIN.js → thread-bindings-Itvfmx6_.js} +6 -3
- package/openclaw.plugin.json +143 -1
- package/package.json +4 -4
- package/skills/feishu-doc/SKILL.md +20 -195
- package/skills/feishu-doc/references/block-types.md +9 -14
- package/skills/feishu-drive/SKILL.md +16 -102
- package/skills/feishu-perm/SKILL.md +10 -110
- package/skills/feishu-wiki/SKILL.md +13 -109
- package/dist/accounts-u9X5Wsan.js +0 -469
- package/dist/doctor-contract-BiD9tyIv.js +0 -102
- package/dist/security-audit-D7WK_BHh.js +0 -11
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as getFeishuRuntime } from "./runtime-C5JxBWZp.js";
|
|
2
|
-
import { r as registerFeishuAiAgent, t as probeFeishu } from "./probe-
|
|
2
|
+
import { r as registerFeishuAiAgent, t as probeFeishu } from "./probe-DVpy58s0.js";
|
|
3
3
|
import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
4
4
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
5
|
import { normalizeAccountId } from "openclaw/plugin-sdk/account-resolution";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
|
-
import { r as createFeishuClient } from "./client-
|
|
3
|
-
import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
|
|
2
|
+
import { r as createFeishuClient } from "./client-Hp7uo_cl.js";
|
|
4
3
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
4
|
+
import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
|
|
5
5
|
import { createHash } from "node:crypto";
|
|
6
6
|
//#region extensions/feishu/src/async.ts
|
|
7
7
|
const RACE_TIMEOUT = Symbol("race-timeout");
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import "./security-audit-shared-BgpY7AiJ.js";
|
|
2
|
+
//#region extensions/feishu/src/message-action-contract.ts
|
|
3
|
+
const FEISHU_NATIVE_CHAT_TARGET_ALIASES = [
|
|
4
|
+
"chatId",
|
|
5
|
+
"chat_id",
|
|
6
|
+
"channel_id"
|
|
7
|
+
];
|
|
8
|
+
function createMessageMutationTargetAliases() {
|
|
9
|
+
return {
|
|
10
|
+
aliases: ["messageId", ...FEISHU_NATIVE_CHAT_TARGET_ALIASES],
|
|
11
|
+
deliveryTargetAliases: [...FEISHU_NATIVE_CHAT_TARGET_ALIASES]
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
const messageActionTargetAliases = {
|
|
15
|
+
read: { aliases: ["messageId"] },
|
|
16
|
+
edit: createMessageMutationTargetAliases(),
|
|
17
|
+
pin: createMessageMutationTargetAliases(),
|
|
18
|
+
unpin: createMessageMutationTargetAliases(),
|
|
19
|
+
"list-pins": { aliases: ["chatId"] },
|
|
20
|
+
"channel-info": { aliases: ["chatId"] }
|
|
21
|
+
};
|
|
22
|
+
//#endregion
|
|
23
|
+
export { messageActionTargetAliases as t };
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { d as isRecord$1 } from "./accounts-u9X5Wsan.js";
|
|
2
1
|
import { r as normalizeFeishuTarget, t as detectIdType } from "./targets-BUjQ1TcA.js";
|
|
3
2
|
import { compileAllowlist, resolveAllowlistMatchByCandidates } from "openclaw/plugin-sdk/allow-from";
|
|
4
3
|
import { ToolAuthorizationError } from "openclaw/plugin-sdk/channel-actions";
|
|
@@ -11,6 +10,7 @@ import { fromMarkdown } from "mdast-util-from-markdown";
|
|
|
11
10
|
import { gfmTableFromMarkdown } from "mdast-util-gfm-table";
|
|
12
11
|
import { gfmTable } from "micromark-extension-gfm-table";
|
|
13
12
|
import { chunkMarkdownTextWithMode } from "openclaw/plugin-sdk/reply-chunking";
|
|
13
|
+
import { createChannelPartialDeliveryError } from "openclaw/plugin-sdk/channel-inbound";
|
|
14
14
|
//#region extensions/feishu/src/card-interaction.ts
|
|
15
15
|
const FEISHU_CARD_INTERACTION_VERSION = "ocf1";
|
|
16
16
|
function isInteractionKind(value) {
|
|
@@ -27,7 +27,7 @@ function createFeishuCardInteractionEnvelope(envelope) {
|
|
|
27
27
|
}
|
|
28
28
|
function buildFeishuCardActionTextFallback(event) {
|
|
29
29
|
const actionValue = event.action.value;
|
|
30
|
-
if (isRecord
|
|
30
|
+
if (isRecord(actionValue)) {
|
|
31
31
|
if (typeof actionValue.text === "string") return actionValue.text;
|
|
32
32
|
if (typeof actionValue.command === "string") return actionValue.command;
|
|
33
33
|
return JSON.stringify(actionValue);
|
|
@@ -37,7 +37,7 @@ function buildFeishuCardActionTextFallback(event) {
|
|
|
37
37
|
function decodeFeishuCardAction(params) {
|
|
38
38
|
const { event, now = Date.now() } = params;
|
|
39
39
|
const actionValue = event.action.value;
|
|
40
|
-
if (!isRecord
|
|
40
|
+
if (!isRecord(actionValue) || actionValue.oc !== "ocf1") return {
|
|
41
41
|
kind: "legacy",
|
|
42
42
|
text: buildFeishuCardActionTextFallback(event)
|
|
43
43
|
};
|
|
@@ -50,7 +50,7 @@ function decodeFeishuCardAction(params) {
|
|
|
50
50
|
reason: "malformed"
|
|
51
51
|
};
|
|
52
52
|
if (actionValue.m !== void 0) {
|
|
53
|
-
if (!isRecord
|
|
53
|
+
if (!isRecord(actionValue.m)) return {
|
|
54
54
|
kind: "invalid",
|
|
55
55
|
reason: "malformed"
|
|
56
56
|
};
|
|
@@ -60,7 +60,7 @@ function decodeFeishuCardAction(params) {
|
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
62
|
if (actionValue.c !== void 0) {
|
|
63
|
-
if (!isRecord
|
|
63
|
+
if (!isRecord(actionValue.c)) return {
|
|
64
64
|
kind: "invalid",
|
|
65
65
|
reason: "malformed"
|
|
66
66
|
};
|
|
@@ -197,6 +197,7 @@ async function resolveFeishuDmIngressAccess(params) {
|
|
|
197
197
|
kind: "direct",
|
|
198
198
|
id: params.conversationId
|
|
199
199
|
},
|
|
200
|
+
...params.contextBinding ? { contextBinding: params.contextBinding } : {},
|
|
200
201
|
event: { mayPair: params.mayPair },
|
|
201
202
|
dmPolicy: normalizeFeishuDmPolicy(params.dmPolicy),
|
|
202
203
|
groupPolicy: "disabled",
|
|
@@ -214,8 +215,10 @@ async function resolveFeishuGroupConversationIngressAccess(params) {
|
|
|
214
215
|
subject: createFeishuIngressSubject({ primaryId: params.chatId }),
|
|
215
216
|
conversation: {
|
|
216
217
|
kind: "group",
|
|
217
|
-
id: params.chatId
|
|
218
|
+
id: params.chatId,
|
|
219
|
+
threadId: params.threadId
|
|
218
220
|
},
|
|
221
|
+
...params.contextBinding ? { contextBinding: params.contextBinding } : {},
|
|
219
222
|
dmPolicy: "disabled",
|
|
220
223
|
groupPolicy,
|
|
221
224
|
groupAllowFrom
|
|
@@ -233,8 +236,10 @@ async function resolveFeishuGroupSenderActivationIngressAccess(params) {
|
|
|
233
236
|
}),
|
|
234
237
|
conversation: {
|
|
235
238
|
kind: "group",
|
|
236
|
-
id: params.chatId
|
|
239
|
+
id: params.chatId,
|
|
240
|
+
threadId: params.threadId
|
|
237
241
|
},
|
|
242
|
+
...params.contextBinding ? { contextBinding: params.contextBinding } : {},
|
|
238
243
|
dmPolicy: "disabled",
|
|
239
244
|
groupPolicy: groupAllowFrom.length > 0 ? "allowlist" : "open",
|
|
240
245
|
groupAllowFrom,
|
|
@@ -754,8 +759,12 @@ function createFeishuSendReceipt(params) {
|
|
|
754
759
|
function assertFeishuMessageApiSuccess(response, errorPrefix) {
|
|
755
760
|
if (response.code !== 0) throw new Error(`${errorPrefix}: ${response.msg || `code ${response.code}`}`);
|
|
756
761
|
}
|
|
757
|
-
function toFeishuSendResult(response, chatId, kind) {
|
|
758
|
-
const messageId = response.data?.message_id
|
|
762
|
+
function toFeishuSendResult(response, chatId, kind, errorPrefix = "Feishu send failed") {
|
|
763
|
+
const messageId = response.data?.message_id?.trim();
|
|
764
|
+
if (!messageId) throw createChannelPartialDeliveryError(/* @__PURE__ */ new Error(`${errorPrefix}: no message_id returned`), {
|
|
765
|
+
messageIds: [],
|
|
766
|
+
visibleReplySent: true
|
|
767
|
+
});
|
|
759
768
|
return {
|
|
760
769
|
messageId,
|
|
761
770
|
chatId,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { r as testing, t as createFeishuThreadBindingManager } from "./thread-bindings-
|
|
1
|
+
import { r as testing, t as createFeishuThreadBindingManager } from "./thread-bindings-Itvfmx6_.js";
|
|
2
2
|
export { createFeishuThreadBindingManager, testing as feishuThreadBindingTesting };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-
|
|
1
|
+
import { r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-VYgGQ-GX.js";
|
|
2
2
|
//#region extensions/feishu/src/session-conversation.ts
|
|
3
3
|
function resolveFeishuParentConversationCandidates(rawId) {
|
|
4
4
|
const parsed = parseFeishuConversationId({ conversationId: rawId });
|
package/dist/session-key-api.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as resolveFeishuSessionConversation } from "./session-conversation-
|
|
1
|
+
import { t as resolveFeishuSessionConversation } from "./session-conversation-DFCIvQK-.js";
|
|
2
2
|
export { resolveFeishuSessionConversation as resolveSessionConversation };
|
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-Dzb5jv3i.js";
|
|
2
2
|
export { feishuPlugin, feishuSetupAdapter, feishuSetupWizard };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
2
|
import { r as normalizeFeishuTarget } from "./targets-BUjQ1TcA.js";
|
|
3
|
-
import { r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-
|
|
4
|
-
import { n as getFeishuThreadBindingManager } from "./thread-bindings-
|
|
3
|
+
import { r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-VYgGQ-GX.js";
|
|
4
|
+
import { n as getFeishuThreadBindingManager } from "./thread-bindings-Itvfmx6_.js";
|
|
5
5
|
import { normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
6
6
|
//#region extensions/feishu/src/subagent-hooks.ts
|
|
7
7
|
var subagent_hooks_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -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-B867acTt.js").then((n) => n.i));
|
|
4
4
|
function registerFeishuSubagentHooks(api) {
|
|
5
5
|
api.on("subagent_delivery_target", async (event) => {
|
|
6
6
|
const { handleFeishuSubagentDeliveryTarget } = await loadFeishuSubagentHooksModule();
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { registerSessionBindingAdapter, resolveThreadBindingConversationIdFromBindingId, resolveThreadBindingIdleTimeoutMsForChannel, resolveThreadBindingMaxAgeMsForChannel, unregisterSessionBindingAdapter } from "openclaw/plugin-sdk/conversation-runtime";
|
|
2
2
|
import { isFutureDateTimestampMs } from "openclaw/plugin-sdk/number-runtime";
|
|
3
3
|
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
|
-
import { normalizeAccountId
|
|
5
|
-
import {
|
|
4
|
+
import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
|
|
5
|
+
import { resolveSessionAgentId } from "openclaw/plugin-sdk/agent-scope-runtime";
|
|
6
6
|
//#region extensions/feishu/src/thread-bindings.ts
|
|
7
7
|
const FEISHU_THREAD_BINDINGS_STATE_KEY = Symbol.for("openclaw.feishuThreadBindingsState");
|
|
8
8
|
let state;
|
|
@@ -107,7 +107,10 @@ function createFeishuThreadBindingManager(params) {
|
|
|
107
107
|
deliveryThreadId: typeof metadata?.deliveryThreadId === "string" && metadata.deliveryThreadId.trim() ? metadata.deliveryThreadId.trim() : existingLocal?.deliveryThreadId,
|
|
108
108
|
targetKind: toFeishuTargetKind(targetKind),
|
|
109
109
|
targetSessionKey: normalizedTargetSessionKey,
|
|
110
|
-
agentId:
|
|
110
|
+
agentId: normalizeOptionalString(metadata?.agentId) ?? existingLocal?.agentId ?? resolveSessionAgentId({
|
|
111
|
+
config: params.cfg,
|
|
112
|
+
sessionKey: normalizedTargetSessionKey
|
|
113
|
+
}),
|
|
111
114
|
label: typeof metadata?.label === "string" && metadata.label.trim() ? metadata.label.trim() : existingLocal?.label,
|
|
112
115
|
boundBy: typeof metadata?.boundBy === "string" && metadata.boundBy.trim() ? metadata.boundBy.trim() : existingLocal?.boundBy,
|
|
113
116
|
boundAt: now,
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "feishu",
|
|
3
|
+
"doctorContract": {
|
|
4
|
+
"configRepair": true
|
|
5
|
+
},
|
|
3
6
|
"name": "Feishu/Lark",
|
|
4
7
|
"description": "OpenClaw Feishu/Lark channel plugin for chats and workplace tools (community maintained by @m1heng).",
|
|
5
8
|
"activation": {
|
|
@@ -310,7 +313,8 @@
|
|
|
310
313
|
"enum": [
|
|
311
314
|
"env",
|
|
312
315
|
"file",
|
|
313
|
-
"exec"
|
|
316
|
+
"exec",
|
|
317
|
+
"store"
|
|
314
318
|
]
|
|
315
319
|
},
|
|
316
320
|
"provider": {
|
|
@@ -580,6 +584,29 @@
|
|
|
580
584
|
],
|
|
581
585
|
"additionalProperties": false
|
|
582
586
|
},
|
|
587
|
+
{
|
|
588
|
+
"type": "object",
|
|
589
|
+
"properties": {
|
|
590
|
+
"source": {
|
|
591
|
+
"type": "string",
|
|
592
|
+
"const": "store"
|
|
593
|
+
},
|
|
594
|
+
"provider": {
|
|
595
|
+
"type": "string",
|
|
596
|
+
"pattern": "^[a-z][a-z0-9_-]{0,63}$"
|
|
597
|
+
},
|
|
598
|
+
"id": {
|
|
599
|
+
"type": "string",
|
|
600
|
+
"pattern": "^[A-Z][A-Z0-9_]{0,127}$"
|
|
601
|
+
}
|
|
602
|
+
},
|
|
603
|
+
"required": [
|
|
604
|
+
"source",
|
|
605
|
+
"provider",
|
|
606
|
+
"id"
|
|
607
|
+
],
|
|
608
|
+
"additionalProperties": false
|
|
609
|
+
},
|
|
583
610
|
{
|
|
584
611
|
"type": "object",
|
|
585
612
|
"properties": {
|
|
@@ -658,6 +685,29 @@
|
|
|
658
685
|
],
|
|
659
686
|
"additionalProperties": false
|
|
660
687
|
},
|
|
688
|
+
{
|
|
689
|
+
"type": "object",
|
|
690
|
+
"properties": {
|
|
691
|
+
"source": {
|
|
692
|
+
"type": "string",
|
|
693
|
+
"const": "store"
|
|
694
|
+
},
|
|
695
|
+
"provider": {
|
|
696
|
+
"type": "string",
|
|
697
|
+
"pattern": "^[a-z][a-z0-9_-]{0,63}$"
|
|
698
|
+
},
|
|
699
|
+
"id": {
|
|
700
|
+
"type": "string",
|
|
701
|
+
"pattern": "^[A-Z][A-Z0-9_]{0,127}$"
|
|
702
|
+
}
|
|
703
|
+
},
|
|
704
|
+
"required": [
|
|
705
|
+
"source",
|
|
706
|
+
"provider",
|
|
707
|
+
"id"
|
|
708
|
+
],
|
|
709
|
+
"additionalProperties": false
|
|
710
|
+
},
|
|
661
711
|
{
|
|
662
712
|
"type": "object",
|
|
663
713
|
"properties": {
|
|
@@ -736,6 +786,29 @@
|
|
|
736
786
|
],
|
|
737
787
|
"additionalProperties": false
|
|
738
788
|
},
|
|
789
|
+
{
|
|
790
|
+
"type": "object",
|
|
791
|
+
"properties": {
|
|
792
|
+
"source": {
|
|
793
|
+
"type": "string",
|
|
794
|
+
"const": "store"
|
|
795
|
+
},
|
|
796
|
+
"provider": {
|
|
797
|
+
"type": "string",
|
|
798
|
+
"pattern": "^[a-z][a-z0-9_-]{0,63}$"
|
|
799
|
+
},
|
|
800
|
+
"id": {
|
|
801
|
+
"type": "string",
|
|
802
|
+
"pattern": "^[A-Z][A-Z0-9_]{0,127}$"
|
|
803
|
+
}
|
|
804
|
+
},
|
|
805
|
+
"required": [
|
|
806
|
+
"source",
|
|
807
|
+
"provider",
|
|
808
|
+
"id"
|
|
809
|
+
],
|
|
810
|
+
"additionalProperties": false
|
|
811
|
+
},
|
|
739
812
|
{
|
|
740
813
|
"type": "object",
|
|
741
814
|
"properties": {
|
|
@@ -1348,6 +1421,29 @@
|
|
|
1348
1421
|
],
|
|
1349
1422
|
"additionalProperties": false
|
|
1350
1423
|
},
|
|
1424
|
+
{
|
|
1425
|
+
"type": "object",
|
|
1426
|
+
"properties": {
|
|
1427
|
+
"source": {
|
|
1428
|
+
"type": "string",
|
|
1429
|
+
"const": "store"
|
|
1430
|
+
},
|
|
1431
|
+
"provider": {
|
|
1432
|
+
"type": "string",
|
|
1433
|
+
"pattern": "^[a-z][a-z0-9_-]{0,63}$"
|
|
1434
|
+
},
|
|
1435
|
+
"id": {
|
|
1436
|
+
"type": "string",
|
|
1437
|
+
"pattern": "^[A-Z][A-Z0-9_]{0,127}$"
|
|
1438
|
+
}
|
|
1439
|
+
},
|
|
1440
|
+
"required": [
|
|
1441
|
+
"source",
|
|
1442
|
+
"provider",
|
|
1443
|
+
"id"
|
|
1444
|
+
],
|
|
1445
|
+
"additionalProperties": false
|
|
1446
|
+
},
|
|
1351
1447
|
{
|
|
1352
1448
|
"type": "object",
|
|
1353
1449
|
"properties": {
|
|
@@ -1426,6 +1522,29 @@
|
|
|
1426
1522
|
],
|
|
1427
1523
|
"additionalProperties": false
|
|
1428
1524
|
},
|
|
1525
|
+
{
|
|
1526
|
+
"type": "object",
|
|
1527
|
+
"properties": {
|
|
1528
|
+
"source": {
|
|
1529
|
+
"type": "string",
|
|
1530
|
+
"const": "store"
|
|
1531
|
+
},
|
|
1532
|
+
"provider": {
|
|
1533
|
+
"type": "string",
|
|
1534
|
+
"pattern": "^[a-z][a-z0-9_-]{0,63}$"
|
|
1535
|
+
},
|
|
1536
|
+
"id": {
|
|
1537
|
+
"type": "string",
|
|
1538
|
+
"pattern": "^[A-Z][A-Z0-9_]{0,127}$"
|
|
1539
|
+
}
|
|
1540
|
+
},
|
|
1541
|
+
"required": [
|
|
1542
|
+
"source",
|
|
1543
|
+
"provider",
|
|
1544
|
+
"id"
|
|
1545
|
+
],
|
|
1546
|
+
"additionalProperties": false
|
|
1547
|
+
},
|
|
1429
1548
|
{
|
|
1430
1549
|
"type": "object",
|
|
1431
1550
|
"properties": {
|
|
@@ -1504,6 +1623,29 @@
|
|
|
1504
1623
|
],
|
|
1505
1624
|
"additionalProperties": false
|
|
1506
1625
|
},
|
|
1626
|
+
{
|
|
1627
|
+
"type": "object",
|
|
1628
|
+
"properties": {
|
|
1629
|
+
"source": {
|
|
1630
|
+
"type": "string",
|
|
1631
|
+
"const": "store"
|
|
1632
|
+
},
|
|
1633
|
+
"provider": {
|
|
1634
|
+
"type": "string",
|
|
1635
|
+
"pattern": "^[a-z][a-z0-9_-]{0,63}$"
|
|
1636
|
+
},
|
|
1637
|
+
"id": {
|
|
1638
|
+
"type": "string",
|
|
1639
|
+
"pattern": "^[A-Z][A-Z0-9_]{0,127}$"
|
|
1640
|
+
}
|
|
1641
|
+
},
|
|
1642
|
+
"required": [
|
|
1643
|
+
"source",
|
|
1644
|
+
"provider",
|
|
1645
|
+
"id"
|
|
1646
|
+
],
|
|
1647
|
+
"additionalProperties": false
|
|
1648
|
+
},
|
|
1507
1649
|
{
|
|
1508
1650
|
"type": "object",
|
|
1509
1651
|
"properties": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/feishu",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.8.1-beta.2",
|
|
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.8.1-beta.2"
|
|
20
20
|
},
|
|
21
21
|
"peerDependenciesMeta": {
|
|
22
22
|
"openclaw": {
|
|
@@ -60,10 +60,10 @@
|
|
|
60
60
|
"minHostVersion": ">=2026.5.29"
|
|
61
61
|
},
|
|
62
62
|
"compat": {
|
|
63
|
-
"pluginApi": ">=2026.
|
|
63
|
+
"pluginApi": ">=2026.8.1-beta.2"
|
|
64
64
|
},
|
|
65
65
|
"build": {
|
|
66
|
-
"openclawVersion": "2026.
|
|
66
|
+
"openclawVersion": "2026.8.1-beta.2"
|
|
67
67
|
},
|
|
68
68
|
"release": {
|
|
69
69
|
"publishToClawHub": true,
|
|
@@ -1,215 +1,40 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: feishu-doc
|
|
3
3
|
description: |
|
|
4
|
-
Feishu document read/write
|
|
4
|
+
Feishu document read/write workflows. Activate when the user mentions Feishu docs, cloud docs, or docx links.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
# Feishu
|
|
7
|
+
# Feishu documents
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Use the single `feishu_doc` tool. Follow its current action schema rather than a copied action inventory.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
From `https://example.feishu.cn/docx/ABC123def`, use `ABC123def` as `doc_token`.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
## Read and edit
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
1. Start with `read` for plain text and block statistics.
|
|
16
|
+
2. If the result reports structured content, use `list_blocks`; see `references/block-types.md` for block meanings.
|
|
17
|
+
3. Use `update_block` or `delete_block` for one known block. Use `insert` with `after_block_id` to place new Markdown after a known block.
|
|
18
|
+
4. Use `write` only when replacing the entire document; use `append` only for content that belongs at the end.
|
|
16
19
|
|
|
17
|
-
|
|
20
|
+
Markdown writes support ordinary text structure and images, but not Markdown tables. For tables, use the explicit table actions exposed by the tool. Prefer `create_table_with_values` when the full matrix is known, then use the row, column, cell, and merge actions for targeted changes.
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
{ "action": "read", "doc_token": "ABC123def" }
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
Returns: title, plain text content, block statistics. Check `hint` field - if present, structured content (tables, images) exists that requires `list_blocks`.
|
|
24
|
-
|
|
25
|
-
### Write Document (Replace All)
|
|
26
|
-
|
|
27
|
-
```json
|
|
28
|
-
{ "action": "write", "doc_token": "ABC123def", "content": "# Title\n\nMarkdown content..." }
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Replaces entire document with markdown content. Supports: headings, lists, code blocks, quotes, links, images (`` auto-uploaded), bold/italic/strikethrough.
|
|
32
|
-
|
|
33
|
-
**Limitation:** Markdown tables are NOT supported.
|
|
34
|
-
|
|
35
|
-
### Append Content
|
|
36
|
-
|
|
37
|
-
```json
|
|
38
|
-
{ "action": "append", "doc_token": "ABC123def", "content": "Additional content" }
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
Appends markdown to end of document.
|
|
42
|
-
|
|
43
|
-
### Create Document
|
|
44
|
-
|
|
45
|
-
```json
|
|
46
|
-
{ "action": "create", "title": "New Document", "owner_open_id": "ou_xxx" }
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
With folder:
|
|
50
|
-
|
|
51
|
-
```json
|
|
52
|
-
{
|
|
53
|
-
"action": "create",
|
|
54
|
-
"title": "New Document",
|
|
55
|
-
"folder_token": "fldcnXXX",
|
|
56
|
-
"owner_open_id": "ou_xxx"
|
|
57
|
-
}
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
Document creation is title-only. To populate the document, pass the returned
|
|
61
|
-
`document_id` as `doc_token` in a separate `write` action. Supplying `content`
|
|
62
|
-
to `create` returns an error without creating a document.
|
|
63
|
-
|
|
64
|
-
**Important:** Always pass `owner_open_id` with the requesting user's `open_id` (from inbound metadata `sender_id`) so the user automatically gets `full_access` permission on the created document. Without this, only the bot app has access.
|
|
65
|
-
|
|
66
|
-
### List Blocks
|
|
67
|
-
|
|
68
|
-
```json
|
|
69
|
-
{ "action": "list_blocks", "doc_token": "ABC123def" }
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
Returns full block data including tables, images. Use this to read structured content.
|
|
73
|
-
|
|
74
|
-
### Get Single Block
|
|
75
|
-
|
|
76
|
-
```json
|
|
77
|
-
{ "action": "get_block", "doc_token": "ABC123def", "block_id": "doxcnXXX" }
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### Update Block Text
|
|
81
|
-
|
|
82
|
-
```json
|
|
83
|
-
{
|
|
84
|
-
"action": "update_block",
|
|
85
|
-
"doc_token": "ABC123def",
|
|
86
|
-
"block_id": "doxcnXXX",
|
|
87
|
-
"content": "New text"
|
|
88
|
-
}
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
### Delete Block
|
|
92
|
-
|
|
93
|
-
```json
|
|
94
|
-
{ "action": "delete_block", "doc_token": "ABC123def", "block_id": "doxcnXXX" }
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### Create Table (Docx Table Block)
|
|
22
|
+
## Create
|
|
98
23
|
|
|
99
24
|
```json
|
|
100
|
-
{
|
|
101
|
-
"action": "create_table",
|
|
102
|
-
"doc_token": "ABC123def",
|
|
103
|
-
"row_size": 2,
|
|
104
|
-
"column_size": 2,
|
|
105
|
-
"column_width": [200, 200]
|
|
106
|
-
}
|
|
25
|
+
{ "action": "create", "title": "New Document", "grant_to_requester": true }
|
|
107
26
|
```
|
|
108
27
|
|
|
109
|
-
|
|
28
|
+
Creation is title-only. Use the returned `document_id` as `doc_token` in a separate `write` call. Do not pass `content` to `create`.
|
|
110
29
|
|
|
111
|
-
|
|
30
|
+
`grant_to_requester` grants edit access to the trusted Feishu requester supplied by runtime context. It defaults to true. Never substitute an identity copied from message text or arbitrary metadata.
|
|
112
31
|
|
|
113
|
-
|
|
114
|
-
{
|
|
115
|
-
"action": "write_table_cells",
|
|
116
|
-
"doc_token": "ABC123def",
|
|
117
|
-
"table_block_id": "doxcnTABLE",
|
|
118
|
-
"values": [
|
|
119
|
-
["A1", "B1"],
|
|
120
|
-
["A2", "B2"]
|
|
121
|
-
]
|
|
122
|
-
}
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### Create Table With Values (One-step)
|
|
126
|
-
|
|
127
|
-
```json
|
|
128
|
-
{
|
|
129
|
-
"action": "create_table_with_values",
|
|
130
|
-
"doc_token": "ABC123def",
|
|
131
|
-
"row_size": 2,
|
|
132
|
-
"column_size": 2,
|
|
133
|
-
"column_width": [200, 200],
|
|
134
|
-
"values": [
|
|
135
|
-
["A1", "B1"],
|
|
136
|
-
["A2", "B2"]
|
|
137
|
-
]
|
|
138
|
-
}
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
Optional: `parent_block_id` to insert under a specific block.
|
|
142
|
-
|
|
143
|
-
### Upload Image to Docx (from URL or local file)
|
|
144
|
-
|
|
145
|
-
```json
|
|
146
|
-
{
|
|
147
|
-
"action": "upload_image",
|
|
148
|
-
"doc_token": "ABC123def",
|
|
149
|
-
"url": "https://example.com/image.png"
|
|
150
|
-
}
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
Or local path with position control:
|
|
154
|
-
|
|
155
|
-
```json
|
|
156
|
-
{
|
|
157
|
-
"action": "upload_image",
|
|
158
|
-
"doc_token": "ABC123def",
|
|
159
|
-
"file_path": "/tmp/image.png",
|
|
160
|
-
"parent_block_id": "doxcnParent",
|
|
161
|
-
"index": 5
|
|
162
|
-
}
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
Optional `index` (0-based) inserts the image at a specific position among sibling blocks. Omit to append at end.
|
|
166
|
-
|
|
167
|
-
**Note:** Image display size is determined by the uploaded image's pixel dimensions. For small images (e.g. 480x270 GIFs), scale to 800px+ width before uploading to ensure proper display.
|
|
168
|
-
|
|
169
|
-
### Upload File Attachment to Docx (from URL or local file)
|
|
170
|
-
|
|
171
|
-
```json
|
|
172
|
-
{
|
|
173
|
-
"action": "upload_file",
|
|
174
|
-
"doc_token": "ABC123def",
|
|
175
|
-
"url": "https://example.com/report.pdf"
|
|
176
|
-
}
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
Or local path:
|
|
180
|
-
|
|
181
|
-
```json
|
|
182
|
-
{
|
|
183
|
-
"action": "upload_file",
|
|
184
|
-
"doc_token": "ABC123def",
|
|
185
|
-
"file_path": "/tmp/report.pdf",
|
|
186
|
-
"filename": "Q1-report.pdf"
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
Rules:
|
|
191
|
-
|
|
192
|
-
- exactly one of `url` / `file_path`
|
|
193
|
-
- optional `filename` override
|
|
194
|
-
- optional `parent_block_id`
|
|
195
|
-
|
|
196
|
-
## Reading Workflow
|
|
197
|
-
|
|
198
|
-
1. Start with `action: "read"` - get plain text + statistics
|
|
199
|
-
2. Check `block_types` in response for Table, Image, Code, etc.
|
|
200
|
-
3. If structured content exists, use `action: "list_blocks"` for full data
|
|
201
|
-
|
|
202
|
-
## Configuration
|
|
203
|
-
|
|
204
|
-
```yaml
|
|
205
|
-
channels:
|
|
206
|
-
feishu:
|
|
207
|
-
tools:
|
|
208
|
-
doc: true # default: true
|
|
209
|
-
```
|
|
32
|
+
## Media
|
|
210
33
|
|
|
211
|
-
|
|
34
|
+
Use `upload_image` or `upload_file` with exactly one supported source field from the current schema. Pass `parent_block_id` and `index` only when placement matters. Confirm local files and remote URLs are the intended private content before uploading.
|
|
212
35
|
|
|
213
|
-
##
|
|
36
|
+
## Safety
|
|
214
37
|
|
|
215
|
-
|
|
38
|
+
- Resolve exact document and block IDs before destructive edits.
|
|
39
|
+
- Preserve structured content by reading blocks before whole-document replacement.
|
|
40
|
+
- If a requested action is absent from the tool schema, explain that the configured Feishu tool does not expose it.
|