From 0aa13d3cf0a9e848767bfcb7c214bdf52654c834 Mon Sep 17 00:00:00 2001 From: openclaw-314 Date: Wed, 9 Sep 2026 16:13:31 +0800 Subject: [PATCH] auto: sync OpenClaw config 2026-09-09 16:13 --- extensions/openclaw-lark/LICENSE | 21 + extensions/openclaw-lark/README.md | 76 ++ extensions/openclaw-lark/bin/openclaw-lark.js | 39 + extensions/openclaw-lark/index.d.ts | 36 + extensions/openclaw-lark/index.js | 188 +++ extensions/openclaw-lark/openclaw.plugin.json | 64 + extensions/openclaw-lark/package.json | 63 + .../openclaw-lark/secret-contract-api.d.ts | 15 + .../openclaw-lark/secret-contract-api.js | 78 ++ .../skills/feishu-bitable/SKILL.md | 248 ++++ .../feishu-bitable/references/examples.md | 813 ++++++++++++ .../references/field-properties.md | 763 +++++++++++ .../references/record-values.md | 911 +++++++++++++ .../skills/feishu-calendar/SKILL.md | 242 ++++ .../skills/feishu-channel-rules/SKILL.md | 18 + .../references/markdown-syntax.md | 138 ++ .../skills/feishu-create-doc/SKILL.md | 719 ++++++++++ .../skills/feishu-fetch-doc/SKILL.md | 93 ++ .../skills/feishu-im-read/SKILL.md | 163 +++ .../openclaw-lark/skills/feishu-task/SKILL.md | 340 +++++ .../skills/feishu-troubleshoot/SKILL.md | 70 + .../skills/feishu-update-doc/SKILL.md | 285 ++++ .../openclaw-lark/src/card/builder.d.ts | 152 +++ extensions/openclaw-lark/src/card/builder.js | 794 +++++++++++ .../openclaw-lark/src/card/card-error.d.ts | 91 ++ .../openclaw-lark/src/card/card-error.js | 206 +++ .../openclaw-lark/src/card/cardkit.d.ts | 90 ++ extensions/openclaw-lark/src/card/cardkit.js | 203 +++ .../src/card/flush-controller.d.ts | 45 + .../src/card/flush-controller.js | 138 ++ .../src/card/image-resolver.d.ts | 45 + .../openclaw-lark/src/card/image-resolver.js | 116 ++ .../src/card/markdown-style.d.ts | 16 + .../openclaw-lark/src/card/markdown-style.js | 106 ++ .../src/card/reasoning-utils.d.ts | 14 + .../openclaw-lark/src/card/reasoning-utils.js | 64 + .../src/card/reply-dispatcher-types.d.ts | 132 ++ .../src/card/reply-dispatcher-types.js | 61 + .../src/card/reply-dispatcher.d.ts | 15 + .../src/card/reply-dispatcher.js | 455 +++++++ .../openclaw-lark/src/card/reply-mode.d.ts | 38 + .../openclaw-lark/src/card/reply-mode.js | 79 ++ .../src/card/streaming-card-controller.d.ts | 118 ++ .../src/card/streaming-card-controller.js | 1045 +++++++++++++++ .../src/card/tool-use-config.d.ts | 26 + .../openclaw-lark/src/card/tool-use-config.js | 76 ++ .../src/card/tool-use-display.d.ts | 37 + .../src/card/tool-use-display.js | 476 +++++++ .../src/card/tool-use-trace-store.d.ts | 51 + .../src/card/tool-use-trace-store.js | 271 ++++ .../src/card/unavailable-guard.d.ts | 35 + .../src/card/unavailable-guard.js | 87 ++ .../src/channel/abort-detect.d.ts | 47 + .../openclaw-lark/src/channel/abort-detect.js | 216 +++ .../openclaw-lark/src/channel/chat-queue.d.ts | 41 + .../openclaw-lark/src/channel/chat-queue.js | 68 + .../src/channel/config-adapter.d.ts | 23 + .../src/channel/config-adapter.js | 107 ++ .../openclaw-lark/src/channel/directory.d.ts | 57 + .../openclaw-lark/src/channel/directory.js | 197 +++ .../src/channel/event-handlers.d.ts | 17 + .../src/channel/event-handlers.js | 380 ++++++ .../src/channel/interactive-dispatch.d.ts | 59 + .../src/channel/interactive-dispatch.js | 188 +++ .../openclaw-lark/src/channel/monitor.d.ts | 17 + .../openclaw-lark/src/channel/monitor.js | 140 ++ .../src/channel/onboarding-config.d.ts | 18 + .../src/channel/onboarding-config.js | 96 ++ .../src/channel/onboarding-migrate.d.ts | 25 + .../src/channel/onboarding-migrate.js | 70 + .../openclaw-lark/src/channel/onboarding.d.ts | 12 + .../openclaw-lark/src/channel/onboarding.js | 300 +++++ .../openclaw-lark/src/channel/plugin.d.ts | 13 + .../openclaw-lark/src/channel/plugin.js | 310 +++++ .../openclaw-lark/src/channel/probe.d.ts | 14 + extensions/openclaw-lark/src/channel/probe.js | 24 + .../openclaw-lark/src/channel/types.d.ts | 37 + extensions/openclaw-lark/src/channel/types.js | 8 + .../openclaw-lark/src/commands/auth.d.ts | 21 + extensions/openclaw-lark/src/commands/auth.js | 165 +++ .../openclaw-lark/src/commands/diagnose.d.ts | 69 + .../openclaw-lark/src/commands/diagnose.js | 848 ++++++++++++ .../openclaw-lark/src/commands/doctor.d.ts | 27 + .../openclaw-lark/src/commands/doctor.js | 588 ++++++++ .../openclaw-lark/src/commands/index.d.ts | 25 + .../openclaw-lark/src/commands/index.js | 219 +++ .../openclaw-lark/src/commands/locale.d.ts | 7 + .../openclaw-lark/src/commands/locale.js | 8 + .../openclaw-lark/src/core/accounts.d.ts | 51 + extensions/openclaw-lark/src/core/accounts.js | 219 +++ .../openclaw-lark/src/core/agent-config.d.ts | 100 ++ .../openclaw-lark/src/core/agent-config.js | 148 +++ .../openclaw-lark/src/core/api-error.d.ts | 48 + .../openclaw-lark/src/core/api-error.js | 117 ++ .../src/core/app-owner-fallback.d.ts | 22 + .../src/core/app-owner-fallback.js | 39 + .../src/core/app-scope-checker.d.ts | 87 ++ .../src/core/app-scope-checker.js | 198 +++ .../openclaw-lark/src/core/auth-errors.d.ts | 144 ++ .../openclaw-lark/src/core/auth-errors.js | 160 +++ .../src/core/card-action-operator.d.ts | 33 + .../src/core/card-action-operator.js | 30 + .../src/core/chat-info-cache.d.ts | 67 + .../openclaw-lark/src/core/chat-info-cache.js | 165 +++ .../src/core/comment-target.d.ts | 65 + .../openclaw-lark/src/core/comment-target.js | 100 ++ .../openclaw-lark/src/core/config-schema.d.ts | 490 +++++++ .../openclaw-lark/src/core/config-schema.js | 223 ++++ .../openclaw-lark/src/core/device-flow.d.ts | 77 ++ .../openclaw-lark/src/core/device-flow.js | 217 +++ .../openclaw-lark/src/core/domains.d.ts | 18 + extensions/openclaw-lark/src/core/domains.js | 34 + .../openclaw-lark/src/core/feishu-fetch.d.ts | 18 + .../openclaw-lark/src/core/feishu-fetch.js | 28 + .../openclaw-lark/src/core/footer-config.d.ts | 24 + .../openclaw-lark/src/core/footer-config.js | 51 + .../openclaw-lark/src/core/lark-client.d.ts | 125 ++ .../openclaw-lark/src/core/lark-client.js | 468 +++++++ .../openclaw-lark/src/core/lark-logger.d.ts | 23 + .../openclaw-lark/src/core/lark-logger.js | 160 +++ .../openclaw-lark/src/core/lark-ticket.d.ts | 29 + .../openclaw-lark/src/core/lark-ticket.js | 40 + .../src/core/message-unavailable.d.ts | 53 + .../src/core/message-unavailable.js | 142 ++ .../openclaw-lark/src/core/owner-policy.d.ts | 32 + .../openclaw-lark/src/core/owner-policy.js | 55 + .../src/core/permission-url.d.ts | 22 + .../openclaw-lark/src/core/permission-url.js | 76 ++ .../openclaw-lark/src/core/raw-request.d.ts | 27 + .../openclaw-lark/src/core/raw-request.js | 90 ++ .../openclaw-lark/src/core/runtime-store.d.ts | 13 + .../openclaw-lark/src/core/runtime-store.js | 29 + .../openclaw-lark/src/core/scope-manager.d.ts | 168 +++ .../openclaw-lark/src/core/scope-manager.js | 224 ++++ .../openclaw-lark/src/core/sdk-compat.d.ts | 20 + .../openclaw-lark/src/core/sdk-compat.js | 28 + .../src/core/security-check.d.ts | 72 + .../openclaw-lark/src/core/security-check.js | 184 +++ .../src/core/shutdown-hooks.d.ts | 22 + .../openclaw-lark/src/core/shutdown-hooks.js | 61 + .../src/core/synthetic-target.d.ts | 33 + .../src/core/synthetic-target.js | 40 + .../openclaw-lark/src/core/targets.d.ts | 60 + extensions/openclaw-lark/src/core/targets.js | 173 +++ .../openclaw-lark/src/core/token-store.d.ts | 54 + .../openclaw-lark/src/core/token-store.js | 326 +++++ .../openclaw-lark/src/core/tool-client.d.ts | 176 +++ .../openclaw-lark/src/core/tool-client.js | 426 ++++++ .../openclaw-lark/src/core/tool-scopes.d.ts | 156 +++ .../openclaw-lark/src/core/tool-scopes.js | 344 +++++ .../openclaw-lark/src/core/tools-config.d.ts | 55 + .../openclaw-lark/src/core/tools-config.js | 143 ++ extensions/openclaw-lark/src/core/types.d.ts | 91 ++ extensions/openclaw-lark/src/core/types.js | 12 + .../openclaw-lark/src/core/uat-client.d.ts | 46 + .../openclaw-lark/src/core/uat-client.js | 192 +++ .../openclaw-lark/src/core/version.d.ts | 31 + extensions/openclaw-lark/src/core/version.js | 69 + .../src/messaging/converters/audio.d.ts | 8 + .../src/messaging/converters/audio.js | 24 + .../src/messaging/converters/calendar.d.ts | 13 + .../src/messaging/converters/calendar.js | 56 + .../converters/content-converter-helpers.d.ts | 30 + .../converters/content-converter-helpers.js | 82 ++ .../converters/content-converter.d.ts | 24 + .../messaging/converters/content-converter.js | 40 + .../src/messaging/converters/file.d.ts | 8 + .../src/messaging/converters/file.js | 24 + .../src/messaging/converters/folder.d.ts | 8 + .../src/messaging/converters/folder.js | 24 + .../src/messaging/converters/hongbao.d.ts | 8 + .../src/messaging/converters/hongbao.js | 20 + .../src/messaging/converters/image.d.ts | 8 + .../src/messaging/converters/image.js | 22 + .../src/messaging/converters/index.d.ts | 8 + .../src/messaging/converters/index.js | 53 + .../interactive/card-converter.d.ts | 76 ++ .../converters/interactive/card-converter.js | 1177 +++++++++++++++++ .../converters/interactive/card-utils.d.ts | 9 + .../converters/interactive/card-utils.js | 47 + .../converters/interactive/index.d.ts | 8 + .../messaging/converters/interactive/index.js | 25 + .../converters/interactive/legacy.d.ts | 11 + .../converters/interactive/legacy.js | 60 + .../converters/interactive/types.d.ts | 23 + .../messaging/converters/interactive/types.js | 27 + .../src/messaging/converters/location.d.ts | 8 + .../src/messaging/converters/location.js | 23 + .../messaging/converters/merge-forward.d.ts | 32 + .../src/messaging/converters/merge-forward.js | 235 ++++ .../src/messaging/converters/post.d.ts | 11 + .../src/messaging/converters/post.js | 139 ++ .../src/messaging/converters/share.d.ts | 9 + .../src/messaging/converters/share.js | 28 + .../src/messaging/converters/sticker.d.ts | 8 + .../src/messaging/converters/sticker.js | 22 + .../src/messaging/converters/system.d.ts | 12 + .../src/messaging/converters/system.js | 36 + .../src/messaging/converters/text.d.ts | 8 + .../src/messaging/converters/text.js | 18 + .../src/messaging/converters/todo.d.ts | 8 + .../src/messaging/converters/todo.js | 45 + .../src/messaging/converters/types.d.ts | 114 ++ .../src/messaging/converters/types.js | 8 + .../src/messaging/converters/unknown.d.ts | 8 + .../src/messaging/converters/unknown.js | 20 + .../src/messaging/converters/utils.d.ts | 22 + .../src/messaging/converters/utils.js | 57 + .../src/messaging/converters/video-chat.d.ts | 8 + .../src/messaging/converters/video-chat.js | 31 + .../src/messaging/converters/video.d.ts | 8 + .../src/messaging/converters/video.js | 35 + .../src/messaging/converters/vote.d.ts | 8 + .../src/messaging/converters/vote.js | 28 + .../src/messaging/inbound/bot-content.d.ts | 84 ++ .../src/messaging/inbound/bot-content.js | 117 ++ .../src/messaging/inbound/bot-loop-guard.d.ts | 48 + .../src/messaging/inbound/bot-loop-guard.js | 89 ++ .../messaging/inbound/comment-context.d.ts | 82 ++ .../src/messaging/inbound/comment-context.js | 353 +++++ .../messaging/inbound/comment-handler.d.ts | 30 + .../src/messaging/inbound/comment-handler.js | 269 ++++ .../src/messaging/inbound/dedup.d.ts | 59 + .../src/messaging/inbound/dedup.js | 121 ++ .../messaging/inbound/dispatch-builders.d.ts | 104 ++ .../messaging/inbound/dispatch-builders.js | 241 ++++ .../messaging/inbound/dispatch-commands.d.ts | 22 + .../messaging/inbound/dispatch-commands.js | 131 ++ .../messaging/inbound/dispatch-context.d.ts | 67 + .../src/messaging/inbound/dispatch-context.js | 153 +++ .../src/messaging/inbound/dispatch.d.ts | 50 + .../src/messaging/inbound/dispatch.js | 477 +++++++ .../src/messaging/inbound/enrich.d.ts | 102 ++ .../src/messaging/inbound/enrich.js | 236 ++++ .../src/messaging/inbound/gate-effects.d.ts | 23 + .../src/messaging/inbound/gate-effects.js | 46 + .../src/messaging/inbound/gate.d.ts | 91 ++ .../src/messaging/inbound/gate.js | 342 +++++ .../messaging/inbound/handler-registry.d.ts | 25 + .../src/messaging/inbound/handler-registry.js | 23 + .../src/messaging/inbound/handler.d.ts | 37 + .../src/messaging/inbound/handler.js | 286 ++++ .../src/messaging/inbound/media-resolver.d.ts | 32 + .../src/messaging/inbound/media-resolver.js | 91 ++ .../messaging/inbound/mention-registry.d.ts | 59 + .../src/messaging/inbound/mention-registry.js | 115 ++ .../src/messaging/inbound/mention.d.ts | 48 + .../src/messaging/inbound/mention.js | 102 ++ .../src/messaging/inbound/parse-io.d.ts | 50 + .../src/messaging/inbound/parse-io.js | 86 ++ .../src/messaging/inbound/parse.d.ts | 28 + .../src/messaging/inbound/parse.js | 128 ++ .../src/messaging/inbound/permission.d.ts | 17 + .../src/messaging/inbound/permission.js | 44 + .../src/messaging/inbound/policy.d.ts | 95 ++ .../src/messaging/inbound/policy.js | 168 +++ .../messaging/inbound/reaction-handler.d.ts | 62 + .../src/messaging/inbound/reaction-handler.js | 259 ++++ .../src/messaging/inbound/sentinel-store.d.ts | 37 + .../src/messaging/inbound/sentinel-store.js | 98 ++ .../messaging/inbound/synthetic-message.d.ts | 26 + .../messaging/inbound/synthetic-message.js | 59 + .../inbound/user-name-cache-store.d.ts | 62 + .../inbound/user-name-cache-store.js | 236 ++++ .../messaging/inbound/user-name-cache.d.ts | 78 ++ .../src/messaging/inbound/user-name-cache.js | 306 +++++ .../inbound/vc-meeting-invited-handler.d.ts | 20 + .../inbound/vc-meeting-invited-handler.js | 236 ++++ .../src/messaging/inbound/vc-sender.d.ts | 41 + .../src/messaging/inbound/vc-sender.js | 53 + .../src/messaging/outbound/actions.d.ts | 16 + .../src/messaging/outbound/actions.js | 329 +++++ .../messaging/outbound/bot-peer-context.d.ts | 42 + .../messaging/outbound/bot-peer-context.js | 40 + .../src/messaging/outbound/chat-manage.d.ts | 64 + .../src/messaging/outbound/chat-manage.js | 117 ++ .../src/messaging/outbound/deliver.d.ts | 186 +++ .../src/messaging/outbound/deliver.js | 425 ++++++ .../src/messaging/outbound/fetch.d.ts | 12 + .../src/messaging/outbound/fetch.js | 17 + .../src/messaging/outbound/forward.d.ts | 26 + .../src/messaging/outbound/forward.js | 51 + .../messaging/outbound/media-url-utils.d.ts | 29 + .../src/messaging/outbound/media-url-utils.js | 172 +++ .../src/messaging/outbound/media.d.ts | 260 ++++ .../src/messaging/outbound/media.js | 865 ++++++++++++ .../outbound/normalize-mentions.d.ts | 50 + .../messaging/outbound/normalize-mentions.js | 166 +++ .../messaging/outbound/outbound-mention.d.ts | 41 + .../messaging/outbound/outbound-mention.js | 112 ++ .../src/messaging/outbound/outbound.d.ts | 79 ++ .../src/messaging/outbound/outbound.js | 195 +++ .../src/messaging/outbound/reactions.d.ts | 124 ++ .../src/messaging/outbound/reactions.js | 384 ++++++ .../src/messaging/outbound/send.d.ts | 153 +++ .../src/messaging/outbound/send.js | 448 +++++++ .../src/messaging/outbound/typing.d.ts | 60 + .../src/messaging/outbound/typing.js | 139 ++ .../src/messaging/shared/message-lookup.d.ts | 54 + .../src/messaging/shared/message-lookup.js | 120 ++ .../openclaw-lark/src/messaging/types.d.ts | 316 +++++ .../openclaw-lark/src/messaging/types.js | 11 + .../src/tools/ask-user-question.d.ts | 32 + .../src/tools/ask-user-question.js | 871 ++++++++++++ .../openclaw-lark/src/tools/auto-auth.d.ts | 57 + .../openclaw-lark/src/tools/auto-auth.js | 904 +++++++++++++ .../openclaw-lark/src/tools/helpers.d.ts | 264 ++++ extensions/openclaw-lark/src/tools/helpers.js | 389 ++++++ .../src/tools/mcp/doc/create.d.ts | 12 + .../openclaw-lark/src/tools/mcp/doc/create.js | 47 + .../src/tools/mcp/doc/fetch.d.ts | 12 + .../openclaw-lark/src/tools/mcp/doc/fetch.js | 39 + .../src/tools/mcp/doc/index.d.ts | 12 + .../openclaw-lark/src/tools/mcp/doc/index.js | 50 + .../src/tools/mcp/doc/update.d.ts | 12 + .../openclaw-lark/src/tools/mcp/doc/update.js | 64 + .../openclaw-lark/src/tools/mcp/shared.d.ts | 59 + .../openclaw-lark/src/tools/mcp/shared.js | 239 ++++ .../tools/oapi/bitable/app-table-field.d.ts | 16 + .../src/tools/oapi/bitable/app-table-field.js | 225 ++++ .../tools/oapi/bitable/app-table-record.d.ts | 20 + .../tools/oapi/bitable/app-table-record.js | 439 ++++++ .../tools/oapi/bitable/app-table-view.d.ts | 16 + .../src/tools/oapi/bitable/app-table-view.js | 172 +++ .../src/tools/oapi/bitable/app-table.d.ts | 17 + .../src/tools/oapi/bitable/app-table.js | 195 +++ .../src/tools/oapi/bitable/app.d.ts | 18 + .../src/tools/oapi/bitable/app.js | 189 +++ .../src/tools/oapi/bitable/index.d.ts | 9 + .../src/tools/oapi/bitable/index.js | 17 + .../src/tools/oapi/calendar/calendar.d.ts | 15 + .../src/tools/oapi/calendar/calendar.js | 125 ++ .../tools/oapi/calendar/event-attendee.d.ts | 14 + .../src/tools/oapi/calendar/event-attendee.js | 161 +++ .../src/tools/oapi/calendar/event.d.ts | 16 + .../src/tools/oapi/calendar/event.js | 712 ++++++++++ .../src/tools/oapi/calendar/freebusy.d.ts | 13 + .../src/tools/oapi/calendar/freebusy.js | 114 ++ .../src/tools/oapi/calendar/index.d.ts | 8 + .../src/tools/oapi/calendar/index.js | 15 + .../src/tools/oapi/chat/chat.d.ts | 16 + .../openclaw-lark/src/tools/oapi/chat/chat.js | 127 ++ .../src/tools/oapi/chat/index.d.ts | 10 + .../src/tools/oapi/chat/index.js | 23 + .../src/tools/oapi/chat/members.d.ts | 11 + .../src/tools/oapi/chat/members.js | 84 ++ .../src/tools/oapi/common/get-user.d.ts | 12 + .../src/tools/oapi/common/get-user.js | 109 ++ .../src/tools/oapi/common/index.d.ts | 6 + .../src/tools/oapi/common/index.js | 11 + .../src/tools/oapi/common/search-user.d.ts | 11 + .../src/tools/oapi/common/search-user.js | 76 ++ .../src/tools/oapi/drive/doc-comments.d.ts | 15 + .../src/tools/oapi/drive/doc-comments.js | 351 +++++ .../src/tools/oapi/drive/doc-media.d.ts | 19 + .../src/tools/oapi/drive/doc-media.js | 371 ++++++ .../src/tools/oapi/drive/file.d.ts | 19 + .../src/tools/oapi/drive/file.js | 519 ++++++++ .../src/tools/oapi/drive/index.d.ts | 12 + .../src/tools/oapi/drive/index.js | 45 + .../openclaw-lark/src/tools/oapi/helpers.d.ts | 183 +++ .../openclaw-lark/src/tools/oapi/helpers.js | 385 ++++++ .../src/tools/oapi/im/format-messages.d.ts | 50 + .../src/tools/oapi/im/format-messages.js | 169 +++ .../src/tools/oapi/im/index.d.ts | 10 + .../openclaw-lark/src/tools/oapi/im/index.js | 25 + .../src/tools/oapi/im/message-read.d.ts | 13 + .../src/tools/oapi/im/message-read.js | 419 ++++++ .../src/tools/oapi/im/message.d.ts | 16 + .../src/tools/oapi/im/message.js | 281 ++++ .../src/tools/oapi/im/resource.d.ts | 13 + .../src/tools/oapi/im/resource.js | 186 +++ .../src/tools/oapi/im/time-utils.d.ts | 46 + .../src/tools/oapi/im/time-utils.js | 212 +++ .../src/tools/oapi/im/user-name-uat.d.ts | 26 + .../src/tools/oapi/im/user-name-uat.js | 143 ++ .../openclaw-lark/src/tools/oapi/index.d.ts | 11 + .../openclaw-lark/src/tools/oapi/index.js | 64 + .../src/tools/oapi/sdk-types.d.ts | 96 ++ .../openclaw-lark/src/tools/oapi/sdk-types.js | 13 + .../src/tools/oapi/search/doc-search.d.ts | 13 + .../src/tools/oapi/search/doc-search.js | 194 +++ .../src/tools/oapi/search/index.d.ts | 12 + .../src/tools/oapi/search/index.js | 37 + .../src/tools/oapi/sheets/index.d.ts | 12 + .../src/tools/oapi/sheets/index.js | 35 + .../src/tools/oapi/sheets/sheet.d.ts | 16 + .../src/tools/oapi/sheets/sheet.js | 688 ++++++++++ .../src/tools/oapi/task/attachment.d.ts | 18 + .../src/tools/oapi/task/attachment.js | 107 ++ .../src/tools/oapi/task/comment.d.ts | 15 + .../src/tools/oapi/task/comment.js | 149 +++ .../src/tools/oapi/task/index.d.ts | 11 + .../src/tools/oapi/task/index.js | 21 + .../src/tools/oapi/task/section.d.ts | 17 + .../src/tools/oapi/task/section.js | 293 ++++ .../src/tools/oapi/task/subtask.d.ts | 14 + .../src/tools/oapi/task/subtask.js | 171 +++ .../src/tools/oapi/task/task.d.ts | 19 + .../openclaw-lark/src/tools/oapi/task/task.js | 512 +++++++ .../src/tools/oapi/task/task_agent.d.ts | 14 + .../src/tools/oapi/task/task_agent.js | 108 ++ .../src/tools/oapi/task/tasklist.d.ts | 19 + .../src/tools/oapi/task/tasklist.js | 276 ++++ .../src/tools/oapi/wiki/index.d.ts | 12 + .../src/tools/oapi/wiki/index.js | 42 + .../src/tools/oapi/wiki/space-node.d.ts | 17 + .../src/tools/oapi/wiki/space-node.js | 233 ++++ .../src/tools/oapi/wiki/space.d.ts | 15 + .../src/tools/oapi/wiki/space.js | 133 ++ .../src/tools/oauth-batch-auth.d.ts | 11 + .../src/tools/oauth-batch-auth.js | 150 +++ .../openclaw-lark/src/tools/oauth-cards.d.ts | 39 + .../openclaw-lark/src/tools/oauth-cards.js | 324 +++++ extensions/openclaw-lark/src/tools/oauth.d.ts | 47 + extensions/openclaw-lark/src/tools/oauth.js | 592 +++++++++ .../src/tools/onboarding-auth.d.ts | 27 + .../src/tools/onboarding-auth.js | 133 ++ .../openclaw-lark/src/tools/tat/im/index.d.ts | 15 + .../openclaw-lark/src/tools/tat/im/index.js | 22 + .../src/tools/tat/im/resource.d.ts | 15 + .../src/tools/tat/im/resource.js | 192 +++ extensions/openclaw-lark/tsdown.config.d.ts | 2 + extensions/openclaw-lark/tsdown.config.js | 25 + extensions/openclaw-lark/vitest.config.d.ts | 2 + extensions/openclaw-lark/vitest.config.js | 12 + openclaw.json | 93 +- plugin-skills/feishu-bitable | 1 + plugin-skills/feishu-calendar | 1 + plugin-skills/feishu-channel-rules | 1 + plugin-skills/feishu-create-doc | 1 + plugin-skills/feishu-fetch-doc | 1 + plugin-skills/feishu-im-read | 1 + plugin-skills/feishu-task | 1 + plugin-skills/feishu-troubleshoot | 1 + plugin-skills/feishu-update-doc | 1 + workspace-finances/IDENTITY.md | 3 +- workspace-fitness/MEMORY.md | 35 +- workspace-fitness/memory/2026-09-09.md | 31 + workspace-travel/IDENTITY.md | 2 + 440 files changed, 51636 insertions(+), 13 deletions(-) create mode 100644 extensions/openclaw-lark/LICENSE create mode 100644 extensions/openclaw-lark/README.md create mode 100755 extensions/openclaw-lark/bin/openclaw-lark.js create mode 100644 extensions/openclaw-lark/index.d.ts create mode 100644 extensions/openclaw-lark/index.js create mode 100644 extensions/openclaw-lark/openclaw.plugin.json create mode 100644 extensions/openclaw-lark/package.json create mode 100644 extensions/openclaw-lark/secret-contract-api.d.ts create mode 100644 extensions/openclaw-lark/secret-contract-api.js create mode 100644 extensions/openclaw-lark/skills/feishu-bitable/SKILL.md create mode 100644 extensions/openclaw-lark/skills/feishu-bitable/references/examples.md create mode 100644 extensions/openclaw-lark/skills/feishu-bitable/references/field-properties.md create mode 100644 extensions/openclaw-lark/skills/feishu-bitable/references/record-values.md create mode 100644 extensions/openclaw-lark/skills/feishu-calendar/SKILL.md create mode 100644 extensions/openclaw-lark/skills/feishu-channel-rules/SKILL.md create mode 100644 extensions/openclaw-lark/skills/feishu-channel-rules/references/markdown-syntax.md create mode 100644 extensions/openclaw-lark/skills/feishu-create-doc/SKILL.md create mode 100644 extensions/openclaw-lark/skills/feishu-fetch-doc/SKILL.md create mode 100644 extensions/openclaw-lark/skills/feishu-im-read/SKILL.md create mode 100644 extensions/openclaw-lark/skills/feishu-task/SKILL.md create mode 100644 extensions/openclaw-lark/skills/feishu-troubleshoot/SKILL.md create mode 100644 extensions/openclaw-lark/skills/feishu-update-doc/SKILL.md create mode 100644 extensions/openclaw-lark/src/card/builder.d.ts create mode 100644 extensions/openclaw-lark/src/card/builder.js create mode 100644 extensions/openclaw-lark/src/card/card-error.d.ts create mode 100644 extensions/openclaw-lark/src/card/card-error.js create mode 100644 extensions/openclaw-lark/src/card/cardkit.d.ts create mode 100644 extensions/openclaw-lark/src/card/cardkit.js create mode 100644 extensions/openclaw-lark/src/card/flush-controller.d.ts create mode 100644 extensions/openclaw-lark/src/card/flush-controller.js create mode 100644 extensions/openclaw-lark/src/card/image-resolver.d.ts create mode 100644 extensions/openclaw-lark/src/card/image-resolver.js create mode 100644 extensions/openclaw-lark/src/card/markdown-style.d.ts create mode 100644 extensions/openclaw-lark/src/card/markdown-style.js create mode 100644 extensions/openclaw-lark/src/card/reasoning-utils.d.ts create mode 100644 extensions/openclaw-lark/src/card/reasoning-utils.js create mode 100644 extensions/openclaw-lark/src/card/reply-dispatcher-types.d.ts create mode 100644 extensions/openclaw-lark/src/card/reply-dispatcher-types.js create mode 100644 extensions/openclaw-lark/src/card/reply-dispatcher.d.ts create mode 100644 extensions/openclaw-lark/src/card/reply-dispatcher.js create mode 100644 extensions/openclaw-lark/src/card/reply-mode.d.ts create mode 100644 extensions/openclaw-lark/src/card/reply-mode.js create mode 100644 extensions/openclaw-lark/src/card/streaming-card-controller.d.ts create mode 100644 extensions/openclaw-lark/src/card/streaming-card-controller.js create mode 100644 extensions/openclaw-lark/src/card/tool-use-config.d.ts create mode 100644 extensions/openclaw-lark/src/card/tool-use-config.js create mode 100644 extensions/openclaw-lark/src/card/tool-use-display.d.ts create mode 100644 extensions/openclaw-lark/src/card/tool-use-display.js create mode 100644 extensions/openclaw-lark/src/card/tool-use-trace-store.d.ts create mode 100644 extensions/openclaw-lark/src/card/tool-use-trace-store.js create mode 100644 extensions/openclaw-lark/src/card/unavailable-guard.d.ts create mode 100644 extensions/openclaw-lark/src/card/unavailable-guard.js create mode 100644 extensions/openclaw-lark/src/channel/abort-detect.d.ts create mode 100644 extensions/openclaw-lark/src/channel/abort-detect.js create mode 100644 extensions/openclaw-lark/src/channel/chat-queue.d.ts create mode 100644 extensions/openclaw-lark/src/channel/chat-queue.js create mode 100644 extensions/openclaw-lark/src/channel/config-adapter.d.ts create mode 100644 extensions/openclaw-lark/src/channel/config-adapter.js create mode 100644 extensions/openclaw-lark/src/channel/directory.d.ts create mode 100644 extensions/openclaw-lark/src/channel/directory.js create mode 100644 extensions/openclaw-lark/src/channel/event-handlers.d.ts create mode 100644 extensions/openclaw-lark/src/channel/event-handlers.js create mode 100644 extensions/openclaw-lark/src/channel/interactive-dispatch.d.ts create mode 100644 extensions/openclaw-lark/src/channel/interactive-dispatch.js create mode 100644 extensions/openclaw-lark/src/channel/monitor.d.ts create mode 100644 extensions/openclaw-lark/src/channel/monitor.js create mode 100644 extensions/openclaw-lark/src/channel/onboarding-config.d.ts create mode 100644 extensions/openclaw-lark/src/channel/onboarding-config.js create mode 100644 extensions/openclaw-lark/src/channel/onboarding-migrate.d.ts create mode 100644 extensions/openclaw-lark/src/channel/onboarding-migrate.js create mode 100644 extensions/openclaw-lark/src/channel/onboarding.d.ts create mode 100644 extensions/openclaw-lark/src/channel/onboarding.js create mode 100644 extensions/openclaw-lark/src/channel/plugin.d.ts create mode 100644 extensions/openclaw-lark/src/channel/plugin.js create mode 100644 extensions/openclaw-lark/src/channel/probe.d.ts create mode 100644 extensions/openclaw-lark/src/channel/probe.js create mode 100644 extensions/openclaw-lark/src/channel/types.d.ts create mode 100644 extensions/openclaw-lark/src/channel/types.js create mode 100644 extensions/openclaw-lark/src/commands/auth.d.ts create mode 100644 extensions/openclaw-lark/src/commands/auth.js create mode 100644 extensions/openclaw-lark/src/commands/diagnose.d.ts create mode 100644 extensions/openclaw-lark/src/commands/diagnose.js create mode 100644 extensions/openclaw-lark/src/commands/doctor.d.ts create mode 100644 extensions/openclaw-lark/src/commands/doctor.js create mode 100644 extensions/openclaw-lark/src/commands/index.d.ts create mode 100644 extensions/openclaw-lark/src/commands/index.js create mode 100644 extensions/openclaw-lark/src/commands/locale.d.ts create mode 100644 extensions/openclaw-lark/src/commands/locale.js create mode 100644 extensions/openclaw-lark/src/core/accounts.d.ts create mode 100644 extensions/openclaw-lark/src/core/accounts.js create mode 100644 extensions/openclaw-lark/src/core/agent-config.d.ts create mode 100644 extensions/openclaw-lark/src/core/agent-config.js create mode 100644 extensions/openclaw-lark/src/core/api-error.d.ts create mode 100644 extensions/openclaw-lark/src/core/api-error.js create mode 100644 extensions/openclaw-lark/src/core/app-owner-fallback.d.ts create mode 100644 extensions/openclaw-lark/src/core/app-owner-fallback.js create mode 100644 extensions/openclaw-lark/src/core/app-scope-checker.d.ts create mode 100644 extensions/openclaw-lark/src/core/app-scope-checker.js create mode 100644 extensions/openclaw-lark/src/core/auth-errors.d.ts create mode 100644 extensions/openclaw-lark/src/core/auth-errors.js create mode 100644 extensions/openclaw-lark/src/core/card-action-operator.d.ts create mode 100644 extensions/openclaw-lark/src/core/card-action-operator.js create mode 100644 extensions/openclaw-lark/src/core/chat-info-cache.d.ts create mode 100644 extensions/openclaw-lark/src/core/chat-info-cache.js create mode 100644 extensions/openclaw-lark/src/core/comment-target.d.ts create mode 100644 extensions/openclaw-lark/src/core/comment-target.js create mode 100644 extensions/openclaw-lark/src/core/config-schema.d.ts create mode 100644 extensions/openclaw-lark/src/core/config-schema.js create mode 100644 extensions/openclaw-lark/src/core/device-flow.d.ts create mode 100644 extensions/openclaw-lark/src/core/device-flow.js create mode 100644 extensions/openclaw-lark/src/core/domains.d.ts create mode 100644 extensions/openclaw-lark/src/core/domains.js create mode 100644 extensions/openclaw-lark/src/core/feishu-fetch.d.ts create mode 100644 extensions/openclaw-lark/src/core/feishu-fetch.js create mode 100644 extensions/openclaw-lark/src/core/footer-config.d.ts create mode 100644 extensions/openclaw-lark/src/core/footer-config.js create mode 100644 extensions/openclaw-lark/src/core/lark-client.d.ts create mode 100644 extensions/openclaw-lark/src/core/lark-client.js create mode 100644 extensions/openclaw-lark/src/core/lark-logger.d.ts create mode 100644 extensions/openclaw-lark/src/core/lark-logger.js create mode 100644 extensions/openclaw-lark/src/core/lark-ticket.d.ts create mode 100644 extensions/openclaw-lark/src/core/lark-ticket.js create mode 100644 extensions/openclaw-lark/src/core/message-unavailable.d.ts create mode 100644 extensions/openclaw-lark/src/core/message-unavailable.js create mode 100644 extensions/openclaw-lark/src/core/owner-policy.d.ts create mode 100644 extensions/openclaw-lark/src/core/owner-policy.js create mode 100644 extensions/openclaw-lark/src/core/permission-url.d.ts create mode 100644 extensions/openclaw-lark/src/core/permission-url.js create mode 100644 extensions/openclaw-lark/src/core/raw-request.d.ts create mode 100644 extensions/openclaw-lark/src/core/raw-request.js create mode 100644 extensions/openclaw-lark/src/core/runtime-store.d.ts create mode 100644 extensions/openclaw-lark/src/core/runtime-store.js create mode 100644 extensions/openclaw-lark/src/core/scope-manager.d.ts create mode 100644 extensions/openclaw-lark/src/core/scope-manager.js create mode 100644 extensions/openclaw-lark/src/core/sdk-compat.d.ts create mode 100644 extensions/openclaw-lark/src/core/sdk-compat.js create mode 100644 extensions/openclaw-lark/src/core/security-check.d.ts create mode 100644 extensions/openclaw-lark/src/core/security-check.js create mode 100644 extensions/openclaw-lark/src/core/shutdown-hooks.d.ts create mode 100644 extensions/openclaw-lark/src/core/shutdown-hooks.js create mode 100644 extensions/openclaw-lark/src/core/synthetic-target.d.ts create mode 100644 extensions/openclaw-lark/src/core/synthetic-target.js create mode 100644 extensions/openclaw-lark/src/core/targets.d.ts create mode 100644 extensions/openclaw-lark/src/core/targets.js create mode 100644 extensions/openclaw-lark/src/core/token-store.d.ts create mode 100644 extensions/openclaw-lark/src/core/token-store.js create mode 100644 extensions/openclaw-lark/src/core/tool-client.d.ts create mode 100644 extensions/openclaw-lark/src/core/tool-client.js create mode 100644 extensions/openclaw-lark/src/core/tool-scopes.d.ts create mode 100644 extensions/openclaw-lark/src/core/tool-scopes.js create mode 100644 extensions/openclaw-lark/src/core/tools-config.d.ts create mode 100644 extensions/openclaw-lark/src/core/tools-config.js create mode 100644 extensions/openclaw-lark/src/core/types.d.ts create mode 100644 extensions/openclaw-lark/src/core/types.js create mode 100644 extensions/openclaw-lark/src/core/uat-client.d.ts create mode 100644 extensions/openclaw-lark/src/core/uat-client.js create mode 100644 extensions/openclaw-lark/src/core/version.d.ts create mode 100644 extensions/openclaw-lark/src/core/version.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/audio.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/audio.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/calendar.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/calendar.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/content-converter-helpers.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/content-converter-helpers.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/content-converter.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/content-converter.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/file.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/file.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/folder.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/folder.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/hongbao.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/hongbao.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/image.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/image.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/index.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/index.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/interactive/card-converter.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/interactive/card-converter.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/interactive/card-utils.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/interactive/card-utils.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/interactive/index.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/interactive/index.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/interactive/legacy.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/interactive/legacy.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/interactive/types.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/interactive/types.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/location.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/location.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/merge-forward.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/merge-forward.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/post.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/post.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/share.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/share.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/sticker.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/sticker.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/system.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/system.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/text.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/text.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/todo.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/todo.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/types.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/types.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/unknown.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/unknown.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/utils.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/utils.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/video-chat.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/video-chat.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/video.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/video.js create mode 100644 extensions/openclaw-lark/src/messaging/converters/vote.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/converters/vote.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/bot-content.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/bot-content.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/bot-loop-guard.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/bot-loop-guard.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/comment-context.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/comment-context.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/comment-handler.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/comment-handler.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/dedup.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/dedup.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/dispatch-builders.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/dispatch-builders.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/dispatch-commands.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/dispatch-commands.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/dispatch-context.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/dispatch-context.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/dispatch.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/dispatch.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/enrich.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/enrich.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/gate-effects.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/gate-effects.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/gate.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/gate.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/handler-registry.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/handler-registry.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/handler.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/handler.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/media-resolver.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/media-resolver.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/mention-registry.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/mention-registry.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/mention.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/mention.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/parse-io.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/parse-io.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/parse.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/parse.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/permission.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/permission.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/policy.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/policy.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/reaction-handler.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/reaction-handler.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/sentinel-store.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/sentinel-store.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/synthetic-message.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/synthetic-message.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/user-name-cache-store.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/user-name-cache-store.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/user-name-cache.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/user-name-cache.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/vc-meeting-invited-handler.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/vc-meeting-invited-handler.js create mode 100644 extensions/openclaw-lark/src/messaging/inbound/vc-sender.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/inbound/vc-sender.js create mode 100644 extensions/openclaw-lark/src/messaging/outbound/actions.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/outbound/actions.js create mode 100644 extensions/openclaw-lark/src/messaging/outbound/bot-peer-context.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/outbound/bot-peer-context.js create mode 100644 extensions/openclaw-lark/src/messaging/outbound/chat-manage.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/outbound/chat-manage.js create mode 100644 extensions/openclaw-lark/src/messaging/outbound/deliver.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/outbound/deliver.js create mode 100644 extensions/openclaw-lark/src/messaging/outbound/fetch.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/outbound/fetch.js create mode 100644 extensions/openclaw-lark/src/messaging/outbound/forward.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/outbound/forward.js create mode 100644 extensions/openclaw-lark/src/messaging/outbound/media-url-utils.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/outbound/media-url-utils.js create mode 100644 extensions/openclaw-lark/src/messaging/outbound/media.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/outbound/media.js create mode 100644 extensions/openclaw-lark/src/messaging/outbound/normalize-mentions.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/outbound/normalize-mentions.js create mode 100644 extensions/openclaw-lark/src/messaging/outbound/outbound-mention.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/outbound/outbound-mention.js create mode 100644 extensions/openclaw-lark/src/messaging/outbound/outbound.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/outbound/outbound.js create mode 100644 extensions/openclaw-lark/src/messaging/outbound/reactions.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/outbound/reactions.js create mode 100644 extensions/openclaw-lark/src/messaging/outbound/send.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/outbound/send.js create mode 100644 extensions/openclaw-lark/src/messaging/outbound/typing.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/outbound/typing.js create mode 100644 extensions/openclaw-lark/src/messaging/shared/message-lookup.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/shared/message-lookup.js create mode 100644 extensions/openclaw-lark/src/messaging/types.d.ts create mode 100644 extensions/openclaw-lark/src/messaging/types.js create mode 100644 extensions/openclaw-lark/src/tools/ask-user-question.d.ts create mode 100644 extensions/openclaw-lark/src/tools/ask-user-question.js create mode 100644 extensions/openclaw-lark/src/tools/auto-auth.d.ts create mode 100644 extensions/openclaw-lark/src/tools/auto-auth.js create mode 100644 extensions/openclaw-lark/src/tools/helpers.d.ts create mode 100644 extensions/openclaw-lark/src/tools/helpers.js create mode 100644 extensions/openclaw-lark/src/tools/mcp/doc/create.d.ts create mode 100644 extensions/openclaw-lark/src/tools/mcp/doc/create.js create mode 100644 extensions/openclaw-lark/src/tools/mcp/doc/fetch.d.ts create mode 100644 extensions/openclaw-lark/src/tools/mcp/doc/fetch.js create mode 100644 extensions/openclaw-lark/src/tools/mcp/doc/index.d.ts create mode 100644 extensions/openclaw-lark/src/tools/mcp/doc/index.js create mode 100644 extensions/openclaw-lark/src/tools/mcp/doc/update.d.ts create mode 100644 extensions/openclaw-lark/src/tools/mcp/doc/update.js create mode 100644 extensions/openclaw-lark/src/tools/mcp/shared.d.ts create mode 100644 extensions/openclaw-lark/src/tools/mcp/shared.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/bitable/app-table-field.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/bitable/app-table-field.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/bitable/app-table-record.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/bitable/app-table-record.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/bitable/app-table-view.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/bitable/app-table-view.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/bitable/app-table.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/bitable/app-table.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/bitable/app.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/bitable/app.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/bitable/index.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/bitable/index.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/calendar/calendar.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/calendar/calendar.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/calendar/event-attendee.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/calendar/event-attendee.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/calendar/event.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/calendar/event.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/calendar/freebusy.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/calendar/freebusy.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/calendar/index.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/calendar/index.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/chat/chat.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/chat/chat.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/chat/index.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/chat/index.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/chat/members.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/chat/members.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/common/get-user.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/common/get-user.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/common/index.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/common/index.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/common/search-user.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/common/search-user.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/drive/doc-comments.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/drive/doc-comments.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/drive/doc-media.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/drive/doc-media.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/drive/file.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/drive/file.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/drive/index.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/drive/index.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/helpers.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/helpers.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/im/format-messages.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/im/format-messages.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/im/index.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/im/index.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/im/message-read.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/im/message-read.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/im/message.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/im/message.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/im/resource.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/im/resource.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/im/time-utils.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/im/time-utils.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/im/user-name-uat.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/im/user-name-uat.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/index.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/index.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/sdk-types.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/sdk-types.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/search/doc-search.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/search/doc-search.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/search/index.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/search/index.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/sheets/index.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/sheets/index.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/sheets/sheet.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/sheets/sheet.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/task/attachment.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/task/attachment.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/task/comment.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/task/comment.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/task/index.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/task/index.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/task/section.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/task/section.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/task/subtask.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/task/subtask.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/task/task.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/task/task.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/task/task_agent.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/task/task_agent.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/task/tasklist.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/task/tasklist.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/wiki/index.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/wiki/index.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/wiki/space-node.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/wiki/space-node.js create mode 100644 extensions/openclaw-lark/src/tools/oapi/wiki/space.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oapi/wiki/space.js create mode 100644 extensions/openclaw-lark/src/tools/oauth-batch-auth.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oauth-batch-auth.js create mode 100644 extensions/openclaw-lark/src/tools/oauth-cards.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oauth-cards.js create mode 100644 extensions/openclaw-lark/src/tools/oauth.d.ts create mode 100644 extensions/openclaw-lark/src/tools/oauth.js create mode 100644 extensions/openclaw-lark/src/tools/onboarding-auth.d.ts create mode 100644 extensions/openclaw-lark/src/tools/onboarding-auth.js create mode 100644 extensions/openclaw-lark/src/tools/tat/im/index.d.ts create mode 100644 extensions/openclaw-lark/src/tools/tat/im/index.js create mode 100644 extensions/openclaw-lark/src/tools/tat/im/resource.d.ts create mode 100644 extensions/openclaw-lark/src/tools/tat/im/resource.js create mode 100644 extensions/openclaw-lark/tsdown.config.d.ts create mode 100644 extensions/openclaw-lark/tsdown.config.js create mode 100644 extensions/openclaw-lark/vitest.config.d.ts create mode 100644 extensions/openclaw-lark/vitest.config.js create mode 120000 plugin-skills/feishu-bitable create mode 120000 plugin-skills/feishu-calendar create mode 120000 plugin-skills/feishu-channel-rules create mode 120000 plugin-skills/feishu-create-doc create mode 120000 plugin-skills/feishu-fetch-doc create mode 120000 plugin-skills/feishu-im-read create mode 120000 plugin-skills/feishu-task create mode 120000 plugin-skills/feishu-troubleshoot create mode 120000 plugin-skills/feishu-update-doc create mode 100644 workspace-fitness/memory/2026-09-09.md diff --git a/extensions/openclaw-lark/LICENSE b/extensions/openclaw-lark/LICENSE new file mode 100644 index 0000000..2b8bbb5 --- /dev/null +++ b/extensions/openclaw-lark/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Lark Technologies Pte. Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/extensions/openclaw-lark/README.md b/extensions/openclaw-lark/README.md new file mode 100644 index 0000000..01da635 --- /dev/null +++ b/extensions/openclaw-lark/README.md @@ -0,0 +1,76 @@ +# OpenClaw Lark/Feishu Plugin + +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) +[![npm version](https://img.shields.io/npm/v/@larksuite/openclaw-lark.svg)](https://www.npmjs.com/package/@larksuite/openclaw-lark) +[![Node.js Version](https://img.shields.io/badge/node-%3E%3D22-blue.svg)](https://nodejs.org/) + +[中文版](./README.zh.md) | English + +This is the official Lark/Feishu plugin for OpenClaw, developed and maintained by the Lark/Feishu Open Platform team. It seamlessly connects your OpenClaw Agent to your Lark/Feishu workspace, enabling it to directly read from and write to messages, docs, bases, calendars, tasks, and more. + +## Features + +This plugin provides comprehensive Lark/Feishu integration for OpenClaw, including: + +| Category | Capabilities | +|------|------| +| 💬 Messenger | Read messages (group/DM history, thread replies), send messages, reply to messages, search messages, download images/files | +| 📄 Docs | Create, update, and read documents | +| 📊 Base | Create/manage bases, tables, fields, records (CRUD, batch operations, advanced filtering), views | +| 📈 Sheets | Create, edit, and view spreadsheets | +| 📅 Calendar | Manage calendars and events (create/query/update/delete/search), manage attendees, check free/busy status | +| ✅ Tasks | Manage tasks (create/query/update/complete), manage task lists, subtasks, and comments | + +Additionally, the plugin supports: +- **📱 Interactive Cards**: Real-time status updates (Thinking/Generating/Complete), plus confirmation buttons for sensitive operations +- **🌊 Streaming Responses**: Live streaming text directly within message cards +- **🔒 Permission Policies**: Flexible access control policies for DMs and group chats +- **⚙️ Advanced Group Configuration**: Per-group settings including allowlists, skill bindings, and custom system prompts + +## Security & Risk Warnings (Read Before Use) + +This plugin integrates with OpenClaw AI automation capabilities and carries inherent risks such as model hallucinations, unpredictable execution, and prompt injection. After you authorize Lark/Feishu permissions, OpenClaw will act under your user identity within the authorized scope, which may lead to high-risk consequences such as leakage of sensitive data or unauthorized operations. Please use with caution. + +To reduce these risks, the plugin enables default security protections at multiple layers. However, these risks still exist. We strongly recommend that you do not proactively modify any default security settings; once relevant restrictions are relaxed, the risks will increase significantly, and you will bear the consequences. + +We recommend using the Lark/Feishu bot connected to OpenClaw as a private conversational assistant. Do not add it to group chats or allow other users to interact with it, to avoid abuse of permissions or data leakage. + +Please fully understand all usage risks. By using this plugin, you are deemed to voluntarily assume all related responsibilities. + + +**Disclaimer:** + +This software is licensed under the MIT License. When running, it calls Lark/Feishu Open Platform APIs. To use these APIs, you must comply with the following agreements and privacy policies: + +- [Feishu Privacy Policy](https://www.feishu.cn/en/privacy?from=openclaw_plugin_readme) +- [Feishu User Terms of Service](https://www.feishu.cn/en/terms?from=openclaw_plugin_readme) +- [Feishu Store App Service Provider Security Management Specifications](https://open.larkoffice.com/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/management-practice/app-service-provider-security-management-specifications) + +- [Lark Privacy Policy](https://www.larksuite.com/user-terms-of-service) +- [Lark User Terms of Service](https://www.larksuite.com/privacy-policy) + +## Requirements & Installation + +Before you start, make sure you have the following: + +- **Node.js**: `v22` or higher. +- **OpenClaw**: OpenClaw is installed and works properly. For details, visit the [OpenClaw official website](https://openclaw.ai). + +> **Note**: OpenClaw version must be **2026.2.26** or higher. Check with `openclaw -v`. If below this version, you may encounter issues. Upgrade with: +> ```bash +> npm install -g openclaw +> ``` + +## Usage Guide + +[How to Use the Official Lark/Feishu Plugin for OpenClaw](https://bytedance.larkoffice.com/docx/MFK7dDFLFoVlOGxWCv5cTXKmnMh) + +## Contributing + +Community contributions are welcome! If you find a bug or have feature suggestions, please submit an [Issue](https://github.com/larksuite/openclaw-larksuite/issues) or a [Pull Request](https://github.com/larksuite/openclaw-larksuite/pulls). + +For major changes, we recommend discussing with us first via an Issue. + +## License + +This project is licensed under the **MIT License**. See [LICENSE](./LICENSE.md) for details. diff --git a/extensions/openclaw-lark/bin/openclaw-lark.js b/extensions/openclaw-lark/bin/openclaw-lark.js new file mode 100755 index 0000000..5bf3fd8 --- /dev/null +++ b/extensions/openclaw-lark/bin/openclaw-lark.js @@ -0,0 +1,39 @@ +#!/usr/bin/env node +import { createRequire } from 'node:module'; +import { dirname, join } from 'node:path'; + +const mod = ['child', 'process'].join('_'); +const { execFileSync } = createRequire(import.meta.url)(`node:${mod}`); + +// --tools-version lets the user pin a specific version +const args = process.argv.slice(2); +let version = 'latest'; + +const vIdx = args.indexOf('--tools-version'); +if (vIdx !== -1) { + version = args[vIdx + 1]; + // Remove --tools-version from forwarded args + args.splice(vIdx, 2); +} + +const allArgs = ['--yes', '--prefer-online', `@larksuite/openclaw-lark-tools@${version}`, ...args]; + +try { + if (process.platform === 'win32') { + // On Windows, npx is a .cmd shim that can be broken or trigger + // DEP0190. Bypass it entirely: run node with the npx-cli.js + // script located next to the running node binary. + const npxCli = join(dirname(process.execPath), 'node_modules', 'npm', 'bin', 'npx-cli.js'); + execFileSync(process.execPath, [npxCli, ...allArgs], { + stdio: 'inherit', + env: { + ...process.env, + NODE_OPTIONS: [process.env.NODE_OPTIONS, '--disable-warning=DEP0190'].filter(Boolean).join(' '), + }, + }); + } else { + execFileSync('npx', allArgs, { stdio: 'inherit' }); + } +} catch (error) { + process.exit(error.status ?? 1); +} diff --git a/extensions/openclaw-lark/index.d.ts b/extensions/openclaw-lark/index.d.ts new file mode 100644 index 0000000..893a145 --- /dev/null +++ b/extensions/openclaw-lark/index.d.ts @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates + * SPDX-License-Identifier: MIT + * + * OpenClaw Lark/Feishu plugin entry point. + * + * Registers the Feishu channel and all tool families: + * doc, wiki, drive, perm, bitable, task, calendar. + */ +import type { OpenClawPluginApi } from 'openclaw/plugin-sdk'; +export { monitorFeishuProvider } from './src/channel/monitor'; +export { sendMessageFeishu, sendCardFeishu, updateCardFeishu, editMessageFeishu } from './src/messaging/outbound/send'; +export { getMessageFeishu } from './src/messaging/outbound/fetch'; +export { uploadImageLark, uploadFileLark, sendImageLark, sendFileLark, sendAudioLark, uploadAndSendMediaLark, } from './src/messaging/outbound/media'; +export { sendTextLark, sendCardLark, sendMediaLark, type SendTextLarkParams, type SendCardLarkParams, type SendMediaLarkParams, } from './src/messaging/outbound/deliver'; +export { type FeishuChannelData } from './src/messaging/outbound/outbound'; +export { probeFeishu } from './src/channel/probe'; +export { addReactionFeishu, removeReactionFeishu, listReactionsFeishu, FeishuEmoji, VALID_FEISHU_EMOJI_TYPES, } from './src/messaging/outbound/reactions'; +export { forwardMessageFeishu } from './src/messaging/outbound/forward'; +export { updateChatFeishu, addChatMembersFeishu, removeChatMembersFeishu, listChatMembersFeishu, } from './src/messaging/outbound/chat-manage'; +export { feishuMessageActions } from './src/messaging/outbound/actions'; +export { mentionedBot, nonBotMentions, extractMessageBody, formatMentionForText, formatMentionForCard, formatMentionAllForText, formatMentionAllForCard, buildMentionedMessage, buildMentionedCardContent, type MentionInfo, } from './src/messaging/inbound/mention'; +export { feishuPlugin } from './src/channel/plugin'; +export type { MessageContext, RawMessage, RawSender, FeishuMessageContext, FeishuReactionCreatedEvent, } from './src/messaging/types'; +export { handleFeishuReaction } from './src/messaging/inbound/reaction-handler'; +export { parseMessageEvent } from './src/messaging/inbound/parse'; +export { checkMessageGate } from './src/messaging/inbound/gate'; +export { isMessageExpired } from './src/messaging/inbound/dedup'; +declare const plugin: { + id: string; + name: string; + description: string; + configSchema: any; + register(api: OpenClawPluginApi): void; +}; +export default plugin; diff --git a/extensions/openclaw-lark/index.js b/extensions/openclaw-lark/index.js new file mode 100644 index 0000000..6547e68 --- /dev/null +++ b/extensions/openclaw-lark/index.js @@ -0,0 +1,188 @@ +"use strict"; +/** + * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates + * SPDX-License-Identifier: MIT + * + * OpenClaw Lark/Feishu plugin entry point. + * + * Registers the Feishu channel and all tool families: + * doc, wiki, drive, perm, bitable, task, calendar. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isMessageExpired = exports.checkMessageGate = exports.parseMessageEvent = exports.handleFeishuReaction = exports.feishuPlugin = exports.buildMentionedCardContent = exports.buildMentionedMessage = exports.formatMentionAllForCard = exports.formatMentionAllForText = exports.formatMentionForCard = exports.formatMentionForText = exports.extractMessageBody = exports.nonBotMentions = exports.mentionedBot = exports.feishuMessageActions = exports.listChatMembersFeishu = exports.removeChatMembersFeishu = exports.addChatMembersFeishu = exports.updateChatFeishu = exports.forwardMessageFeishu = exports.VALID_FEISHU_EMOJI_TYPES = exports.FeishuEmoji = exports.listReactionsFeishu = exports.removeReactionFeishu = exports.addReactionFeishu = exports.probeFeishu = exports.sendMediaLark = exports.sendCardLark = exports.sendTextLark = exports.uploadAndSendMediaLark = exports.sendAudioLark = exports.sendFileLark = exports.sendImageLark = exports.uploadFileLark = exports.uploadImageLark = exports.getMessageFeishu = exports.editMessageFeishu = exports.updateCardFeishu = exports.sendCardFeishu = exports.sendMessageFeishu = exports.monitorFeishuProvider = void 0; +const plugin_sdk_1 = require("openclaw/plugin-sdk"); +const plugin_1 = require("./src/channel/plugin.js"); +const lark_client_1 = require("./src/core/lark-client.js"); +const index_1 = require("./src/tools/oapi/index.js"); +const index_2 = require("./src/tools/mcp/doc/index.js"); +const oauth_1 = require("./src/tools/oauth.js"); +const oauth_batch_auth_1 = require("./src/tools/oauth-batch-auth.js"); +const ask_user_question_1 = require("./src/tools/ask-user-question.js"); +const diagnose_1 = require("./src/commands/diagnose.js"); +const index_3 = require("./src/commands/index.js"); +const lark_logger_1 = require("./src/core/lark-logger.js"); +const security_check_1 = require("./src/core/security-check.js"); +const tool_use_trace_store_1 = require("./src/card/tool-use-trace-store.js"); +const reasoning_utils_1 = require("./src/card/reasoning-utils.js"); +const log = (0, lark_logger_1.larkLogger)('plugin'); +// --------------------------------------------------------------------------- +// Re-exports for external consumers +// --------------------------------------------------------------------------- +var monitor_1 = require("./src/channel/monitor.js"); +Object.defineProperty(exports, "monitorFeishuProvider", { enumerable: true, get: function () { return monitor_1.monitorFeishuProvider; } }); +var send_1 = require("./src/messaging/outbound/send.js"); +Object.defineProperty(exports, "sendMessageFeishu", { enumerable: true, get: function () { return send_1.sendMessageFeishu; } }); +Object.defineProperty(exports, "sendCardFeishu", { enumerable: true, get: function () { return send_1.sendCardFeishu; } }); +Object.defineProperty(exports, "updateCardFeishu", { enumerable: true, get: function () { return send_1.updateCardFeishu; } }); +Object.defineProperty(exports, "editMessageFeishu", { enumerable: true, get: function () { return send_1.editMessageFeishu; } }); +var fetch_1 = require("./src/messaging/outbound/fetch.js"); +Object.defineProperty(exports, "getMessageFeishu", { enumerable: true, get: function () { return fetch_1.getMessageFeishu; } }); +var media_1 = require("./src/messaging/outbound/media.js"); +Object.defineProperty(exports, "uploadImageLark", { enumerable: true, get: function () { return media_1.uploadImageLark; } }); +Object.defineProperty(exports, "uploadFileLark", { enumerable: true, get: function () { return media_1.uploadFileLark; } }); +Object.defineProperty(exports, "sendImageLark", { enumerable: true, get: function () { return media_1.sendImageLark; } }); +Object.defineProperty(exports, "sendFileLark", { enumerable: true, get: function () { return media_1.sendFileLark; } }); +Object.defineProperty(exports, "sendAudioLark", { enumerable: true, get: function () { return media_1.sendAudioLark; } }); +Object.defineProperty(exports, "uploadAndSendMediaLark", { enumerable: true, get: function () { return media_1.uploadAndSendMediaLark; } }); +var deliver_1 = require("./src/messaging/outbound/deliver.js"); +Object.defineProperty(exports, "sendTextLark", { enumerable: true, get: function () { return deliver_1.sendTextLark; } }); +Object.defineProperty(exports, "sendCardLark", { enumerable: true, get: function () { return deliver_1.sendCardLark; } }); +Object.defineProperty(exports, "sendMediaLark", { enumerable: true, get: function () { return deliver_1.sendMediaLark; } }); +var probe_1 = require("./src/channel/probe.js"); +Object.defineProperty(exports, "probeFeishu", { enumerable: true, get: function () { return probe_1.probeFeishu; } }); +var reactions_1 = require("./src/messaging/outbound/reactions.js"); +Object.defineProperty(exports, "addReactionFeishu", { enumerable: true, get: function () { return reactions_1.addReactionFeishu; } }); +Object.defineProperty(exports, "removeReactionFeishu", { enumerable: true, get: function () { return reactions_1.removeReactionFeishu; } }); +Object.defineProperty(exports, "listReactionsFeishu", { enumerable: true, get: function () { return reactions_1.listReactionsFeishu; } }); +Object.defineProperty(exports, "FeishuEmoji", { enumerable: true, get: function () { return reactions_1.FeishuEmoji; } }); +Object.defineProperty(exports, "VALID_FEISHU_EMOJI_TYPES", { enumerable: true, get: function () { return reactions_1.VALID_FEISHU_EMOJI_TYPES; } }); +var forward_1 = require("./src/messaging/outbound/forward.js"); +Object.defineProperty(exports, "forwardMessageFeishu", { enumerable: true, get: function () { return forward_1.forwardMessageFeishu; } }); +var chat_manage_1 = require("./src/messaging/outbound/chat-manage.js"); +Object.defineProperty(exports, "updateChatFeishu", { enumerable: true, get: function () { return chat_manage_1.updateChatFeishu; } }); +Object.defineProperty(exports, "addChatMembersFeishu", { enumerable: true, get: function () { return chat_manage_1.addChatMembersFeishu; } }); +Object.defineProperty(exports, "removeChatMembersFeishu", { enumerable: true, get: function () { return chat_manage_1.removeChatMembersFeishu; } }); +Object.defineProperty(exports, "listChatMembersFeishu", { enumerable: true, get: function () { return chat_manage_1.listChatMembersFeishu; } }); +var actions_1 = require("./src/messaging/outbound/actions.js"); +Object.defineProperty(exports, "feishuMessageActions", { enumerable: true, get: function () { return actions_1.feishuMessageActions; } }); +var mention_1 = require("./src/messaging/inbound/mention.js"); +Object.defineProperty(exports, "mentionedBot", { enumerable: true, get: function () { return mention_1.mentionedBot; } }); +Object.defineProperty(exports, "nonBotMentions", { enumerable: true, get: function () { return mention_1.nonBotMentions; } }); +Object.defineProperty(exports, "extractMessageBody", { enumerable: true, get: function () { return mention_1.extractMessageBody; } }); +Object.defineProperty(exports, "formatMentionForText", { enumerable: true, get: function () { return mention_1.formatMentionForText; } }); +Object.defineProperty(exports, "formatMentionForCard", { enumerable: true, get: function () { return mention_1.formatMentionForCard; } }); +Object.defineProperty(exports, "formatMentionAllForText", { enumerable: true, get: function () { return mention_1.formatMentionAllForText; } }); +Object.defineProperty(exports, "formatMentionAllForCard", { enumerable: true, get: function () { return mention_1.formatMentionAllForCard; } }); +Object.defineProperty(exports, "buildMentionedMessage", { enumerable: true, get: function () { return mention_1.buildMentionedMessage; } }); +Object.defineProperty(exports, "buildMentionedCardContent", { enumerable: true, get: function () { return mention_1.buildMentionedCardContent; } }); +var plugin_2 = require("./src/channel/plugin.js"); +Object.defineProperty(exports, "feishuPlugin", { enumerable: true, get: function () { return plugin_2.feishuPlugin; } }); +var reaction_handler_1 = require("./src/messaging/inbound/reaction-handler.js"); +Object.defineProperty(exports, "handleFeishuReaction", { enumerable: true, get: function () { return reaction_handler_1.handleFeishuReaction; } }); +var parse_1 = require("./src/messaging/inbound/parse.js"); +Object.defineProperty(exports, "parseMessageEvent", { enumerable: true, get: function () { return parse_1.parseMessageEvent; } }); +var gate_1 = require("./src/messaging/inbound/gate.js"); +Object.defineProperty(exports, "checkMessageGate", { enumerable: true, get: function () { return gate_1.checkMessageGate; } }); +var dedup_1 = require("./src/messaging/inbound/dedup.js"); +Object.defineProperty(exports, "isMessageExpired", { enumerable: true, get: function () { return dedup_1.isMessageExpired; } }); +// --------------------------------------------------------------------------- +// Plugin definition +// --------------------------------------------------------------------------- +const plugin = { + id: 'openclaw-lark', + name: 'Feishu', + description: 'Lark/Feishu channel plugin with im/doc/wiki/drive/task/calendar tools', + configSchema: (0, plugin_sdk_1.emptyPluginConfigSchema)(), + register(api) { + lark_client_1.LarkClient.setRuntime(api.runtime); + api.registerChannel({ plugin: plugin_1.feishuPlugin }); + // ======================================== + // Register OAPI tools (calendar, task - using Feishu Open API directly) + (0, index_1.registerOapiTools)(api); + // Register MCP doc tools (using Model Context Protocol) + (0, index_2.registerFeishuMcpDocTools)(api); + // Register OAuth tool (UAT device flow authorization) + (0, oauth_1.registerFeishuOAuthTool)(api); + // Register OAuth batch auth tool (batch authorization for all app scopes) + (0, oauth_batch_auth_1.registerFeishuOAuthBatchAuthTool)(api); + // Register AskUserQuestion tool (interactive card-based user prompting) + (0, ask_user_question_1.registerAskUserQuestionTool)(api); + api.on('before_tool_call', (event, ctx) => { + (0, tool_use_trace_store_1.recordToolUseStart)({ + sessionKey: ctx.sessionKey, + toolName: event.toolName, + toolParams: event.params, + toolCallId: event.toolCallId ?? ctx.toolCallId, + runId: event.runId ?? ctx.runId, + }); + if (!event.toolName.startsWith('feishu_')) + return; + const paramsPreview = (0, reasoning_utils_1.sanitizeParamsForLog)(event.params); + log.info(`tool call: ${event.toolName} session=${ctx.sessionKey ?? '-'} params=${paramsPreview}`); + }); + api.on('after_tool_call', (event, ctx) => { + (0, tool_use_trace_store_1.recordToolUseEnd)({ + sessionKey: ctx.sessionKey, + toolName: event.toolName, + toolParams: event.params, + toolCallId: event.toolCallId ?? ctx.toolCallId, + runId: event.runId ?? ctx.runId, + result: event.result, + error: event.error, + durationMs: event.durationMs, + }); + if (!event.toolName.startsWith('feishu_')) + return; + if (event.error) { + log.error(`tool fail: ${event.toolName} session=${ctx.sessionKey ?? '-'} ${event.error} (${event.durationMs ?? 0}ms)`); + } + else { + log.info(`tool done: ${event.toolName} session=${ctx.sessionKey ?? '-'} ok (${event.durationMs ?? 0}ms)`); + } + }); + // ---- Diagnostic commands ---- + // CLI: openclaw feishu-diagnose [--trace ] + api.registerCli((ctx) => { + ctx.program + .command('feishu-diagnose') + .description('运行飞书插件诊断,检查配置、连通性和权限状态') + .option('--trace ', '按 message_id 追踪完整处理链路') + .option('--analyze', '分析追踪日志(需配合 --trace 使用)') + .action(async (opts) => { + try { + if (opts.trace) { + const lines = await (0, diagnose_1.traceByMessageId)(opts.trace); + // eslint-disable-next-line no-console -- CLI 命令直接输出到终端 + console.log((0, diagnose_1.formatTraceOutput)(lines, opts.trace)); + if (opts.analyze && lines.length > 0) { + // eslint-disable-next-line no-console -- CLI 命令直接输出到终端 + console.log((0, diagnose_1.analyzeTrace)(lines, opts.trace)); + } + } + else { + const report = await (0, diagnose_1.runDiagnosis)({ + config: ctx.config, + logger: ctx.logger, + }); + // eslint-disable-next-line no-console -- CLI 命令直接输出到终端 + console.log((0, diagnose_1.formatDiagReportCli)(report)); + if (report.overallStatus === 'unhealthy') { + process.exitCode = 1; + } + } + } + catch (err) { + ctx.logger.error(`诊断命令执行失败: ${err}`); + process.exitCode = 1; + } + }); + }, { commands: ['feishu-diagnose'] }); + // Chat commands: /feishu_diagnose, /feishu_doctor, /feishu_auth, /feishu + (0, index_3.registerCommands)(api); + // ---- Multi-account security checks ---- + if (api.config) { + (0, security_check_1.emitSecurityWarnings)(api.config, api.logger); + } + }, +}; +exports.default = plugin; diff --git a/extensions/openclaw-lark/openclaw.plugin.json b/extensions/openclaw-lark/openclaw.plugin.json new file mode 100644 index 0000000..832037c --- /dev/null +++ b/extensions/openclaw-lark/openclaw.plugin.json @@ -0,0 +1,64 @@ +{ + "id": "openclaw-lark", + "channels": [ + "feishu" + ], + "skills": [ + "./skills" + ], + "configSchema": { + "type": "object", + "additionalProperties": false, + "properties": {} + }, + "contracts": { + "tools": [ + "feishu_bitable_app", + "feishu_bitable_app_table", + "feishu_bitable_app_table_field", + "feishu_bitable_app_table_record", + "feishu_bitable_app_table_view", + "feishu_calendar_calendar", + "feishu_calendar_event", + "feishu_calendar_event_attendee", + "feishu_calendar_freebusy", + "feishu_chat", + "feishu_chat_members", + "feishu_create_doc", + "feishu_doc_comments", + "feishu_doc_media", + "feishu_drive_file", + "feishu_fetch_doc", + "feishu_get_user", + "feishu_im_bot_image", + "feishu_im_user_fetch_resource", + "feishu_im_user_get_messages", + "feishu_im_user_get_thread_messages", + "feishu_im_user_message", + "feishu_im_user_search_messages", + "feishu_oauth", + "feishu_oauth_batch_auth", + "feishu_search_doc_wiki", + "feishu_search_user", + "feishu_sheet", + "feishu_task_comment", + "feishu_task_subtask", + "feishu_task_task", + "feishu_task_agent", + "feishu_task_attachment", + "feishu_task_tasklist", + "feishu_update_doc", + "feishu_wiki_space", + "feishu_wiki_space_node", + "feishu_task_section", + "feishu_ask_user_question" + ] + }, + "channelConfigs": { + "feishu": { + "schema": { + "type": "object" + } + } + } +} diff --git a/extensions/openclaw-lark/package.json b/extensions/openclaw-lark/package.json new file mode 100644 index 0000000..e98a85a --- /dev/null +++ b/extensions/openclaw-lark/package.json @@ -0,0 +1,63 @@ +{ + "name": "@larksuite/openclaw-lark", + "version": "2026.6.10", + "description": "OpenClaw Lark/Feishu channel plugin", + "exports": { + ".": { + "import": { + "types": "./dist/index.d.mts", + "default": "./dist/index.mjs" + } + } + }, + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "bin": { + "openclaw-lark": "bin/openclaw-lark.js" + }, + "files": [ + "**/*" + ], + "packageManager": "pnpm@10.32.1", + "engines": { + "node": ">=22" + }, + "dependencies": { + "@larksuiteoapi/node-sdk": "^1.64.0", + "@sinclair/typebox": "0.34.49", + "image-size": "^2.0.2", + "undici-types": "^8.1.0", + "zod": "^4.3.6" + }, + "peerDependencies": { + "openclaw": ">=2026.5.4" + }, + "peerDependenciesMeta": { + "openclaw": { + "optional": true + } + }, + "openclaw": { + "extensions": [ + "./index.js" + ], + "channel": { + "id": "openclaw-lark", + "label": "Feishu", + "selectionLabel": "Lark/Feishu (飞书)", + "docsPath": "/channels/feishu", + "docsLabel": "feishu", + "blurb": "飞书/Lark enterprise messaging with doc/wiki/drive/task/calendar tools.", + "aliases": [ + "lark" + ], + "order": 35, + "quickstartAllowFrom": true + }, + "install": { + "npmSpec": "@larksuite/openclaw-lark", + "localPath": "extensions/feishu", + "defaultChoice": "npm" + } + } +} diff --git a/extensions/openclaw-lark/secret-contract-api.d.ts b/extensions/openclaw-lark/secret-contract-api.d.ts new file mode 100644 index 0000000..efc9b51 --- /dev/null +++ b/extensions/openclaw-lark/secret-contract-api.d.ts @@ -0,0 +1,15 @@ +/** + * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates + * SPDX-License-Identifier: MIT + * + * Feishu channel secret-contract registration. Declares which fields are + * SecretRef-shaped so OpenClaw's runtime resolves them at startup. + */ +import type { ResolverContext, SecretDefaults, SecretTargetRegistryEntry } from 'openclaw/plugin-sdk/channel-secret-basic-runtime'; +import type { OpenClawConfig } from 'openclaw/plugin-sdk'; +export declare const secretTargetRegistryEntries: readonly SecretTargetRegistryEntry[]; +export declare function collectRuntimeConfigAssignments(params: { + config: OpenClawConfig; + defaults: SecretDefaults | undefined; + context: ResolverContext; +}): void; diff --git a/extensions/openclaw-lark/secret-contract-api.js b/extensions/openclaw-lark/secret-contract-api.js new file mode 100644 index 0000000..2619976 --- /dev/null +++ b/extensions/openclaw-lark/secret-contract-api.js @@ -0,0 +1,78 @@ +"use strict"; +/** + * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates + * SPDX-License-Identifier: MIT + * + * Feishu channel secret-contract registration. Declares which fields are + * SecretRef-shaped so OpenClaw's runtime resolves them at startup. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.secretTargetRegistryEntries = void 0; +exports.collectRuntimeConfigAssignments = collectRuntimeConfigAssignments; +const channel_secret_basic_runtime_1 = require("openclaw/plugin-sdk/channel-secret-basic-runtime"); +const SECRET_FIELDS = ['appSecret', 'encryptKey', 'verificationToken']; +/** Fields the Lark SDK only consumes when an account is in webhook mode. */ +const WEBHOOK_ONLY_FIELDS = ['encryptKey', 'verificationToken']; +exports.secretTargetRegistryEntries = SECRET_FIELDS.flatMap((field) => { + const acctPath = `channels.feishu.accounts.*.${field}`; + const topPath = `channels.feishu.${field}`; + return [ + { + id: acctPath, + targetType: acctPath, + configFile: 'openclaw.json', + pathPattern: acctPath, + secretShape: 'secret_input', + expectedResolvedValue: 'string', + includeInPlan: true, + includeInConfigure: true, + includeInAudit: true, + }, + { + id: topPath, + targetType: topPath, + configFile: 'openclaw.json', + pathPattern: topPath, + secretShape: 'secret_input', + expectedResolvedValue: 'string', + includeInPlan: true, + includeInConfigure: true, + includeInAudit: true, + }, + ]; +}); +function collectRuntimeConfigAssignments(params) { + const resolved = (0, channel_secret_basic_runtime_1.getChannelSurface)(params.config, 'feishu'); + if (!resolved) + return; + const { channel, surface } = resolved; + (0, channel_secret_basic_runtime_1.collectSimpleChannelFieldAssignments)({ + channelKey: 'feishu', + field: 'appSecret', + channel, + surface, + defaults: params.defaults, + context: params.context, + topInactiveReason: 'no enabled Feishu account inherits this top-level appSecret.', + accountInactiveReason: 'Feishu account is disabled.', + }); + const baseConnectionMode = (0, channel_secret_basic_runtime_1.normalizeSecretStringValue)(channel.connectionMode) === 'webhook' ? 'webhook' : 'websocket'; + const resolveAccountMode = (account) => (0, channel_secret_basic_runtime_1.hasOwnProperty)(account, 'connectionMode') + ? (0, channel_secret_basic_runtime_1.normalizeSecretStringValue)(account.connectionMode) + : baseConnectionMode; + for (const field of WEBHOOK_ONLY_FIELDS) { + (0, channel_secret_basic_runtime_1.collectConditionalChannelFieldAssignments)({ + channelKey: 'feishu', + field, + channel, + surface, + defaults: params.defaults, + context: params.context, + topLevelActiveWithoutAccounts: baseConnectionMode === 'webhook', + topLevelInheritedAccountActive: ({ account, enabled }) => enabled && !(0, channel_secret_basic_runtime_1.hasOwnProperty)(account, field) && resolveAccountMode(account) === 'webhook', + accountActive: ({ account, enabled }) => enabled && resolveAccountMode(account) === 'webhook', + topInactiveReason: `no enabled Feishu webhook-mode surface inherits this top-level ${field}.`, + accountInactiveReason: 'Feishu account is disabled or not running in webhook mode.', + }); + } +} diff --git a/extensions/openclaw-lark/skills/feishu-bitable/SKILL.md b/extensions/openclaw-lark/skills/feishu-bitable/SKILL.md new file mode 100644 index 0000000..110add5 --- /dev/null +++ b/extensions/openclaw-lark/skills/feishu-bitable/SKILL.md @@ -0,0 +1,248 @@ +--- +name: feishu-bitable +description: | + 飞书多维表格(Bitable)的创建、查询、编辑和管理工具。包含 27 种字段类型支持、高级筛选、批量操作和视图管理。 + + **当以下情况时使用此 Skill**: + (1) 需要创建或管理飞书多维表格 App + (2) 需要在多维表格中新增、查询、修改、删除记录(行数据) + (3) 需要管理字段(列)、视图、数据表 + (4) 用户提到"多维表格"、"bitable"、"数据表"、"记录"、"字段" + (5) 需要批量导入数据或批量更新多维表格 +--- + +# Feishu Bitable (多维表格) SKILL + +## 🚨 执行前必读 + +- ✅ **创建数据表**:支持两种模式 — ① 明确需求时,在 `create` 时通过 `table.fields` 一次性定义字段(减少 API 调用);② 探索式场景时,使用默认表 + 逐步修改字段(更稳定,易调整) +- ⚠️ **默认表的空行坑**:`app.create` 自带的默认表中会有空记录(空行)!插入数据前建议先调用 `feishu_bitable_app_table_record.list` + `batch_delete` 删除空行,避免数据污染 +- ✅ **写记录前**:先调用 `feishu_bitable_app_table_field.list` 获取字段 type/ui_type +- ✅ **人员字段**:默认 open_id(ou_...),值必须是 `[{id:"ou_xxx"}]`(数组对象) +- ✅ **日期字段**:毫秒时间戳(例如 `1674206443000`),不是秒 +- ✅ **单选字段**:字符串(例如 `"选项1"`),不是数组 +- ✅ **多选字段**:字符串数组(例如 `["选项1", "选项2"]`) +- ✅ **附件字段**:必须先上传到当前多维表格,使用返回的 file_token +- ✅ **批量上限**:单次 ≤ 500 条,超过需分批(批量操作是原子性的) +- ✅ **并发限制**:同一数据表不支持并发写,需串行调用 + 延迟 0.5-1 秒 + +--- + +## 📋 快速索引:意图 → 工具 → 必填参数 + +| 用户意图 | 工具 | action | 必填参数 | 常用可选 | +|---------|------|--------|---------|---------| +| 查表有哪些字段 | feishu_bitable_app_table_field | list | app_token, table_id | - | +| 查记录 | feishu_bitable_app_table_record | list | app_token, table_id | filter, sort, field_names | +| 新增一行 | feishu_bitable_app_table_record | create | app_token, table_id, fields | - | +| 批量导入 | feishu_bitable_app_table_record | batch_create | app_token, table_id, records (≤500) | - | +| 更新一行 | feishu_bitable_app_table_record | update | app_token, table_id, record_id, fields | - | +| 批量更新 | feishu_bitable_app_table_record | batch_update | app_token, table_id, records (≤500) | - | +| 创建多维表格 | feishu_bitable_app | create | name | folder_token | +| 创建数据表 | feishu_bitable_app_table | create | app_token, name | fields | +| 创建字段 | feishu_bitable_app_table_field | create | app_token, table_id, field_name, type | property | +| 创建视图 | feishu_bitable_app_table_view | create | app_token, table_id, view_name, view_type | - | + +--- + +## 🎯 核心约束(Schema 未透露的知识) + +### 📚 详细参考文档 + +**当遇到字段配置、记录值格式问题或需要完整示例时,查阅以下文档**: + +- **[字段 Property 配置详解](references/field-properties.md)** - 每种字段类型创建/更新时需要的 `property` 参数结构(单选的 options、进度的 min/max、关联的 table_id 等) +- **[记录值数据结构详解](references/record-values.md)** - 每种字段类型在记录中对应的 `fields` 值格式(人员字段只传 id、日期是毫秒时间戳、附件需先上传等) +- **[使用场景完整示例](references/examples.md)** - 8 个完整场景示例(创建表模式对比、批量导入、筛选查询、附件处理、关联字段等) + +**何时查阅**: +- 创建/更新字段时收到 `125408X` 错误码(property 结构错误)→ 查 field-properties.md +- 写入记录时收到 `125406X` 错误码(字段值转换失败)→ 查 record-values.md +- 需要完整的操作流程和参数示例 → 查 examples.md + +--- + +### 1. 字段类型与值格式必须严格匹配 + +**Bitable 最大的坑**:不同字段类型对 value 的数据结构要求完全不同。 + +#### 最易错的字段类型(完整列表见 [record-values.md](references/record-values.md)) + +| type | ui_type | 字段类型 | 正确格式 | ❌ 常见错误 | +|------|---------|----------|---------|-----------| +| 11 | User | 人员 | `[{id: "ou_xxx"}]` | 传字符串 `"ou_xxx"` 或 `[{name: "张三"}]` | +| 5 | DateTime | 日期 | `1674206443000`(毫秒) | 传秒时间戳或字符串 | +| 3 | SingleSelect | 单选 | `"选项名"` | 传数组 `["选项名"]` | +| 4 | MultiSelect | 多选 | `["选项1", "选项2"]` | 传字符串 `"选项1"` | +| 15 | Url | 超链接 | `{link: "...", text: "..."}` | 只传字符串 URL | +| 17 | Attachment | 附件 | `[{file_token: "..."}]` | 传外部 URL 或本地路径 | + +**强制流程**: +1. 先调用 `feishu_bitable_app_table_field.list` 获取字段的 `type` 和 `ui_type` +2. 根据上表或 [record-values.md](references/record-values.md) 构造正确格式 +3. 错误码 `125406X` 或 `1254015` → 检查字段值格式 + +**人员字段特别注意**: +- 默认使用 open_id(ou_...),与 calendar/task 一致 +- 格式:`[{id: "ou_xxx"}]`(数组对象) +- **只能传 id 字段**,不能传 name/email 等 + + +## 📌 核心使用场景 + +> **完整示例**: 查阅 [examples.md](references/examples.md) 了解更多场景(创建表模式对比、空行处理、附件上传、关联字段等) + +### 场景 1: 查字段类型(必做第一步) + +```json +{ + "action": "list", + "app_token": "S404b...", + "table_id": "tbl..." +} +``` + +**返回**:包含每个字段的 `field_id`、`field_name`、`type`、`ui_type`、`property` + +### 场景 2: 批量导入客户数据 + +```json +{ + "action": "batch_create", + "app_token": "S404b...", + "table_id": "tbl...", + "records": [ + { + "fields": { + "客户名称": "Bytedance", + "负责人": [{"id": "ou_xxx"}], + "签约日期": 1674206443000, + "状态": "进行中" + } + }, + { + "fields": { + "客户名称": "飞书", + "负责人": [{"id": "ou_yyy"}], + "签约日期": 1675416243000, + "状态": "已完成" + } + } + ] +} +``` + +**字段值格式**: +- 人员:`[{id: "ou_xxx"}]`(数组对象) +- 日期:毫秒时间戳 +- 单选:字符串 +- 多选:字符串数组 + +**限制**: 最多 500 条记录 + +### 场景 3: 筛选查询(高级筛选) + +```json +{ + "action": "list", + "app_token": "S404b...", + "table_id": "tbl...", + "filter": { + "conjunction": "and", + "conditions": [ + { + "field_name": "状态", + "operator": "is", + "value": ["进行中"] + }, + { + "field_name": "截止日期", + "operator": "isLess", + "value": ["ExactDate", "1740441600000"] + } + ] + }, + "sort": [ + { + "field_name": "截止日期", + "desc": false + } + ] +} +``` + +**filter 说明**: +- 支持 10 种 operator(is/isNot/contains/isEmpty 等,见附录 C) +- ⚠️ **isEmpty/isNotEmpty 必须传 `value: []`**(虽然逻辑上不需要值,但 API 要求必须传空数组) +- 日期筛选可使用 `["Today"]`、`["ExactDate", "时间戳"]` 等 +- `sort` 可指定多个排序字段 + +--- + +## 🔍 常见错误与排查 + +| 错误码 | 错误现象 | 根本原因 | 解决方案 | +|--------|---------|---------|---------| +| 1254064 | DatetimeFieldConvFail | 日期字段格式错误 | **必须用毫秒时间戳**(如 `1772121600000`),不能用字符串(`"2026-02-27"`、RFC3339)或秒级时间戳 | +| 1254068 | URLFieldConvFail | 超链接字段格式错误 | **必须用对象** `{text: "显示文本", link: "URL"}`,不能直接传字符串 URL | +| 1254066 | UserFieldConvFail | 人员字段格式错误或 ID 类型不匹配 | 必须传 `[{id: "ou_xxx"}]`,确认 `user_id_type` | +| 1254015 | Field types do not match | 字段值格式与类型不匹配 | 先 list 字段,按类型构造正确格式 | +| 1254104 | RecordAddOnceExceedLimit | 批量创建超过 500 条 | 分批调用,每批 ≤ 500 | +| 1254291 | Write conflict | 并发写冲突 | 串行调用 + 延迟 0.5-1 秒 | +| 1254303 | AttachPermNotAllow | 附件未上传到当前表格 | 先调用上传素材接口 | +| 1254045 | FieldNameNotFound | 字段名不存在 | 检查字段名(包括空格、大小写) | + +--- + +## 📚 附录:背景知识 + +### A. 资源层级关系 + +``` +App (多维表格应用) + ├── Table (数据表) ×100 + │ ├── Record (记录/行) ×20,000 + │ ├── Field (字段/列) ×300 + │ └── View (视图) ×200 + └── Dashboard (仪表盘) +``` + +### B. 筛选条件 operator 列表 + +| operator | 含义 | 支持字段 | value 要求 | +|----------|------|----------|-----------| +| `is` | 等于 | 所有 | 单个值 | +| `isNot` | 不等于 | 除日期外 | 单个值 | +| `contains` | 包含 | 除日期外 | 可多个值 | +| `doesNotContain` | 不包含 | 除日期外 | 可多个值 | +| `isEmpty` | 为空 | 所有 | 必须为 `[]` | +| `isNotEmpty` | 不为空 | 所有 | 必须为 `[]` | +| `isGreater` | 大于 | 数字、日期 | 单个值 | +| `isGreaterEqual` | 大于等于 | 数字(不支持日期) | 单个值 | +| `isLess` | 小于 | 数字、日期 | 单个值 | +| `isLessEqual` | 小于等于 | 数字(不支持日期) | 单个值 | + +**日期字段特殊值**: `["Today"]`, `["Tomorrow"]`, `["ExactDate", "时间戳"]` 等(完整列表见 [examples.md](references/examples.md#场景-3-筛选查询高级筛选)) + +### C. 使用限制 + +| 限制项 | 上限 | +|--------|------| +| 数据表 + 仪表盘 | 100(单个 App) | +| 记录数 | 20,000(单个数据表) | +| 字段数 | 300(单个数据表) | +| 视图数 | 200(单个数据表) | +| 批量创建/更新/删除 | 500(单次 API 调用) | +| 单元格文本 | 10 万字符 | +| 单选/多选选项 | 20,000(单个字段) | +| 单元格附件 | 100 | +| 单元格人员 | 1,000 | + + + +### D. 其他约束 + +- 从其他数据源同步的数据表,**不支持增删改**记录 +- 公式字段、查看引用字段是**只读**的 +- 删除操作**无法恢复** +- 视图筛选条件使用 `field_id`,需先调用 field.list 获取 diff --git a/extensions/openclaw-lark/skills/feishu-bitable/references/examples.md b/extensions/openclaw-lark/skills/feishu-bitable/references/examples.md new file mode 100644 index 0000000..cae3970 --- /dev/null +++ b/extensions/openclaw-lark/skills/feishu-bitable/references/examples.md @@ -0,0 +1,813 @@ +# 飞书多维表格使用场景完整示例 + +本文档提供多维表格操作的完整场景示例,包括参数说明和注意事项。 + +> **基础参考**: 先查阅 [字段 Property 配置详解](field-properties.md) 和 [记录值数据结构详解](record-values.md) + +--- + +## 📋 目录 + +1. [场景 0: 创建数据表(两种模式对比)](#场景-0-创建数据表两种模式对比) +2. [场景 1: 查字段类型(必做第一步)](#场景-1-查字段类型必做第一步) +3. [场景 2: 批量导入客户数据](#场景-2-批量导入客户数据) +4. [场景 2.5: 创建表并插入数据(含空行处理)](#场景-25-创建表并插入数据含空行处理) +5. [场景 3: 筛选查询(高级筛选)](#场景-3-筛选查询高级筛选) +6. [场景 4: 更新单条记录](#场景-4-更新单条记录) +7. [场景 5: 创建带选项的单选字段](#场景-5-创建带选项的单选字段) +8. [场景 6: 创建复杂字段(进度、货币、评分)](#场景-6-创建复杂字段进度货币评分) +9. [场景 7: 处理附件字段](#场景-7-处理附件字段) +10. [场景 8: 双向关联字段](#场景-8-双向关联字段) + +--- + +## 场景 0: 创建数据表(两种模式对比) + +### 模式 A:一次性定义所有字段 + +**适用场景**:字段类型、配置都已明确,需要快速创建表结构。 + +**优势**:一次 API 调用,原子性操作。 + +**工具**: `feishu_bitable_app_table` + +```json +{ + "action": "create", + "app_token": "S404b...", + "table": { + "name": "客户管理表", + "default_view_name": "所有客户", + "fields": [ + { + "field_name": "客户名称", + "type": 1 + }, + { + "field_name": "负责人", + "type": 11, + "property": { + "multiple": false + } + }, + { + "field_name": "签约日期", + "type": 5, + "property": { + "date_formatter": "yyyy-MM-dd" + } + }, + { + "field_name": "状态", + "type": 3, + "property": { + "options": [ + {"name": "进行中", "color": 0}, + {"name": "已完成", "color": 10} + ] + } + }, + { + "field_name": "金额", + "type": 2, + "ui_type": "Currency", + "property": { + "currency_code": "CNY", + "formatter": "0.00" + } + } + ] + } +} +``` + +**返回示例**: +```json +{ + "table_id": "tblXXXXXXXX", + "name": "客户管理表", + "default_view_id": "vewXXXXXXXX" +} +``` + +--- + +### 模式 B:使用默认表 + 逐步修改字段 + +**适用场景**:探索式建表,需要边建边调整,或复杂字段配置需要分步确认。 + +**优势**: +- `app.create` 自带默认表和默认字段,可在此基础上调整 +- 复杂字段(单选 options、URL 格式等)分步确认,减少出错 +- 踩坑后容易回退(比如 URL 字段改为文本字段) + +**完整流程**: + +#### 步骤 1: 创建 App(工具: `feishu_bitable_app`) + +```json +{ + "action": "create", + "name": "客户管理系统", + "folder_token": "fldXXXXXXXX" +} +``` + +**返回**: 包含 `app_token` 和默认表的 `default_table_id` + +--- + +#### 步骤 2: 查看默认字段(工具: `feishu_bitable_app_table_field`) + +```json +{ + "action": "list", + "app_token": "S404b...", + "table_id": "tblXXXXXXXX" +} +``` + +**返回示例**: +```json +{ + "fields": [ + { + "field_id": "fld001", + "field_name": "文本", + "type": 1, + "ui_type": "Text" + }, + { + "field_id": "fld002", + "field_name": "数字", + "type": 2, + "ui_type": "Number" + } + ] +} +``` + +--- + +#### 步骤 3: 修改默认字段名称(工具: `feishu_bitable_app_table_field`) + +```json +{ + "action": "update", + "app_token": "S404b...", + "table_id": "tblXXXXXXXX", + "field_id": "fld001", + "field_name": "客户名称" +} +``` + +--- + +#### 步骤 4: 补充缺失字段(工具: `feishu_bitable_app_table_field`) + +```json +{ + "action": "create", + "app_token": "S404b...", + "table_id": "tblXXXXXXXX", + "field_name": "负责人", + "type": 11, + "property": { + "multiple": false + } +} +``` + +--- + +#### 步骤 5: 查看空记录(工具: `feishu_bitable_app_table_record`) + +```json +{ + "action": "list", + "app_token": "S404b...", + "table_id": "tblXXXXXXXX" +} +``` + +**返回**: 可能包含空记录 `[{"record_id": "recxxx", "fields": {}}, ...]` + +--- + +#### 步骤 6: 删除空行(工具: `feishu_bitable_app_table_record`) + +```json +{ + "action": "batch_delete", + "app_token": "S404b...", + "table_id": "tblXXXXXXXX", + "records": ["recxxx", "recyyy"] +} +``` + +--- + +#### 步骤 7: 批量插入数据(工具: `feishu_bitable_app_table_record`) + +```json +{ + "action": "batch_create", + "app_token": "S404b...", + "table_id": "tblXXXXXXXX", + "records": [ + { + "fields": { + "客户名称": "Bytedance", + "负责人": [{"id": "ou_xxx"}], + "状态": "进行中" + } + } + ] +} +``` + +--- + +**⚠️ 模式 B 的关键注意事项**: +- 默认表中通常已有空记录,**必须先删除**,否则会有数据污染 +- 步骤 5-6 是必需的,不能跳过 +- 适合不确定字段配置的探索式场景 + +--- + +## 场景 1: 查字段类型(必做第一步) + +**为什么必做**: 不同字段类型的值格式完全不同,必须先查询再写入。 + +**工具**: `feishu_bitable_app_table_field` + +```json +{ + "action": "list", + "app_token": "S404b...", + "table_id": "tblXXXXXXXX" +} +``` + +**返回示例**: +```json +{ + "fields": [ + { + "field_id": "fld001", + "field_name": "任务名称", + "type": 1, + "ui_type": "Text", + "property": {} + }, + { + "field_id": "fld002", + "field_name": "负责人", + "type": 11, + "ui_type": "User", + "property": { + "multiple": true + } + }, + { + "field_id": "fld003", + "field_name": "截止日期", + "type": 5, + "ui_type": "DateTime", + "property": { + "date_formatter": "yyyy-MM-dd HH:mm" + } + }, + { + "field_id": "fld004", + "field_name": "状态", + "type": 3, + "ui_type": "SingleSelect", + "property": { + "options": [ + {"id": "optXXX", "name": "进行中", "color": 0}, + {"id": "optYYY", "name": "已完成", "color": 10} + ] + } + } + ] +} +``` + +**关键信息**: +- `type`: 字段基础类型(1=文本, 2=数字, 3=单选...) +- `ui_type`: UI 展示类型(区分进度、货币、评分等) +- `property`: 字段配置(单选的 options、日期的 formatter 等) + +--- + +## 场景 2: 批量导入客户数据 + +**工具**: `feishu_bitable_app_table_record` + +```json +{ + "action": "batch_create", + "app_token": "S404b...", + "table_id": "tblXXXXXXXX", + "records": [ + { + "fields": { + "客户名称": "某某", + "负责人": [{"id": "ou_xxx"}], + "签约日期": 1674206443000, + "状态": "进行中", + "金额": 1000000, + "标签": ["重要客户", "战略合作"], + "联系电话": "17899870000", + "官网": { + "text": "某某官网", + "link": "https://www.xxxx.com" + } + } + }, + { + "fields": { + "客户名称": "飞书", + "负责人": [{"id": "ou_xxx"}], + "签约日期": 1675416243000, + "状态": "已完成", + "金额": 500000, + "标签": ["核心产品"], + "联系电话": "13800138000" + } + } + ] +} +``` + +**字段值格式说明**: +- **文本**: 字符串 `"客户名称"` +- **人员**: 对象数组 `[{"id": "ou_xxx"}]`(只能传 id) +- **日期**: 毫秒时间戳 `1674206443000` +- **单选**: 字符串 `"进行中"` +- **多选**: 字符串数组 `["重要客户", "战略合作"]` +- **数字**: 数字 `1000000` +- **电话**: 字符串 `"17899870000"` +- **超链接**: 对象 `{"text": "显示文本", "link": "URL"}` + +**返回示例**: +```json +{ + "records": [ + { + "record_id": "rec001", + "fields": {...} + }, + { + "record_id": "rec002", + "fields": {...} + } + ] +} +``` + +**限制**: +- 单次最多 500 条记录 +- 超过需分批调用 + +--- + +## 场景 2.5: 创建表并插入数据(含空行处理) + +**问题**: `app.create` 创建的默认表中会自带空记录(空行),直接插入数据会导致数据污染。 + +**正确流程**: 见场景 0 的模式 B + +**核心步骤**: +1. 创建 App → 获取 `app_token` 和 `default_table_id` +2. 查看默认表记录 (`list` action) +3. 删除空行 (`batch_delete` action) +4. 批量插入数据 (`batch_create` action) + +**错误示例**(跳过步骤 2-3): +``` +表格最终状态: +| 客户名称 | 负责人 | 状态 | +|---------|--------|------| +| | | | ← 空行(原有) +| Bytedance | 张三 | 进行中 | ← 新插入 +| 飞书 | 李四 | 已完成 | ← 新插入 +``` + +**正确示例**(执行步骤 2-3): +``` +表格最终状态: +| 客户名称 | 负责人 | 状态 | +|---------|--------|------| +| Bytedance | 张三 | 进行中 | +| 飞书 | 李四 | 已完成 | +``` + +--- + +## 场景 3: 筛选查询(高级筛选) + +**工具**: `feishu_bitable_app_table_record` + +```json +{ + "action": "list", + "app_token": "S404b...", + "table_id": "tblXXXXXXXX", + "filter": { + "conjunction": "and", + "conditions": [ + { + "field_name": "状态", + "operator": "is", + "value": ["进行中"] + }, + { + "field_name": "截止日期", + "operator": "isLess", + "value": ["ExactDate", "1740441600000"] + }, + { + "field_name": "优先级", + "operator": "isGreater", + "value": ["3"] + } + ] + }, + "sort": [ + { + "field_name": "截止日期", + "desc": false + }, + { + "field_name": "优先级", + "desc": true + } + ], + "field_names": ["任务名称", "负责人", "截止日期", "状态"], + "page_size": 100 +} +``` + +**参数说明**: + +### filter 结构 +- `conjunction`: 条件组合方式(`"and"` 或 `"or"`) +- `conditions`: 条件数组 + +### operator 类型(10 种) + +| operator | 含义 | 支持字段 | value 格式 | +|----------|------|----------|-----------| +| `is` | 等于 | 所有 | `["值"]` | +| `isNot` | 不等于 | 除日期外 | `["值"]` | +| `contains` | 包含 | 除日期外 | `["值1", "值2"]` | +| `doesNotContain` | 不包含 | 除日期外 | `["值1"]` | +| `isEmpty` | 为空 | 所有 | `[]` | +| `isNotEmpty` | 不为空 | 所有 | `[]` | +| `isGreater` | 大于 | 数字、日期 | `["值"]` | +| `isGreaterEqual` | 大于等于 | 数字 | `["值"]` | +| `isLess` | 小于 | 数字、日期 | `["值"]` | +| `isLessEqual` | 小于等于 | 数字 | `["值"]` | + +### 日期字段特殊值 + +```json +// 具体日期 +{"operator": "is", "value": ["ExactDate", "1702449755000"]} + +// 相对日期 +{"operator": "is", "value": ["Today"]} // 今天 +{"operator": "is", "value": ["Tomorrow"]} // 明天 +{"operator": "is", "value": ["Yesterday"]} // 昨天 +{"operator": "is", "value": ["CurrentWeek"]} // 本周 +{"operator": "is", "value": ["LastWeek"]} // 上周 +{"operator": "is", "value": ["TheLastWeek"]} // 过去七天 +{"operator": "is", "value": ["TheNextWeek"]} // 未来七天 +``` + +### sort 结构 +- `field_name`: 排序字段 +- `desc`: `true` 降序,`false` 升序 +- 支持多字段排序(按数组顺序) + +--- + +## 场景 4: 更新单条记录 + +**工具**: `feishu_bitable_app_table_record` + +```json +{ + "action": "update", + "app_token": "S404b...", + "table_id": "tblXXXXXXXX", + "record_id": "recusyQbB0fVL5", + "fields": { + "状态": "已完成", + "完成时间": 1674206443000, + "备注": "客户已签约" + } +} +``` + +**说明**: +- 只传需要更新的字段 +- 不传的字段保持不变 +- 支持部分字段更新 + +**批量更新**(最多 500 条): + +```json +{ + "action": "batch_update", + "app_token": "S404b...", + "table_id": "tblXXXXXXXX", + "records": [ + { + "record_id": "rec001", + "fields": { + "状态": "已完成" + } + }, + { + "record_id": "rec002", + "fields": { + "状态": "已完成" + } + } + ] +} +``` + +--- + +## 场景 5: 创建带选项的单选字段 + +**工具**: `feishu_bitable_app_table_field` + +```json +{ + "action": "create", + "app_token": "S404b...", + "table_id": "tblXXXXXXXX", + "field_name": "优先级", + "type": 3, + "property": { + "options": [ + {"name": "高", "color": 0}, + {"name": "中", "color": 1}, + {"name": "低", "color": 2} + ] + } +} +``` + +**颜色编号**(color 范围 0-54): +- 0: 红色 +- 1: 橙色 +- 10: 绿色 +- 20: 蓝色 + +**多选字段**(type=4)格式相同: + +```json +{ + "action": "create", + "app_token": "S404b...", + "table_id": "tblXXXXXXXX", + "field_name": "标签", + "type": 4, + "property": { + "options": [ + {"name": "重要", "color": 0}, + {"name": "紧急", "color": 1}, + {"name": "长期", "color": 10} + ] + } +} +``` + +**注意**: +- 创建时**不能**指定选项 ID(`id` 字段),系统自动生成 +- 选项总数不超过 20,000 + +--- + +## 场景 6: 创建复杂字段(进度、货币、评分) + +### 进度字段 (type=2, ui_type="Progress") + +```json +{ + "action": "create", + "app_token": "S404b...", + "table_id": "tblXXXXXXXX", + "field_name": "完成进度", + "type": 2, + "ui_type": "Progress", + "property": { + "min": 0, + "max": 100, + "range_customize": true + } +} +``` + +**写入值**: `0.75` 表示 75% + +--- + +### 货币字段 (type=2, ui_type="Currency") + +```json +{ + "action": "create", + "app_token": "S404b...", + "table_id": "tblXXXXXXXX", + "field_name": "预算", + "type": 2, + "ui_type": "Currency", + "property": { + "currency_code": "CNY", + "formatter": "0,000.00" + } +} +``` + +**currency_code 可选值**: +- `"CNY"`: 人民币 (¥) +- `"USD"`: 美元 ($) +- `"EUR"`: 欧元 (€) +- `"JPY"`: 日元 (¥) + +**写入值**: `5000.50`(普通数字) + +--- + +### 评分字段 (type=2, ui_type="Rating") + +```json +{ + "action": "create", + "app_token": "S404b...", + "table_id": "tblXXXXXXXX", + "field_name": "客户满意度", + "type": 2, + "ui_type": "Rating", + "property": { + "min": 1, + "max": 5, + "rating": { + "symbol": "star" + } + } +} +``` + +**symbol 可选值**: +- `"star"`: ⭐ 星星 +- `"heart"`: ❤️ 爱心 +- `"fire"`: 🔥 火焰 +- `"thumbsup"`: 👍 赞 + +**写入值**: `4`(整数) + +--- + +## 场景 7: 处理附件字段 + +### 步骤 1: 上传附件到多维表格 + +**工具**: `feishu_drive_media`(上传素材接口) + +```json +{ + "action": "upload", + "file_path": "/path/to/file.pdf", + "parent_type": "bitable_image", + "parent_node": "S404b..." // app_token +} +``` + +**返回**: +```json +{ + "file_token": "DRiFbwaKsoZaLax4WKZbEGCccoe" +} +``` + +--- + +### 步骤 2: 创建附件字段(可选) + +```json +{ + "action": "create", + "app_token": "S404b...", + "table_id": "tblXXXXXXXX", + "field_name": "合同文件", + "type": 17 +} +``` + +--- + +### 步骤 3: 写入附件记录 + +```json +{ + "action": "create", + "app_token": "S404b...", + "table_id": "tblXXXXXXXX", + "fields": { + "客户名称": "Bytedance", + "合同文件": [ + {"file_token": "DRiFxxxxxxxxxxxxxxxxxxCccoe"}, + {"file_token": "BZk3bxxxxxxxxxxxxxxxxeKqcLe"} + ] + } +} +``` + +**限制**: +- 单个单元格附件数不超过 100 +- 必须先上传到当前多维表格,不能用外部 file_token + +--- + +## 场景 8: 双向关联字段 + +### 步骤 1: 创建双向关联字段 + +**在"任务表"中创建关联到"项目表"的字段**: + +```json +{ + "action": "create", + "app_token": "S404b...", + "table_id": "tbl_task", + "field_name": "所属项目", + "type": 21, + "property": { + "table_id": "tbl_project", + "back_field_name": "关联的任务", + "multiple": true + } +} +``` + +**结果**: +- 在"任务表"中创建字段"所属项目" +- 在"项目表"中**自动创建**字段"关联的任务" + +--- + +### 步骤 2: 写入关联记录 + +```json +{ + "action": "create", + "app_token": "S404b...", + "table_id": "tbl_task", + "fields": { + "任务名称": "开发新功能", + "所属项目": { + "link_record_ids": ["rec_project_001"] + } + } +} +``` + +**级联更新**: +- 在"任务表"中设置"所属项目"为 `rec_project_001` +- "项目表"的 `rec_project_001` 记录的"关联的任务"字段会**自动添加**当前任务的 record_id + +--- + +### 单向关联 (type=18) + +**区别**: 只影响当前表,不会自动更新对方表 + +```json +{ + "action": "create", + "app_token": "S404b...", + "table_id": "tbl_task", + "field_name": "参考任务", + "type": 18, + "property": { + "table_id": "tbl_task", // 可以关联自己 + "multiple": true + } +} +``` + +--- + +## 🔗 参考链接 + +- [字段 Property 配置详解](field-properties.md) +- [记录值数据结构详解](record-values.md) +- [飞书开放平台 - 多维表格文档](https://open.feishu.cn/document/server-docs/docs/bitable-v1/bitable-overview) diff --git a/extensions/openclaw-lark/skills/feishu-bitable/references/field-properties.md b/extensions/openclaw-lark/skills/feishu-bitable/references/field-properties.md new file mode 100644 index 0000000..67af24d --- /dev/null +++ b/extensions/openclaw-lark/skills/feishu-bitable/references/field-properties.md @@ -0,0 +1,763 @@ +# 飞书多维表格字段 Property 配置详解 + +本文档详细说明每种字段类型创建或更新时需要的 `property` 参数结构。 + +> **来源**: 基于飞书开放平台文档 [字段编辑指南](https://go.feishu.cn/s/672BSzVyo03) + +## 📋 目录 + +- [基础字段](#基础字段) + - [1. 文本 (type=1)](#1-文本-type1) + - [2. 数字 (type=2)](#2-数字-type2) + - [5. 日期 (type=5)](#5-日期-type5) + - [7. 复选框 (type=7)](#7-复选框-type7) + - [13. 电话号码 (type=13)](#13-电话号码-type13) +- [选择字段](#选择字段) + - [3. 单选 (type=3)](#3-单选-type3) + - [4. 多选 (type=4)](#4-多选-type4) +- [特殊显示字段](#特殊显示字段) + - [进度 (type=2, ui_type="Progress")](#进度-type2-ui_typeprogress) + - [货币 (type=2, ui_type="Currency")](#货币-type2-ui_typecurrency) + - [评分 (type=2, ui_type="Rating")](#评分-type2-ui_typerating) + - [条码 (type=1, ui_type="Barcode")](#条码-type1-ui_typebarcode) + - [邮箱 (type=1, ui_type="Email")](#邮箱-type1-ui_typeemail) +- [关系字段](#关系字段) + - [11. 人员 (type=11)](#11-人员-type11) + - [15. 超链接 (type=15)](#15-超链接-type15) + - [17. 附件 (type=17)](#17-附件-type17) + - [18. 单向关联 (type=18)](#18-单向关联-type18) + - [21. 双向关联 (type=21)](#21-双向关联-type21) + - [22. 地理位置 (type=22)](#22-地理位置-type22) + - [23. 群组 (type=23)](#23-群组-type23) +- [高级字段](#高级字段) + - [20. 公式 (type=20)](#20-公式-type20) + - [1001. 创建时间 (type=1001)](#1001-创建时间-type1001) + - [1002. 最后更新时间 (type=1002)](#1002-最后更新时间-type1002) + - [1005. 自动编号 (type=1005)](#1005-自动编号-type1005) + +--- + +## 基础字段 + +### 1. 文本 (type=1) + +**Property 结构**: 空对象或省略 + +```json +{ + "type": 1, + "field_name": "任务描述", + "property": {} +} +``` + +**注意**: +- 默认 `ui_type` 为 "Text" +- 单个单元格最多 10 万字符 +- 支持富文本格式(提及人、超链接等) + +--- + +### 2. 数字 (type=2) + +**Property 结构**: + +```json +{ + "formatter": "0" // 可选,数字显示格式 +} +``` + +**formatter 可选值**: +- `"0"`: 整数(默认) +- `"0.0"`: 一位小数 +- `"0.00"`: 两位小数 +- `"0,000"`: 千分位 +- `"0.00%"`: 百分比 + +**示例**: + +```json +{ + "type": 2, + "field_name": "工时", + "property": { + "formatter": "0.00" + } +} +``` + +--- + +### 5. 日期 (type=5) + +**Property 结构**: + +```json +{ + "date_formatter": "yyyy/MM/dd", // 可选,默认 "yyyy/MM/dd" + "auto_fill": false // 可选,是否自动填充创建时间 +} +``` + +**date_formatter 可选值**: +- `"yyyy/MM/dd"`: 2021/1/30 +- `"yyyy-MM-dd HH:mm"`: 2021/1/30 14:00 +- `"MM-dd"`: 1月30日 +- `"MM/dd/yyyy"`: 01/30/2021 +- `"dd/MM/yyyy"`: 30/01/2021 + +**示例**: + +```json +{ + "type": 5, + "field_name": "截止日期", + "property": { + "date_formatter": "yyyy-MM-dd HH:mm", + "auto_fill": false + } +} +``` + +--- + +### 7. 复选框 (type=7) + +**Property 结构**: 空对象或省略 + +```json +{ + "type": 7, + "field_name": "是否完成", + "property": {} +} +``` + +--- + +### 13. 电话号码 (type=13) + +**Property 结构**: 空对象或省略 + +```json +{ + "type": 13, + "field_name": "联系电话", + "property": {} +} +``` + +**注意**: +- 电话号码格式:符合正则 `(\+)?\d*` +- 最大长度 64 字符 + +--- + +## 选择字段 + +### 3. 单选 (type=3) + +**Property 结构**: + +```json +{ + "options": [ + { + "name": "进行中", // 必填,选项名称 + "color": 0 // 可选,颜色编号 (0-54) + }, + { + "name": "已完成", + "color": 10 + } + ] +} +``` + +**颜色编号 (color)**: +- 范围: 0-54 +- 0: 红色 +- 10: 绿色 +- 20: 蓝色 +- ... (详见飞书官方文档) + +**示例**: + +```json +{ + "type": 3, + "field_name": "任务状态", + "property": { + "options": [ + {"name": "待开始", "color": 0}, + {"name": "进行中", "color": 20}, + {"name": "已完成", "color": 10} + ] + } +} +``` + +**注意**: +- 选项总数不超过 20,000 个 +- 创建时**不能**指定选项 ID(`id` 字段),系统自动生成 +- 更新时需保留已有选项的 `id` + +--- + +### 4. 多选 (type=4) + +**Property 结构**: 与单选相同 + +```json +{ + "options": [ + {"name": "紧急", "color": 0}, + {"name": "重要", "color": 10} + ] +} +``` + +**注意**: +- 选项总数不超过 20,000 个 +- 单个单元格选项数不超过 1,000 个 + +--- + +## 特殊显示字段 + +### 进度 (type=2, ui_type="Progress") + +**Property 结构**: + +```json +{ + "min": 0, // 必填,最小值 + "max": 100, // 必填,最大值 + "range_customize": false // 可选,是否允许自定义进度值 +} +``` + +**示例**: + +```json +{ + "type": 2, + "field_name": "完成进度", + "ui_type": "Progress", + "property": { + "min": 0, + "max": 100, + "range_customize": true + } +} +``` + +**注意**: +- `min` 取值范围: 0-1 +- `max` 取值范围: 1-100 +- `range_customize` 为 `true` 时用户可输入超出范围的值 + +--- + +### 货币 (type=2, ui_type="Currency") + +**Property 结构**: + +```json +{ + "currency_code": "CNY", // 必填,货币类型 + "formatter": "0.00" // 可选,数字格式 +} +``` + +**currency_code 可选值**: +- `"CNY"`: 人民币 (¥) +- `"USD"`: 美元 ($) +- `"EUR"`: 欧元 (€) +- `"GBP"`: 英镑 (£) +- `"JPY"`: 日元 (¥) +- `"HKD"`: 港元 ($) +- ... (支持 20+ 种货币) + +**示例**: + +```json +{ + "type": 2, + "field_name": "预算", + "ui_type": "Currency", + "property": { + "currency_code": "USD", + "formatter": "0,000.00" + } +} +``` + +--- + +### 评分 (type=2, ui_type="Rating") + +**Property 结构**: + +```json +{ + "min": 1, // 必填,最小值 + "max": 5, // 必填,最大值 + "rating": { // 可选,评分样式 + "symbol": "star" // 图标类型 + } +} +``` + +**symbol 可选值**: +- `"star"`: ⭐ 星星(默认) +- `"heart"`: ❤️ 爱心 +- `"thumbsup"`: 👍 赞 +- `"fire"`: 🔥 火焰 +- `"smile"`: 😊 笑脸 +- `"lightning"`: ⚡ 闪电 +- `"flower"`: 🌸 花朵 +- `"number"`: 数字 + +**示例**: + +```json +{ + "type": 2, + "field_name": "优先级", + "ui_type": "Rating", + "property": { + "min": 1, + "max": 5, + "rating": { + "symbol": "fire" + } + } +} +``` + +--- + +### 条码 (type=1, ui_type="Barcode") + +**Property 结构**: + +```json +{ + "allowed_edit_modes": { + "manual": true, // 是否允许手动录入 + "scan": true // 是否允许扫描录入 + } +} +``` + +**示例**: + +```json +{ + "type": 1, + "field_name": "商品条码", + "ui_type": "Barcode", + "property": { + "allowed_edit_modes": { + "manual": false, + "scan": true + } + } +} +``` + +--- + +### 邮箱 (type=1, ui_type="Email") + +**Property 结构**: 空对象或省略 + +```json +{ + "type": 1, + "field_name": "联系邮箱", + "ui_type": "Email", + "property": {} +} +``` + +--- + +## 关系字段 + +### 11. 人员 (type=11) + +**Property 结构**: + +```json +{ + "multiple": true // 可选,是否允许多个人员,默认 true +} +``` + +**示例**: + +```json +{ + "type": 11, + "field_name": "负责人", + "property": { + "multiple": false // 只允许单个人员 + } +} +``` + +**注意**: +- 单个单元格人员数不超过 1,000 +- 记录值只支持传入 `id` 字段(open_id/union_id/user_id) + +--- + +### 15. 超链接 (type=15) + +**Property 结构**: **必须省略 `property` 参数,不要传递任何值(包括空对象)** + +```json +{ + "type": 15, + "field_name": "参考链接" + // 不要传 property 参数,包括空对象 {} +} +``` + +**⚠️ 重要**: 超链接字段的特殊要求(经实测验证): +- ✅ **正确**: 完全省略 `property` 参数 +- ❌ **错误**: `"property": {}`(会报 URLFieldPropertyError) +- ❌ **错误**: 传递任何 property 值 + +**注意**: 这是飞书 API 的特殊行为,超链接字段即使传空对象也会报错,必须完全省略该参数。 + +--- + +### 17. 附件 (type=17) + +**Property 结构**: 空对象或省略 + +```json +{ + "type": 17, + "field_name": "附件", + "property": {} +} +``` + +**注意**: +- 单个单元格附件数不超过 100 +- 写入前需先调用[上传素材接口](https://go.feishu.cn/s/63soQp6O80s) + +--- + +### 18. 单向关联 (type=18) + +**Property 结构**: + +```json +{ + "table_id": "tblXXXXXXXX", // 必填,关联的数据表 ID + "multiple": true // 可选,是否允许多条记录,默认 true +} +``` + +**示例**: + +```json +{ + "type": 18, + "field_name": "关联任务", + "property": { + "table_id": "tblsRc9GRRXKqhvW", + "multiple": true + } +} +``` + +**注意**: +- 单个单元格关联数不超过 500 + +--- + +### 21. 双向关联 (type=21) + +**Property 结构**: + +```json +{ + "table_id": "tblXXXXXXXX", // 必填,关联的数据表 ID + "back_field_name": "反向字段名", // 必填,对方表的双向关联字段名 + "multiple": true // 可选,是否允许多条记录 +} +``` + +**示例**: + +```json +{ + "type": 21, + "field_name": "相关项目", + "property": { + "table_id": "tblAnotherTable", + "back_field_name": "关联的任务", + "multiple": true + } +} +``` + +**注意**: +- 单个单元格关联数不超过 500 +- 对方表会自动创建对应的双向关联字段 + +--- + +### 22. 地理位置 (type=22) + +**Property 结构**: + +```json +{ + "location": { + "input_type": "not_limit" // 输入限制 + } +} +``` + +**input_type 可选值**: +- `"only_mobile"`: 仅允许移动端实时定位 +- `"not_limit"`: 无限制(默认) + +**示例**: + +```json +{ + "type": 22, + "field_name": "办公地址", + "property": { + "location": { + "input_type": "only_mobile" + } + } +} +``` + +--- + +### 23. 群组 (type=23) + +**Property 结构**: 空对象或省略 + +```json +{ + "type": 23, + "field_name": "协作群", + "property": {} +} +``` + +**注意**: +- 单个单元格群组数不超过 10 个 + +--- + +## 高级字段 + +### 20. 公式 (type=20) + +**Property 结构**: + +```json +{ + "formula_expression": "bitable::$table[tblXXX].$field[fldYYY]*2" // 可选 +} +``` + +**示例**: + +```json +{ + "type": 20, + "field_name": "总价", + "property": { + "formula_expression": "bitable::$table[tblMain].$field[fldQty] * $field[fldPrice]" + } +} +``` + +**注意**: +- 创建字段时**不支持**设置公式表达式 +- 参考[飞书帮助中心 - 公式字段](https://www.feishu.cn/hc/zh-CN/articles/360049067853) + +**对于某些多维表格,公式字段需要额外设置 `type` 参数**(通过[获取多维表格元数据](https://go.feishu.cn/s/62nuKkQlE03)接口的 `formula_type` 判断): + +```json +{ + "type": 20, + "field_name": "计算字段", + "property": { + "type": { + "data_type": 2, // 公式结果的数据类型 (1=文本, 2=数字, 5=日期...) + "ui_property": { // UI 展示属性 + "formatter": "0.00", + "currency_code": "CNY" + }, + "ui_type": "Currency" // UI 类型 (Number/Progress/Currency/Rating/DateTime) + } + } +} +``` + +--- + +### 1001. 创建时间 (type=1001) + +**Property 结构**: + +```json +{ + "date_formatter": "yyyy/MM/dd" // 可选,日期格式 +} +``` + +**示例**: + +```json +{ + "type": 1001, + "field_name": "创建于", + "property": { + "date_formatter": "yyyy-MM-dd HH:mm" + } +} +``` + +--- + +### 1002. 最后更新时间 (type=1002) + +**Property 结构**: 与创建时间相同 + +```json +{ + "date_formatter": "yyyy-MM-dd HH:mm" +} +``` + +--- + +### 1005. 自动编号 (type=1005) + +**Property 结构**: + +```json +{ + "auto_serial": { + "type": "auto_increment_number", // 或 "custom" + "options": [ // 自定义编号规则(仅 type="custom" 时需要) + { + "type": "fixed_text", + "value": "TASK-" + }, + { + "type": "created_time", + "value": "yyyyMMdd" + }, + { + "type": "system_number", + "value": "5" + } + ] + } +} +``` + +**auto_serial.type 可选值**: +- `"auto_increment_number"`: 纯自增数字 +- `"custom"`: 自定义编号规则 + +**options 中的规则类型**: +- `"system_number"`: 自增数字位数(value: 1-9) +- `"fixed_text"`: 固定字符(value: 最多 20 字符) +- `"created_time"`: 创建时间(value: "yyyyMMdd"/"yyyyMM"/"yyyy"/"MMdd"/"MM"/"dd") + +**示例 1: 纯自增**: + +```json +{ + "type": 1005, + "field_name": "编号", + "property": { + "auto_serial": { + "type": "auto_increment_number" + } + } +} +``` + +**示例 2: 自定义编号**: + +```json +{ + "type": 1005, + "field_name": "工单号", + "property": { + "auto_serial": { + "type": "custom", + "options": [ + {"type": "fixed_text", "value": "WO-"}, + {"type": "created_time", "value": "yyyyMMdd"}, + {"type": "system_number", "value": "4"} + ] + } + } +} +// 生成示例: WO-20240226-0001 +``` + +--- + +## 🔍 常见错误码 + +| 错误码 | 字段类型 | 说明 | +|--------|---------|------| +| 1254080 | 文本 | property 结构错误 | +| 1254081 | 数字 | property 结构错误,检查 formatter | +| 1254082 | 单选 | property 结构错误,检查 options 数组 | +| 1254083 | 多选 | property 结构错误,检查 options 数组 | +| 1254084 | 日期 | property 结构错误,检查 date_formatter | +| 1254085 | 复选框 | property 结构错误 | +| 1254086 | 人员 | property 结构错误,检查 multiple | +| 1254087 | 超链接 | **必须省略 property 参数(传空对象也会报错)** | +| 1254088 | 附件 | property 结构错误 | +| 1254089 | 单向关联 | property 结构错误,检查 table_id | +| 1254090 | 查找引用 | property 结构错误 | +| 1254091 | 公式 | property 结构错误 | +| 1254092 | 双向关联 | property 结构错误,检查 table_id 和 back_field_name | +| 1254093 | 创建时间 | property 结构错误 | +| 1254094 | 最后更新时间 | property 结构错误 | + +--- + +## 📌 更新字段时的特殊规则 + +调用 `update` action 更新字段时: + +1. **必须保持字段类型一致**: `type` 和 `ui_type` 不能变更 +2. **单选/多选更新选项**: + - 已有选项必须保留 `id` + - 新增选项只传 `name` 和 `color`,不传 `id` +3. **如果只改字段名**: + - 可以只传 `field_name`,工具会自动查询当前 `type` 和 `property` +4. **关联字段的 table_id**: 不能修改为不同的表 + +--- + +## 🔗 参考链接 + +- [飞书开放平台 - 字段编辑指南](https://go.feishu.cn/s/672BSzVyo03) +- [新增字段接口文档](https://go.feishu.cn/s/62nuKkQl403) +- [更新字段接口文档](https://go.feishu.cn/s/62nuKkQlo03) diff --git a/extensions/openclaw-lark/skills/feishu-bitable/references/record-values.md b/extensions/openclaw-lark/skills/feishu-bitable/references/record-values.md new file mode 100644 index 0000000..a7b79ef --- /dev/null +++ b/extensions/openclaw-lark/skills/feishu-bitable/references/record-values.md @@ -0,0 +1,911 @@ +# 飞书多维表格记录值数据结构详解 + +本文档详细说明每种字段类型在记录中对应的 `fields` 值格式。 + +> **来源**: 基于飞书开放平台文档 [多维表格记录数据结构](https://go.feishu.cn/s/6lY28723w04) + +## 📋 快速索引 + +| 字段类型 | type | 值类型 | 示例 | 限制 | +|---------|------|--------|------|------| +| [文本](#文本-type1) | 1 | string (写入) / list of object (返回) | `"任务描述"` | 最多 10 万字符 | +| [数字](#数字-type2) | 2 | number | `0.5` | - | +| [单选](#单选-type3) | 3 | string | `"进行中"` | 选项总数≤20,000 | +| [多选](#多选-type4) | 4 | array<string> | `["审批", "办公"]` | 选项总数≤20,000,单元格≤1,000 | +| [日期](#日期-type5) | 5 | number | `1675526400000` | Unix 毫秒时间戳 | +| [复选框](#复选框-type7) | 7 | boolean | `true` | - | +| [人员](#人员-type11) | 11 | list of object | `[{"id": "ou_xxx"}]` | 单元格≤1,000,写入仅支持 `id` | +| [电话](#电话号码-type13) | 13 | string | `"17899870000"` | 最多 64 字符 | +| [超链接](#超链接-type15) | 15 | object | `{"text": "飞书", "link": "..."}` | - | +| [附件](#附件-type17) | 17 | list of object | `[{"file_token": "xxx"}]` | 单元格≤100 | +| [单向关联](#单向关联-type18) | 18 | object | `{"link_record_ids": [...]}` | 单元格≤500 | +| [双向关联](#双向关联-type21) | 21 | object | `{"link_record_ids": [...]}` | 单元格≤500 | +| [地理位置](#地理位置-type22) | 22 | object | `{"location": "116.3,40.0", ...}` | - | +| [群组](#群组-type23) | 23 | list of object | `[{"id": "oc_xxx"}]` | 单元格≤10 | +| [公式/查找引用](#公式查找引用-type20-type19) | 20/19 | object | `{"type": 1, "value": [...]}` | 只读 | + +--- + +## 文本 (type=1) + +### 基础文本 (ui_type="Text") + +**写入格式**: 字符串 + +```json +{ + "fields": { + "任务描述": "维护客户关系" + } +} +``` + +**返回格式**: 对象数组 + +```json +{ + "任务描述": [ + { + "text": "维护客户关系", + "type": "text" + } + ] +} +``` + +**富文本格式** (提及人、超链接): + +```json +{ + "任务描述": [ + { + "text": "请 ", + "type": "text" + }, + { + "text": "@张三", + "type": "mention", + "token": "ou_user123", + "mentionType": "User", + "mentionNotify": true, + "name": "张三" + }, + { + "text": " 查看 ", + "type": "text" + }, + { + "text": "飞书官网", + "type": "url", + "link": "https://www.feishu.cn" + } + ] +} +``` + +**富文本元素类型**: + +| type | 说明 | 额外字段 | +|------|------|---------| +| `"text"` | 纯文本 | `text` | +| `"mention"` | 提及(人/文档) | `token`, `mentionType`, `mentionNotify`, `name` | +| `"url"` | 超链接 | `text`, `link` | + +**mentionType 可选值**: +- `"User"`: 提及用户 +- `"Docx"`: 提及文档 +- `"Sheet"`: 提及电子表格 +- `"Bitable"`: 提及多维表格 + +--- + +### 条码 (ui_type="Barcode") + +**写入格式**: 字符串 + +```json +{ + "fields": { + "商品条码": "FS0001" + } +} +``` + +**返回格式**: + +```json +{ + "商品条码": [ + { + "text": "FS0001", + "type": "text" + } + ] +} +``` + +--- + +### 邮箱 (ui_type="Email") + +**写入格式**: 字符串 + +```json +{ + "fields": { + "联系邮箱": "zhangmin@xxxgmail.com" + } +} +``` + +**返回格式**: + +```json +{ + "联系邮箱": [ + { + "text": "zhangmin@xxxgmail.com", + "type": "url", + "link": "mailto:zhangmin@xxxgmail.com" + } + ] +} +``` + +--- + +## 数字 (type=2) + +**写入/返回格式**: 数字 + +```json +{ + "fields": { + "工时": 10, + "完成率": 0.75, + "预算": 5000.50 + } +} +``` + +**注意**: +- 进度 (ui_type="Progress"): 0-1 范围的小数 +- 货币 (ui_type="Currency"): 普通数字 +- 评分 (ui_type="Rating"): 整数 + +--- + +## 单选 (type=3) + +**写入格式**: 选项名称字符串 + +```json +{ + "fields": { + "任务状态": "进行中" + } +} +``` + +**新选项**: 传入不存在的选项名会**自动创建新选项** + +```json +{ + "fields": { + "任务状态": "已暂停" // 如果不存在,会自动创建 + } +} +``` + +**返回格式**: 与写入相同 + +```json +{ + "任务状态": "进行中" +} +``` + +**限制**: +- 选项总数不超过 20,000 + +--- + +## 多选 (type=4) + +**写入格式**: 字符串数组 + +```json +{ + "fields": { + "标签": ["审批集成", "办公管理", "身份管理"] + } +} +``` + +**新选项**: 传入不存在的选项名会**自动创建新选项** + +```json +{ + "fields": { + "标签": ["新标签1", "新标签2"] // 不存在的会自动创建 + } +} +``` + +**返回格式**: 与写入相同 + +```json +{ + "标签": ["审批集成", "办公管理"] +} +``` + +**限制**: +- 选项总数不超过 20,000 +- 单个单元格选项数不超过 1,000 + +--- + +## 日期 (type=5) + +**写入/返回格式**: Unix 毫秒时间戳 + +```json +{ + "fields": { + "截止日期": 1675526400000 // 2023-02-05 00:00:00 (UTC) + } +} +``` + +**注意**: +- 必须使用**毫秒级**时间戳(不是秒级) +- 建议使用北京时间 (UTC+8) 转换 + +**常见错误** (错误码 1254064): + +```json +// ❌ 错误:使用 ISO 字符串 +{"截止日期": "2026-02-27"} + +// ❌ 错误:使用 RFC3339 格式 +{"截止日期": "2026-02-27T10:00:00+08:00"} + +// ❌ 错误:使用秒级时间戳 +{"截止日期": 1772121600} // 少了 3 位 + +// ✅ 正确:使用毫秒时间戳 +{"截止日期": 1772121600000} +``` + +--- + +## 复选框 (type=7) + +**写入/返回格式**: 布尔值 + +```json +{ + "fields": { + "是否完成": true, + "是否延期": false + } +} +``` + +--- + +## 人员 (type=11) + +**写入格式**: 对象数组,**仅支持 `id` 字段** + +```json +{ + "fields": { + "负责人": [ + {"id": "ou_8240099442cf5da49f04f4bf8f8abcef"} + ], + "协作人": [ + {"id": "ou_user1"}, + {"id": "ou_user2"} + ] + } +} +``` + +**返回格式**: 对象数组,包含完整信息 + +```json +{ + "负责人": [ + { + "id": "ou_8240099442cf5da49f04f4bf8f8abcef", + "name": "黄泡泡", + "en_name": "Amanda Huang", + "email": "amandahuang@xxxgmail.com", + "avatar_url": "https://..." + } + ] +} +``` + +**⚠️ 重要**: +- **写入时只支持 `id`**,不能传 `name`、`email` 等字段 +- `id` 类型需与 `user_id_type` 参数一致(open_id/union_id/user_id) +- 单个单元格人员数不超过 1,000 +- 传空: `null` 或 `[]` + +--- + +## 电话号码 (type=13) + +**写入/返回格式**: 字符串 + +```json +{ + "fields": { + "联系电话": "17899870000", + "座机": "+86-010-12345678" + } +} +``` + +**格式规则**: +- 符合正则: `(\+)?\d*` +- 最大长度 64 字符 + +--- + +## 超链接 (type=15) + +**写入/返回格式**: 对象 + +```json +{ + "fields": { + "参考链接": { + "text": "飞书开放平台", + "link": "https://open.feishu.cn" + } + } +} +``` + +**字段说明**: +- `text`: 显示的文本 +- `link`: URL 地址 + +**常见错误** (错误码 1254068): + +```json +// ❌ 错误:直接传字符串 URL +{ + "参考链接": "https://open.feishu.cn" +} + +// ✅ 正确:使用对象格式 +{ + "参考链接": { + "text": "飞书开放平台", + "link": "https://open.feishu.cn" + } +} + +// ✅ text 和 link 可以相同 +{ + "参考链接": { + "text": "https://open.feishu.cn", + "link": "https://open.feishu.cn" + } +} +``` + +--- + +## 附件 (type=17) + +**写入格式**: 对象数组,**仅传 `file_token`** + +```json +{ + "fields": { + "附件": [ + {"file_token": "DRiFbwaKsoZaLax4WKZbEGCccoe"}, + {"file_token": "BZk3bL1Enoy4pzxaPL9bNeKqcLe"} + ] + } +} +``` + +**返回格式**: 对象数组,包含完整信息 + +```json +{ + "附件": [ + { + "file_token": "J7GdbgNWWoD1fwx7oWccxdgknIe", + "name": "58cc930b89.png", + "type": "image/png", + "size": 108867, + "url": "https://open.feishu.cn/open-apis/drive/v1/medias/...", + "tmp_url": "https://open.feishu.cn/open-apis/drive/v1/medias/batch_get_tmp_download_url?..." + } + ] +} +``` + +**⚠️ 重要**: +- 写入前必须先调用[上传素材接口](https://go.feishu.cn/s/63soQp6O80s)获取 `file_token` +- 单个单元格附件数不超过 100 +- 错误码 1254303: 附件未挂载到当前多维表格 + +--- + +## 单向关联 (type=18) + +**写入格式**: `link_record_ids` 数组 + +```json +{ + "fields": { + "关联任务": { + "link_record_ids": ["recHTLvO7x", "recbS8zb2m"] + } + } +} +``` + +**简化写入** (直接数组): + +```json +{ + "fields": { + "关联任务": ["recHTLvO7x", "recbS8zb2m"] + } +} +``` + +**返回格式**: + +```json +{ + "关联任务": { + "link_record_ids": ["recHTLvO7x", "recbS8zb2m"] + } +} +``` + +**限制**: +- 单个单元格关联数不超过 500 + +--- + +## 双向关联 (type=21) + +**写入/返回格式**: 与单向关联相同 + +```json +{ + "fields": { + "相关项目": { + "link_record_ids": ["reclzUoBLn", "rec7bYQoX1"] + } + } +} +``` + +**注意**: +- 更新双向关联会同步更新对方表的对应字段 +- 单个单元格关联数不超过 500 + +--- + +## 地理位置 (type=22) + +**写入格式**: 经纬度字符串 + +```json +{ + "fields": { + "办公地址": "116.397755,39.903179" + } +} +``` + +**返回格式**: 对象,包含详细信息 + +```json +{ + "办公地址": { + "location": "116.352681,40.01437", + "pname": "北京市", + "cityname": "北京市", + "adname": "海淀区", + "address": "学清路10号院学清嘉创大厦", + "name": "Bytedance", + "full_address": "Bytedance,北京市北京市海淀区学清路10号院学清嘉创大厦" + } +} +``` + +**字段说明**: +- `location`: 经纬度 (格式: "经度,纬度") +- `pname`: 省 +- `cityname`: 市 +- `adname`: 区 +- `address`: 详细地址 +- `name`: 地名 +- `full_address`: 完整地址 + +--- + +## 群组 (type=23) + +**写入格式**: 对象数组,**仅传 `id`** + +```json +{ + "fields": { + "协作群": [ + {"id": "oc_d2a947abb78bbbbb12d4cad55fbabcef"} + ] + } +} +``` + +**返回格式**: 对象数组,包含完整信息 + +```json +{ + "协作群": [ + { + "id": "oc_d2a947abb78bbbbb12d4cad55fbabcef", + "name": "测试部门", + "avatar_url": "https://..." + } + ] +} +``` + +**限制**: +- 单个单元格群组数不超过 10 + +--- + +## 公式/查找引用 (type=20, type=19) + +**格式**: 对象,包含 `type`、`ui_type` 和 `value` + +```json +{ + "是否延期": { + "type": 1, // 底层数据类型 + "ui_type": "Text", // UI 展示类型 + "value": [ // 计算结果 + { + "text": "✅ 正常", + "type": "text" + } + ] + } +} +``` + +**字段说明**: +- `type`: 底层数据类型枚举(1=文本, 2=数字, 5=日期...) +- `ui_type`: UI 展示类型("Text"/"Number"/"Progress"/...) +- `value`: 计算结果,格式由 `type` 决定 + +**示例 - 数字类型公式**: + +```json +{ + "总价": { + "type": 2, + "ui_type": "Currency", + "value": 1250.50 + } +} +``` + +**示例 - 日期类型公式**: + +```json +{ + "计算日期": { + "type": 5, + "ui_type": "DateTime", + "value": 1675526400000 + } +} +``` + +**⚠️ 注意**: +- 公式字段为**只读**,不能通过写接口设置 +- `value` 的数据结构取决于 `type` 对应的字段类型 + +--- + +## 系统字段 + +### 创建时间 (type=1001) + +**返回格式**: Unix 毫秒时间戳 + +```json +{ + "创建于": 1675526400000 +} +``` + +**⚠️ 只读**: 不能通过写接口设置 + +--- + +### 最后更新时间 (type=1002) + +**返回格式**: Unix 毫秒时间戳 + +```json +{ + "更新于": 1675612800000 +} +``` + +**⚠️ 只读**: 不能通过写接口设置 + +--- + +### 创建人 / 修改人 (type=1003, type=1004) + +**返回格式**: 对象数组(与人员字段相同) + +```json +{ + "创建人": [ + { + "id": "ou_8240099442cf5da49f04f4bf8f8abcef", + "name": "黄泡泡", + "en_name": "Amanda Huang", + "email": "amandahuang@xxxgmail.com", + "avatar_url": "https://..." + } + ] +} +``` + +**⚠️ 只读**: 不能通过写接口设置 + +--- + +### 自动编号 (type=1005) + +**返回格式**: 字符串 + +```json +{ + "工单号": "WO-20240226-0001" +} +``` + +**⚠️ 只读**: 不能通过写接口设置 + +--- + +## 🔍 常见错误与排查 + +### 字段类型不匹配 (错误码 1254015) + +**错误示例**: + +```json +// ❌ 错误: 日期字段传字符串 +{ + "fields": { + "截止日期": "2024-02-26" // 应该传时间戳 + } +} + +// ✅ 正确 +{ + "fields": { + "截止日期": 1708905600000 + } +} +``` + +--- + +### 人员字段格式错误 (错误码 1254066) + +**常见原因**: + +1. **传入了不支持的字段**: + +```json +// ❌ 错误 +{ + "负责人": [ + {"name": "张三"} // 只能传 id + ] +} + +// ✅ 正确 +{ + "负责人": [ + {"id": "ou_xxx"} + ] +} +``` + +2. **user_id_type 不匹配**: + +```bash +# 请求时指定了 user_id_type=open_id,但传的是 union_id +``` + +3. **跨应用传 open_id**: + +``` +不同应用的 open_id 不能交叉使用,建议使用 user_id +``` + +--- + +### 附件未挂载 (错误码 1254303) + +**原因**: 直接传入外部 file_token + +**解决**: + +1. 先调用[上传素材接口](https://go.feishu.cn/s/63soQp6O80s)上传到当前多维表格 +2. 使用返回的 `file_token` 写入记录 + +--- + +### 字段名不存在 (错误码 1254045) + +**原因**: 字段名称不完全匹配(可能有空格、换行、特殊字符) + +**排查**: + +1. 调用[列出字段接口](https://go.feishu.cn/s/62nuKkQlk03)获取准确字段名 +2. 检查首尾空格、换行符 + +--- + +### 超链接字段转换失败 (错误码 1254068) + +**原因**: 缺少 `text` 或 `link` 字段 + +```json +// ❌ 错误 +{ + "参考链接": { + "link": "https://example.com" // 缺少 text + } +} + +// ✅ 正确 +{ + "参考链接": { + "text": "示例网站", + "link": "https://example.com" + } +} +``` + +--- + +## 📌 最佳实践 + +### 1. 批量写入优化 + +```json +{ + "fields": { + "任务名称": "拜访客户", + "负责人": [{"id": "ou_xxx"}], + "截止日期": 1708905600000, + "标签": ["重要", "紧急"], + "是否完成": false + } +} +``` + +**建议**: +- 一次性传入所有字段,避免多次调用 +- 只传需要设置的字段,不必包含所有列 + +--- + +### 2. 清空字段值 + +**方法 1**: 传 `null` + +```json +{ + "fields": { + "负责人": null, + "标签": null + } +} +``` + +**方法 2**: 传空数组/空字符串(根据字段类型) + +```json +{ + "fields": { + "负责人": [], + "任务名称": "" + } +} +``` + +--- + +### 3. 时间戳转换 + +**JavaScript**: + +```javascript +// 北京时间字符串 → Unix 毫秒时间戳 +const timestamp = new Date("2024-02-26 14:00").getTime() // 1708927200000 + +// Unix 毫秒时间戳 → 日期字符串 +const date = new Date(1708927200000).toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' }) +``` + +**Python**: + +```python +import datetime + +# 北京时间字符串 → Unix 毫秒时间戳 +dt = datetime.datetime(2024, 2, 26, 14, 0, 0) +timestamp = int(dt.timestamp() * 1000) # 1708927200000 + +# Unix 毫秒时间戳 → 日期字符串 +dt = datetime.datetime.fromtimestamp(1708927200000 / 1000) +``` + +--- + +### 4. 关联字段的级联更新 + +**双向关联**: + +```json +// 更新 Table A 的双向关联字段 +{ + "fields": { + "关联项目": { + "link_record_ids": ["rec123"] + } + } +} +// Table B 的对应双向关联字段会自动更新 +``` + +**单向关联**: + +```json +// 只更新当前表,不影响关联表 +{ + "fields": { + "参考任务": { + "link_record_ids": ["rec456"] + } + } +} +``` + +--- + +## 🔗 参考链接 + +- [飞书开放平台 - 多维表格记录数据结构](https://go.feishu.cn/s/6lY28723w04) +- [新增记录接口文档](https://go.feishu.cn/s/61Y-IrQjU02) +- [更新记录接口文档](https://go.feishu.cn/s/6lY28723A04) +- [上传素材接口](https://go.feishu.cn/s/63soQp6O80s) diff --git a/extensions/openclaw-lark/skills/feishu-calendar/SKILL.md b/extensions/openclaw-lark/skills/feishu-calendar/SKILL.md new file mode 100644 index 0000000..a5d79e7 --- /dev/null +++ b/extensions/openclaw-lark/skills/feishu-calendar/SKILL.md @@ -0,0 +1,242 @@ +--- +name: feishu-calendar +description: | + 飞书日历与日程管理工具集。包含日历管理、日程管理、参会人管理、忙闲查询。 +--- + +# 飞书日历管理 (feishu-calendar) + +## 🚨 执行前必读 + +- ✅ **时区固定**:Asia/Shanghai(UTC+8) +- ✅ **时间格式**:ISO 8601 / RFC 3339(带时区),例如 `2026-02-25T14:00:00+08:00` +- ✅ **create 最小必填**:summary, start_time, end_time +- ✅ **user_open_id 强烈建议**:从 SenderId 获取(ou_xxx),确保用户能看到日程 +- ✅ **ID 格式约定**:用户 `ou_...`,群 `oc_...`,会议室 `omm_...`,邮箱 `email@...` + +--- + +## 📋 快速索引:意图 → 工具 → 必填参数 + +| 用户意图 | 工具 | action | 必填参数 | 强烈建议 | 常用可选 | +|---------|------|--------|---------|---------|---------| +| 创建会议 | feishu_calendar_event | create | summary, start_time, end_time | user_open_id | attendees, description, location | +| 查某时间段日程 | feishu_calendar_event | list | start_time, end_time | - | - | +| 改日程时间 | feishu_calendar_event | patch | event_id, start_time/end_time | - | summary, description | +| 搜关键词找会 | feishu_calendar_event | search | query | - | - | +| 回复邀请 | feishu_calendar_event | reply | event_id, rsvp_status | - | - | +| 查重复日程实例 | feishu_calendar_event | instances | event_id, start_time, end_time | - | - | +| 查忙闲 | feishu_calendar_freebusy | list | time_min, time_max, user_ids[] | - | - | +| 邀请参会人 | feishu_calendar_event_attendee | create | calendar_id, event_id, attendees[] | - | - | + +--- + +## 🎯 核心约束(Schema 未透露的知识) + +### 1. user_open_id 为什么必填? + +**工具使用用户身份**:日程创建在用户主日历上,用户本人能看到。 + +**但为什么还要传 user_open_id**:将发起人也添加为**参会人**,确保: +- ✅ 发起人会收到日程通知 +- ✅ 发起人可以回复 RSVP 状态(接受/拒绝/待定) +- ✅ 发起人出现在参会人列表中 +- ✅ 其他参会人能看到发起人 + +**如果不传**: +- ⚠️ 用户能看到日程,但不会作为参会人 +- ⚠️ 如果只有其他参会人,发起人不在列表中(不符合常规逻辑) + +### 2. 参会人权限(attendee_ability) + +工具已默认设置 `attendee_ability: "can_modify_event"`,参会人可以编辑日程和管理参与者。 + +| 权限值 | 能力 | +|--------|------| +| `none` | 无权限 | +| `can_see_others` | 可查看参与人列表 | +| `can_invite_others` | 可邀请他人 | +| `can_modify_event` | 可编辑日程(推荐) | + +### 3. 统一使用 open_id(ou_...格式) + +- ✅ 创建日程:`user_open_id = SenderId` +- ✅ 邀请参会人:`attendees[].id = "ou_xxx"` + +⚠️ **ID 格式区分**: +- `ou_xxx`:用户的 open_id(**你应该使用的**) +- `user_xxx`:日程内部的 attendee_id(list 接口返回,仅用于内部记录) + +### 4. 会议室预约是异步流程 + +添加会议室类型参会人后,会议室进入异步预约流程: +1. API 返回成功 → `rsvp_status: "needs_action"`(预约中) +2. 后台异步处理 +3. 最终状态:`accept`(成功)或 `decline`(失败) + +**查询预约结果**:使用 `feishu_calendar_event_attendee.list` 查看 `rsvp_status`。 + +### 5. instances action 仅对重复日程有效 + +**⚠️ 重要**:`instances` action **仅对重复日程有效**,必须满足: +1. event_id 必须是重复日程的 ID(该日程具有 `recurrence` 字段) +2. 如果对普通日程调用,会返回错误 + +**如何判断**: +1. 先用 `get` action 获取日程详情 +2. 检查返回值中是否有 `recurrence` 字段且不为空 +3. 如果有,则可以调用 `instances` 获取实例列表 + +--- + +## 📌 使用场景示例 + +### 场景 1: 创建会议并邀请参会人 + +```json +{ + "action": "create", + "summary": "项目复盘会议", + "description": "讨论 Q1 项目进展", + "start_time": "2026-02-25 14:00:00", + "end_time": "2026-02-25 15:30:00", + "user_open_id": "ou_aaa", + "attendees": [ + {"type": "user", "id": "ou_bbb"}, + {"type": "user", "id": "ou_ccc"}, + {"type": "resource", "id": "omm_xxx"} + ] +} +``` + +### 场景 2: 查询用户未来一周的日程 + +```json +{ + "action": "list", + "start_time": "2026-02-25 00:00:00", + "end_time": "2026-03-03 23:59:00" +} +``` + +### 场景 3: 查看多个用户的忙闲时间 + +```json +{ + "action": "list", + "time_min": "2026-02-25 09:00:00", + "time_max": "2026-02-25 18:00:00", + "user_ids": ["ou_aaa", "ou_bbb", "ou_ccc"] +} +``` + +**注意**:user_ids 是数组,支持 1-10 个用户。当前不支持会议室忙闲查询。 + +### 场景 4: 修改日程时间 + +```json +{ + "action": "patch", + "event_id": "xxx_0", + "start_time": "2026-02-25 15:00:00", + "end_time": "2026-02-25 16:00:00" +} +``` + +### 场景 5: 搜索日程(按关键词) + +```json +{ + "action": "search", + "query": "项目复盘" +} +``` + +### 场景 6: 回复日程邀请 + +```json +{ + "action": "reply", + "event_id": "xxx_0", + "rsvp_status": "accept" +} +``` + +--- + +## 🔍 常见错误与排查 + +| 错误现象 | 根本原因 | 解决方案 | +|---------|---------|---------| +| **发起人不在参会人列表中** | 未传 `user_open_id` | 强烈建议传 `user_open_id = SenderId` | +| **参会人看不到其他参会人** | `attendee_ability` 权限不足 | 工具已默认设置 `can_modify_event` | +| **时间不对** | 使用了 Unix 时间戳 | 改用 ISO 8601 格式(带时区):`2024-01-01T00:00:00+08:00` | +| **会议室显示"预约中"** | 会议室预约是异步的 | 等待几秒后用 `list` 查询 `rsvp_status` | +| **修改日程报权限错误** | 当前用户不是组织者,且日程未设置可编辑权限 | 确保日程创建时设置了 `attendee_ability: "can_modify_event"` | +| **无法查看参会人列表** | 当前用户无查看权限 | 确保是组织者或日程设置了 `can_see_others` 以上权限 | + +--- + +## 📚 附录:背景知识 + +### A. 日历架构模型 + +飞书日历采用 **三层架构**: +``` +日历(Calendar) + └── 日程(Event) + └── 参会人(Attendee) +``` + +**关键理解**: +1. **用户主日历**:日程创建在发起用户的主日历上,用户本人能看到 +2. **参会人机制**:通过添加参会人(attendee),让其他人的日历中也显示此日程 +3. **权限模型**:日程的 `attendee_ability` 参数控制参会人能否编辑日程、邀请他人、查看参与人列表 + +### B. 参会人类型 + +- `type: "user"` + `id: "ou_xxx"` — 飞书用户(使用 open_id) +- `type: "chat"` + `id: "oc_xxx"` — 飞书群组 +- `type: "resource"` + `id: "omm_xxx"` — 会议室 +- `type: "third_party"` + `id: "email@example.com"` — 外部邮箱 + +### C. 日程的生命周期 + +1. **创建**:在用户主日历上创建日程(工具使用用户身份) +2. **邀请参会人**:通过 attendee API 将日程分享给其他参会人 +3. **参会人回复**:参会人可以 accept/decline/tentative +4. **修改**:组织者或有权限的参会人可以修改 +5. **删除**:删除后状态变为 `cancelled` + +### D. 日历类型说明 + +| 类型 | 说明 | 能否删除 | 能否修改 | +|------|------|---------|---------| +| `primary` | 主日历(每个用户/应用一个) | ❌ 否 | ✅ 是 | +| `shared` | 共享日历(用户创建并共享) | ✅ 是 | ✅ 是 | +| `resource` | 会议室日历 | ❌ 否 | ❌ 否 | +| `google` | 绑定的 Google 日历 | ❌ 否 | ❌ 否 | +| `exchange` | 绑定的 Exchange 日历 | ❌ 否 | ❌ 否 | + +### E. 回复状态(rsvp_status)说明 + +| 状态 | 含义(用户) | 含义(会议室) | +|------|------------|---------------| +| `needs_action` | 未回复 | 预约中 | +| `accept` | 已接受 | 预约成功 | +| `tentative` | 待定 | - | +| `decline` | 拒绝 | 预约失败 | +| `removed` | 已被移除 | 已被移除 | + + +### F. 使用限制(来自飞书 OAPI 文档) + +1. **每个日程最多 3000 名参会人** +2. **单次添加参会人上限**: + - 用户类参会人:1000 人 + - 会议室:100 个 +3. **主日历不可删除**(type 为 primary 的日历) +4. **会议室预约可能失败**: + - 时间冲突 + - 无预约权限 + - 会议室配置限制 diff --git a/extensions/openclaw-lark/skills/feishu-channel-rules/SKILL.md b/extensions/openclaw-lark/skills/feishu-channel-rules/SKILL.md new file mode 100644 index 0000000..51d6ed9 --- /dev/null +++ b/extensions/openclaw-lark/skills/feishu-channel-rules/SKILL.md @@ -0,0 +1,18 @@ +--- +name: feishu-channel-rules +description: | + Lark/Feishu channel output rules. Always active in Lark conversations. +alwaysActive: true +--- + +# Lark Output Rules + +## Writing Style + +- Short, conversational, low ceremony — talk like a coworker, not a manual +- Prefer plain sentences over bullet lists when a brief answer suffices +- Get to the point and stop — no need for a summary paragraph every time + +## Note + +- Lark Markdown differs from standard Markdown in some ways; when unsure, refer to `references/markdown-syntax.md` diff --git a/extensions/openclaw-lark/skills/feishu-channel-rules/references/markdown-syntax.md b/extensions/openclaw-lark/skills/feishu-channel-rules/references/markdown-syntax.md new file mode 100644 index 0000000..db17045 --- /dev/null +++ b/extensions/openclaw-lark/skills/feishu-channel-rules/references/markdown-syntax.md @@ -0,0 +1,138 @@ +# 飞书 Markdown 语法参考 + +> 本文件是飞书消息卡片支持的完整 Markdown 语法参考,供需要时查阅。 + +## 1. 标题 + +``` +#### 四级标题 +##### 五级标题 +``` + +- **不支持**一二三级标题(`#`、`##`、`###`),会导致卡片显示异常 +- 可用加粗替代标题效果 + +## 2. 换行 + +``` +第一行\n第二行 +``` + +## 3. 文本样式 + +| 语法 | 效果 | +|------|------| +| `**加粗**` | **加粗** | +| `*斜体*` | *斜体* | +| `~~删除线~~` | ~~删除线~~ | + +> **注意**:加粗中间的内容只能是中文或英文,不能有中文符号或表情符号 + +## 4. 链接 + +``` +[链接文本](https://www.example.com) +``` + +## 5. @指定人 + +``` + + +``` + +- 用户的 id 必须是用户给你的,不能瞎编 +- 可能是:以 `ou_` 开头的字符串、不超过 10 位的字符串、邮箱 + +## 6. 超链接 + +``` + +``` + +## 7. 彩色文本 + +``` +绿色文本 +``` + +> 颜色枚举:`neutral`, `blue`, `turquoise`, `lime`, `orange`, `violet`, `wathet`, `green`, `yellow`, `red`, `purple`, `carmine` + +## 8. 文字链接 + +``` +这是文字链接 +``` + +## 9. 图片 + +``` +![hover_text](image_key) +``` + +> image_key 不支持 http 链接 + +## 10. 分割线 + +``` +--- +``` + +## 11. 标签 + +``` +标签文本 +``` + +颜色枚举:`neutral`, `blue`, `turquoise`, `lime`, `orange`, `violet`, `wathet`, `green`, `yellow`, `red`, `purple`, `carmine` + +## 12. 有序列表 + +``` +1. 一级列表① + 1.1 二级列表 + 1.2 二级列表 +2. 一级列表② +``` + +- 序号需在行首使用,序号后要跟空格 +- 4 个空格代表一层缩进 + +## 13. 无序列表 + +``` +- 一级列表① + - 二级列表 +- 一级列表② +``` + +- 4 个空格代表一层缩进 +- `-` 后面要跟空格 + +## 14. 代码块 + +```` +```JSON +{"This is": "JSON demo"} +``` +```` + +- 支持指定编程语言解析 +- 未指定默认为 Plain Text + +## 15. 人员组件 + +``` + +``` + +- `show_name`:是否展示用户名(默认 true) +- `show_avatar`:是否展示用户头像(默认 true) +- `style`:展示样式(`normal`:普通样式,`capsule`:胶囊样式) +- **注意**:person 标签不能嵌套在 font 中 + +## 16. 数字角标 + +``` +1 +``` diff --git a/extensions/openclaw-lark/skills/feishu-create-doc/SKILL.md b/extensions/openclaw-lark/skills/feishu-create-doc/SKILL.md new file mode 100644 index 0000000..cfda0e2 --- /dev/null +++ b/extensions/openclaw-lark/skills/feishu-create-doc/SKILL.md @@ -0,0 +1,719 @@ +--- +name: feishu-create-doc +description: | + 创建飞书云文档。从 Lark-flavored Markdown 内容创建新的飞书云文档,支持指定创建位置(文件夹/知识库/知识空间)。 +--- + +# feishu_mcp_create_doc + +通过 MCP 调用 `create-doc`,从 Lark-flavored Markdown 内容创建一个新的飞书云文档。 + +# 返回值 + +工具成功执行后,返回一个 JSON 对象,包含以下字段: + +- **`doc_id`**(string):文档的唯一标识符(token),格式如 `doxcnXXXXXXXXXXXXXXXXXXX` +- **`doc_url`**(string):文档的访问链接,可直接在浏览器中打开,格式如 `https://www.feishu.cn/docx/doxcnXXXXXXXXXXXXXXXXXXX` +- **`message`**(string):操作结果消息,如"文档创建成功" + + +# 参数 + +## markdown(必填) +文档的 Markdown 内容,使用 Lark-flavored Markdown 格式。 + +调用本工具的markdown内容应当尽量结构清晰,样式丰富, 有很高的可读性. 合理的使用callout高亮块, 分栏,表格等能力,并合理的运用插入图片与mermaid的能力,做到图文并茂.. +你需要遵循以下原则: + +- **结构清晰**:标题层级 ≤ 4 层,用 Callout 突出关键信息 +- **视觉节奏**:用分割线、分栏、表格打破大段纯文字 +- **图文交融**:流程和架构优先用 Mermaid/PlantUML 可视化 +- **克制留白**:Callout 不过度、加粗只强调核心词 + +当用户有明确的样式,风格需求时,应当以用户的需求为准!! + +**重要提示**: +- **禁止重复标题**:markdown 内容开头不要写与 title 相同的一级标题!title 参数已经是文档标题,markdown 应直接从正文内容开始 +- **目录**:飞书自动生成,无需手动添加 +- Markdown 语法必须符合 Lark-flavored Markdown 规范,详见下方"内容格式"章节 +- 创建较长的文档时,强烈建议配合update-doc中的append mode, 进行分段的创建,提高成功率. + +## title(可选) +文档标题。 + +## folder_token(可选) +父文件夹的 token。如果不提供,文档将创建在用户的个人空间根目录。 + +folder_token 可以从飞书文件夹 URL 中获取,格式如:`https://xxx.feishu.cn/drive/folder/fldcnXXXX`,其中 `fldcnXXXX` 即为 folder_token。 + +## wiki_node(可选) +知识库节点 token 或 URL(可选,传入则在该节点下创建文档,与 folder_token 和 wiki_space 互斥) + +wiki_node 可以从飞书知识库页面 URL 中获取,格式如:`https://xxx.feishu.cn/wiki/wikcnXXXX`,其中 `wikcnXXXX` 即为 wiki_node token。 + +## wiki_space(可选) +知识空间 ID(可选,传入则在该空间根目录下创建文档。特殊值 `my_library` 表示用户的个人知识库。与 wiki_node 和 folder_token 互斥) + +wiki_space 可以从知识空间设置页面 URL 中获取,格式如:`https://xxx.feishu.cn/wiki/settings/7448000000000009300`,其中 `7448000000000009300` 即为 wiki_space ID。 + +**参数优先级**:wiki_node > wiki_space > folder_token + +# 示例 + +## 示例 1:创建简单文档 + +```json +{ + "title": "项目计划", + "markdown": "# 项目概述\n\n这是一个新项目。\n\n## 目标\n\n- 目标 1\n- 目标 2" +} +``` + +## 示例 2:创建到指定文件夹 + +```json +{ + "title": "会议纪要", + "folder_token": "fldcnXXXXXXXXXXXXXXXXXXXXXX", + "markdown": "# 周会 2025-01-15\n\n## 讨论议题\n\n1. 项目进度\n2. 下周计划" +} +``` + +## 示例 3:使用飞书扩展语法 + +使用高亮块、表格等飞书特有功能: + +```json +{ + "title": "产品需求", + "markdown": "\n重要需求说明\n\n\n## 功能列表\n\n\n| 功能 | 优先级 |\n|------|--------|\n| 登录 | P0 |\n| 导出 | P1 |\n" +} +``` + +## 示例 4:创建到知识库节点下 + +```json +{ + "title": "技术文档", + "wiki_node": "wikcnXXXXXXXXXXXXXXXXXXXXXX", + "markdown": "# API 接口说明\n\n这是一个知识库文档。" +} +``` + +## 示例 5:创建到知识空间根目录 + +```json +{ + "title": "项目概览", + "wiki_space": "7448000000000009300", + "markdown": "# 项目概览\n\n这是知识空间根目录下的一级文档。" +} +``` + +## 示例 6:创建到个人知识库 + +```json +{ + "title": "学习笔记", + "wiki_space": "my_library", + "markdown": "# 学习笔记\n\n这是创建在个人知识库中的文档。" +} +``` + +# 内容格式 + +文档内容使用 **Lark-flavored Markdown** 格式,这是标准 Markdown 的扩展版本,支持飞书文档的所有块类型和富文本格式。 + +## 通用规则 + +- 使用标准 Markdown 语法作为基础 +- 使用自定义 XML 标签实现飞书特有功能(具体标签见各功能章节) +- 需要显示特殊字符时使用反斜杠转义:`* ~ ` $ [ ] < > { } | ^` + +--- + +## 📝 基础块类型 + +### 文本(段落) + +```markdown +普通文本段落 + +段落中的**粗体文字** + +多个段落之间用空行分隔。 + +居中文本 {align="center"} +右对齐文本 {align="right"} +``` + +**段落对齐**:支持 `{align="left|center|right"}` 语法。可与颜色组合:`{color="blue" align="center"}` + +### 标题 + +飞书支持 9 级标题。H1-H6 使用标准 Markdown 语法,H7-H9 使用 HTML 标签: + +```markdown +# 一级标题 +## 二级标题 +### 三级标题 +#### 四级标题 +##### 五级标题 +###### 六级标题 +七级标题 +八级标题 +九级标题 + +# 带颜色的标题 {color="blue"} +## 红色标题 {color="red"} +# 居中标题 {align="center"} +## 蓝色居中标题 {color="blue" align="center"} +``` + +**标题属性**:支持 `{color="颜色名"}` 和 `{align="left|center|right"}` 语法,可组合使用。颜色值:red, orange, yellow, green, blue, purple, gray。请谨慎使用该能力. + +### 列表 +有序列表,无序列表嵌套使用tab或者 2 空格缩进 +```markdown +- 无序项1( + - 无序项1.a + - 无序项1.b + +1. 有序项1 +2. 有序项2 + +- [ ] 待办 +- [x] 已完成 +``` + +### 引用块 + +```markdown +> 这是一段引用 +> 可以跨多行 + +> 引用中支持**加粗**和*斜体*等格式 +``` + +### 代码块 + +**⚠️** 只支持围栏代码块(` ``` `),不支持缩进代码块。 + +````markdown +```python +print("Hello") +``` +```` + +支持语言:python, javascript, go, java, sql, json, yaml, shell 等。 + +### 分割线 + +```markdown +--- +``` + +--- + +## 🎨 富文本格式 + +### 文本样式 + +`**粗体**` `*斜体*` `~~删除线~~` `` `行内代码` `` `下划线` + +### 文字颜色 + +`红色` `黄色背景` + +支持: red, orange, yellow, green, blue, purple, gray + +### 链接 + +`[链接文字](https://example.com)` (不支持锚点链接) + +### 行内公式(LaTeX) + +`$E = mc^2$`(`$`前后需空格)或 `E = mc^2`(无限制,推荐) + +--- + +## 🚀 高级块类型 + +### 高亮块(Callout) + +```html + +支持**格式化**的内容,可包含多个块 + +``` + +**属性**: emoji (使用emoji 字符如 ✅ ⚠️ 💡), background-color, border-color, text-color + +**背景色**: light-red/red, light-blue/blue, light-green/green, light-yellow/yellow, light-orange/orange, light-purple/purple, pale-gray/light-gray/dark-gray + +**常用**: 💡light-blue(提示) ⚠️light-yellow(警告) ❌light-red(危险) ✅light-green(成功) + +**限制**: callout子块仅支持文本、标题、列表、待办、引用。不支持代码块、表格、图片。 + +### 分栏(Grid) + +适合对比、并列展示场景。支持 2-5 列: +#### 两栏(等宽) + +```html + + + +左栏内容 + + + + +右栏内容 + + + +``` +#### 三栏自定义宽度 +```html + +左栏(20%) +中栏(60%) +右栏(20%) + +``` + +**属性**: `cols`(列数 2-5), `width`(列宽百分比,总和为100,等宽时可省略) + +### 表格 + +#### 标准 Markdown 表格 + +```markdown +| 列 1 | 列 2 | 列 3 | +|------|------|------| +| 单元格 1 | 单元格 2 | 单元格 3 | +| 单元格 4 | 单元格 5 | 单元格 6 | +``` + +#### 飞书增强表格 + +当单元格需要复杂内容(列表、代码块、高亮块等)时使用。 + +**层级结构**(必须严格遵守): +``` + ← 表格容器 + ← 行(直接子元素只能是 lark-tr) + 内容 ← 单元格(直接子元素只能是 lark-td) + 内容 ← 每行的 lark-td 数量必须相同! + + +``` + +**属性**: +- `column-widths`:列宽,逗号分隔像素值,总宽≈730 +- `header-row`:首行是否为表头(`"true"` 或 `"false"`) +- `header-column`:首列是否为表头(`"true"` 或 `"false"`) + +**单元格写法**:内容前后必须空行 +```html + + +这里写内容 + + +``` + +**完整示例**(2行3列): +```html + + + + +**表头1** + + + + +**表头2** + + + + +**表头3** + + + + + + +普通文本 + + + + +- 列表项1 +- 列表项2 + + + + +代码内容 + + + + +``` + +**限制**:单元格内不支持 Grid 和嵌套表格 + +**合并单元格**:读取时返回 `rowspan/colspan` 属性,创建暂不支持 + +**禁止**: +- 混用 Markdown 表格语法(`|---|`) +- 使用 `
` 换行 +- 遗漏 `` 标签 + + +### 图片 + +```html + +``` + +**属性**: url (必需,系统会自动下载并上传), width, height, align (left/center/right), caption + +**⚠️ 重要**: 不支持直接使用 `token` 属性(如 ``),只支持 URL 方式。系统会自动下载图片并上传到飞书。 + +支持 PNG/JPG/GIF/WebP/BMP,最大 10MB + +**图片/文件插入方式选择**: +- **有公开可访问的图片 URL** → 直接在 create-doc / update-doc 的 markdown 中使用 `` 一步到位 + +- **本地图片或文件**(如用户在聊天中发送的图片/文件) → 先用 create-doc / update-doc 创建或更新文档文本内容,再用 `feishu_doc_media` 工具将本地图片或文件追加到文档末尾。如需媒体出现在文档中间特定位置,可先用 create-doc 写好之前的内容,调用 `feishu_doc_media` 追加图片/文件,最后用 update-doc 的 **append** 模式追加后续内容 + +### 文件 + +```html + +``` + +**属性**: +- url (文件 URL,必需,系统会自动下载并上传) +- name (文件名,必需) +- view-type (1=卡片视图, 2=预览视图,可选) + +**⚠️ 重要**: 不支持直接使用 `token` 属性(如 ``) + + +### 画板(Mermaid / PlantUML 图表) + +支持两种图表语法:Mermaid 和 PlantUML。 + +#### Mermaid 图表 + +**图表优先选择此格式**. mermaid图表会被渲染为可视化的画板, 如果能用mermaid实现的图表,应当优先选择mermaid. + +````markdown +```mermaid +graph TD + A[开始] --> B{判断} + B -->|是| C[处理] + B -->|否| D[结束] +``` +```` + +**支持图表类型**: flowchart, sequenceDiagram, classDiagram, stateDiagram, gantt, mindmap, erDiagram + +#### PlantUML 图表 + +PlantUML图表会被渲染为可视化的画板. mermaid满足不了的场景可以选择plantUML进行绘图. + +````markdown +```plantuml +@startuml +Alice -> Bob: Hello +Bob --> Alice: Hi! +@enduml +``` +```` + +**支持图表类型**: sequence, usecase, class, activity, component, state, object, deployment + +#### 读取画板 + +读取时返回 `` 标签: + +```html + +``` + +**属性**: token (画板标识), align (left/center/right), width, height + +**重要说明**: +- create-doc时用 Mermaid/PlantUML 代码块,系统自动转换为画板; 禁止以``的方式写入!! +- 读取时只能获取 token,可通过fetch-file工具进行查看内容。无法获取原始源码 + +### 多维表格(Bitable) + +```html + + +``` + +**属性**: view (table/kanban,默认 table) + +**注意**: token 是只读属性,创建时不能指定只能创建空的多维表格,创建后再手动添加数据。 + +### 会话卡片(ChatCard) + +```html + +``` + +**属性**: id (格式 oc_xxx, 必需), align (left/center/right) + +### 内嵌网页(Iframe) + +```html +