@larksuite/openclaw-lark 2026.3.9
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 +10 -0
- package/README.md +283 -0
- package/index.d.ts +37 -0
- package/index.d.ts.map +1 -0
- package/index.js +119 -0
- package/index.js.map +1 -0
- package/openclaw.plugin.json +10 -0
- package/package.json +47 -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 +244 -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 +293 -0
- package/skills/feishu-troubleshoot/SKILL.md +70 -0
- package/skills/feishu-update-doc/SKILL.md +285 -0
- package/src/card/builder.d.ts +100 -0
- package/src/card/builder.d.ts.map +1 -0
- package/src/card/builder.js +381 -0
- package/src/card/builder.js.map +1 -0
- package/src/card/cardkit.d.ts +91 -0
- package/src/card/cardkit.d.ts.map +1 -0
- package/src/card/cardkit.js +182 -0
- package/src/card/cardkit.js.map +1 -0
- package/src/card/flush-controller.d.ts +46 -0
- package/src/card/flush-controller.d.ts.map +1 -0
- package/src/card/flush-controller.js +135 -0
- package/src/card/flush-controller.js.map +1 -0
- package/src/card/markdown-style.d.ts +17 -0
- package/src/card/markdown-style.d.ts.map +1 -0
- package/src/card/markdown-style.js +98 -0
- package/src/card/markdown-style.js.map +1 -0
- package/src/card/reply-dispatcher-types.d.ts +121 -0
- package/src/card/reply-dispatcher-types.d.ts.map +1 -0
- package/src/card/reply-dispatcher-types.js +58 -0
- package/src/card/reply-dispatcher-types.js.map +1 -0
- package/src/card/reply-dispatcher.d.ts +16 -0
- package/src/card/reply-dispatcher.d.ts.map +1 -0
- package/src/card/reply-dispatcher.js +293 -0
- package/src/card/reply-dispatcher.js.map +1 -0
- package/src/card/reply-mode.d.ts +39 -0
- package/src/card/reply-mode.d.ts.map +1 -0
- package/src/card/reply-mode.js +66 -0
- package/src/card/reply-mode.js.map +1 -0
- package/src/card/streaming-card-controller.d.ts +88 -0
- package/src/card/streaming-card-controller.d.ts.map +1 -0
- package/src/card/streaming-card-controller.js +717 -0
- package/src/card/streaming-card-controller.js.map +1 -0
- package/src/card/unavailable-guard.d.ts +36 -0
- package/src/card/unavailable-guard.d.ts.map +1 -0
- package/src/card/unavailable-guard.js +84 -0
- package/src/card/unavailable-guard.js.map +1 -0
- package/src/channel/abort-detect.d.ts +35 -0
- package/src/channel/abort-detect.d.ts.map +1 -0
- package/src/channel/abort-detect.js +125 -0
- package/src/channel/abort-detect.js.map +1 -0
- package/src/channel/chat-queue.d.ts +42 -0
- package/src/channel/chat-queue.d.ts.map +1 -0
- package/src/channel/chat-queue.js +59 -0
- package/src/channel/chat-queue.js.map +1 -0
- package/src/channel/config-adapter.d.ts +24 -0
- package/src/channel/config-adapter.d.ts.map +1 -0
- package/src/channel/config-adapter.js +102 -0
- package/src/channel/config-adapter.js.map +1 -0
- package/src/channel/directory.d.ts +58 -0
- package/src/channel/directory.d.ts.map +1 -0
- package/src/channel/directory.js +192 -0
- package/src/channel/directory.js.map +1 -0
- package/src/channel/event-handlers.d.ts +16 -0
- package/src/channel/event-handlers.d.ts.map +1 -0
- package/src/channel/event-handlers.js +222 -0
- package/src/channel/event-handlers.js.map +1 -0
- package/src/channel/monitor.d.ts +18 -0
- package/src/channel/monitor.d.ts.map +1 -0
- package/src/channel/monitor.js +128 -0
- package/src/channel/monitor.js.map +1 -0
- package/src/channel/onboarding-config.d.ts +18 -0
- package/src/channel/onboarding-config.d.ts.map +1 -0
- package/src/channel/onboarding-config.js +89 -0
- package/src/channel/onboarding-config.js.map +1 -0
- package/src/channel/onboarding-migrate.d.ts +26 -0
- package/src/channel/onboarding-migrate.d.ts.map +1 -0
- package/src/channel/onboarding-migrate.js +68 -0
- package/src/channel/onboarding-migrate.js.map +1 -0
- package/src/channel/onboarding.d.ts +13 -0
- package/src/channel/onboarding.d.ts.map +1 -0
- package/src/channel/onboarding.js +297 -0
- package/src/channel/onboarding.js.map +1 -0
- package/src/channel/plugin.d.ts +14 -0
- package/src/channel/plugin.d.ts.map +1 -0
- package/src/channel/plugin.js +279 -0
- package/src/channel/plugin.js.map +1 -0
- package/src/channel/probe.d.ts +15 -0
- package/src/channel/probe.d.ts.map +1 -0
- package/src/channel/probe.js +22 -0
- package/src/channel/probe.js.map +1 -0
- package/src/channel/types.d.ts +37 -0
- package/src/channel/types.d.ts.map +1 -0
- package/src/channel/types.js +8 -0
- package/src/channel/types.js.map +1 -0
- package/src/commands/auth.d.ts +16 -0
- package/src/commands/auth.d.ts.map +1 -0
- package/src/commands/auth.js +85 -0
- package/src/commands/auth.js.map +1 -0
- package/src/commands/diagnose.d.ts +70 -0
- package/src/commands/diagnose.d.ts.map +1 -0
- package/src/commands/diagnose.js +808 -0
- package/src/commands/diagnose.js.map +1 -0
- package/src/commands/doctor.d.ts +18 -0
- package/src/commands/doctor.d.ts.map +1 -0
- package/src/commands/doctor.js +439 -0
- package/src/commands/doctor.js.map +1 -0
- package/src/commands/index.d.ts +9 -0
- package/src/commands/index.d.ts.map +1 -0
- package/src/commands/index.js +208 -0
- package/src/commands/index.js.map +1 -0
- package/src/core/accounts.d.ts +38 -0
- package/src/core/accounts.d.ts.map +1 -0
- package/src/core/accounts.js +179 -0
- package/src/core/accounts.js.map +1 -0
- package/src/core/agent-config.d.ts +101 -0
- package/src/core/agent-config.d.ts.map +1 -0
- package/src/core/agent-config.js +140 -0
- package/src/core/agent-config.js.map +1 -0
- package/src/core/api-error.d.ts +49 -0
- package/src/core/api-error.d.ts.map +1 -0
- package/src/core/api-error.js +113 -0
- package/src/core/api-error.js.map +1 -0
- package/src/core/app-owner-fallback.d.ts +22 -0
- package/src/core/app-owner-fallback.d.ts.map +1 -0
- package/src/core/app-owner-fallback.js +39 -0
- package/src/core/app-owner-fallback.js.map +1 -0
- package/src/core/app-scope-checker.d.ts +88 -0
- package/src/core/app-scope-checker.d.ts.map +1 -0
- package/src/core/app-scope-checker.js +191 -0
- package/src/core/app-scope-checker.js.map +1 -0
- package/src/core/auth-errors.d.ts +143 -0
- package/src/core/auth-errors.d.ts.map +1 -0
- package/src/core/auth-errors.js +156 -0
- package/src/core/auth-errors.js.map +1 -0
- package/src/core/chat-info-cache.d.ts +58 -0
- package/src/core/chat-info-cache.d.ts.map +1 -0
- package/src/core/chat-info-cache.js +153 -0
- package/src/core/chat-info-cache.js.map +1 -0
- package/src/core/config-schema.d.ts +449 -0
- package/src/core/config-schema.d.ts.map +1 -0
- package/src/core/config-schema.js +201 -0
- package/src/core/config-schema.js.map +1 -0
- package/src/core/device-flow.d.ts +78 -0
- package/src/core/device-flow.d.ts.map +1 -0
- package/src/core/device-flow.js +213 -0
- package/src/core/device-flow.js.map +1 -0
- package/src/core/feishu-fetch.d.ts +19 -0
- package/src/core/feishu-fetch.d.ts.map +1 -0
- package/src/core/feishu-fetch.js +26 -0
- package/src/core/feishu-fetch.js.map +1 -0
- package/src/core/footer-config.d.ts +25 -0
- package/src/core/footer-config.d.ts.map +1 -0
- package/src/core/footer-config.js +40 -0
- package/src/core/footer-config.js.map +1 -0
- package/src/core/lark-client.d.ts +109 -0
- package/src/core/lark-client.d.ts.map +1 -0
- package/src/core/lark-client.js +354 -0
- package/src/core/lark-client.js.map +1 -0
- package/src/core/lark-logger.d.ts +24 -0
- package/src/core/lark-logger.d.ts.map +1 -0
- package/src/core/lark-logger.js +155 -0
- package/src/core/lark-logger.js.map +1 -0
- package/src/core/lark-ticket.d.ts +30 -0
- package/src/core/lark-ticket.d.ts.map +1 -0
- package/src/core/lark-ticket.js +36 -0
- package/src/core/lark-ticket.js.map +1 -0
- package/src/core/message-unavailable.d.ts +54 -0
- package/src/core/message-unavailable.d.ts.map +1 -0
- package/src/core/message-unavailable.js +131 -0
- package/src/core/message-unavailable.js.map +1 -0
- package/src/core/owner-policy.d.ts +32 -0
- package/src/core/owner-policy.d.ts.map +1 -0
- package/src/core/owner-policy.js +53 -0
- package/src/core/owner-policy.js.map +1 -0
- package/src/core/permission-url.d.ts +23 -0
- package/src/core/permission-url.d.ts.map +1 -0
- package/src/core/permission-url.js +73 -0
- package/src/core/permission-url.js.map +1 -0
- package/src/core/raw-request.d.ts +28 -0
- package/src/core/raw-request.d.ts.map +1 -0
- package/src/core/raw-request.js +63 -0
- package/src/core/raw-request.js.map +1 -0
- package/src/core/scope-manager.d.ts +169 -0
- package/src/core/scope-manager.d.ts.map +1 -0
- package/src/core/scope-manager.js +214 -0
- package/src/core/scope-manager.js.map +1 -0
- package/src/core/security-check.d.ts +73 -0
- package/src/core/security-check.d.ts.map +1 -0
- package/src/core/security-check.js +175 -0
- package/src/core/security-check.js.map +1 -0
- package/src/core/shutdown-hooks.d.ts +23 -0
- package/src/core/shutdown-hooks.d.ts.map +1 -0
- package/src/core/shutdown-hooks.js +57 -0
- package/src/core/shutdown-hooks.js.map +1 -0
- package/src/core/targets.d.ts +50 -0
- package/src/core/targets.d.ts.map +1 -0
- package/src/core/targets.js +128 -0
- package/src/core/targets.js.map +1 -0
- package/src/core/token-store.d.ts +55 -0
- package/src/core/token-store.d.ts.map +1 -0
- package/src/core/token-store.js +315 -0
- package/src/core/token-store.js.map +1 -0
- package/src/core/tool-client.d.ts +177 -0
- package/src/core/tool-client.d.ts.map +1 -0
- package/src/core/tool-client.js +381 -0
- package/src/core/tool-client.js.map +1 -0
- package/src/core/tool-scopes.d.ts +154 -0
- package/src/core/tool-scopes.d.ts.map +1 -0
- package/src/core/tool-scopes.js +326 -0
- package/src/core/tool-scopes.js.map +1 -0
- package/src/core/tools-config.d.ts +35 -0
- package/src/core/tools-config.d.ts.map +1 -0
- package/src/core/tools-config.js +88 -0
- package/src/core/tools-config.js.map +1 -0
- package/src/core/types.d.ts +88 -0
- package/src/core/types.d.ts.map +1 -0
- package/src/core/types.js +12 -0
- package/src/core/types.js.map +1 -0
- package/src/core/uat-client.d.ts +47 -0
- package/src/core/uat-client.d.ts.map +1 -0
- package/src/core/uat-client.js +173 -0
- package/src/core/uat-client.js.map +1 -0
- package/src/core/version.d.ts +26 -0
- package/src/core/version.d.ts.map +1 -0
- package/src/core/version.js +50 -0
- package/src/core/version.js.map +1 -0
- package/src/messaging/converters/audio.d.ts +9 -0
- package/src/messaging/converters/audio.d.ts.map +1 -0
- package/src/messaging/converters/audio.js +22 -0
- package/src/messaging/converters/audio.js.map +1 -0
- package/src/messaging/converters/calendar.d.ts +14 -0
- package/src/messaging/converters/calendar.d.ts.map +1 -0
- package/src/messaging/converters/calendar.js +51 -0
- package/src/messaging/converters/calendar.js.map +1 -0
- package/src/messaging/converters/content-converter.d.ts +42 -0
- package/src/messaging/converters/content-converter.d.ts.map +1 -0
- package/src/messaging/converters/content-converter.js +107 -0
- package/src/messaging/converters/content-converter.js.map +1 -0
- package/src/messaging/converters/file.d.ts +9 -0
- package/src/messaging/converters/file.d.ts.map +1 -0
- package/src/messaging/converters/file.js +21 -0
- package/src/messaging/converters/file.js.map +1 -0
- package/src/messaging/converters/folder.d.ts +9 -0
- package/src/messaging/converters/folder.d.ts.map +1 -0
- package/src/messaging/converters/folder.js +21 -0
- package/src/messaging/converters/folder.js.map +1 -0
- package/src/messaging/converters/hongbao.d.ts +9 -0
- package/src/messaging/converters/hongbao.d.ts.map +1 -0
- package/src/messaging/converters/hongbao.js +17 -0
- package/src/messaging/converters/hongbao.js.map +1 -0
- package/src/messaging/converters/image.d.ts +9 -0
- package/src/messaging/converters/image.d.ts.map +1 -0
- package/src/messaging/converters/image.js +19 -0
- package/src/messaging/converters/image.js.map +1 -0
- package/src/messaging/converters/index.d.ts +9 -0
- package/src/messaging/converters/index.d.ts.map +1 -0
- package/src/messaging/converters/index.js +51 -0
- package/src/messaging/converters/index.js.map +1 -0
- package/src/messaging/converters/interactive/card-converter.d.ts +77 -0
- package/src/messaging/converters/interactive/card-converter.d.ts.map +1 -0
- package/src/messaging/converters/interactive/card-converter.js +1174 -0
- package/src/messaging/converters/interactive/card-converter.js.map +1 -0
- package/src/messaging/converters/interactive/card-utils.d.ts +10 -0
- package/src/messaging/converters/interactive/card-utils.d.ts.map +1 -0
- package/src/messaging/converters/interactive/card-utils.js +43 -0
- package/src/messaging/converters/interactive/card-utils.js.map +1 -0
- package/src/messaging/converters/interactive/index.d.ts +9 -0
- package/src/messaging/converters/interactive/index.d.ts.map +1 -0
- package/src/messaging/converters/interactive/index.js +22 -0
- package/src/messaging/converters/interactive/index.js.map +1 -0
- package/src/messaging/converters/interactive/legacy.d.ts +12 -0
- package/src/messaging/converters/interactive/legacy.d.ts.map +1 -0
- package/src/messaging/converters/interactive/legacy.js +58 -0
- package/src/messaging/converters/interactive/legacy.js.map +1 -0
- package/src/messaging/converters/interactive/types.d.ts +24 -0
- package/src/messaging/converters/interactive/types.d.ts.map +1 -0
- package/src/messaging/converters/interactive/types.js +25 -0
- package/src/messaging/converters/interactive/types.js.map +1 -0
- package/src/messaging/converters/location.d.ts +9 -0
- package/src/messaging/converters/location.d.ts.map +1 -0
- package/src/messaging/converters/location.js +20 -0
- package/src/messaging/converters/location.js.map +1 -0
- package/src/messaging/converters/merge-forward.d.ts +33 -0
- package/src/messaging/converters/merge-forward.d.ts.map +1 -0
- package/src/messaging/converters/merge-forward.js +226 -0
- package/src/messaging/converters/merge-forward.js.map +1 -0
- package/src/messaging/converters/post.d.ts +12 -0
- package/src/messaging/converters/post.d.ts.map +1 -0
- package/src/messaging/converters/post.js +136 -0
- package/src/messaging/converters/post.js.map +1 -0
- package/src/messaging/converters/share.d.ts +10 -0
- package/src/messaging/converters/share.d.ts.map +1 -0
- package/src/messaging/converters/share.js +24 -0
- package/src/messaging/converters/share.js.map +1 -0
- package/src/messaging/converters/sticker.d.ts +9 -0
- package/src/messaging/converters/sticker.d.ts.map +1 -0
- package/src/messaging/converters/sticker.js +19 -0
- package/src/messaging/converters/sticker.js.map +1 -0
- package/src/messaging/converters/system.d.ts +13 -0
- package/src/messaging/converters/system.d.ts.map +1 -0
- package/src/messaging/converters/system.js +33 -0
- package/src/messaging/converters/system.js.map +1 -0
- package/src/messaging/converters/text.d.ts +9 -0
- package/src/messaging/converters/text.d.ts.map +1 -0
- package/src/messaging/converters/text.js +15 -0
- package/src/messaging/converters/text.js.map +1 -0
- package/src/messaging/converters/todo.d.ts +9 -0
- package/src/messaging/converters/todo.d.ts.map +1 -0
- package/src/messaging/converters/todo.js +42 -0
- package/src/messaging/converters/todo.js.map +1 -0
- package/src/messaging/converters/types.d.ts +108 -0
- package/src/messaging/converters/types.d.ts.map +1 -0
- package/src/messaging/converters/types.js +8 -0
- package/src/messaging/converters/types.js.map +1 -0
- package/src/messaging/converters/unknown.d.ts +9 -0
- package/src/messaging/converters/unknown.d.ts.map +1 -0
- package/src/messaging/converters/unknown.js +17 -0
- package/src/messaging/converters/unknown.js.map +1 -0
- package/src/messaging/converters/utils.d.ts +23 -0
- package/src/messaging/converters/utils.d.ts.map +1 -0
- package/src/messaging/converters/utils.js +52 -0
- package/src/messaging/converters/utils.js.map +1 -0
- package/src/messaging/converters/video-chat.d.ts +9 -0
- package/src/messaging/converters/video-chat.d.ts.map +1 -0
- package/src/messaging/converters/video-chat.js +24 -0
- package/src/messaging/converters/video-chat.js.map +1 -0
- package/src/messaging/converters/video.d.ts +9 -0
- package/src/messaging/converters/video.d.ts.map +1 -0
- package/src/messaging/converters/video.js +33 -0
- package/src/messaging/converters/video.js.map +1 -0
- package/src/messaging/converters/vote.d.ts +9 -0
- package/src/messaging/converters/vote.d.ts.map +1 -0
- package/src/messaging/converters/vote.js +25 -0
- package/src/messaging/converters/vote.js.map +1 -0
- package/src/messaging/inbound/dedup.d.ts +60 -0
- package/src/messaging/inbound/dedup.d.ts.map +1 -0
- package/src/messaging/inbound/dedup.js +117 -0
- package/src/messaging/inbound/dedup.js.map +1 -0
- package/src/messaging/inbound/dispatch-builders.d.ts +84 -0
- package/src/messaging/inbound/dispatch-builders.d.ts.map +1 -0
- package/src/messaging/inbound/dispatch-builders.js +153 -0
- package/src/messaging/inbound/dispatch-builders.js.map +1 -0
- package/src/messaging/inbound/dispatch-commands.d.ts +28 -0
- package/src/messaging/inbound/dispatch-commands.d.ts.map +1 -0
- package/src/messaging/inbound/dispatch-commands.js +113 -0
- package/src/messaging/inbound/dispatch-commands.js.map +1 -0
- package/src/messaging/inbound/dispatch-context.d.ts +68 -0
- package/src/messaging/inbound/dispatch-context.d.ts.map +1 -0
- package/src/messaging/inbound/dispatch-context.js +137 -0
- package/src/messaging/inbound/dispatch-context.js.map +1 -0
- package/src/messaging/inbound/dispatch.d.ts +48 -0
- package/src/messaging/inbound/dispatch.d.ts.map +1 -0
- package/src/messaging/inbound/dispatch.js +193 -0
- package/src/messaging/inbound/dispatch.js.map +1 -0
- package/src/messaging/inbound/enrich.d.ts +103 -0
- package/src/messaging/inbound/enrich.d.ts.map +1 -0
- package/src/messaging/inbound/enrich.js +228 -0
- package/src/messaging/inbound/enrich.js.map +1 -0
- package/src/messaging/inbound/gate-effects.d.ts +24 -0
- package/src/messaging/inbound/gate-effects.d.ts.map +1 -0
- package/src/messaging/inbound/gate-effects.js +44 -0
- package/src/messaging/inbound/gate-effects.js.map +1 -0
- package/src/messaging/inbound/gate.d.ts +61 -0
- package/src/messaging/inbound/gate.d.ts.map +1 -0
- package/src/messaging/inbound/gate.js +234 -0
- package/src/messaging/inbound/gate.js.map +1 -0
- package/src/messaging/inbound/handler.d.ts +36 -0
- package/src/messaging/inbound/handler.d.ts.map +1 -0
- package/src/messaging/inbound/handler.js +174 -0
- package/src/messaging/inbound/handler.js.map +1 -0
- package/src/messaging/inbound/media-resolver.d.ts +33 -0
- package/src/messaging/inbound/media-resolver.d.ts.map +1 -0
- package/src/messaging/inbound/media-resolver.js +88 -0
- package/src/messaging/inbound/media-resolver.js.map +1 -0
- package/src/messaging/inbound/mention.d.ts +40 -0
- package/src/messaging/inbound/mention.d.ts.map +1 -0
- package/src/messaging/inbound/mention.js +82 -0
- package/src/messaging/inbound/mention.js.map +1 -0
- package/src/messaging/inbound/parse-io.d.ts +51 -0
- package/src/messaging/inbound/parse-io.d.ts.map +1 -0
- package/src/messaging/inbound/parse-io.js +82 -0
- package/src/messaging/inbound/parse-io.js.map +1 -0
- package/src/messaging/inbound/parse.d.ts +29 -0
- package/src/messaging/inbound/parse.d.ts.map +1 -0
- package/src/messaging/inbound/parse.js +107 -0
- package/src/messaging/inbound/parse.js.map +1 -0
- package/src/messaging/inbound/permission.d.ts +18 -0
- package/src/messaging/inbound/permission.d.ts.map +1 -0
- package/src/messaging/inbound/permission.js +41 -0
- package/src/messaging/inbound/permission.js.map +1 -0
- package/src/messaging/inbound/policy.d.ts +95 -0
- package/src/messaging/inbound/policy.d.ts.map +1 -0
- package/src/messaging/inbound/policy.js +161 -0
- package/src/messaging/inbound/policy.js.map +1 -0
- package/src/messaging/inbound/reaction-handler.d.ts +62 -0
- package/src/messaging/inbound/reaction-handler.d.ts.map +1 -0
- package/src/messaging/inbound/reaction-handler.js +221 -0
- package/src/messaging/inbound/reaction-handler.js.map +1 -0
- package/src/messaging/inbound/user-name-cache.d.ts +83 -0
- package/src/messaging/inbound/user-name-cache.d.ts.map +1 -0
- package/src/messaging/inbound/user-name-cache.js +242 -0
- package/src/messaging/inbound/user-name-cache.js.map +1 -0
- package/src/messaging/outbound/actions.d.ts +17 -0
- package/src/messaging/outbound/actions.d.ts.map +1 -0
- package/src/messaging/outbound/actions.js +310 -0
- package/src/messaging/outbound/actions.js.map +1 -0
- package/src/messaging/outbound/chat-manage.d.ts +65 -0
- package/src/messaging/outbound/chat-manage.d.ts.map +1 -0
- package/src/messaging/outbound/chat-manage.js +112 -0
- package/src/messaging/outbound/chat-manage.js.map +1 -0
- package/src/messaging/outbound/deliver.d.ts +156 -0
- package/src/messaging/outbound/deliver.d.ts.map +1 -0
- package/src/messaging/outbound/deliver.js +299 -0
- package/src/messaging/outbound/deliver.js.map +1 -0
- package/src/messaging/outbound/fetch.d.ts +13 -0
- package/src/messaging/outbound/fetch.d.ts.map +1 -0
- package/src/messaging/outbound/fetch.js +13 -0
- package/src/messaging/outbound/fetch.js.map +1 -0
- package/src/messaging/outbound/forward.d.ts +27 -0
- package/src/messaging/outbound/forward.d.ts.map +1 -0
- package/src/messaging/outbound/forward.js +49 -0
- package/src/messaging/outbound/forward.js.map +1 -0
- package/src/messaging/outbound/media-url-utils.d.ts +30 -0
- package/src/messaging/outbound/media-url-utils.d.ts.map +1 -0
- package/src/messaging/outbound/media-url-utils.js +131 -0
- package/src/messaging/outbound/media-url-utils.js.map +1 -0
- package/src/messaging/outbound/media.d.ts +256 -0
- package/src/messaging/outbound/media.d.ts.map +1 -0
- package/src/messaging/outbound/media.js +749 -0
- package/src/messaging/outbound/media.js.map +1 -0
- package/src/messaging/outbound/outbound.d.ts +90 -0
- package/src/messaging/outbound/outbound.d.ts.map +1 -0
- package/src/messaging/outbound/outbound.js +112 -0
- package/src/messaging/outbound/outbound.js.map +1 -0
- package/src/messaging/outbound/reactions.d.ts +125 -0
- package/src/messaging/outbound/reactions.d.ts.map +1 -0
- package/src/messaging/outbound/reactions.js +379 -0
- package/src/messaging/outbound/reactions.js.map +1 -0
- package/src/messaging/outbound/send.d.ts +136 -0
- package/src/messaging/outbound/send.d.ts.map +1 -0
- package/src/messaging/outbound/send.js +289 -0
- package/src/messaging/outbound/send.js.map +1 -0
- package/src/messaging/outbound/typing.d.ts +61 -0
- package/src/messaging/outbound/typing.d.ts.map +1 -0
- package/src/messaging/outbound/typing.js +136 -0
- package/src/messaging/outbound/typing.js.map +1 -0
- package/src/messaging/shared/message-lookup.d.ts +55 -0
- package/src/messaging/shared/message-lookup.d.ts.map +1 -0
- package/src/messaging/shared/message-lookup.js +118 -0
- package/src/messaging/shared/message-lookup.js.map +1 -0
- package/src/messaging/types.d.ts +177 -0
- package/src/messaging/types.d.ts.map +1 -0
- package/src/messaging/types.js +11 -0
- package/src/messaging/types.js.map +1 -0
- package/src/tools/auto-auth.d.ts +57 -0
- package/src/tools/auto-auth.d.ts.map +1 -0
- package/src/tools/auto-auth.js +925 -0
- package/src/tools/auto-auth.js.map +1 -0
- package/src/tools/helpers.d.ts +220 -0
- package/src/tools/helpers.d.ts.map +1 -0
- package/src/tools/helpers.js +298 -0
- package/src/tools/helpers.js.map +1 -0
- package/src/tools/mcp/doc/create.d.ts +13 -0
- package/src/tools/mcp/doc/create.d.ts.map +1 -0
- package/src/tools/mcp/doc/create.js +45 -0
- package/src/tools/mcp/doc/create.js.map +1 -0
- package/src/tools/mcp/doc/fetch.d.ts +13 -0
- package/src/tools/mcp/doc/fetch.d.ts.map +1 -0
- package/src/tools/mcp/doc/fetch.js +37 -0
- package/src/tools/mcp/doc/fetch.js.map +1 -0
- package/src/tools/mcp/doc/index.d.ts +13 -0
- package/src/tools/mcp/doc/index.d.ts.map +1 -0
- package/src/tools/mcp/doc/index.js +42 -0
- package/src/tools/mcp/doc/index.js.map +1 -0
- package/src/tools/mcp/doc/update.d.ts +13 -0
- package/src/tools/mcp/doc/update.d.ts.map +1 -0
- package/src/tools/mcp/doc/update.js +62 -0
- package/src/tools/mcp/doc/update.js.map +1 -0
- package/src/tools/mcp/shared.d.ts +58 -0
- package/src/tools/mcp/shared.d.ts.map +1 -0
- package/src/tools/mcp/shared.js +224 -0
- package/src/tools/mcp/shared.js.map +1 -0
- package/src/tools/oapi/bitable/app-table-field.d.ts +17 -0
- package/src/tools/oapi/bitable/app-table-field.d.ts.map +1 -0
- package/src/tools/oapi/bitable/app-table-field.js +224 -0
- package/src/tools/oapi/bitable/app-table-field.js.map +1 -0
- package/src/tools/oapi/bitable/app-table-record.d.ts +21 -0
- package/src/tools/oapi/bitable/app-table-record.d.ts.map +1 -0
- package/src/tools/oapi/bitable/app-table-record.js +449 -0
- package/src/tools/oapi/bitable/app-table-record.js.map +1 -0
- package/src/tools/oapi/bitable/app-table-view.d.ts +18 -0
- package/src/tools/oapi/bitable/app-table-view.d.ts.map +1 -0
- package/src/tools/oapi/bitable/app-table-view.js +197 -0
- package/src/tools/oapi/bitable/app-table-view.js.map +1 -0
- package/src/tools/oapi/bitable/app-table.d.ts +20 -0
- package/src/tools/oapi/bitable/app-table.d.ts.map +1 -0
- package/src/tools/oapi/bitable/app-table.js +249 -0
- package/src/tools/oapi/bitable/app-table.js.map +1 -0
- package/src/tools/oapi/bitable/app.d.ts +19 -0
- package/src/tools/oapi/bitable/app.d.ts.map +1 -0
- package/src/tools/oapi/bitable/app.js +188 -0
- package/src/tools/oapi/bitable/app.js.map +1 -0
- package/src/tools/oapi/bitable/index.d.ts +10 -0
- package/src/tools/oapi/bitable/index.d.ts.map +1 -0
- package/src/tools/oapi/bitable/index.js +10 -0
- package/src/tools/oapi/bitable/index.js.map +1 -0
- package/src/tools/oapi/calendar/calendar.d.ts +16 -0
- package/src/tools/oapi/calendar/calendar.d.ts.map +1 -0
- package/src/tools/oapi/calendar/calendar.js +124 -0
- package/src/tools/oapi/calendar/calendar.js.map +1 -0
- package/src/tools/oapi/calendar/event-attendee.d.ts +17 -0
- package/src/tools/oapi/calendar/event-attendee.d.ts.map +1 -0
- package/src/tools/oapi/calendar/event-attendee.js +275 -0
- package/src/tools/oapi/calendar/event-attendee.js.map +1 -0
- package/src/tools/oapi/calendar/event.d.ts +17 -0
- package/src/tools/oapi/calendar/event.d.ts.map +1 -0
- package/src/tools/oapi/calendar/event.js +721 -0
- package/src/tools/oapi/calendar/event.js.map +1 -0
- package/src/tools/oapi/calendar/freebusy.d.ts +14 -0
- package/src/tools/oapi/calendar/freebusy.d.ts.map +1 -0
- package/src/tools/oapi/calendar/freebusy.js +113 -0
- package/src/tools/oapi/calendar/freebusy.js.map +1 -0
- package/src/tools/oapi/calendar/index.d.ts +9 -0
- package/src/tools/oapi/calendar/index.d.ts.map +1 -0
- package/src/tools/oapi/calendar/index.js +9 -0
- package/src/tools/oapi/calendar/index.js.map +1 -0
- package/src/tools/oapi/chat/chat.d.ts +17 -0
- package/src/tools/oapi/chat/chat.d.ts.map +1 -0
- package/src/tools/oapi/chat/chat.js +126 -0
- package/src/tools/oapi/chat/chat.js.map +1 -0
- package/src/tools/oapi/chat/index.d.ts +11 -0
- package/src/tools/oapi/chat/index.d.ts.map +1 -0
- package/src/tools/oapi/chat/index.js +16 -0
- package/src/tools/oapi/chat/index.js.map +1 -0
- package/src/tools/oapi/chat/members.d.ts +12 -0
- package/src/tools/oapi/chat/members.d.ts.map +1 -0
- package/src/tools/oapi/chat/members.js +83 -0
- package/src/tools/oapi/chat/members.js.map +1 -0
- package/src/tools/oapi/common/get-user.d.ts +13 -0
- package/src/tools/oapi/common/get-user.d.ts.map +1 -0
- package/src/tools/oapi/common/get-user.js +108 -0
- package/src/tools/oapi/common/get-user.js.map +1 -0
- package/src/tools/oapi/common/index.d.ts +7 -0
- package/src/tools/oapi/common/index.d.ts.map +1 -0
- package/src/tools/oapi/common/index.js +7 -0
- package/src/tools/oapi/common/index.js.map +1 -0
- package/src/tools/oapi/common/search-user.d.ts +12 -0
- package/src/tools/oapi/common/search-user.d.ts.map +1 -0
- package/src/tools/oapi/common/search-user.js +75 -0
- package/src/tools/oapi/common/search-user.js.map +1 -0
- package/src/tools/oapi/drive/doc-comments.d.ts +16 -0
- package/src/tools/oapi/drive/doc-comments.d.ts.map +1 -0
- package/src/tools/oapi/drive/doc-comments.js +288 -0
- package/src/tools/oapi/drive/doc-comments.js.map +1 -0
- package/src/tools/oapi/drive/doc-media.d.ts +20 -0
- package/src/tools/oapi/drive/doc-media.d.ts.map +1 -0
- package/src/tools/oapi/drive/doc-media.js +337 -0
- package/src/tools/oapi/drive/doc-media.js.map +1 -0
- package/src/tools/oapi/drive/file.d.ts +20 -0
- package/src/tools/oapi/drive/file.d.ts.map +1 -0
- package/src/tools/oapi/drive/file.js +485 -0
- package/src/tools/oapi/drive/file.js.map +1 -0
- package/src/tools/oapi/drive/index.d.ts +13 -0
- package/src/tools/oapi/drive/index.d.ts.map +1 -0
- package/src/tools/oapi/drive/index.js +37 -0
- package/src/tools/oapi/drive/index.js.map +1 -0
- package/src/tools/oapi/helpers.d.ts +174 -0
- package/src/tools/oapi/helpers.d.ts.map +1 -0
- package/src/tools/oapi/helpers.js +341 -0
- package/src/tools/oapi/helpers.js.map +1 -0
- package/src/tools/oapi/im/format-messages.d.ts +51 -0
- package/src/tools/oapi/im/format-messages.d.ts.map +1 -0
- package/src/tools/oapi/im/format-messages.js +166 -0
- package/src/tools/oapi/im/format-messages.js.map +1 -0
- package/src/tools/oapi/im/index.d.ts +11 -0
- package/src/tools/oapi/im/index.d.ts.map +1 -0
- package/src/tools/oapi/im/index.js +18 -0
- package/src/tools/oapi/im/index.js.map +1 -0
- package/src/tools/oapi/im/message-read.d.ts +14 -0
- package/src/tools/oapi/im/message-read.d.ts.map +1 -0
- package/src/tools/oapi/im/message-read.js +412 -0
- package/src/tools/oapi/im/message-read.js.map +1 -0
- package/src/tools/oapi/im/message.d.ts +17 -0
- package/src/tools/oapi/im/message.d.ts.map +1 -0
- package/src/tools/oapi/im/message.js +171 -0
- package/src/tools/oapi/im/message.js.map +1 -0
- package/src/tools/oapi/im/resource.d.ts +14 -0
- package/src/tools/oapi/im/resource.d.ts.map +1 -0
- package/src/tools/oapi/im/resource.js +152 -0
- package/src/tools/oapi/im/resource.js.map +1 -0
- package/src/tools/oapi/im/time-utils.d.ts +47 -0
- package/src/tools/oapi/im/time-utils.d.ts.map +1 -0
- package/src/tools/oapi/im/time-utils.js +202 -0
- package/src/tools/oapi/im/time-utils.js.map +1 -0
- package/src/tools/oapi/im/user-name-uat.d.ts +24 -0
- package/src/tools/oapi/im/user-name-uat.d.ts.map +1 -0
- package/src/tools/oapi/im/user-name-uat.js +128 -0
- package/src/tools/oapi/im/user-name-uat.js.map +1 -0
- package/src/tools/oapi/index.d.ts +12 -0
- package/src/tools/oapi/index.d.ts.map +1 -0
- package/src/tools/oapi/index.js +59 -0
- package/src/tools/oapi/index.js.map +1 -0
- package/src/tools/oapi/sdk-types.d.ts +97 -0
- package/src/tools/oapi/sdk-types.d.ts.map +1 -0
- package/src/tools/oapi/sdk-types.js +13 -0
- package/src/tools/oapi/sdk-types.js.map +1 -0
- package/src/tools/oapi/search/doc-search.d.ts +14 -0
- package/src/tools/oapi/search/doc-search.d.ts.map +1 -0
- package/src/tools/oapi/search/doc-search.js +203 -0
- package/src/tools/oapi/search/doc-search.js.map +1 -0
- package/src/tools/oapi/search/index.d.ts +13 -0
- package/src/tools/oapi/search/index.d.ts.map +1 -0
- package/src/tools/oapi/search/index.js +34 -0
- package/src/tools/oapi/search/index.js.map +1 -0
- package/src/tools/oapi/sheets/index.d.ts +13 -0
- package/src/tools/oapi/sheets/index.d.ts.map +1 -0
- package/src/tools/oapi/sheets/index.js +32 -0
- package/src/tools/oapi/sheets/index.js.map +1 -0
- package/src/tools/oapi/sheets/sheet.d.ts +17 -0
- package/src/tools/oapi/sheets/sheet.d.ts.map +1 -0
- package/src/tools/oapi/sheets/sheet.js +652 -0
- package/src/tools/oapi/sheets/sheet.js.map +1 -0
- package/src/tools/oapi/task/comment.d.ts +16 -0
- package/src/tools/oapi/task/comment.d.ts.map +1 -0
- package/src/tools/oapi/task/comment.js +142 -0
- package/src/tools/oapi/task/comment.js.map +1 -0
- package/src/tools/oapi/task/index.d.ts +9 -0
- package/src/tools/oapi/task/index.d.ts.map +1 -0
- package/src/tools/oapi/task/index.js +9 -0
- package/src/tools/oapi/task/index.js.map +1 -0
- package/src/tools/oapi/task/subtask.d.ts +15 -0
- package/src/tools/oapi/task/subtask.d.ts.map +1 -0
- package/src/tools/oapi/task/subtask.js +164 -0
- package/src/tools/oapi/task/subtask.js.map +1 -0
- package/src/tools/oapi/task/task.d.ts +17 -0
- package/src/tools/oapi/task/task.d.ts.map +1 -0
- package/src/tools/oapi/task/task.js +346 -0
- package/src/tools/oapi/task/task.js.map +1 -0
- package/src/tools/oapi/task/tasklist.d.ts +22 -0
- package/src/tools/oapi/task/tasklist.d.ts.map +1 -0
- package/src/tools/oapi/task/tasklist.js +323 -0
- package/src/tools/oapi/task/tasklist.js.map +1 -0
- package/src/tools/oapi/wiki/index.d.ts +13 -0
- package/src/tools/oapi/wiki/index.d.ts.map +1 -0
- package/src/tools/oapi/wiki/index.js +35 -0
- package/src/tools/oapi/wiki/index.js.map +1 -0
- package/src/tools/oapi/wiki/space-node.d.ts +18 -0
- package/src/tools/oapi/wiki/space-node.d.ts.map +1 -0
- package/src/tools/oapi/wiki/space-node.js +253 -0
- package/src/tools/oapi/wiki/space-node.js.map +1 -0
- package/src/tools/oapi/wiki/space.d.ts +16 -0
- package/src/tools/oapi/wiki/space.d.ts.map +1 -0
- package/src/tools/oapi/wiki/space.js +132 -0
- package/src/tools/oapi/wiki/space.js.map +1 -0
- package/src/tools/oauth-batch-auth.d.ts +12 -0
- package/src/tools/oauth-batch-auth.d.ts.map +1 -0
- package/src/tools/oauth-batch-auth.js +142 -0
- package/src/tools/oauth-batch-auth.js.map +1 -0
- package/src/tools/oauth-cards.d.ts +27 -0
- package/src/tools/oauth-cards.d.ts.map +1 -0
- package/src/tools/oauth-cards.js +251 -0
- package/src/tools/oauth-cards.js.map +1 -0
- package/src/tools/oauth.d.ts +48 -0
- package/src/tools/oauth.d.ts.map +1 -0
- package/src/tools/oauth.js +619 -0
- package/src/tools/oauth.js.map +1 -0
- package/src/tools/onboarding-auth.d.ts +28 -0
- package/src/tools/onboarding-auth.d.ts.map +1 -0
- package/src/tools/onboarding-auth.js +131 -0
- package/src/tools/onboarding-auth.js.map +1 -0
- package/src/tools/tat/im/index.d.ts +16 -0
- package/src/tools/tat/im/index.d.ts.map +1 -0
- package/src/tools/tat/im/index.js +19 -0
- package/src/tools/tat/im/index.js.map +1 -0
- package/src/tools/tat/im/resource.d.ts +16 -0
- package/src/tools/tat/im/resource.d.ts.map +1 -0
- package/src/tools/tat/im/resource.js +158 -0
- package/src/tools/tat/im/resource.js.map +1 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
5
|
+
* Access control policies for the Feishu/Lark channel plugin.
|
|
6
|
+
*
|
|
7
|
+
* Provides allowlist matching, group configuration lookup, tool policy
|
|
8
|
+
* extraction, and group access checks.
|
|
9
|
+
*/
|
|
10
|
+
import type { ChannelGroupContext, GroupToolPolicyConfig } from 'openclaw/plugin-sdk';
|
|
11
|
+
import type { FeishuConfig, FeishuGroupConfig } from '../../core/types';
|
|
12
|
+
export interface FeishuAllowlistMatch {
|
|
13
|
+
allowed: boolean;
|
|
14
|
+
matchKey?: string;
|
|
15
|
+
matchSource?: 'wildcard' | 'id' | 'name';
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Check whether a sender is permitted by a given allowlist.
|
|
19
|
+
*
|
|
20
|
+
* Entries are normalised to lowercase strings before comparison.
|
|
21
|
+
* A single "*" entry acts as a wildcard that matches everyone.
|
|
22
|
+
* When the allowlist is empty the result is `{ allowed: false }`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveFeishuAllowlistMatch(params: {
|
|
25
|
+
allowFrom: Array<string | number>;
|
|
26
|
+
senderId: string;
|
|
27
|
+
senderName?: string | null;
|
|
28
|
+
}): FeishuAllowlistMatch;
|
|
29
|
+
/**
|
|
30
|
+
* Look up the per-group configuration by group ID.
|
|
31
|
+
*
|
|
32
|
+
* Performs a case-insensitive lookup against the keys in `cfg.groups`.
|
|
33
|
+
* Returns `undefined` when no matching group entry is found.
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveFeishuGroupConfig(params: {
|
|
36
|
+
cfg?: FeishuConfig;
|
|
37
|
+
groupId?: string | null;
|
|
38
|
+
}): FeishuGroupConfig | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Extract the tool policy configuration from the group config that
|
|
41
|
+
* corresponds to the given group context.
|
|
42
|
+
*
|
|
43
|
+
* ★ 多账号配置隔离:SDK 回调传入的 params.cfg 是顶层全局配置,
|
|
44
|
+
* cfg.channels.feishu 不包含 per-account 的覆盖值。
|
|
45
|
+
* 这里通过 getLarkAccount() 获取当前 account 合并后的配置,
|
|
46
|
+
* 确保每个账号的 groups / tool policy 配置独立生效。
|
|
47
|
+
*/
|
|
48
|
+
export declare function resolveFeishuGroupToolPolicy(params: ChannelGroupContext): GroupToolPolicyConfig | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Determine whether an inbound group message should be processed.
|
|
51
|
+
*
|
|
52
|
+
* - `disabled` --> always rejected
|
|
53
|
+
* - `open` --> always allowed
|
|
54
|
+
* - `allowlist` --> allowed only when the sender matches the allowlist
|
|
55
|
+
*/
|
|
56
|
+
export declare function isFeishuGroupAllowed(params: {
|
|
57
|
+
groupPolicy: 'open' | 'allowlist' | 'disabled';
|
|
58
|
+
allowFrom: Array<string | number>;
|
|
59
|
+
senderId: string;
|
|
60
|
+
senderName?: string | null;
|
|
61
|
+
}): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Split a raw `groupAllowFrom` array into legacy chat-ID entries
|
|
64
|
+
* (`oc_xxx`) and sender-level entries.
|
|
65
|
+
*
|
|
66
|
+
* Older Feishu configs used `groupAllowFrom` with `oc_xxx` chat IDs to
|
|
67
|
+
* control which groups are allowed. The correct semantic (aligned with
|
|
68
|
+
* Telegram) is sender IDs. This function separates the two concerns so
|
|
69
|
+
* both layers can work independently.
|
|
70
|
+
*/
|
|
71
|
+
export declare function splitLegacyGroupAllowFrom(rawGroupAllowFrom: Array<string | number>): {
|
|
72
|
+
legacyChatIds: string[];
|
|
73
|
+
senderAllowFrom: string[];
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Resolve the effective sender-level group policy and the merged
|
|
77
|
+
* `allowFrom` list for sender filtering within a group.
|
|
78
|
+
*
|
|
79
|
+
* The precedence chain for `senderPolicy` is:
|
|
80
|
+
* per-group `groupPolicy` > default ("*") group `groupPolicy` >
|
|
81
|
+
* global `groupPolicy` > "open" (default).
|
|
82
|
+
*
|
|
83
|
+
* The `senderAllowFrom` is the union of global (non-oc_) entries,
|
|
84
|
+
* per-group entries, and default ("*") entries (when no per-group config).
|
|
85
|
+
*/
|
|
86
|
+
export declare function resolveGroupSenderPolicyContext(params: {
|
|
87
|
+
groupConfig?: FeishuGroupConfig;
|
|
88
|
+
defaultConfig?: FeishuGroupConfig;
|
|
89
|
+
accountFeishuCfg?: FeishuConfig;
|
|
90
|
+
senderGroupAllowFrom: Array<string | number>;
|
|
91
|
+
}): {
|
|
92
|
+
senderPolicy: 'open' | 'allowlist' | 'disabled';
|
|
93
|
+
senderAllowFrom: Array<string | number>;
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../../../src/messaging/inbound/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACtF,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAOxE,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,UAAU,GAAG,IAAI,GAAG,MAAM,CAAC;CAC1C;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IAClD,SAAS,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,GAAG,oBAAoB,CAyBvB;AAMD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE;IAC/C,GAAG,CAAC,EAAE,YAAY,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GAAG,iBAAiB,GAAG,SAAS,CAiBhC;AAMD;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,mBAAmB,GAAG,qBAAqB,GAAG,SAAS,CAe3G;AAMD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAC3C,WAAW,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,CAAC;IAC/C,SAAS,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,GAAG,OAAO,CAUV;AAMD;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CAAC,iBAAiB,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG;IACpF,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B,CAYA;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,+BAA+B,CAAC,MAAM,EAAE;IACtD,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,gBAAgB,CAAC,EAAE,YAAY,CAAC;IAChC,oBAAoB,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;CAC9C,GAAG;IACF,YAAY,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,CAAC;IAChD,eAAe,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;CACzC,CAaA"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
5
|
+
* Access control policies for the Feishu/Lark channel plugin.
|
|
6
|
+
*
|
|
7
|
+
* Provides allowlist matching, group configuration lookup, tool policy
|
|
8
|
+
* extraction, and group access checks.
|
|
9
|
+
*/
|
|
10
|
+
import { getLarkAccount } from '../../core/accounts';
|
|
11
|
+
/**
|
|
12
|
+
* Check whether a sender is permitted by a given allowlist.
|
|
13
|
+
*
|
|
14
|
+
* Entries are normalised to lowercase strings before comparison.
|
|
15
|
+
* A single "*" entry acts as a wildcard that matches everyone.
|
|
16
|
+
* When the allowlist is empty the result is `{ allowed: false }`.
|
|
17
|
+
*/
|
|
18
|
+
export function resolveFeishuAllowlistMatch(params) {
|
|
19
|
+
const allowFrom = params.allowFrom.map((entry) => String(entry).trim().toLowerCase()).filter(Boolean);
|
|
20
|
+
if (allowFrom.length === 0) {
|
|
21
|
+
return { allowed: false };
|
|
22
|
+
}
|
|
23
|
+
// Wildcard: allow everyone
|
|
24
|
+
if (allowFrom.includes('*')) {
|
|
25
|
+
return { allowed: true, matchKey: '*', matchSource: 'wildcard' };
|
|
26
|
+
}
|
|
27
|
+
// Match by sender ID
|
|
28
|
+
const senderId = params.senderId.toLowerCase();
|
|
29
|
+
if (allowFrom.includes(senderId)) {
|
|
30
|
+
return { allowed: true, matchKey: senderId, matchSource: 'id' };
|
|
31
|
+
}
|
|
32
|
+
/* // Match by sender display name
|
|
33
|
+
const senderName = params.senderName?.toLowerCase();
|
|
34
|
+
if (senderName && allowFrom.includes(senderName)) {
|
|
35
|
+
return { allowed: true, matchKey: senderName, matchSource: 'name' };
|
|
36
|
+
}*/
|
|
37
|
+
return { allowed: false };
|
|
38
|
+
}
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Group configuration lookup
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
/**
|
|
43
|
+
* Look up the per-group configuration by group ID.
|
|
44
|
+
*
|
|
45
|
+
* Performs a case-insensitive lookup against the keys in `cfg.groups`.
|
|
46
|
+
* Returns `undefined` when no matching group entry is found.
|
|
47
|
+
*/
|
|
48
|
+
export function resolveFeishuGroupConfig(params) {
|
|
49
|
+
const groups = params.cfg?.groups ?? {};
|
|
50
|
+
const groupId = params.groupId?.trim();
|
|
51
|
+
if (!groupId) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
// Direct (exact-key) lookup first
|
|
55
|
+
const direct = groups[groupId];
|
|
56
|
+
if (direct) {
|
|
57
|
+
return direct;
|
|
58
|
+
}
|
|
59
|
+
// Case-insensitive fallback
|
|
60
|
+
const lowered = groupId.toLowerCase();
|
|
61
|
+
const matchKey = Object.keys(groups).find((key) => key.toLowerCase() === lowered);
|
|
62
|
+
return matchKey ? groups[matchKey] : undefined;
|
|
63
|
+
}
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// Group tool policy
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
/**
|
|
68
|
+
* Extract the tool policy configuration from the group config that
|
|
69
|
+
* corresponds to the given group context.
|
|
70
|
+
*
|
|
71
|
+
* ★ 多账号配置隔离:SDK 回调传入的 params.cfg 是顶层全局配置,
|
|
72
|
+
* cfg.channels.feishu 不包含 per-account 的覆盖值。
|
|
73
|
+
* 这里通过 getLarkAccount() 获取当前 account 合并后的配置,
|
|
74
|
+
* 确保每个账号的 groups / tool policy 配置独立生效。
|
|
75
|
+
*/
|
|
76
|
+
export function resolveFeishuGroupToolPolicy(params) {
|
|
77
|
+
// 使用 getLarkAccount 获取 per-account 合并后的飞书渠道配置,
|
|
78
|
+
// 而非直接读取 cfg.channels.feishu(顶层全局配置)。
|
|
79
|
+
const account = getLarkAccount(params.cfg, params.accountId ?? undefined);
|
|
80
|
+
const accountFeishuCfg = account.config;
|
|
81
|
+
if (!accountFeishuCfg) {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
const groupConfig = resolveFeishuGroupConfig({
|
|
85
|
+
cfg: accountFeishuCfg,
|
|
86
|
+
groupId: params.groupId,
|
|
87
|
+
});
|
|
88
|
+
return groupConfig?.tools;
|
|
89
|
+
}
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
// Group access gate
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
/**
|
|
94
|
+
* Determine whether an inbound group message should be processed.
|
|
95
|
+
*
|
|
96
|
+
* - `disabled` --> always rejected
|
|
97
|
+
* - `open` --> always allowed
|
|
98
|
+
* - `allowlist` --> allowed only when the sender matches the allowlist
|
|
99
|
+
*/
|
|
100
|
+
export function isFeishuGroupAllowed(params) {
|
|
101
|
+
const { groupPolicy } = params;
|
|
102
|
+
if (groupPolicy === 'disabled') {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
if (groupPolicy === 'open') {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
// allowlist
|
|
109
|
+
return resolveFeishuAllowlistMatch(params).allowed;
|
|
110
|
+
}
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
// Legacy compat: groupAllowFrom splitting
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
/**
|
|
115
|
+
* Split a raw `groupAllowFrom` array into legacy chat-ID entries
|
|
116
|
+
* (`oc_xxx`) and sender-level entries.
|
|
117
|
+
*
|
|
118
|
+
* Older Feishu configs used `groupAllowFrom` with `oc_xxx` chat IDs to
|
|
119
|
+
* control which groups are allowed. The correct semantic (aligned with
|
|
120
|
+
* Telegram) is sender IDs. This function separates the two concerns so
|
|
121
|
+
* both layers can work independently.
|
|
122
|
+
*/
|
|
123
|
+
export function splitLegacyGroupAllowFrom(rawGroupAllowFrom) {
|
|
124
|
+
const legacyChatIds = [];
|
|
125
|
+
const senderAllowFrom = [];
|
|
126
|
+
for (const entry of rawGroupAllowFrom) {
|
|
127
|
+
const str = String(entry);
|
|
128
|
+
if (str.startsWith('oc_')) {
|
|
129
|
+
legacyChatIds.push(str);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
senderAllowFrom.push(str);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return { legacyChatIds, senderAllowFrom };
|
|
136
|
+
}
|
|
137
|
+
// ---------------------------------------------------------------------------
|
|
138
|
+
// Sender policy context resolution
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
/**
|
|
141
|
+
* Resolve the effective sender-level group policy and the merged
|
|
142
|
+
* `allowFrom` list for sender filtering within a group.
|
|
143
|
+
*
|
|
144
|
+
* The precedence chain for `senderPolicy` is:
|
|
145
|
+
* per-group `groupPolicy` > default ("*") group `groupPolicy` >
|
|
146
|
+
* global `groupPolicy` > "open" (default).
|
|
147
|
+
*
|
|
148
|
+
* The `senderAllowFrom` is the union of global (non-oc_) entries,
|
|
149
|
+
* per-group entries, and default ("*") entries (when no per-group config).
|
|
150
|
+
*/
|
|
151
|
+
export function resolveGroupSenderPolicyContext(params) {
|
|
152
|
+
const { groupConfig, defaultConfig, accountFeishuCfg, senderGroupAllowFrom } = params;
|
|
153
|
+
const senderPolicy = groupConfig?.groupPolicy ?? defaultConfig?.groupPolicy ?? accountFeishuCfg?.groupPolicy ?? 'open';
|
|
154
|
+
const senderAllowFrom = [
|
|
155
|
+
...senderGroupAllowFrom,
|
|
156
|
+
...(groupConfig?.allowFrom ?? []),
|
|
157
|
+
...(!groupConfig && defaultConfig?.allowFrom ? defaultConfig.allowFrom : []),
|
|
158
|
+
];
|
|
159
|
+
return { senderPolicy, senderAllowFrom };
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../../../src/messaging/inbound/policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
5
|
+
* Reaction event handler for the Feishu/Lark channel plugin.
|
|
6
|
+
*
|
|
7
|
+
* Handles `im.message.reaction.created_v1` events by building a
|
|
8
|
+
* {@link MessageContext} directly and dispatching to the agent via
|
|
9
|
+
* {@link dispatchToAgent}, bypassing the full 7-stage message pipeline.
|
|
10
|
+
*
|
|
11
|
+
* Controlled by `reactionNotifications` (default: "own"):
|
|
12
|
+
* - `"off"` — reaction events are silently ignored.
|
|
13
|
+
* - `"own"` — only reactions on the bot's own messages are dispatched.
|
|
14
|
+
* - `"all"` — reactions on any message in the chat are dispatched.
|
|
15
|
+
*/
|
|
16
|
+
import type { ClawdbotConfig, RuntimeEnv, HistoryEntry } from 'openclaw/plugin-sdk';
|
|
17
|
+
import type { FeishuReactionCreatedEvent } from '../types';
|
|
18
|
+
import { type FeishuMessageInfo } from '../shared/message-lookup';
|
|
19
|
+
export interface ReactionContext {
|
|
20
|
+
/** Real chatId (from message API, or `p2p:${operatorOpenId}` fallback). */
|
|
21
|
+
chatId: string;
|
|
22
|
+
/** Resolved chat type. */
|
|
23
|
+
chatType: 'p2p' | 'group';
|
|
24
|
+
/** Thread ID from the fetched message, if any. */
|
|
25
|
+
threadId?: string;
|
|
26
|
+
/** Whether the chat is thread-capable (topic or thread-mode group). */
|
|
27
|
+
threadCapable?: boolean;
|
|
28
|
+
/** Fetched message info used to build the synthetic event. */
|
|
29
|
+
msg: FeishuMessageInfo;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Pre-resolve reaction context before enqueuing.
|
|
33
|
+
*
|
|
34
|
+
* Performs account config checks, safety filters, API fetch of the
|
|
35
|
+
* original message, ownership verification, chat type resolution, and
|
|
36
|
+
* thread-capable detection. Returns `null` when the reaction should
|
|
37
|
+
* be skipped (mode off, safety filter, timeout, ownership mismatch,
|
|
38
|
+
* thread-capable group with threadSession enabled).
|
|
39
|
+
*
|
|
40
|
+
* This function is intentionally separated so that the caller
|
|
41
|
+
* (event-handlers.ts) can resolve the real chatId *before* enqueuing,
|
|
42
|
+
* ensuring the reaction shares the same queue key as normal messages
|
|
43
|
+
* for the same chat.
|
|
44
|
+
*/
|
|
45
|
+
export declare function resolveReactionContext(params: {
|
|
46
|
+
cfg: ClawdbotConfig;
|
|
47
|
+
event: FeishuReactionCreatedEvent;
|
|
48
|
+
botOpenId?: string;
|
|
49
|
+
runtime?: RuntimeEnv;
|
|
50
|
+
accountId?: string;
|
|
51
|
+
}): Promise<ReactionContext | null>;
|
|
52
|
+
export declare function handleFeishuReaction(params: {
|
|
53
|
+
cfg: ClawdbotConfig;
|
|
54
|
+
event: FeishuReactionCreatedEvent;
|
|
55
|
+
botOpenId?: string;
|
|
56
|
+
runtime?: RuntimeEnv;
|
|
57
|
+
chatHistories?: Map<string, HistoryEntry[]>;
|
|
58
|
+
accountId?: string;
|
|
59
|
+
/** Pre-resolved context from resolveReactionContext(). */
|
|
60
|
+
preResolved: ReactionContext;
|
|
61
|
+
}): Promise<void>;
|
|
62
|
+
//# sourceMappingURL=reaction-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reaction-handler.d.ts","sourceRoot":"","sources":["../../../../src/messaging/inbound/reaction-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEpF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;AAG3D,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAepF,MAAM,WAAW,eAAe;IAC9B,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,QAAQ,EAAE,KAAK,GAAG,OAAO,CAAC;IAC1B,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,8DAA8D;IAC9D,GAAG,EAAE,iBAAiB,CAAC;CACxB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,sBAAsB,CAAC,MAAM,EAAE;IACnD,GAAG,EAAE,cAAc,CAAC;IACpB,KAAK,EAAE,0BAA0B,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CA8GlC;AAMD,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,GAAG,EAAE,cAAc,CAAC;IACpB,KAAK,EAAE,0BAA0B,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,WAAW,EAAE,eAAe,CAAC;CAC9B,GAAG,OAAO,CAAC,IAAI,CAAC,CAgGhB"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
5
|
+
* Reaction event handler for the Feishu/Lark channel plugin.
|
|
6
|
+
*
|
|
7
|
+
* Handles `im.message.reaction.created_v1` events by building a
|
|
8
|
+
* {@link MessageContext} directly and dispatching to the agent via
|
|
9
|
+
* {@link dispatchToAgent}, bypassing the full 7-stage message pipeline.
|
|
10
|
+
*
|
|
11
|
+
* Controlled by `reactionNotifications` (default: "own"):
|
|
12
|
+
* - `"off"` — reaction events are silently ignored.
|
|
13
|
+
* - `"own"` — only reactions on the bot's own messages are dispatched.
|
|
14
|
+
* - `"all"` — reactions on any message in the chat are dispatched.
|
|
15
|
+
*/
|
|
16
|
+
import * as crypto from 'node:crypto';
|
|
17
|
+
import { DEFAULT_GROUP_HISTORY_LIMIT } from 'openclaw/plugin-sdk';
|
|
18
|
+
import { getLarkAccount } from '../../core/accounts';
|
|
19
|
+
import { getMessageFeishu } from '../shared/message-lookup';
|
|
20
|
+
import { isThreadCapableGroup, getChatTypeFeishu } from '../../core/chat-info-cache';
|
|
21
|
+
import { resolveUserName } from './user-name-cache';
|
|
22
|
+
import { dispatchToAgent } from './dispatch';
|
|
23
|
+
import { resolveFeishuGroupConfig } from './policy';
|
|
24
|
+
import { larkLogger } from '../../core/lark-logger';
|
|
25
|
+
const logger = larkLogger('inbound/reaction-handler');
|
|
26
|
+
const REACTION_VERIFY_TIMEOUT_MS = 3_000;
|
|
27
|
+
/**
|
|
28
|
+
* Pre-resolve reaction context before enqueuing.
|
|
29
|
+
*
|
|
30
|
+
* Performs account config checks, safety filters, API fetch of the
|
|
31
|
+
* original message, ownership verification, chat type resolution, and
|
|
32
|
+
* thread-capable detection. Returns `null` when the reaction should
|
|
33
|
+
* be skipped (mode off, safety filter, timeout, ownership mismatch,
|
|
34
|
+
* thread-capable group with threadSession enabled).
|
|
35
|
+
*
|
|
36
|
+
* This function is intentionally separated so that the caller
|
|
37
|
+
* (event-handlers.ts) can resolve the real chatId *before* enqueuing,
|
|
38
|
+
* ensuring the reaction shares the same queue key as normal messages
|
|
39
|
+
* for the same chat.
|
|
40
|
+
*/
|
|
41
|
+
export async function resolveReactionContext(params) {
|
|
42
|
+
const { cfg, event, botOpenId, runtime, accountId } = params;
|
|
43
|
+
const log = runtime?.log ?? ((...args) => logger.info(args.map(String).join(' ')));
|
|
44
|
+
const account = getLarkAccount(cfg, accountId);
|
|
45
|
+
const reactionMode = account.config?.reactionNotifications ?? 'own';
|
|
46
|
+
if (reactionMode === 'off') {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const emojiType = event.reaction_type?.emoji_type;
|
|
50
|
+
const messageId = event.message_id;
|
|
51
|
+
const operatorOpenId = event.user_id?.open_id ?? '';
|
|
52
|
+
if (!emojiType || !messageId || !operatorOpenId) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
// ---- Safety filters (aligned with official) ----
|
|
56
|
+
if (event.operator_type === 'app' || operatorOpenId === botOpenId) {
|
|
57
|
+
log(`feishu[${accountId}]: ignoring app/self reaction on ${messageId}`);
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
if (emojiType === 'Typing') {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
// "own" mode requires botOpenId to verify message ownership
|
|
64
|
+
if (reactionMode === 'own' && !botOpenId) {
|
|
65
|
+
log(`feishu[${accountId}]: bot open_id unavailable, skipping reaction on ${messageId}`);
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
// ---- Fetch original message with timeout (fail-closed) ----
|
|
69
|
+
const msg = await Promise.race([
|
|
70
|
+
getMessageFeishu({ cfg, messageId, accountId }),
|
|
71
|
+
new Promise((resolve) => setTimeout(() => resolve(null), REACTION_VERIFY_TIMEOUT_MS)),
|
|
72
|
+
]).catch(() => null);
|
|
73
|
+
if (!msg) {
|
|
74
|
+
log(`feishu[${accountId}]: reacted message ${messageId} not found or timed out, skipping`);
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
// The mget API returns app_id (cli_xxx) as sender.id for bot messages,
|
|
78
|
+
// not the bot's open_id (ou_xxx). Match against the account's appId.
|
|
79
|
+
const isBotMessage = msg.senderType === 'app' && msg.senderId === account.appId;
|
|
80
|
+
if (reactionMode === 'own' && !isBotMessage) {
|
|
81
|
+
log(`feishu[${accountId}]: reaction on non-bot message ${messageId}, skipping (senderId=${msg.senderId}, senderType=${msg.senderType}, botOpenId=${botOpenId}, appId=${account.appId})`);
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
// ---- Resolve effective chatId ----
|
|
85
|
+
const rawChatId = event.chat_id?.trim() || msg.chatId?.trim() || '';
|
|
86
|
+
const effectiveChatId = rawChatId || `p2p:${operatorOpenId}`;
|
|
87
|
+
// ---- Resolve chat type ----
|
|
88
|
+
// im.message.reaction.created_v1 does NOT include chat_id or chat_type
|
|
89
|
+
// (confirmed from Feishu docs). The message GET API returns chat_id but
|
|
90
|
+
// NOT chat_type. So we must determine chat_type via im.chat.get.
|
|
91
|
+
//
|
|
92
|
+
// Determine chat type: event payload → fetched message → im.chat.get API.
|
|
93
|
+
// The first two sources are almost always empty for reaction events, so
|
|
94
|
+
// getChatTypeFeishu is the primary path.
|
|
95
|
+
let chatType = event.chat_type === 'group'
|
|
96
|
+
? 'group'
|
|
97
|
+
: event.chat_type === 'p2p' || event.chat_type === 'private'
|
|
98
|
+
? 'p2p'
|
|
99
|
+
: msg.chatType === 'group' || msg.chatType === 'p2p'
|
|
100
|
+
? msg.chatType
|
|
101
|
+
: 'p2p'; // tentative default, overridden below when chatId is available
|
|
102
|
+
// When we have a real chat_id (from event or message API), query the
|
|
103
|
+
// authoritative chat type via im.chat.get. This is the only reliable
|
|
104
|
+
// source for reaction events.
|
|
105
|
+
if (rawChatId && chatType === 'p2p' && !event.chat_type && !msg.chatType) {
|
|
106
|
+
try {
|
|
107
|
+
chatType = await getChatTypeFeishu({ cfg, chatId: rawChatId, accountId });
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// getChatTypeFeishu already logs errors and defaults to "p2p"
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// ---- Thread session: skip for thread-capable groups ----
|
|
114
|
+
// The mget API does not return thread_id, so we cannot route the
|
|
115
|
+
// synthetic event to the correct thread session. Skip reaction handling
|
|
116
|
+
// only for thread-capable groups (topic / thread-mode); p2p and regular
|
|
117
|
+
// groups are unaffected since they have no threads.
|
|
118
|
+
let threadCapable = false;
|
|
119
|
+
const threadSessionEnabled = account.config?.threadSession === true;
|
|
120
|
+
if (rawChatId && chatType === 'group') {
|
|
121
|
+
threadCapable = await isThreadCapableGroup({ cfg, chatId: rawChatId, accountId });
|
|
122
|
+
if (threadSessionEnabled && threadCapable) {
|
|
123
|
+
log(`feishu[${accountId}]: reaction on thread-capable group ${rawChatId}, skipping (threadSession enabled)`);
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
chatId: effectiveChatId,
|
|
129
|
+
chatType,
|
|
130
|
+
threadId: msg.threadId,
|
|
131
|
+
threadCapable,
|
|
132
|
+
msg,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
// Public API
|
|
137
|
+
// ---------------------------------------------------------------------------
|
|
138
|
+
export async function handleFeishuReaction(params) {
|
|
139
|
+
const { cfg, event, runtime, chatHistories, accountId, preResolved } = params;
|
|
140
|
+
const log = runtime?.log ?? ((...args) => logger.info(args.map(String).join(' ')));
|
|
141
|
+
const error = runtime?.error ?? ((...args) => logger.error(args.map(String).join(' ')));
|
|
142
|
+
const emojiType = event.reaction_type?.emoji_type;
|
|
143
|
+
const messageId = event.message_id;
|
|
144
|
+
const operatorOpenId = event.user_id?.open_id ?? '';
|
|
145
|
+
// ---- Step A: Account resolution + accountScopedCfg ----
|
|
146
|
+
const account = getLarkAccount(cfg, accountId);
|
|
147
|
+
const accountFeishuCfg = account.config;
|
|
148
|
+
const accountScopedCfg = {
|
|
149
|
+
...cfg,
|
|
150
|
+
channels: { ...cfg.channels, feishu: accountFeishuCfg },
|
|
151
|
+
};
|
|
152
|
+
// ---- Step B: Build MessageContext directly ----
|
|
153
|
+
const excerpt = preResolved.msg.content.length > 200 ? preResolved.msg.content.slice(0, 200) + '…' : preResolved.msg.content;
|
|
154
|
+
const syntheticText = excerpt
|
|
155
|
+
? `[reacted with ${emojiType} to message ${messageId}: "${excerpt}"]`
|
|
156
|
+
: `[reacted with ${emojiType} to message ${messageId}]`;
|
|
157
|
+
const syntheticMessageId = `${messageId}:reaction:${emojiType}:${crypto.randomUUID()}`;
|
|
158
|
+
let ctx = {
|
|
159
|
+
chatId: preResolved.chatId,
|
|
160
|
+
messageId: syntheticMessageId,
|
|
161
|
+
senderId: operatorOpenId,
|
|
162
|
+
chatType: preResolved.chatType,
|
|
163
|
+
content: syntheticText,
|
|
164
|
+
contentType: 'text',
|
|
165
|
+
resources: [],
|
|
166
|
+
mentions: [],
|
|
167
|
+
threadId: preResolved.threadId,
|
|
168
|
+
rawMessage: {
|
|
169
|
+
message_id: syntheticMessageId,
|
|
170
|
+
chat_id: preResolved.chatId,
|
|
171
|
+
chat_type: preResolved.chatType,
|
|
172
|
+
message_type: 'text',
|
|
173
|
+
content: JSON.stringify({ text: syntheticText }),
|
|
174
|
+
create_time: event.action_time ?? String(Date.now()),
|
|
175
|
+
thread_id: preResolved.threadId,
|
|
176
|
+
},
|
|
177
|
+
rawSender: {
|
|
178
|
+
sender_id: {
|
|
179
|
+
open_id: operatorOpenId,
|
|
180
|
+
user_id: event.user_id?.user_id,
|
|
181
|
+
union_id: event.user_id?.union_id,
|
|
182
|
+
},
|
|
183
|
+
sender_type: 'user',
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
// ---- Step C: Sender name resolution ----
|
|
187
|
+
const senderResult = await resolveUserName({ account, openId: operatorOpenId, log });
|
|
188
|
+
if (senderResult.name) {
|
|
189
|
+
ctx = { ...ctx, senderName: senderResult.name };
|
|
190
|
+
}
|
|
191
|
+
log(`feishu[${accountId}]: reaction "${emojiType}" by ${operatorOpenId} on ${messageId} (chatId=${preResolved.chatId}, chatType=${preResolved.chatType}${preResolved.threadId ? `, thread=${preResolved.threadId}` : ''}), dispatching to AI`);
|
|
192
|
+
logger.info(`reaction "${emojiType}" by ${operatorOpenId} on ${messageId} (chatType=${preResolved.chatType})`);
|
|
193
|
+
// ---- Step D: Group config resolution ----
|
|
194
|
+
const isGroup = ctx.chatType === 'group';
|
|
195
|
+
const groupConfig = isGroup ? resolveFeishuGroupConfig({ cfg: accountFeishuCfg, groupId: ctx.chatId }) : undefined;
|
|
196
|
+
const defaultGroupConfig = isGroup ? accountFeishuCfg?.groups?.['*'] : undefined;
|
|
197
|
+
const historyLimit = Math.max(0, accountFeishuCfg?.historyLimit ?? accountScopedCfg.messages?.groupChat?.historyLimit ?? DEFAULT_GROUP_HISTORY_LIMIT);
|
|
198
|
+
// ---- Step E: Dispatch directly to agent ----
|
|
199
|
+
try {
|
|
200
|
+
await dispatchToAgent({
|
|
201
|
+
ctx,
|
|
202
|
+
permissionError: undefined,
|
|
203
|
+
mediaPayload: {},
|
|
204
|
+
quotedContent: undefined,
|
|
205
|
+
account,
|
|
206
|
+
accountScopedCfg,
|
|
207
|
+
runtime,
|
|
208
|
+
chatHistories,
|
|
209
|
+
historyLimit,
|
|
210
|
+
replyToMessageId: messageId,
|
|
211
|
+
commandAuthorized: false,
|
|
212
|
+
groupConfig,
|
|
213
|
+
defaultGroupConfig,
|
|
214
|
+
skipTyping: true,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
catch (err) {
|
|
218
|
+
error(`feishu[${accountId}]: error dispatching reaction event: ${String(err)}`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=reaction-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reaction-handler.js","sourceRoot":"","sources":["../../../../src/messaging/inbound/reaction-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
5
|
+
* Account-scoped LRU cache for Feishu user display names.
|
|
6
|
+
*
|
|
7
|
+
* Provides:
|
|
8
|
+
* - `UserNameCache` — per-account LRU Map with TTL
|
|
9
|
+
* - `getUserNameCache(accountId)` — singleton registry
|
|
10
|
+
* - `batchResolveUserNames()` — batch API via `contact/v3/users/batch`
|
|
11
|
+
* - `resolveUserName()` — single-user fallback via `contact.user.get`
|
|
12
|
+
* - `clearUserNameCache()` — teardown hook (called from LarkClient.clearCache)
|
|
13
|
+
*/
|
|
14
|
+
import type { LarkAccount } from '../../core/types';
|
|
15
|
+
import { type PermissionError } from './permission';
|
|
16
|
+
export declare class UserNameCache {
|
|
17
|
+
private map;
|
|
18
|
+
private maxSize;
|
|
19
|
+
private ttlMs;
|
|
20
|
+
constructor(maxSize?: number, ttlMs?: number);
|
|
21
|
+
/** Check whether the cache holds a (possibly empty) entry for this openId. */
|
|
22
|
+
has(openId: string): boolean;
|
|
23
|
+
/** Get a cached name (refreshes LRU position). Returns `undefined` on miss or expiry. */
|
|
24
|
+
get(openId: string): string | undefined;
|
|
25
|
+
/** Write a single entry (evicts oldest if over capacity). */
|
|
26
|
+
set(openId: string, name: string): void;
|
|
27
|
+
/** Write multiple entries at once. */
|
|
28
|
+
setMany(entries: Iterable<[string, string]>): void;
|
|
29
|
+
/** Return openIds that are NOT present (or expired) in the cache. */
|
|
30
|
+
filterMissing(openIds: string[]): string[];
|
|
31
|
+
/** Bulk read — returns a Map of openId→name for all hits (including empty-string names). */
|
|
32
|
+
getMany(openIds: string[]): Map<string, string>;
|
|
33
|
+
/** Clear all entries. */
|
|
34
|
+
clear(): void;
|
|
35
|
+
private evict;
|
|
36
|
+
}
|
|
37
|
+
/** Get (or create) the UserNameCache for a given account. */
|
|
38
|
+
export declare function getUserNameCache(accountId: string): UserNameCache;
|
|
39
|
+
/**
|
|
40
|
+
* Clear user-name caches.
|
|
41
|
+
* - With `accountId`: clear that single cache.
|
|
42
|
+
* - Without: clear all caches.
|
|
43
|
+
*/
|
|
44
|
+
export declare function clearUserNameCache(accountId?: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* Batch-resolve user display names.
|
|
47
|
+
*
|
|
48
|
+
* 1. Check cache → collect misses
|
|
49
|
+
* 2. Deduplicate
|
|
50
|
+
* 3. Call `GET /open-apis/contact/v3/users/batch` in chunks of 50
|
|
51
|
+
* 4. Write results back to cache
|
|
52
|
+
* 5. Return full Map<openId, name> (cache hits + API results)
|
|
53
|
+
*
|
|
54
|
+
* Best-effort: API errors are logged but never thrown.
|
|
55
|
+
*/
|
|
56
|
+
export declare function batchResolveUserNames(params: {
|
|
57
|
+
account: LarkAccount;
|
|
58
|
+
openIds: string[];
|
|
59
|
+
log: (...args: unknown[]) => void;
|
|
60
|
+
}): Promise<Map<string, string>>;
|
|
61
|
+
/**
|
|
62
|
+
* Create a `batchResolveNames` callback for use in `ConvertContext`.
|
|
63
|
+
*
|
|
64
|
+
* The returned function calls `batchResolveUserNames` with the given
|
|
65
|
+
* account and log function, populating the TAT user-name cache.
|
|
66
|
+
*/
|
|
67
|
+
export declare function createBatchResolveNames(account: LarkAccount, log: (...args: unknown[]) => void): (openIds: string[]) => Promise<void>;
|
|
68
|
+
export interface ResolveUserNameResult {
|
|
69
|
+
name?: string;
|
|
70
|
+
permissionError?: PermissionError;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Resolve a single user's display name.
|
|
74
|
+
*
|
|
75
|
+
* Checks the account-scoped cache first, then falls back to the
|
|
76
|
+
* `contact.user.get` API (same as the old `resolveFeishuSenderName`).
|
|
77
|
+
*/
|
|
78
|
+
export declare function resolveUserName(params: {
|
|
79
|
+
account: LarkAccount;
|
|
80
|
+
openId: string;
|
|
81
|
+
log: (...args: unknown[]) => void;
|
|
82
|
+
}): Promise<ResolveUserNameResult>;
|
|
83
|
+
//# sourceMappingURL=user-name-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-name-cache.d.ts","sourceRoot":"","sources":["../../../../src/messaging/inbound/user-name-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,EAA0B,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAc5E,qBAAa,aAAa;IACxB,OAAO,CAAC,GAAG,CAAiC;IAC5C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;gBAEV,OAAO,SAAmB,EAAE,KAAK,SAAiB;IAK9D,8EAA8E;IAC9E,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAU5B,yFAAyF;IACzF,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAavC,6DAA6D;IAC7D,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAMvC,sCAAsC;IACtC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI;IAQlD,qEAAqE;IACrE,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE;IAI1C,4FAA4F;IAC5F,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAU/C,yBAAyB;IACzB,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,KAAK;CAOd;AAQD,6DAA6D;AAC7D,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,CAOjE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAQ3D;AASD;;;;;;;;;;GAUG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE;IAClD,OAAO,EAAE,WAAW,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACnC,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAmD/B;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,WAAW,EACpB,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAChC,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAItC;AAMD,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE;IAC5C,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACnC,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAqCjC"}
|