@larksuite/openclaw-lark 2025.7.15-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +76 -0
- package/bin/openclaw-lark.js +39 -0
- package/index.d.ts +36 -0
- package/index.js +188 -0
- package/openclaw.plugin.json +64 -0
- package/package.json +63 -0
- package/secret-contract-api.d.ts +15 -0
- package/secret-contract-api.js +78 -0
- package/skills/feishu-bitable/SKILL.md +248 -0
- package/skills/feishu-bitable/references/examples.md +813 -0
- package/skills/feishu-bitable/references/field-properties.md +763 -0
- package/skills/feishu-bitable/references/record-values.md +911 -0
- package/skills/feishu-calendar/SKILL.md +242 -0
- package/skills/feishu-channel-rules/SKILL.md +18 -0
- package/skills/feishu-channel-rules/references/markdown-syntax.md +138 -0
- package/skills/feishu-create-doc/SKILL.md +719 -0
- package/skills/feishu-fetch-doc/SKILL.md +93 -0
- package/skills/feishu-im-read/SKILL.md +163 -0
- package/skills/feishu-task/SKILL.md +340 -0
- package/skills/feishu-troubleshoot/SKILL.md +70 -0
- package/skills/feishu-update-doc/SKILL.md +285 -0
- package/src/card/builder.d.ts +152 -0
- package/src/card/builder.js +794 -0
- package/src/card/card-error.d.ts +91 -0
- package/src/card/card-error.js +206 -0
- package/src/card/cardkit.d.ts +90 -0
- package/src/card/cardkit.js +203 -0
- package/src/card/flush-controller.d.ts +45 -0
- package/src/card/flush-controller.js +138 -0
- package/src/card/image-resolver.d.ts +45 -0
- package/src/card/image-resolver.js +116 -0
- package/src/card/markdown-style.d.ts +16 -0
- package/src/card/markdown-style.js +106 -0
- package/src/card/reasoning-utils.d.ts +14 -0
- package/src/card/reasoning-utils.js +64 -0
- package/src/card/reply-dispatcher-types.d.ts +132 -0
- package/src/card/reply-dispatcher-types.js +61 -0
- package/src/card/reply-dispatcher.d.ts +15 -0
- package/src/card/reply-dispatcher.js +447 -0
- package/src/card/reply-mode.d.ts +41 -0
- package/src/card/reply-mode.js +70 -0
- package/src/card/streaming-card-controller.d.ts +118 -0
- package/src/card/streaming-card-controller.js +1045 -0
- package/src/card/tool-use-config.d.ts +26 -0
- package/src/card/tool-use-config.js +76 -0
- package/src/card/tool-use-display.d.ts +37 -0
- package/src/card/tool-use-display.js +476 -0
- package/src/card/tool-use-trace-store.d.ts +51 -0
- package/src/card/tool-use-trace-store.js +271 -0
- package/src/card/unavailable-guard.d.ts +35 -0
- package/src/card/unavailable-guard.js +87 -0
- package/src/channel/abort-detect.d.ts +47 -0
- package/src/channel/abort-detect.js +219 -0
- package/src/channel/chat-queue.d.ts +41 -0
- package/src/channel/chat-queue.js +68 -0
- package/src/channel/config-adapter.d.ts +23 -0
- package/src/channel/config-adapter.js +107 -0
- package/src/channel/directory.d.ts +57 -0
- package/src/channel/directory.js +197 -0
- package/src/channel/event-handlers.d.ts +17 -0
- package/src/channel/event-handlers.js +380 -0
- package/src/channel/interactive-dispatch.d.ts +59 -0
- package/src/channel/interactive-dispatch.js +195 -0
- package/src/channel/monitor.d.ts +17 -0
- package/src/channel/monitor.js +140 -0
- package/src/channel/onboarding-config.d.ts +18 -0
- package/src/channel/onboarding-config.js +96 -0
- package/src/channel/onboarding-migrate.d.ts +25 -0
- package/src/channel/onboarding-migrate.js +70 -0
- package/src/channel/onboarding.d.ts +12 -0
- package/src/channel/onboarding.js +300 -0
- package/src/channel/plugin.d.ts +13 -0
- package/src/channel/plugin.js +310 -0
- package/src/channel/probe.d.ts +14 -0
- package/src/channel/probe.js +24 -0
- package/src/channel/types.d.ts +37 -0
- package/src/channel/types.js +8 -0
- package/src/commands/auth.d.ts +21 -0
- package/src/commands/auth.js +165 -0
- package/src/commands/diagnose.d.ts +69 -0
- package/src/commands/diagnose.js +848 -0
- package/src/commands/doctor.d.ts +27 -0
- package/src/commands/doctor.js +588 -0
- package/src/commands/index.d.ts +25 -0
- package/src/commands/index.js +219 -0
- package/src/commands/locale.d.ts +7 -0
- package/src/commands/locale.js +8 -0
- package/src/core/accounts.d.ts +51 -0
- package/src/core/accounts.js +219 -0
- package/src/core/agent-config.d.ts +100 -0
- package/src/core/agent-config.js +148 -0
- package/src/core/api-error.d.ts +48 -0
- package/src/core/api-error.js +117 -0
- package/src/core/app-owner-fallback.d.ts +22 -0
- package/src/core/app-owner-fallback.js +39 -0
- package/src/core/app-scope-checker.d.ts +87 -0
- package/src/core/app-scope-checker.js +198 -0
- package/src/core/auth-errors.d.ts +144 -0
- package/src/core/auth-errors.js +160 -0
- package/src/core/card-action-operator.d.ts +33 -0
- package/src/core/card-action-operator.js +30 -0
- package/src/core/chat-info-cache.d.ts +67 -0
- package/src/core/chat-info-cache.js +165 -0
- package/src/core/comment-target.d.ts +65 -0
- package/src/core/comment-target.js +100 -0
- package/src/core/config-schema.d.ts +490 -0
- package/src/core/config-schema.js +223 -0
- package/src/core/device-flow.d.ts +77 -0
- package/src/core/device-flow.js +217 -0
- package/src/core/domains.d.ts +18 -0
- package/src/core/domains.js +34 -0
- package/src/core/feishu-fetch.d.ts +18 -0
- package/src/core/feishu-fetch.js +28 -0
- package/src/core/footer-config.d.ts +24 -0
- package/src/core/footer-config.js +51 -0
- package/src/core/lark-client.d.ts +125 -0
- package/src/core/lark-client.js +468 -0
- package/src/core/lark-logger.d.ts +23 -0
- package/src/core/lark-logger.js +160 -0
- package/src/core/lark-ticket.d.ts +29 -0
- package/src/core/lark-ticket.js +40 -0
- package/src/core/message-unavailable.d.ts +53 -0
- package/src/core/message-unavailable.js +142 -0
- package/src/core/owner-policy.d.ts +32 -0
- package/src/core/owner-policy.js +55 -0
- package/src/core/permission-url.d.ts +22 -0
- package/src/core/permission-url.js +76 -0
- package/src/core/raw-request.d.ts +27 -0
- package/src/core/raw-request.js +90 -0
- package/src/core/runtime-store.d.ts +13 -0
- package/src/core/runtime-store.js +29 -0
- package/src/core/scope-manager.d.ts +168 -0
- package/src/core/scope-manager.js +224 -0
- package/src/core/sdk-compat.d.ts +20 -0
- package/src/core/sdk-compat.js +28 -0
- package/src/core/security-check.d.ts +72 -0
- package/src/core/security-check.js +184 -0
- package/src/core/shutdown-hooks.d.ts +22 -0
- package/src/core/shutdown-hooks.js +61 -0
- package/src/core/synthetic-target.d.ts +33 -0
- package/src/core/synthetic-target.js +40 -0
- package/src/core/targets.d.ts +60 -0
- package/src/core/targets.js +173 -0
- package/src/core/token-store.d.ts +54 -0
- package/src/core/token-store.js +326 -0
- package/src/core/tool-client.d.ts +176 -0
- package/src/core/tool-client.js +426 -0
- package/src/core/tool-scopes.d.ts +156 -0
- package/src/core/tool-scopes.js +344 -0
- package/src/core/tools-config.d.ts +55 -0
- package/src/core/tools-config.js +143 -0
- package/src/core/types.d.ts +91 -0
- package/src/core/types.js +12 -0
- package/src/core/uat-client.d.ts +46 -0
- package/src/core/uat-client.js +192 -0
- package/src/core/version.d.ts +31 -0
- package/src/core/version.js +69 -0
- package/src/messaging/converters/audio.d.ts +8 -0
- package/src/messaging/converters/audio.js +24 -0
- package/src/messaging/converters/calendar.d.ts +13 -0
- package/src/messaging/converters/calendar.js +56 -0
- package/src/messaging/converters/content-converter-helpers.d.ts +30 -0
- package/src/messaging/converters/content-converter-helpers.js +82 -0
- package/src/messaging/converters/content-converter.d.ts +24 -0
- package/src/messaging/converters/content-converter.js +40 -0
- package/src/messaging/converters/file.d.ts +8 -0
- package/src/messaging/converters/file.js +24 -0
- package/src/messaging/converters/folder.d.ts +8 -0
- package/src/messaging/converters/folder.js +24 -0
- package/src/messaging/converters/hongbao.d.ts +8 -0
- package/src/messaging/converters/hongbao.js +20 -0
- package/src/messaging/converters/image.d.ts +8 -0
- package/src/messaging/converters/image.js +22 -0
- package/src/messaging/converters/index.d.ts +8 -0
- package/src/messaging/converters/index.js +53 -0
- package/src/messaging/converters/interactive/card-converter.d.ts +76 -0
- package/src/messaging/converters/interactive/card-converter.js +1177 -0
- package/src/messaging/converters/interactive/card-utils.d.ts +9 -0
- package/src/messaging/converters/interactive/card-utils.js +47 -0
- package/src/messaging/converters/interactive/index.d.ts +8 -0
- package/src/messaging/converters/interactive/index.js +25 -0
- package/src/messaging/converters/interactive/legacy.d.ts +11 -0
- package/src/messaging/converters/interactive/legacy.js +60 -0
- package/src/messaging/converters/interactive/types.d.ts +23 -0
- package/src/messaging/converters/interactive/types.js +27 -0
- package/src/messaging/converters/location.d.ts +8 -0
- package/src/messaging/converters/location.js +23 -0
- package/src/messaging/converters/merge-forward.d.ts +32 -0
- package/src/messaging/converters/merge-forward.js +235 -0
- package/src/messaging/converters/post.d.ts +11 -0
- package/src/messaging/converters/post.js +235 -0
- package/src/messaging/converters/share.d.ts +9 -0
- package/src/messaging/converters/share.js +28 -0
- package/src/messaging/converters/sticker.d.ts +8 -0
- package/src/messaging/converters/sticker.js +22 -0
- package/src/messaging/converters/system.d.ts +12 -0
- package/src/messaging/converters/system.js +36 -0
- package/src/messaging/converters/text.d.ts +8 -0
- package/src/messaging/converters/text.js +18 -0
- package/src/messaging/converters/todo.d.ts +8 -0
- package/src/messaging/converters/todo.js +45 -0
- package/src/messaging/converters/types.d.ts +114 -0
- package/src/messaging/converters/types.js +8 -0
- package/src/messaging/converters/unknown.d.ts +8 -0
- package/src/messaging/converters/unknown.js +20 -0
- package/src/messaging/converters/utils.d.ts +22 -0
- package/src/messaging/converters/utils.js +57 -0
- package/src/messaging/converters/video-chat.d.ts +8 -0
- package/src/messaging/converters/video-chat.js +31 -0
- package/src/messaging/converters/video.d.ts +8 -0
- package/src/messaging/converters/video.js +35 -0
- package/src/messaging/converters/vote.d.ts +8 -0
- package/src/messaging/converters/vote.js +28 -0
- package/src/messaging/inbound/bot-content.d.ts +84 -0
- package/src/messaging/inbound/bot-content.js +117 -0
- package/src/messaging/inbound/bot-loop-guard.d.ts +48 -0
- package/src/messaging/inbound/bot-loop-guard.js +89 -0
- package/src/messaging/inbound/comment-context.d.ts +82 -0
- package/src/messaging/inbound/comment-context.js +353 -0
- package/src/messaging/inbound/comment-handler.d.ts +30 -0
- package/src/messaging/inbound/comment-handler.js +269 -0
- package/src/messaging/inbound/dedup.d.ts +59 -0
- package/src/messaging/inbound/dedup.js +121 -0
- package/src/messaging/inbound/dispatch-builders.d.ts +104 -0
- package/src/messaging/inbound/dispatch-builders.js +241 -0
- package/src/messaging/inbound/dispatch-commands.d.ts +22 -0
- package/src/messaging/inbound/dispatch-commands.js +131 -0
- package/src/messaging/inbound/dispatch-context.d.ts +67 -0
- package/src/messaging/inbound/dispatch-context.js +153 -0
- package/src/messaging/inbound/dispatch.d.ts +50 -0
- package/src/messaging/inbound/dispatch.js +477 -0
- package/src/messaging/inbound/enrich.d.ts +102 -0
- package/src/messaging/inbound/enrich.js +236 -0
- package/src/messaging/inbound/gate-effects.d.ts +23 -0
- package/src/messaging/inbound/gate-effects.js +46 -0
- package/src/messaging/inbound/gate.d.ts +91 -0
- package/src/messaging/inbound/gate.js +342 -0
- package/src/messaging/inbound/handler-registry.d.ts +25 -0
- package/src/messaging/inbound/handler-registry.js +23 -0
- package/src/messaging/inbound/handler.d.ts +37 -0
- package/src/messaging/inbound/handler.js +286 -0
- package/src/messaging/inbound/media-resolver.d.ts +32 -0
- package/src/messaging/inbound/media-resolver.js +91 -0
- package/src/messaging/inbound/mention-registry.d.ts +59 -0
- package/src/messaging/inbound/mention-registry.js +115 -0
- package/src/messaging/inbound/mention.d.ts +48 -0
- package/src/messaging/inbound/mention.js +102 -0
- package/src/messaging/inbound/parse-io.d.ts +50 -0
- package/src/messaging/inbound/parse-io.js +86 -0
- package/src/messaging/inbound/parse.d.ts +28 -0
- package/src/messaging/inbound/parse.js +128 -0
- package/src/messaging/inbound/permission.d.ts +17 -0
- package/src/messaging/inbound/permission.js +44 -0
- package/src/messaging/inbound/policy.d.ts +95 -0
- package/src/messaging/inbound/policy.js +168 -0
- package/src/messaging/inbound/reaction-handler.d.ts +62 -0
- package/src/messaging/inbound/reaction-handler.js +259 -0
- package/src/messaging/inbound/sentinel-store.d.ts +37 -0
- package/src/messaging/inbound/sentinel-store.js +98 -0
- package/src/messaging/inbound/synthetic-message.d.ts +26 -0
- package/src/messaging/inbound/synthetic-message.js +59 -0
- package/src/messaging/inbound/user-name-cache-store.d.ts +62 -0
- package/src/messaging/inbound/user-name-cache-store.js +236 -0
- package/src/messaging/inbound/user-name-cache.d.ts +78 -0
- package/src/messaging/inbound/user-name-cache.js +306 -0
- package/src/messaging/inbound/vc-meeting-invited-handler.d.ts +20 -0
- package/src/messaging/inbound/vc-meeting-invited-handler.js +236 -0
- package/src/messaging/inbound/vc-sender.d.ts +41 -0
- package/src/messaging/inbound/vc-sender.js +53 -0
- package/src/messaging/outbound/actions.d.ts +16 -0
- package/src/messaging/outbound/actions.js +329 -0
- package/src/messaging/outbound/bot-peer-context.d.ts +42 -0
- package/src/messaging/outbound/bot-peer-context.js +40 -0
- package/src/messaging/outbound/chat-manage.d.ts +64 -0
- package/src/messaging/outbound/chat-manage.js +117 -0
- package/src/messaging/outbound/deliver.d.ts +186 -0
- package/src/messaging/outbound/deliver.js +410 -0
- package/src/messaging/outbound/fetch.d.ts +12 -0
- package/src/messaging/outbound/fetch.js +17 -0
- package/src/messaging/outbound/forward.d.ts +26 -0
- package/src/messaging/outbound/forward.js +51 -0
- package/src/messaging/outbound/media-url-utils.d.ts +29 -0
- package/src/messaging/outbound/media-url-utils.js +172 -0
- package/src/messaging/outbound/media.d.ts +260 -0
- package/src/messaging/outbound/media.js +865 -0
- package/src/messaging/outbound/normalize-mentions.d.ts +50 -0
- package/src/messaging/outbound/normalize-mentions.js +166 -0
- package/src/messaging/outbound/outbound-mention.d.ts +41 -0
- package/src/messaging/outbound/outbound-mention.js +112 -0
- package/src/messaging/outbound/outbound.d.ts +79 -0
- package/src/messaging/outbound/outbound.js +195 -0
- package/src/messaging/outbound/reactions.d.ts +124 -0
- package/src/messaging/outbound/reactions.js +384 -0
- package/src/messaging/outbound/send.d.ts +153 -0
- package/src/messaging/outbound/send.js +417 -0
- package/src/messaging/outbound/typing.d.ts +60 -0
- package/src/messaging/outbound/typing.js +139 -0
- package/src/messaging/shared/message-lookup.d.ts +54 -0
- package/src/messaging/shared/message-lookup.js +120 -0
- package/src/messaging/types.d.ts +316 -0
- package/src/messaging/types.js +11 -0
- package/src/tools/ask-user-question.d.ts +32 -0
- package/src/tools/ask-user-question.js +922 -0
- package/src/tools/auto-auth.d.ts +57 -0
- package/src/tools/auto-auth.js +904 -0
- package/src/tools/helpers.d.ts +264 -0
- package/src/tools/helpers.js +389 -0
- package/src/tools/mcp/doc/create.d.ts +12 -0
- package/src/tools/mcp/doc/create.js +47 -0
- package/src/tools/mcp/doc/fetch.d.ts +12 -0
- package/src/tools/mcp/doc/fetch.js +39 -0
- package/src/tools/mcp/doc/index.d.ts +12 -0
- package/src/tools/mcp/doc/index.js +50 -0
- package/src/tools/mcp/doc/update.d.ts +12 -0
- package/src/tools/mcp/doc/update.js +64 -0
- package/src/tools/mcp/shared.d.ts +59 -0
- package/src/tools/mcp/shared.js +239 -0
- package/src/tools/oapi/bitable/app-table-field.d.ts +16 -0
- package/src/tools/oapi/bitable/app-table-field.js +225 -0
- package/src/tools/oapi/bitable/app-table-record.d.ts +20 -0
- package/src/tools/oapi/bitable/app-table-record.js +439 -0
- package/src/tools/oapi/bitable/app-table-view.d.ts +16 -0
- package/src/tools/oapi/bitable/app-table-view.js +172 -0
- package/src/tools/oapi/bitable/app-table.d.ts +17 -0
- package/src/tools/oapi/bitable/app-table.js +195 -0
- package/src/tools/oapi/bitable/app.d.ts +18 -0
- package/src/tools/oapi/bitable/app.js +189 -0
- package/src/tools/oapi/bitable/index.d.ts +9 -0
- package/src/tools/oapi/bitable/index.js +17 -0
- package/src/tools/oapi/calendar/calendar.d.ts +15 -0
- package/src/tools/oapi/calendar/calendar.js +125 -0
- package/src/tools/oapi/calendar/event-attendee.d.ts +14 -0
- package/src/tools/oapi/calendar/event-attendee.js +161 -0
- package/src/tools/oapi/calendar/event.d.ts +16 -0
- package/src/tools/oapi/calendar/event.js +712 -0
- package/src/tools/oapi/calendar/freebusy.d.ts +13 -0
- package/src/tools/oapi/calendar/freebusy.js +114 -0
- package/src/tools/oapi/calendar/index.d.ts +8 -0
- package/src/tools/oapi/calendar/index.js +15 -0
- package/src/tools/oapi/chat/chat.d.ts +16 -0
- package/src/tools/oapi/chat/chat.js +127 -0
- package/src/tools/oapi/chat/index.d.ts +10 -0
- package/src/tools/oapi/chat/index.js +23 -0
- package/src/tools/oapi/chat/members.d.ts +11 -0
- package/src/tools/oapi/chat/members.js +84 -0
- package/src/tools/oapi/common/get-user.d.ts +12 -0
- package/src/tools/oapi/common/get-user.js +109 -0
- package/src/tools/oapi/common/index.d.ts +6 -0
- package/src/tools/oapi/common/index.js +11 -0
- package/src/tools/oapi/common/search-user.d.ts +11 -0
- package/src/tools/oapi/common/search-user.js +76 -0
- package/src/tools/oapi/drive/doc-comments.d.ts +15 -0
- package/src/tools/oapi/drive/doc-comments.js +351 -0
- package/src/tools/oapi/drive/doc-media.d.ts +19 -0
- package/src/tools/oapi/drive/doc-media.js +371 -0
- package/src/tools/oapi/drive/file.d.ts +19 -0
- package/src/tools/oapi/drive/file.js +519 -0
- package/src/tools/oapi/drive/index.d.ts +12 -0
- package/src/tools/oapi/drive/index.js +45 -0
- package/src/tools/oapi/helpers.d.ts +183 -0
- package/src/tools/oapi/helpers.js +385 -0
- package/src/tools/oapi/im/format-messages.d.ts +50 -0
- package/src/tools/oapi/im/format-messages.js +169 -0
- package/src/tools/oapi/im/index.d.ts +10 -0
- package/src/tools/oapi/im/index.js +25 -0
- package/src/tools/oapi/im/message-read.d.ts +13 -0
- package/src/tools/oapi/im/message-read.js +419 -0
- package/src/tools/oapi/im/message.d.ts +16 -0
- package/src/tools/oapi/im/message.js +152 -0
- package/src/tools/oapi/im/resource.d.ts +13 -0
- package/src/tools/oapi/im/resource.js +186 -0
- package/src/tools/oapi/im/time-utils.d.ts +46 -0
- package/src/tools/oapi/im/time-utils.js +212 -0
- package/src/tools/oapi/im/user-name-uat.d.ts +26 -0
- package/src/tools/oapi/im/user-name-uat.js +143 -0
- package/src/tools/oapi/index.d.ts +11 -0
- package/src/tools/oapi/index.js +64 -0
- package/src/tools/oapi/sdk-types.d.ts +96 -0
- package/src/tools/oapi/sdk-types.js +13 -0
- package/src/tools/oapi/search/doc-search.d.ts +13 -0
- package/src/tools/oapi/search/doc-search.js +194 -0
- package/src/tools/oapi/search/index.d.ts +12 -0
- package/src/tools/oapi/search/index.js +37 -0
- package/src/tools/oapi/sheets/index.d.ts +12 -0
- package/src/tools/oapi/sheets/index.js +35 -0
- package/src/tools/oapi/sheets/sheet.d.ts +16 -0
- package/src/tools/oapi/sheets/sheet.js +688 -0
- package/src/tools/oapi/task/attachment.d.ts +18 -0
- package/src/tools/oapi/task/attachment.js +107 -0
- package/src/tools/oapi/task/comment.d.ts +15 -0
- package/src/tools/oapi/task/comment.js +149 -0
- package/src/tools/oapi/task/index.d.ts +11 -0
- package/src/tools/oapi/task/index.js +21 -0
- package/src/tools/oapi/task/section.d.ts +17 -0
- package/src/tools/oapi/task/section.js +293 -0
- package/src/tools/oapi/task/subtask.d.ts +14 -0
- package/src/tools/oapi/task/subtask.js +171 -0
- package/src/tools/oapi/task/task.d.ts +19 -0
- package/src/tools/oapi/task/task.js +512 -0
- package/src/tools/oapi/task/task_agent.d.ts +14 -0
- package/src/tools/oapi/task/task_agent.js +108 -0
- package/src/tools/oapi/task/tasklist.d.ts +19 -0
- package/src/tools/oapi/task/tasklist.js +276 -0
- package/src/tools/oapi/wiki/index.d.ts +12 -0
- package/src/tools/oapi/wiki/index.js +42 -0
- package/src/tools/oapi/wiki/space-node.d.ts +17 -0
- package/src/tools/oapi/wiki/space-node.js +233 -0
- package/src/tools/oapi/wiki/space.d.ts +15 -0
- package/src/tools/oapi/wiki/space.js +133 -0
- package/src/tools/oauth-batch-auth.d.ts +11 -0
- package/src/tools/oauth-batch-auth.js +150 -0
- package/src/tools/oauth-cards.d.ts +39 -0
- package/src/tools/oauth-cards.js +324 -0
- package/src/tools/oauth.d.ts +47 -0
- package/src/tools/oauth.js +592 -0
- package/src/tools/onboarding-auth.d.ts +27 -0
- package/src/tools/onboarding-auth.js +133 -0
- package/src/tools/tat/im/index.d.ts +15 -0
- package/src/tools/tat/im/index.js +22 -0
- package/src/tools/tat/im/resource.d.ts +15 -0
- package/src/tools/tat/im/resource.js +192 -0
- package/tsdown.config.d.ts +2 -0
- package/tsdown.config.js +25 -0
- package/vitest.config.d.ts +2 -0
- package/vitest.config.js +12 -0
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*
|
|
6
|
+
* Message sending for the Lark/Feishu channel plugin.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.sendMessageFeishu = sendMessageFeishu;
|
|
10
|
+
exports.sendCardFeishu = sendCardFeishu;
|
|
11
|
+
exports.updateCardFeishu = updateCardFeishu;
|
|
12
|
+
exports.buildMarkdownCard = buildMarkdownCard;
|
|
13
|
+
exports.buildI18nMarkdownCard = buildI18nMarkdownCard;
|
|
14
|
+
exports.sendMarkdownCardFeishu = sendMarkdownCardFeishu;
|
|
15
|
+
exports.editMessageFeishu = editMessageFeishu;
|
|
16
|
+
const accounts_1 = require("../../core/accounts.js");
|
|
17
|
+
const lark_client_1 = require("../../core/lark-client.js");
|
|
18
|
+
const lark_logger_1 = require("../../core/lark-logger.js");
|
|
19
|
+
const chat_queue_1 = require("../../channel/chat-queue.js");
|
|
20
|
+
const targets_1 = require("../../core/targets.js");
|
|
21
|
+
const message_unavailable_1 = require("../../core/message-unavailable.js");
|
|
22
|
+
const markdown_style_1 = require("../../card/markdown-style.js");
|
|
23
|
+
const mention_1 = require("../inbound/mention.js");
|
|
24
|
+
const sentinel_store_1 = require("../inbound/sentinel-store.js");
|
|
25
|
+
const normalize_mentions_1 = require("./normalize-mentions.js");
|
|
26
|
+
const outbound_mention_1 = require("./outbound-mention.js");
|
|
27
|
+
const bot_peer_context_1 = require("./bot-peer-context.js");
|
|
28
|
+
const sendLog = (0, lark_logger_1.larkLogger)('outbound/send');
|
|
29
|
+
/**
|
|
30
|
+
* Runs the outbound text through mention normalization. Returns the
|
|
31
|
+
* input unchanged on any failure so a parser bug never blocks send.
|
|
32
|
+
* Sentinels collected during normalization are returned for the caller
|
|
33
|
+
* to record after a successful send.
|
|
34
|
+
*/
|
|
35
|
+
async function normalizeFeishuOutboundText(cfg, to, text, accountId) {
|
|
36
|
+
if (!text?.trim())
|
|
37
|
+
return { text, sentinels: [], resolvedAccountId: accountId };
|
|
38
|
+
try {
|
|
39
|
+
const account = (0, accounts_1.getLarkAccount)(cfg, accountId ?? undefined);
|
|
40
|
+
const ctx = {
|
|
41
|
+
chatId: to,
|
|
42
|
+
account,
|
|
43
|
+
log: (...args) => sendLog.warn(args.map(String).join(' ')),
|
|
44
|
+
};
|
|
45
|
+
const r = await (0, normalize_mentions_1.normalizeOutboundMentions)(text, ctx);
|
|
46
|
+
let outText = r.normalizedText;
|
|
47
|
+
// Deterministic backstop on the real reply path: when this dispatch is
|
|
48
|
+
// replying to a designated bot peer (set via runWithBotPeerContext in the
|
|
49
|
+
// inbound dispatch), guarantee an @-mention so the peer actually receives
|
|
50
|
+
// the message even if the model didn't write one. No-op when no peer is
|
|
51
|
+
// in scope. De-duped across chunks: once the peer @ has appeared (whether
|
|
52
|
+
// the model wrote it or we injected it), later chunks of the same reply
|
|
53
|
+
// are left untouched so we don't @ on every chunk.
|
|
54
|
+
const peer = (0, bot_peer_context_1.currentBotPeerContext)();
|
|
55
|
+
if (peer && !peer.mentioned) {
|
|
56
|
+
outText = (0, outbound_mention_1.ensureMention)(outText, peer.peerOpenId, peer.peerName);
|
|
57
|
+
if (outText.includes(`user_id="${peer.peerOpenId}"`)) {
|
|
58
|
+
peer.mentioned = true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return { text: outText, sentinels: r.sentinels, resolvedAccountId: account.accountId };
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
sendLog.warn(`normalizeOutboundMentions failed, using raw text: ${String(err)}`);
|
|
65
|
+
return { text, sentinels: [], resolvedAccountId: accountId };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function recordFeishuSendSentinels(resolvedAccountId, to, threadId, sentinels) {
|
|
69
|
+
if (!resolvedAccountId || sentinels.length === 0)
|
|
70
|
+
return;
|
|
71
|
+
const threadKey = (0, chat_queue_1.threadScopedKey)(to, threadId);
|
|
72
|
+
(0, sentinel_store_1.getSentinelStore)(resolvedAccountId).recordSentinels(threadKey, sentinels);
|
|
73
|
+
}
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// sendMessageFeishu
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
/**
|
|
78
|
+
* Send a text message (rendered as a Feishu "post" with markdown support)
|
|
79
|
+
* to a chat or user.
|
|
80
|
+
*
|
|
81
|
+
* The message text is wrapped in Feishu's post format using the `md` tag
|
|
82
|
+
* for rich rendering. If `replyToMessageId` is provided, the message is
|
|
83
|
+
* sent as a threaded reply; otherwise it is sent as a new message using
|
|
84
|
+
* the appropriate `receive_id_type`.
|
|
85
|
+
*
|
|
86
|
+
* Markdown tables and code blocks are sent as-is so Feishu renders them
|
|
87
|
+
* natively in the post(`tag:md`); only `optimizeMarkdownStyle` is applied.
|
|
88
|
+
*
|
|
89
|
+
* @param params - See {@link SendFeishuMessageParams}.
|
|
90
|
+
* @returns The send result containing the new message ID.
|
|
91
|
+
*/
|
|
92
|
+
async function sendMessageFeishu(params) {
|
|
93
|
+
const { cfg, to, replyToMessageId, mentions, accountId, replyInThread, i18nTexts, threadId } = params;
|
|
94
|
+
let { text } = params;
|
|
95
|
+
// Mention normalization. Single-locale path rewrites `text`; the
|
|
96
|
+
// i18nTexts path rewrites each locale below. Sentinels are recorded
|
|
97
|
+
// after the send succeeds.
|
|
98
|
+
let normalizationSentinels = [];
|
|
99
|
+
let normalizationAccountId = accountId ?? undefined;
|
|
100
|
+
if (!i18nTexts && text?.trim()) {
|
|
101
|
+
const r = await normalizeFeishuOutboundText(cfg, to, text, accountId ?? undefined);
|
|
102
|
+
text = r.text;
|
|
103
|
+
normalizationSentinels = r.sentinels;
|
|
104
|
+
normalizationAccountId = r.resolvedAccountId;
|
|
105
|
+
}
|
|
106
|
+
const client = lark_client_1.LarkClient.fromCfg(cfg, accountId).sdk;
|
|
107
|
+
// Build the post-format content envelope.
|
|
108
|
+
let contentPayload;
|
|
109
|
+
if (i18nTexts && Object.keys(i18nTexts).length > 0) {
|
|
110
|
+
// Multi-locale post: build each locale's content independently.
|
|
111
|
+
const postBody = {};
|
|
112
|
+
for (const [locale, localeText] of Object.entries(i18nTexts)) {
|
|
113
|
+
let processed = localeText;
|
|
114
|
+
// Apply mention prefix if targets are provided.
|
|
115
|
+
if (mentions && mentions.length > 0) {
|
|
116
|
+
processed = (0, mention_1.buildMentionedMessage)(mentions, processed);
|
|
117
|
+
}
|
|
118
|
+
// Apply Markdown style optimization.
|
|
119
|
+
processed = (0, markdown_style_1.optimizeMarkdownStyle)(processed, 1);
|
|
120
|
+
postBody[locale] = {
|
|
121
|
+
content: [[{ tag: 'md', text: processed }]],
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
contentPayload = JSON.stringify(postBody);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
// Single-locale (zh_cn) post: original behavior.
|
|
128
|
+
let messageText = text;
|
|
129
|
+
// Apply mention prefix if targets are provided.
|
|
130
|
+
if (mentions && mentions.length > 0) {
|
|
131
|
+
messageText = (0, mention_1.buildMentionedMessage)(mentions, messageText);
|
|
132
|
+
}
|
|
133
|
+
// Apply Markdown style optimization.
|
|
134
|
+
messageText = (0, markdown_style_1.optimizeMarkdownStyle)(messageText, 1);
|
|
135
|
+
contentPayload = JSON.stringify({
|
|
136
|
+
zh_cn: {
|
|
137
|
+
content: [[{ tag: 'md', text: messageText }]],
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
if (replyToMessageId) {
|
|
142
|
+
// Send as a threaded reply.
|
|
143
|
+
// 规范化 message_id,处理合成 ID(如 "om_xxx:auth-complete")
|
|
144
|
+
const normalizedId = (0, targets_1.normalizeMessageId)(replyToMessageId);
|
|
145
|
+
const response = await (0, message_unavailable_1.runWithMessageUnavailableGuard)({
|
|
146
|
+
messageId: normalizedId,
|
|
147
|
+
operation: 'im.message.reply(post)',
|
|
148
|
+
fn: () => client.im.message.reply({
|
|
149
|
+
path: {
|
|
150
|
+
message_id: normalizedId,
|
|
151
|
+
},
|
|
152
|
+
data: {
|
|
153
|
+
content: contentPayload,
|
|
154
|
+
msg_type: 'post',
|
|
155
|
+
reply_in_thread: replyInThread,
|
|
156
|
+
},
|
|
157
|
+
}),
|
|
158
|
+
});
|
|
159
|
+
recordFeishuSendSentinels(normalizationAccountId, to, threadId, normalizationSentinels);
|
|
160
|
+
return {
|
|
161
|
+
messageId: response?.data?.message_id ?? '',
|
|
162
|
+
chatId: response?.data?.chat_id ?? '',
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
// Send as a new message.
|
|
166
|
+
const target = (0, targets_1.normalizeFeishuTarget)(to);
|
|
167
|
+
if (!target) {
|
|
168
|
+
throw new Error(`[feishu-send] Invalid target: "${to}"`);
|
|
169
|
+
}
|
|
170
|
+
const receiveIdType = (0, targets_1.resolveReceiveIdType)(target);
|
|
171
|
+
const response = await client.im.message.create({
|
|
172
|
+
params: {
|
|
173
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
174
|
+
receive_id_type: receiveIdType,
|
|
175
|
+
},
|
|
176
|
+
data: {
|
|
177
|
+
receive_id: target,
|
|
178
|
+
msg_type: 'post',
|
|
179
|
+
content: contentPayload,
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
recordFeishuSendSentinels(normalizationAccountId, to, threadId, normalizationSentinels);
|
|
183
|
+
return {
|
|
184
|
+
messageId: response?.data?.message_id ?? '',
|
|
185
|
+
chatId: response?.data?.chat_id ?? '',
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
// ---------------------------------------------------------------------------
|
|
189
|
+
// sendCardFeishu
|
|
190
|
+
// ---------------------------------------------------------------------------
|
|
191
|
+
/**
|
|
192
|
+
* Send an interactive card message to a chat or user.
|
|
193
|
+
*
|
|
194
|
+
* @param params - See {@link SendFeishuCardParams}.
|
|
195
|
+
* @returns The send result containing the new message ID.
|
|
196
|
+
*/
|
|
197
|
+
async function sendCardFeishu(params) {
|
|
198
|
+
const { cfg, to, card, replyToMessageId, accountId, replyInThread } = params;
|
|
199
|
+
const client = lark_client_1.LarkClient.fromCfg(cfg, accountId).sdk;
|
|
200
|
+
const contentPayload = JSON.stringify(card);
|
|
201
|
+
if (replyToMessageId) {
|
|
202
|
+
// 规范化 message_id,处理合成 ID(如 "om_xxx:auth-complete")
|
|
203
|
+
const normalizedId = (0, targets_1.normalizeMessageId)(replyToMessageId);
|
|
204
|
+
const response = await (0, message_unavailable_1.runWithMessageUnavailableGuard)({
|
|
205
|
+
messageId: normalizedId,
|
|
206
|
+
operation: 'im.message.reply(interactive)',
|
|
207
|
+
fn: () => client.im.message.reply({
|
|
208
|
+
path: {
|
|
209
|
+
message_id: normalizedId,
|
|
210
|
+
},
|
|
211
|
+
data: {
|
|
212
|
+
content: contentPayload,
|
|
213
|
+
msg_type: 'interactive',
|
|
214
|
+
reply_in_thread: replyInThread,
|
|
215
|
+
},
|
|
216
|
+
}),
|
|
217
|
+
});
|
|
218
|
+
return {
|
|
219
|
+
messageId: response?.data?.message_id ?? '',
|
|
220
|
+
chatId: response?.data?.chat_id ?? '',
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
const target = (0, targets_1.normalizeFeishuTarget)(to);
|
|
224
|
+
if (!target) {
|
|
225
|
+
throw new Error(`[feishu-send] Invalid target: "${to}"`);
|
|
226
|
+
}
|
|
227
|
+
const receiveIdType = (0, targets_1.resolveReceiveIdType)(target);
|
|
228
|
+
const response = await client.im.message.create({
|
|
229
|
+
params: {
|
|
230
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
231
|
+
receive_id_type: receiveIdType,
|
|
232
|
+
},
|
|
233
|
+
data: {
|
|
234
|
+
receive_id: target,
|
|
235
|
+
msg_type: 'interactive',
|
|
236
|
+
content: contentPayload,
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
return {
|
|
240
|
+
messageId: response?.data?.message_id ?? '',
|
|
241
|
+
chatId: response?.data?.chat_id ?? '',
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
// ---------------------------------------------------------------------------
|
|
245
|
+
// updateCardFeishu
|
|
246
|
+
// ---------------------------------------------------------------------------
|
|
247
|
+
/**
|
|
248
|
+
* Update (PATCH) the content of an existing interactive card message.
|
|
249
|
+
*
|
|
250
|
+
* Only messages originally sent by the bot can be updated. The card
|
|
251
|
+
* must have been created with `"update_multi": true` in its config if
|
|
252
|
+
* all recipients should see the update.
|
|
253
|
+
*
|
|
254
|
+
* @param params.cfg - Plugin configuration.
|
|
255
|
+
* @param params.messageId - The card message ID to update.
|
|
256
|
+
* @param params.card - The new card content.
|
|
257
|
+
* @param params.accountId - Optional account identifier.
|
|
258
|
+
*/
|
|
259
|
+
async function updateCardFeishu(params) {
|
|
260
|
+
const { cfg, messageId, card, accountId } = params;
|
|
261
|
+
const client = lark_client_1.LarkClient.fromCfg(cfg, accountId).sdk;
|
|
262
|
+
await (0, message_unavailable_1.runWithMessageUnavailableGuard)({
|
|
263
|
+
messageId,
|
|
264
|
+
operation: 'im.message.patch(interactive)',
|
|
265
|
+
fn: () => client.im.message.patch({
|
|
266
|
+
path: {
|
|
267
|
+
message_id: messageId,
|
|
268
|
+
},
|
|
269
|
+
data: {
|
|
270
|
+
content: JSON.stringify(card),
|
|
271
|
+
},
|
|
272
|
+
}),
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
// ---------------------------------------------------------------------------
|
|
276
|
+
// buildMarkdownCard
|
|
277
|
+
// ---------------------------------------------------------------------------
|
|
278
|
+
/**
|
|
279
|
+
* Build a simple Feishu Interactive Message Card containing a single
|
|
280
|
+
* markdown element.
|
|
281
|
+
*
|
|
282
|
+
* This is a convenience wrapper for the most common card layout: a
|
|
283
|
+
* wide-screen card with one markdown block.
|
|
284
|
+
*
|
|
285
|
+
* @param text - The markdown text to render in the card.
|
|
286
|
+
* @returns A card JSON object ready to be sent via {@link sendCardFeishu}.
|
|
287
|
+
*/
|
|
288
|
+
function buildMarkdownCard(text) {
|
|
289
|
+
const optimizedText = (0, markdown_style_1.optimizeMarkdownStyle)(text);
|
|
290
|
+
return {
|
|
291
|
+
schema: '2.0',
|
|
292
|
+
config: {
|
|
293
|
+
wide_screen_mode: true,
|
|
294
|
+
},
|
|
295
|
+
body: {
|
|
296
|
+
elements: [
|
|
297
|
+
{
|
|
298
|
+
tag: 'markdown',
|
|
299
|
+
content: optimizedText,
|
|
300
|
+
},
|
|
301
|
+
],
|
|
302
|
+
},
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Build an i18n-aware Feishu Interactive Message Card containing a single
|
|
307
|
+
* markdown element with per-locale content.
|
|
308
|
+
*
|
|
309
|
+
* Uses the CardKit v2 `i18n_content` field so the Feishu client
|
|
310
|
+
* auto-selects the locale matching the user's language setting.
|
|
311
|
+
*
|
|
312
|
+
* @param i18nTexts - A map of locale to markdown text (e.g. { zh_cn: '...', en_us: '...' }).
|
|
313
|
+
* @returns A card JSON object ready to be sent via {@link sendCardFeishu}.
|
|
314
|
+
*/
|
|
315
|
+
function buildI18nMarkdownCard(i18nTexts) {
|
|
316
|
+
const locales = Object.keys(i18nTexts);
|
|
317
|
+
// Determine fallback content (prefer en_us, then first available locale).
|
|
318
|
+
const fallbackLocale = locales.includes('en_us') ? 'en_us' : locales[0];
|
|
319
|
+
const fallbackText = (0, markdown_style_1.optimizeMarkdownStyle)(i18nTexts[fallbackLocale]);
|
|
320
|
+
// Build i18n_content with optimized text for each locale.
|
|
321
|
+
const i18nContent = {};
|
|
322
|
+
for (const [locale, text] of Object.entries(i18nTexts)) {
|
|
323
|
+
i18nContent[locale] = (0, markdown_style_1.optimizeMarkdownStyle)(text);
|
|
324
|
+
}
|
|
325
|
+
return {
|
|
326
|
+
schema: '2.0',
|
|
327
|
+
config: {
|
|
328
|
+
wide_screen_mode: true,
|
|
329
|
+
},
|
|
330
|
+
body: {
|
|
331
|
+
elements: [
|
|
332
|
+
{
|
|
333
|
+
tag: 'markdown',
|
|
334
|
+
content: fallbackText,
|
|
335
|
+
i18n_content: i18nContent,
|
|
336
|
+
},
|
|
337
|
+
],
|
|
338
|
+
},
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
// ---------------------------------------------------------------------------
|
|
342
|
+
// sendMarkdownCardFeishu
|
|
343
|
+
// ---------------------------------------------------------------------------
|
|
344
|
+
/**
|
|
345
|
+
* Build a markdown card and send it in one step.
|
|
346
|
+
*
|
|
347
|
+
* If mention targets are provided, they are prepended to the markdown
|
|
348
|
+
* content using the card mention syntax.
|
|
349
|
+
*
|
|
350
|
+
* @param params.cfg - Plugin configuration.
|
|
351
|
+
* @param params.to - Target identifier.
|
|
352
|
+
* @param params.text - Markdown content for the card.
|
|
353
|
+
* @param params.replyToMessageId - Optional message ID for threaded reply.
|
|
354
|
+
* @param params.mentions - Optional mention targets.
|
|
355
|
+
* @param params.accountId - Optional account identifier.
|
|
356
|
+
* @returns The send result containing the new message ID.
|
|
357
|
+
*/
|
|
358
|
+
async function sendMarkdownCardFeishu(params) {
|
|
359
|
+
const { cfg, to, text, replyToMessageId, mentions, accountId, replyInThread } = params;
|
|
360
|
+
// Normalize @-mentions and apply the bot-peer ensureMention backstop on the
|
|
361
|
+
// card path too (mirrors sendMessageFeishu), so a reply rendered as a card
|
|
362
|
+
// still reaches the designated peer bot.
|
|
363
|
+
const normalized = await normalizeFeishuOutboundText(cfg, to, text, accountId ?? undefined);
|
|
364
|
+
let cardText = normalized.text;
|
|
365
|
+
if (mentions && mentions.length > 0) {
|
|
366
|
+
cardText = (0, mention_1.buildMentionedCardContent)(mentions, cardText);
|
|
367
|
+
}
|
|
368
|
+
const card = buildMarkdownCard(cardText);
|
|
369
|
+
const result = await sendCardFeishu({
|
|
370
|
+
cfg,
|
|
371
|
+
to,
|
|
372
|
+
card,
|
|
373
|
+
replyToMessageId,
|
|
374
|
+
replyInThread,
|
|
375
|
+
accountId,
|
|
376
|
+
});
|
|
377
|
+
recordFeishuSendSentinels(normalized.resolvedAccountId, to, undefined, normalized.sentinels);
|
|
378
|
+
return result;
|
|
379
|
+
}
|
|
380
|
+
// ---------------------------------------------------------------------------
|
|
381
|
+
// editMessageFeishu
|
|
382
|
+
// ---------------------------------------------------------------------------
|
|
383
|
+
/**
|
|
384
|
+
* Edit the content of an existing message.
|
|
385
|
+
*
|
|
386
|
+
* Updates the message body via the IM message update API. Only
|
|
387
|
+
* messages sent by the bot can be edited.
|
|
388
|
+
*
|
|
389
|
+
* @param params.cfg - Plugin configuration.
|
|
390
|
+
* @param params.messageId - The message ID to edit.
|
|
391
|
+
* @param params.text - The new message text.
|
|
392
|
+
* @param params.accountId - Optional account identifier.
|
|
393
|
+
*/
|
|
394
|
+
async function editMessageFeishu(params) {
|
|
395
|
+
const { cfg, messageId, text, accountId } = params;
|
|
396
|
+
const client = lark_client_1.LarkClient.fromCfg(cfg, accountId).sdk;
|
|
397
|
+
// Use cardVersion=1 consistent with sendMessageFeishu post path.
|
|
398
|
+
const optimizedText = (0, markdown_style_1.optimizeMarkdownStyle)(text, 1);
|
|
399
|
+
const contentPayload = JSON.stringify({
|
|
400
|
+
zh_cn: {
|
|
401
|
+
content: [[{ tag: 'md', text: optimizedText }]],
|
|
402
|
+
},
|
|
403
|
+
});
|
|
404
|
+
await (0, message_unavailable_1.runWithMessageUnavailableGuard)({
|
|
405
|
+
messageId,
|
|
406
|
+
operation: 'im.message.update(post)',
|
|
407
|
+
fn: () => client.im.message.update({
|
|
408
|
+
path: {
|
|
409
|
+
message_id: messageId,
|
|
410
|
+
},
|
|
411
|
+
data: {
|
|
412
|
+
content: contentPayload,
|
|
413
|
+
msg_type: 'post',
|
|
414
|
+
},
|
|
415
|
+
}),
|
|
416
|
+
});
|
|
417
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
5
|
+
* Typing indicator management for the Lark/Feishu channel plugin.
|
|
6
|
+
*
|
|
7
|
+
* Feishu does not expose a first-class "typing indicator" API the way
|
|
8
|
+
* some other messaging platforms do. Instead, this module simulates a
|
|
9
|
+
* typing state by adding a recognisable emoji reaction (the "Typing"
|
|
10
|
+
* emoji) to the user's message while the bot is processing, and
|
|
11
|
+
* removing it once the response is ready.
|
|
12
|
+
*
|
|
13
|
+
* This provides a lightweight visual cue that the bot has acknowledged
|
|
14
|
+
* the message and is working on a reply.
|
|
15
|
+
*/
|
|
16
|
+
import type { OpenClawConfig } from 'openclaw/plugin-sdk';
|
|
17
|
+
/**
|
|
18
|
+
* Tracks the state of an active typing indicator so it can be
|
|
19
|
+
* removed later.
|
|
20
|
+
*/
|
|
21
|
+
export interface TypingIndicatorState {
|
|
22
|
+
/** The message ID that the reaction was added to. */
|
|
23
|
+
messageId: string;
|
|
24
|
+
/** The reaction ID returned by the API, or null if the add failed. */
|
|
25
|
+
reactionId: string | null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Add a typing indicator to a message by creating an emoji reaction.
|
|
29
|
+
*
|
|
30
|
+
* The reaction is added silently -- any errors (network issues, missing
|
|
31
|
+
* permissions, rate limits) are caught and logged rather than propagated
|
|
32
|
+
* to the caller. This ensures that a failure to show the typing cue
|
|
33
|
+
* never blocks the actual message processing.
|
|
34
|
+
*
|
|
35
|
+
* @param params.cfg - Plugin configuration with Feishu credentials.
|
|
36
|
+
* @param params.messageId - The message ID to add the typing reaction to.
|
|
37
|
+
* @param params.accountId - Optional account identifier for multi-account setups.
|
|
38
|
+
* @returns A state object that should be passed to {@link removeTypingIndicator}.
|
|
39
|
+
*/
|
|
40
|
+
export declare function addTypingIndicator(params: {
|
|
41
|
+
cfg: OpenClawConfig;
|
|
42
|
+
messageId: string;
|
|
43
|
+
accountId?: string;
|
|
44
|
+
}): Promise<TypingIndicatorState>;
|
|
45
|
+
/**
|
|
46
|
+
* Remove a previously added typing indicator reaction from a message.
|
|
47
|
+
*
|
|
48
|
+
* If the indicator was never successfully added (reactionId is null),
|
|
49
|
+
* this function is a no-op. Errors are silently caught so removal
|
|
50
|
+
* failures do not disrupt downstream logic.
|
|
51
|
+
*
|
|
52
|
+
* @param params.cfg - Plugin configuration with Feishu credentials.
|
|
53
|
+
* @param params.state - The typing indicator state returned by {@link addTypingIndicator}.
|
|
54
|
+
* @param params.accountId - Optional account identifier for multi-account setups.
|
|
55
|
+
*/
|
|
56
|
+
export declare function removeTypingIndicator(params: {
|
|
57
|
+
cfg: OpenClawConfig;
|
|
58
|
+
state: TypingIndicatorState;
|
|
59
|
+
accountId?: string;
|
|
60
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*
|
|
6
|
+
* Typing indicator management for the Lark/Feishu channel plugin.
|
|
7
|
+
*
|
|
8
|
+
* Feishu does not expose a first-class "typing indicator" API the way
|
|
9
|
+
* some other messaging platforms do. Instead, this module simulates a
|
|
10
|
+
* typing state by adding a recognisable emoji reaction (the "Typing"
|
|
11
|
+
* emoji) to the user's message while the bot is processing, and
|
|
12
|
+
* removing it once the response is ready.
|
|
13
|
+
*
|
|
14
|
+
* This provides a lightweight visual cue that the bot has acknowledged
|
|
15
|
+
* the message and is working on a reply.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.addTypingIndicator = addTypingIndicator;
|
|
19
|
+
exports.removeTypingIndicator = removeTypingIndicator;
|
|
20
|
+
const lark_client_1 = require("../../core/lark-client.js");
|
|
21
|
+
const targets_1 = require("../../core/targets.js");
|
|
22
|
+
const message_unavailable_1 = require("../../core/message-unavailable.js");
|
|
23
|
+
const lark_logger_1 = require("../../core/lark-logger.js");
|
|
24
|
+
const log = (0, lark_logger_1.larkLogger)('outbound/typing');
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Constants
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
/**
|
|
29
|
+
* The emoji type used to represent the typing indicator.
|
|
30
|
+
*
|
|
31
|
+
* "Typing" is a built-in Feishu emoji that shows a pencil / keyboard
|
|
32
|
+
* animation, making it a natural choice for a typing cue.
|
|
33
|
+
*/
|
|
34
|
+
const TYPING_EMOJI_TYPE = 'Typing';
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// addTypingIndicator
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
/**
|
|
39
|
+
* Add a typing indicator to a message by creating an emoji reaction.
|
|
40
|
+
*
|
|
41
|
+
* The reaction is added silently -- any errors (network issues, missing
|
|
42
|
+
* permissions, rate limits) are caught and logged rather than propagated
|
|
43
|
+
* to the caller. This ensures that a failure to show the typing cue
|
|
44
|
+
* never blocks the actual message processing.
|
|
45
|
+
*
|
|
46
|
+
* @param params.cfg - Plugin configuration with Feishu credentials.
|
|
47
|
+
* @param params.messageId - The message ID to add the typing reaction to.
|
|
48
|
+
* @param params.accountId - Optional account identifier for multi-account setups.
|
|
49
|
+
* @returns A state object that should be passed to {@link removeTypingIndicator}.
|
|
50
|
+
*/
|
|
51
|
+
async function addTypingIndicator(params) {
|
|
52
|
+
const { cfg, messageId, accountId } = params;
|
|
53
|
+
// 规范化 message_id,处理合成 ID(如 "om_xxx:auth-complete")
|
|
54
|
+
const normalizedId = (0, targets_1.normalizeMessageId)(messageId);
|
|
55
|
+
const state = {
|
|
56
|
+
messageId: normalizedId, // 保存规范化后的 ID
|
|
57
|
+
reactionId: null,
|
|
58
|
+
};
|
|
59
|
+
try {
|
|
60
|
+
const client = lark_client_1.LarkClient.fromCfg(cfg, accountId).sdk;
|
|
61
|
+
const response = await (0, message_unavailable_1.runWithMessageUnavailableGuard)({
|
|
62
|
+
messageId: normalizedId,
|
|
63
|
+
operation: 'im.messageReaction.create(typing)',
|
|
64
|
+
fn: () => client.im.messageReaction.create({
|
|
65
|
+
path: {
|
|
66
|
+
message_id: normalizedId,
|
|
67
|
+
},
|
|
68
|
+
data: {
|
|
69
|
+
reaction_type: {
|
|
70
|
+
emoji_type: TYPING_EMOJI_TYPE,
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
}),
|
|
74
|
+
});
|
|
75
|
+
state.reactionId = response?.data?.reaction_id ?? null;
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
if ((0, message_unavailable_1.isMessageUnavailableError)(error)) {
|
|
79
|
+
log.debug(`Skip add typing indicator for unavailable message`, { messageId: normalizedId });
|
|
80
|
+
return state;
|
|
81
|
+
}
|
|
82
|
+
// Silently swallow the error. The typing indicator is a best-effort
|
|
83
|
+
// visual cue and must not interfere with message processing.
|
|
84
|
+
log.debug(`Failed to add typing indicator`, {
|
|
85
|
+
messageId,
|
|
86
|
+
error: error instanceof Error ? error.message : error,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
return state;
|
|
90
|
+
}
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// removeTypingIndicator
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
/**
|
|
95
|
+
* Remove a previously added typing indicator reaction from a message.
|
|
96
|
+
*
|
|
97
|
+
* If the indicator was never successfully added (reactionId is null),
|
|
98
|
+
* this function is a no-op. Errors are silently caught so removal
|
|
99
|
+
* failures do not disrupt downstream logic.
|
|
100
|
+
*
|
|
101
|
+
* @param params.cfg - Plugin configuration with Feishu credentials.
|
|
102
|
+
* @param params.state - The typing indicator state returned by {@link addTypingIndicator}.
|
|
103
|
+
* @param params.accountId - Optional account identifier for multi-account setups.
|
|
104
|
+
*/
|
|
105
|
+
async function removeTypingIndicator(params) {
|
|
106
|
+
const { cfg, state, accountId } = params;
|
|
107
|
+
const reactionId = state.reactionId;
|
|
108
|
+
if (!reactionId) {
|
|
109
|
+
// Nothing to remove -- the indicator was never added or the add
|
|
110
|
+
// call did not return a reaction ID.
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
const client = lark_client_1.LarkClient.fromCfg(cfg, accountId).sdk;
|
|
115
|
+
await (0, message_unavailable_1.runWithMessageUnavailableGuard)({
|
|
116
|
+
messageId: state.messageId,
|
|
117
|
+
operation: 'im.messageReaction.delete(typing)',
|
|
118
|
+
fn: () => client.im.messageReaction.delete({
|
|
119
|
+
path: {
|
|
120
|
+
message_id: state.messageId,
|
|
121
|
+
reaction_id: reactionId,
|
|
122
|
+
},
|
|
123
|
+
}),
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
if ((0, message_unavailable_1.isMessageUnavailableError)(error)) {
|
|
128
|
+
log.debug(`Skip remove typing indicator for unavailable message`, { messageId: state.messageId });
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
// Silently swallow the error. A leftover reaction is acceptable;
|
|
132
|
+
// it will not confuse the user and will disappear if the message
|
|
133
|
+
// is deleted or the reaction is manually removed.
|
|
134
|
+
log.debug(`Failed to remove typing indicator`, {
|
|
135
|
+
messageId: state.messageId,
|
|
136
|
+
error: error instanceof Error ? error.message : error,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
5
|
+
* Message fetching for the Lark/Feishu channel plugin.
|
|
6
|
+
*
|
|
7
|
+
* Shared between inbound (reaction handler, enrich) and outbound modules.
|
|
8
|
+
* Extracted from `outbound/fetch.ts` to eliminate inbound→outbound
|
|
9
|
+
* dependency inversion.
|
|
10
|
+
*/
|
|
11
|
+
import type { ClawdbotConfig } from 'openclaw/plugin-sdk';
|
|
12
|
+
/**
|
|
13
|
+
* Normalised information about a Feishu message, returned by
|
|
14
|
+
* {@link getMessageFeishu}.
|
|
15
|
+
*/
|
|
16
|
+
export interface FeishuMessageInfo {
|
|
17
|
+
/** Unique Feishu message ID. */
|
|
18
|
+
messageId: string;
|
|
19
|
+
/** Chat ID where the message lives. */
|
|
20
|
+
chatId: string;
|
|
21
|
+
/** Chat type ("p2p" or "group"), when available in the API response. */
|
|
22
|
+
chatType?: string;
|
|
23
|
+
/** Open ID of the sender (if available). */
|
|
24
|
+
senderId?: string;
|
|
25
|
+
/** Display name of the sender (resolved from user-name cache). */
|
|
26
|
+
senderName?: string;
|
|
27
|
+
/** Feishu sender type: "user" for human users, "app" for bots/apps. */
|
|
28
|
+
senderType?: string;
|
|
29
|
+
/** The parsed text / content of the message. */
|
|
30
|
+
content: string;
|
|
31
|
+
/** Feishu content type indicator (text, post, image, interactive, ...). */
|
|
32
|
+
contentType: string;
|
|
33
|
+
/** Unix-millisecond timestamp of when the message was created. */
|
|
34
|
+
createTime?: number;
|
|
35
|
+
/** Thread ID if the message belongs to a thread (omt_xxx format). */
|
|
36
|
+
threadId?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Retrieve a single message by its ID from the Feishu IM API.
|
|
40
|
+
*
|
|
41
|
+
* Returns a normalised {@link FeishuMessageInfo} object, or `null` if the
|
|
42
|
+
* message cannot be found or the API returns an error.
|
|
43
|
+
*
|
|
44
|
+
* @param params.cfg - Plugin configuration with Feishu credentials.
|
|
45
|
+
* @param params.messageId - The message ID to fetch.
|
|
46
|
+
* @param params.accountId - Optional account identifier for multi-account setups.
|
|
47
|
+
*/
|
|
48
|
+
export declare function getMessageFeishu(params: {
|
|
49
|
+
cfg: ClawdbotConfig;
|
|
50
|
+
messageId: string;
|
|
51
|
+
accountId?: string;
|
|
52
|
+
/** When true, merge_forward content is recursively expanded via API. */
|
|
53
|
+
expandForward?: boolean;
|
|
54
|
+
}): Promise<FeishuMessageInfo | null>;
|