@colinlu50/openclaw-lark-stream 2026.3.17
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 +141 -0
- package/README.zh.md +70 -0
- package/bin/openclaw-lark.js +48 -0
- package/index.d.ts +36 -0
- package/index.js +118 -0
- package/openclaw.plugin.json +10 -0
- package/package.json +66 -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 +24 -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 +106 -0
- package/src/card/builder.js +443 -0
- package/src/card/cardkit.d.ts +90 -0
- package/src/card/cardkit.js +181 -0
- package/src/card/flush-controller.d.ts +45 -0
- package/src/card/flush-controller.js +134 -0
- package/src/card/image-resolver.d.ts +45 -0
- package/src/card/image-resolver.js +112 -0
- package/src/card/markdown-style.d.ts +16 -0
- package/src/card/markdown-style.js +97 -0
- package/src/card/reply-dispatcher-types.d.ts +120 -0
- package/src/card/reply-dispatcher-types.js +57 -0
- package/src/card/reply-dispatcher.d.ts +15 -0
- package/src/card/reply-dispatcher.js +299 -0
- package/src/card/reply-mode.d.ts +38 -0
- package/src/card/reply-mode.js +65 -0
- package/src/card/streaming-card-controller.d.ts +101 -0
- package/src/card/streaming-card-controller.js +810 -0
- package/src/card/unavailable-guard.d.ts +35 -0
- package/src/card/unavailable-guard.js +83 -0
- package/src/channel/abort-detect.d.ts +34 -0
- package/src/channel/abort-detect.js +124 -0
- package/src/channel/chat-queue.d.ts +41 -0
- package/src/channel/chat-queue.js +58 -0
- package/src/channel/config-adapter.d.ts +23 -0
- package/src/channel/config-adapter.js +101 -0
- package/src/channel/directory.d.ts +57 -0
- package/src/channel/directory.js +191 -0
- package/src/channel/event-handlers.d.ts +15 -0
- package/src/channel/event-handlers.js +221 -0
- package/src/channel/monitor.d.ts +17 -0
- package/src/channel/monitor.js +129 -0
- package/src/channel/onboarding-config.d.ts +17 -0
- package/src/channel/onboarding-config.js +88 -0
- package/src/channel/onboarding-migrate.d.ts +25 -0
- package/src/channel/onboarding-migrate.js +67 -0
- package/src/channel/onboarding.d.ts +12 -0
- package/src/channel/onboarding.js +296 -0
- package/src/channel/plugin.d.ts +13 -0
- package/src/channel/plugin.js +278 -0
- package/src/channel/probe.d.ts +14 -0
- package/src/channel/probe.js +21 -0
- package/src/channel/types.d.ts +36 -0
- package/src/channel/types.js +7 -0
- package/src/commands/auth.d.ts +21 -0
- package/src/commands/auth.js +161 -0
- package/src/commands/diagnose.d.ts +69 -0
- package/src/commands/diagnose.js +807 -0
- package/src/commands/doctor.d.ts +26 -0
- package/src/commands/doctor.js +584 -0
- package/src/commands/index.d.ts +25 -0
- package/src/commands/index.js +212 -0
- package/src/commands/locale.d.ts +7 -0
- package/src/commands/locale.js +7 -0
- package/src/core/accounts.d.ts +37 -0
- package/src/core/accounts.js +163 -0
- package/src/core/agent-config.d.ts +100 -0
- package/src/core/agent-config.js +139 -0
- package/src/core/api-error.d.ts +48 -0
- package/src/core/api-error.js +112 -0
- package/src/core/app-owner-fallback.d.ts +21 -0
- package/src/core/app-owner-fallback.js +38 -0
- package/src/core/app-scope-checker.d.ts +87 -0
- package/src/core/app-scope-checker.js +190 -0
- package/src/core/auth-errors.d.ts +144 -0
- package/src/core/auth-errors.js +154 -0
- package/src/core/chat-info-cache.d.ts +57 -0
- package/src/core/chat-info-cache.js +152 -0
- package/src/core/config-schema.d.ts +448 -0
- package/src/core/config-schema.js +200 -0
- package/src/core/device-flow.d.ts +77 -0
- package/src/core/device-flow.js +212 -0
- package/src/core/domains.d.ts +18 -0
- package/src/core/domains.js +28 -0
- package/src/core/feishu-fetch.d.ts +18 -0
- package/src/core/feishu-fetch.js +25 -0
- package/src/core/footer-config.d.ts +24 -0
- package/src/core/footer-config.js +39 -0
- package/src/core/lark-client.d.ts +108 -0
- package/src/core/lark-client.js +353 -0
- package/src/core/lark-logger.d.ts +23 -0
- package/src/core/lark-logger.js +154 -0
- package/src/core/lark-ticket.d.ts +29 -0
- package/src/core/lark-ticket.js +35 -0
- package/src/core/message-unavailable.d.ts +53 -0
- package/src/core/message-unavailable.js +130 -0
- package/src/core/owner-policy.d.ts +31 -0
- package/src/core/owner-policy.js +52 -0
- package/src/core/permission-url.d.ts +22 -0
- package/src/core/permission-url.js +72 -0
- package/src/core/raw-request.d.ts +27 -0
- package/src/core/raw-request.js +62 -0
- package/src/core/scope-manager.d.ts +168 -0
- package/src/core/scope-manager.js +213 -0
- package/src/core/security-check.d.ts +72 -0
- package/src/core/security-check.js +174 -0
- package/src/core/shutdown-hooks.d.ts +22 -0
- package/src/core/shutdown-hooks.js +56 -0
- package/src/core/targets.d.ts +60 -0
- package/src/core/targets.js +164 -0
- package/src/core/token-store.d.ts +54 -0
- package/src/core/token-store.js +314 -0
- package/src/core/tool-client.d.ts +176 -0
- package/src/core/tool-client.js +380 -0
- package/src/core/tool-scopes.d.ts +153 -0
- package/src/core/tool-scopes.js +326 -0
- package/src/core/tools-config.d.ts +55 -0
- package/src/core/tools-config.js +137 -0
- package/src/core/types.d.ts +87 -0
- package/src/core/types.js +11 -0
- package/src/core/uat-client.d.ts +46 -0
- package/src/core/uat-client.js +187 -0
- package/src/core/version.d.ts +25 -0
- package/src/core/version.js +49 -0
- package/src/messaging/converters/audio.d.ts +8 -0
- package/src/messaging/converters/audio.js +21 -0
- package/src/messaging/converters/calendar.d.ts +13 -0
- package/src/messaging/converters/calendar.js +50 -0
- package/src/messaging/converters/content-converter.d.ts +41 -0
- package/src/messaging/converters/content-converter.js +106 -0
- package/src/messaging/converters/file.d.ts +8 -0
- package/src/messaging/converters/file.js +20 -0
- package/src/messaging/converters/folder.d.ts +8 -0
- package/src/messaging/converters/folder.js +20 -0
- package/src/messaging/converters/hongbao.d.ts +8 -0
- package/src/messaging/converters/hongbao.js +16 -0
- package/src/messaging/converters/image.d.ts +8 -0
- package/src/messaging/converters/image.js +18 -0
- package/src/messaging/converters/index.d.ts +8 -0
- package/src/messaging/converters/index.js +50 -0
- package/src/messaging/converters/interactive/card-converter.d.ts +76 -0
- package/src/messaging/converters/interactive/card-converter.js +1173 -0
- package/src/messaging/converters/interactive/card-utils.d.ts +9 -0
- package/src/messaging/converters/interactive/card-utils.js +42 -0
- package/src/messaging/converters/interactive/index.d.ts +8 -0
- package/src/messaging/converters/interactive/index.js +21 -0
- package/src/messaging/converters/interactive/legacy.d.ts +11 -0
- package/src/messaging/converters/interactive/legacy.js +57 -0
- package/src/messaging/converters/interactive/types.d.ts +23 -0
- package/src/messaging/converters/interactive/types.js +24 -0
- package/src/messaging/converters/location.d.ts +8 -0
- package/src/messaging/converters/location.js +19 -0
- package/src/messaging/converters/merge-forward.d.ts +32 -0
- package/src/messaging/converters/merge-forward.js +225 -0
- package/src/messaging/converters/post.d.ts +11 -0
- package/src/messaging/converters/post.js +135 -0
- package/src/messaging/converters/share.d.ts +9 -0
- package/src/messaging/converters/share.js +23 -0
- package/src/messaging/converters/sticker.d.ts +8 -0
- package/src/messaging/converters/sticker.js +18 -0
- package/src/messaging/converters/system.d.ts +12 -0
- package/src/messaging/converters/system.js +32 -0
- package/src/messaging/converters/text.d.ts +8 -0
- package/src/messaging/converters/text.js +14 -0
- package/src/messaging/converters/todo.d.ts +8 -0
- package/src/messaging/converters/todo.js +41 -0
- package/src/messaging/converters/types.d.ts +107 -0
- package/src/messaging/converters/types.js +7 -0
- package/src/messaging/converters/unknown.d.ts +8 -0
- package/src/messaging/converters/unknown.js +16 -0
- package/src/messaging/converters/utils.d.ts +22 -0
- package/src/messaging/converters/utils.js +51 -0
- package/src/messaging/converters/video-chat.d.ts +8 -0
- package/src/messaging/converters/video-chat.js +23 -0
- package/src/messaging/converters/video.d.ts +8 -0
- package/src/messaging/converters/video.js +32 -0
- package/src/messaging/converters/vote.d.ts +8 -0
- package/src/messaging/converters/vote.js +24 -0
- package/src/messaging/inbound/dedup.d.ts +59 -0
- package/src/messaging/inbound/dedup.js +116 -0
- package/src/messaging/inbound/dispatch-builders.d.ts +84 -0
- package/src/messaging/inbound/dispatch-builders.js +152 -0
- package/src/messaging/inbound/dispatch-commands.d.ts +27 -0
- package/src/messaging/inbound/dispatch-commands.js +112 -0
- package/src/messaging/inbound/dispatch-context.d.ts +67 -0
- package/src/messaging/inbound/dispatch-context.js +136 -0
- package/src/messaging/inbound/dispatch.d.ts +47 -0
- package/src/messaging/inbound/dispatch.js +264 -0
- package/src/messaging/inbound/enrich.d.ts +102 -0
- package/src/messaging/inbound/enrich.js +227 -0
- package/src/messaging/inbound/gate-effects.d.ts +23 -0
- package/src/messaging/inbound/gate-effects.js +43 -0
- package/src/messaging/inbound/gate.d.ts +60 -0
- package/src/messaging/inbound/gate.js +233 -0
- package/src/messaging/inbound/handler.d.ts +35 -0
- package/src/messaging/inbound/handler.js +173 -0
- package/src/messaging/inbound/media-resolver.d.ts +32 -0
- package/src/messaging/inbound/media-resolver.js +87 -0
- package/src/messaging/inbound/mention.d.ts +39 -0
- package/src/messaging/inbound/mention.js +81 -0
- package/src/messaging/inbound/parse-io.d.ts +50 -0
- package/src/messaging/inbound/parse-io.js +81 -0
- package/src/messaging/inbound/parse.d.ts +28 -0
- package/src/messaging/inbound/parse.js +106 -0
- package/src/messaging/inbound/permission.d.ts +17 -0
- package/src/messaging/inbound/permission.js +40 -0
- package/src/messaging/inbound/policy.d.ts +94 -0
- package/src/messaging/inbound/policy.js +160 -0
- package/src/messaging/inbound/reaction-handler.d.ts +61 -0
- package/src/messaging/inbound/reaction-handler.js +221 -0
- package/src/messaging/inbound/user-name-cache.d.ts +82 -0
- package/src/messaging/inbound/user-name-cache.js +241 -0
- package/src/messaging/outbound/actions.d.ts +16 -0
- package/src/messaging/outbound/actions.js +309 -0
- package/src/messaging/outbound/chat-manage.d.ts +64 -0
- package/src/messaging/outbound/chat-manage.js +111 -0
- package/src/messaging/outbound/deliver.d.ts +155 -0
- package/src/messaging/outbound/deliver.js +298 -0
- package/src/messaging/outbound/fetch.d.ts +12 -0
- package/src/messaging/outbound/fetch.js +12 -0
- package/src/messaging/outbound/forward.d.ts +26 -0
- package/src/messaging/outbound/forward.js +48 -0
- package/src/messaging/outbound/media-url-utils.d.ts +29 -0
- package/src/messaging/outbound/media-url-utils.js +130 -0
- package/src/messaging/outbound/media.d.ts +260 -0
- package/src/messaging/outbound/media.js +758 -0
- package/src/messaging/outbound/outbound.d.ts +89 -0
- package/src/messaging/outbound/outbound.js +121 -0
- package/src/messaging/outbound/reactions.d.ts +124 -0
- package/src/messaging/outbound/reactions.js +378 -0
- package/src/messaging/outbound/send.d.ts +152 -0
- package/src/messaging/outbound/send.js +355 -0
- package/src/messaging/outbound/typing.d.ts +71 -0
- package/src/messaging/outbound/typing.js +179 -0
- package/src/messaging/shared/message-lookup.d.ts +54 -0
- package/src/messaging/shared/message-lookup.js +117 -0
- package/src/messaging/types.d.ts +176 -0
- package/src/messaging/types.js +10 -0
- package/src/tools/auto-auth.d.ts +56 -0
- package/src/tools/auto-auth.js +919 -0
- package/src/tools/helpers.d.ts +260 -0
- package/src/tools/helpers.js +364 -0
- package/src/tools/mcp/doc/create.d.ts +12 -0
- package/src/tools/mcp/doc/create.js +44 -0
- package/src/tools/mcp/doc/fetch.d.ts +12 -0
- package/src/tools/mcp/doc/fetch.js +36 -0
- package/src/tools/mcp/doc/index.d.ts +12 -0
- package/src/tools/mcp/doc/index.js +41 -0
- package/src/tools/mcp/doc/update.d.ts +12 -0
- package/src/tools/mcp/doc/update.js +61 -0
- package/src/tools/mcp/shared.d.ts +59 -0
- package/src/tools/mcp/shared.js +226 -0
- package/src/tools/oapi/bitable/app-table-field.d.ts +16 -0
- package/src/tools/oapi/bitable/app-table-field.js +222 -0
- package/src/tools/oapi/bitable/app-table-record.d.ts +20 -0
- package/src/tools/oapi/bitable/app-table-record.js +436 -0
- package/src/tools/oapi/bitable/app-table-view.d.ts +17 -0
- package/src/tools/oapi/bitable/app-table-view.js +195 -0
- package/src/tools/oapi/bitable/app-table.d.ts +19 -0
- package/src/tools/oapi/bitable/app-table.js +247 -0
- package/src/tools/oapi/bitable/app.d.ts +18 -0
- package/src/tools/oapi/bitable/app.js +186 -0
- package/src/tools/oapi/bitable/index.d.ts +9 -0
- package/src/tools/oapi/bitable/index.js +9 -0
- package/src/tools/oapi/calendar/calendar.d.ts +15 -0
- package/src/tools/oapi/calendar/calendar.js +122 -0
- package/src/tools/oapi/calendar/event-attendee.d.ts +16 -0
- package/src/tools/oapi/calendar/event-attendee.js +263 -0
- package/src/tools/oapi/calendar/event.d.ts +16 -0
- package/src/tools/oapi/calendar/event.js +709 -0
- package/src/tools/oapi/calendar/freebusy.d.ts +13 -0
- package/src/tools/oapi/calendar/freebusy.js +111 -0
- package/src/tools/oapi/calendar/index.d.ts +8 -0
- package/src/tools/oapi/calendar/index.js +8 -0
- package/src/tools/oapi/chat/chat.d.ts +16 -0
- package/src/tools/oapi/chat/chat.js +124 -0
- package/src/tools/oapi/chat/index.d.ts +10 -0
- package/src/tools/oapi/chat/index.js +15 -0
- package/src/tools/oapi/chat/members.d.ts +11 -0
- package/src/tools/oapi/chat/members.js +81 -0
- package/src/tools/oapi/common/get-user.d.ts +12 -0
- package/src/tools/oapi/common/get-user.js +106 -0
- package/src/tools/oapi/common/index.d.ts +6 -0
- package/src/tools/oapi/common/index.js +6 -0
- package/src/tools/oapi/common/search-user.d.ts +11 -0
- package/src/tools/oapi/common/search-user.js +73 -0
- package/src/tools/oapi/drive/doc-comments.d.ts +15 -0
- package/src/tools/oapi/drive/doc-comments.js +279 -0
- package/src/tools/oapi/drive/doc-media.d.ts +19 -0
- package/src/tools/oapi/drive/doc-media.js +335 -0
- package/src/tools/oapi/drive/file.d.ts +19 -0
- package/src/tools/oapi/drive/file.js +483 -0
- package/src/tools/oapi/drive/index.d.ts +12 -0
- package/src/tools/oapi/drive/index.js +36 -0
- package/src/tools/oapi/helpers.d.ts +182 -0
- package/src/tools/oapi/helpers.js +354 -0
- package/src/tools/oapi/im/format-messages.d.ts +50 -0
- package/src/tools/oapi/im/format-messages.js +165 -0
- package/src/tools/oapi/im/index.d.ts +10 -0
- package/src/tools/oapi/im/index.js +17 -0
- package/src/tools/oapi/im/message-read.d.ts +13 -0
- package/src/tools/oapi/im/message-read.js +411 -0
- package/src/tools/oapi/im/message.d.ts +16 -0
- package/src/tools/oapi/im/message.js +149 -0
- package/src/tools/oapi/im/resource.d.ts +13 -0
- package/src/tools/oapi/im/resource.js +150 -0
- package/src/tools/oapi/im/time-utils.d.ts +46 -0
- package/src/tools/oapi/im/time-utils.js +201 -0
- package/src/tools/oapi/im/user-name-uat.d.ts +26 -0
- package/src/tools/oapi/im/user-name-uat.js +140 -0
- package/src/tools/oapi/index.d.ts +11 -0
- package/src/tools/oapi/index.js +58 -0
- package/src/tools/oapi/sdk-types.d.ts +96 -0
- package/src/tools/oapi/sdk-types.js +12 -0
- package/src/tools/oapi/search/doc-search.d.ts +13 -0
- package/src/tools/oapi/search/doc-search.js +191 -0
- package/src/tools/oapi/search/index.d.ts +12 -0
- package/src/tools/oapi/search/index.js +33 -0
- package/src/tools/oapi/sheets/index.d.ts +12 -0
- package/src/tools/oapi/sheets/index.js +31 -0
- package/src/tools/oapi/sheets/sheet.d.ts +16 -0
- package/src/tools/oapi/sheets/sheet.js +652 -0
- package/src/tools/oapi/task/comment.d.ts +15 -0
- package/src/tools/oapi/task/comment.js +140 -0
- package/src/tools/oapi/task/index.d.ts +8 -0
- package/src/tools/oapi/task/index.js +8 -0
- package/src/tools/oapi/task/subtask.d.ts +14 -0
- package/src/tools/oapi/task/subtask.js +162 -0
- package/src/tools/oapi/task/task.d.ts +16 -0
- package/src/tools/oapi/task/task.js +344 -0
- package/src/tools/oapi/task/tasklist.d.ts +21 -0
- package/src/tools/oapi/task/tasklist.js +321 -0
- package/src/tools/oapi/wiki/index.d.ts +12 -0
- package/src/tools/oapi/wiki/index.js +34 -0
- package/src/tools/oapi/wiki/space-node.d.ts +17 -0
- package/src/tools/oapi/wiki/space-node.js +230 -0
- package/src/tools/oapi/wiki/space.d.ts +15 -0
- package/src/tools/oapi/wiki/space.js +130 -0
- package/src/tools/oauth-batch-auth.d.ts +11 -0
- package/src/tools/oauth-batch-auth.js +142 -0
- package/src/tools/oauth-cards.d.ts +39 -0
- package/src/tools/oauth-cards.js +315 -0
- package/src/tools/oauth.d.ts +47 -0
- package/src/tools/oauth.js +620 -0
- package/src/tools/onboarding-auth.d.ts +27 -0
- package/src/tools/onboarding-auth.js +130 -0
- package/src/tools/tat/im/index.d.ts +15 -0
- package/src/tools/tat/im/index.js +18 -0
- package/src/tools/tat/im/resource.d.ts +15 -0
- package/src/tools/tat/im/resource.js +157 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
5
|
+
* Guard against operating on unavailable (deleted/recalled) messages.
|
|
6
|
+
*
|
|
7
|
+
* Encapsulates the terminateDueToUnavailable / shouldSkipForUnavailable
|
|
8
|
+
* logic previously scattered as closures in reply-dispatcher.ts.
|
|
9
|
+
*/
|
|
10
|
+
export interface UnavailableGuardParams {
|
|
11
|
+
replyToMessageId: string | undefined;
|
|
12
|
+
getCardMessageId: () => string | null;
|
|
13
|
+
onTerminate: () => void;
|
|
14
|
+
}
|
|
15
|
+
export declare class UnavailableGuard {
|
|
16
|
+
private terminated;
|
|
17
|
+
private readonly replyToMessageId;
|
|
18
|
+
private readonly getCardMessageId;
|
|
19
|
+
private readonly onTerminate;
|
|
20
|
+
constructor(params: UnavailableGuardParams);
|
|
21
|
+
get isTerminated(): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Check whether the reply pipeline should skip further operations.
|
|
24
|
+
* Returns true if the message is already known to be unavailable.
|
|
25
|
+
*/
|
|
26
|
+
shouldSkip(source: string): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Attempt to terminate the reply pipeline due to an unavailable message.
|
|
29
|
+
*
|
|
30
|
+
* @param source - Descriptive label for the caller (for logging).
|
|
31
|
+
* @param err - Optional error that triggered the check.
|
|
32
|
+
* @returns true if the pipeline was (or already had been) terminated.
|
|
33
|
+
*/
|
|
34
|
+
terminate(source: string, err?: unknown): boolean;
|
|
35
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
5
|
+
* Guard against operating on unavailable (deleted/recalled) messages.
|
|
6
|
+
*
|
|
7
|
+
* Encapsulates the terminateDueToUnavailable / shouldSkipForUnavailable
|
|
8
|
+
* logic previously scattered as closures in reply-dispatcher.ts.
|
|
9
|
+
*/
|
|
10
|
+
import { larkLogger } from '../core/lark-logger';
|
|
11
|
+
import { extractLarkApiCode } from '../core/api-error';
|
|
12
|
+
import { getMessageUnavailableState, isMessageUnavailable, isMessageUnavailableError, isTerminalMessageApiCode, markMessageUnavailable, } from '../core/message-unavailable';
|
|
13
|
+
const log = larkLogger('card/unavailable-guard');
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// UnavailableGuard
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
export class UnavailableGuard {
|
|
18
|
+
terminated = false;
|
|
19
|
+
replyToMessageId;
|
|
20
|
+
getCardMessageId;
|
|
21
|
+
onTerminate;
|
|
22
|
+
constructor(params) {
|
|
23
|
+
this.replyToMessageId = params.replyToMessageId;
|
|
24
|
+
this.getCardMessageId = params.getCardMessageId;
|
|
25
|
+
this.onTerminate = params.onTerminate;
|
|
26
|
+
}
|
|
27
|
+
get isTerminated() {
|
|
28
|
+
return this.terminated;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Check whether the reply pipeline should skip further operations.
|
|
32
|
+
* Returns true if the message is already known to be unavailable.
|
|
33
|
+
*/
|
|
34
|
+
shouldSkip(source) {
|
|
35
|
+
if (this.terminated)
|
|
36
|
+
return true;
|
|
37
|
+
if (!this.replyToMessageId)
|
|
38
|
+
return false;
|
|
39
|
+
if (!isMessageUnavailable(this.replyToMessageId))
|
|
40
|
+
return false;
|
|
41
|
+
return this.terminate(source);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Attempt to terminate the reply pipeline due to an unavailable message.
|
|
45
|
+
*
|
|
46
|
+
* @param source - Descriptive label for the caller (for logging).
|
|
47
|
+
* @param err - Optional error that triggered the check.
|
|
48
|
+
* @returns true if the pipeline was (or already had been) terminated.
|
|
49
|
+
*/
|
|
50
|
+
terminate(source, err) {
|
|
51
|
+
if (this.terminated)
|
|
52
|
+
return true;
|
|
53
|
+
const fromError = isMessageUnavailableError(err) ? err : undefined;
|
|
54
|
+
const cardMessageId = this.getCardMessageId();
|
|
55
|
+
const state = getMessageUnavailableState(this.replyToMessageId) ?? getMessageUnavailableState(cardMessageId ?? undefined);
|
|
56
|
+
let apiCode = fromError?.apiCode ?? state?.apiCode;
|
|
57
|
+
if (!apiCode && err) {
|
|
58
|
+
const detectedCode = extractLarkApiCode(err);
|
|
59
|
+
if (isTerminalMessageApiCode(detectedCode)) {
|
|
60
|
+
const fallbackMessageId = this.replyToMessageId ?? cardMessageId ?? undefined;
|
|
61
|
+
if (fallbackMessageId) {
|
|
62
|
+
markMessageUnavailable({
|
|
63
|
+
messageId: fallbackMessageId,
|
|
64
|
+
apiCode: detectedCode,
|
|
65
|
+
operation: source,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
apiCode = detectedCode;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (!apiCode)
|
|
72
|
+
return false;
|
|
73
|
+
this.terminated = true;
|
|
74
|
+
this.onTerminate();
|
|
75
|
+
const affectedMessageId = fromError?.messageId ?? this.replyToMessageId ?? cardMessageId ?? 'unknown';
|
|
76
|
+
log.warn('reply pipeline terminated by unavailable message', {
|
|
77
|
+
source,
|
|
78
|
+
apiCode,
|
|
79
|
+
messageId: affectedMessageId,
|
|
80
|
+
});
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
5
|
+
* Abort trigger detection for the Lark/Feishu channel plugin.
|
|
6
|
+
*
|
|
7
|
+
* Provides a fast-path check to determine whether an inbound message is
|
|
8
|
+
* an abort/stop command *before* it enters the per-chat serial queue.
|
|
9
|
+
*
|
|
10
|
+
* The trigger word list and normalisation logic are copied from the
|
|
11
|
+
* OpenClaw core (`src/auto-reply/reply/abort.ts`) so the plugin can
|
|
12
|
+
* make a lightweight decision without importing the full reply pipeline.
|
|
13
|
+
* The message still flows through `tryFastAbortFromMessage()` for
|
|
14
|
+
* authoritative handling.
|
|
15
|
+
*/
|
|
16
|
+
import type { FeishuMessageEvent } from '../messaging/types';
|
|
17
|
+
/** Exact trigger-word match (same logic as OpenClaw core `isAbortTrigger`). */
|
|
18
|
+
export declare function isAbortTrigger(text: string): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Extended abort detection: matches both bare trigger words and the
|
|
21
|
+
* `/stop` command form. Used by the monitor fast-path.
|
|
22
|
+
*/
|
|
23
|
+
export declare function isLikelyAbortText(text: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Extract the raw text payload from a Feishu message event.
|
|
26
|
+
*
|
|
27
|
+
* Only handles `text` type messages. The `message.content` field is a
|
|
28
|
+
* JSON string like `{"text":"hello"}`. Returns `undefined` for
|
|
29
|
+
* non-text messages or parse failures.
|
|
30
|
+
*
|
|
31
|
+
* In group chats, bot mention placeholders (`@_user_N`) are stripped so
|
|
32
|
+
* a message like `@Bot stop` is detected as `stop`.
|
|
33
|
+
*/
|
|
34
|
+
export declare function extractRawTextFromEvent(event: FeishuMessageEvent): string | undefined;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
5
|
+
* Abort trigger detection for the Lark/Feishu channel plugin.
|
|
6
|
+
*
|
|
7
|
+
* Provides a fast-path check to determine whether an inbound message is
|
|
8
|
+
* an abort/stop command *before* it enters the per-chat serial queue.
|
|
9
|
+
*
|
|
10
|
+
* The trigger word list and normalisation logic are copied from the
|
|
11
|
+
* OpenClaw core (`src/auto-reply/reply/abort.ts`) so the plugin can
|
|
12
|
+
* make a lightweight decision without importing the full reply pipeline.
|
|
13
|
+
* The message still flows through `tryFastAbortFromMessage()` for
|
|
14
|
+
* authoritative handling.
|
|
15
|
+
*/
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Trigger word list (synced with OpenClaw core abort.ts)
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
const ABORT_TRIGGERS = new Set([
|
|
20
|
+
'stop',
|
|
21
|
+
'esc',
|
|
22
|
+
'abort',
|
|
23
|
+
'wait',
|
|
24
|
+
'exit',
|
|
25
|
+
'interrupt',
|
|
26
|
+
'detente',
|
|
27
|
+
'deten',
|
|
28
|
+
'detén',
|
|
29
|
+
'arrete',
|
|
30
|
+
'arrête',
|
|
31
|
+
'停止',
|
|
32
|
+
'やめて',
|
|
33
|
+
'止めて',
|
|
34
|
+
'रुको',
|
|
35
|
+
'توقف',
|
|
36
|
+
'стоп',
|
|
37
|
+
'остановись',
|
|
38
|
+
'останови',
|
|
39
|
+
'остановить',
|
|
40
|
+
'прекрати',
|
|
41
|
+
'halt',
|
|
42
|
+
'anhalten',
|
|
43
|
+
'aufhören',
|
|
44
|
+
'hoer auf',
|
|
45
|
+
'stopp',
|
|
46
|
+
'pare',
|
|
47
|
+
'stop openclaw',
|
|
48
|
+
'openclaw stop',
|
|
49
|
+
'stop action',
|
|
50
|
+
'stop current action',
|
|
51
|
+
'stop run',
|
|
52
|
+
'stop current run',
|
|
53
|
+
'stop agent',
|
|
54
|
+
'stop the agent',
|
|
55
|
+
"stop don't do anything",
|
|
56
|
+
'stop dont do anything',
|
|
57
|
+
'stop do not do anything',
|
|
58
|
+
'stop doing anything',
|
|
59
|
+
'do not do that',
|
|
60
|
+
'please stop',
|
|
61
|
+
'stop please',
|
|
62
|
+
]);
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
// Normalisation helpers
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
const TRAILING_ABORT_PUNCTUATION_RE = /[.!?…,,。;;::'"'")\]}]+$/u;
|
|
67
|
+
function normalizeAbortTriggerText(text) {
|
|
68
|
+
return text
|
|
69
|
+
.trim()
|
|
70
|
+
.toLowerCase()
|
|
71
|
+
.replace(/['`]/g, "'")
|
|
72
|
+
.replace(/\s+/g, ' ')
|
|
73
|
+
.replace(TRAILING_ABORT_PUNCTUATION_RE, '')
|
|
74
|
+
.trim();
|
|
75
|
+
}
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
// Public API
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
/** Exact trigger-word match (same logic as OpenClaw core `isAbortTrigger`). */
|
|
80
|
+
export function isAbortTrigger(text) {
|
|
81
|
+
if (!text)
|
|
82
|
+
return false;
|
|
83
|
+
const normalized = normalizeAbortTriggerText(text);
|
|
84
|
+
return ABORT_TRIGGERS.has(normalized);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Extended abort detection: matches both bare trigger words and the
|
|
88
|
+
* `/stop` command form. Used by the monitor fast-path.
|
|
89
|
+
*/
|
|
90
|
+
export function isLikelyAbortText(text) {
|
|
91
|
+
if (!text)
|
|
92
|
+
return false;
|
|
93
|
+
const trimmed = text.trim().toLowerCase();
|
|
94
|
+
if (trimmed === '/stop')
|
|
95
|
+
return true;
|
|
96
|
+
return isAbortTrigger(trimmed);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Extract the raw text payload from a Feishu message event.
|
|
100
|
+
*
|
|
101
|
+
* Only handles `text` type messages. The `message.content` field is a
|
|
102
|
+
* JSON string like `{"text":"hello"}`. Returns `undefined` for
|
|
103
|
+
* non-text messages or parse failures.
|
|
104
|
+
*
|
|
105
|
+
* In group chats, bot mention placeholders (`@_user_N`) are stripped so
|
|
106
|
+
* a message like `@Bot stop` is detected as `stop`.
|
|
107
|
+
*/
|
|
108
|
+
export function extractRawTextFromEvent(event) {
|
|
109
|
+
if (!event.message || event.message.message_type !== 'text') {
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
const parsed = JSON.parse(event.message.content);
|
|
114
|
+
let text = parsed?.text;
|
|
115
|
+
if (typeof text !== 'string')
|
|
116
|
+
return undefined;
|
|
117
|
+
// Strip bot mention placeholders (@_user_1, @_user_2, etc.)
|
|
118
|
+
text = text.replace(/@_user_\d+/g, '').trim();
|
|
119
|
+
return text || undefined;
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
5
|
+
* Process-level chat task queue.
|
|
6
|
+
*
|
|
7
|
+
* Although located in channel/, this module is intentionally shared
|
|
8
|
+
* across channel, messaging, tools, and card layers as a process-level
|
|
9
|
+
* singleton. Consumers: monitor.ts, dispatch.ts, oauth.ts, auto-auth.ts.
|
|
10
|
+
*
|
|
11
|
+
* Ensures tasks targeting the same account+chat are executed serially.
|
|
12
|
+
* Used by both websocket inbound messages and synthetic message paths.
|
|
13
|
+
*/
|
|
14
|
+
type QueueStatus = 'queued' | 'immediate';
|
|
15
|
+
export interface ActiveDispatcherEntry {
|
|
16
|
+
abortCard: () => Promise<void>;
|
|
17
|
+
abortController?: AbortController;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Append `:thread:{threadId}` suffix when threadId is present.
|
|
21
|
+
* Consistent with the SDK's `:thread:` separator convention.
|
|
22
|
+
*/
|
|
23
|
+
export declare function threadScopedKey(base: string, threadId?: string): string;
|
|
24
|
+
export declare function buildQueueKey(accountId: string, chatId: string, threadId?: string): string;
|
|
25
|
+
export declare function registerActiveDispatcher(key: string, entry: ActiveDispatcherEntry): void;
|
|
26
|
+
export declare function unregisterActiveDispatcher(key: string): void;
|
|
27
|
+
export declare function getActiveDispatcher(key: string): ActiveDispatcherEntry | undefined;
|
|
28
|
+
/** Check whether the queue has an active task for the given key. */
|
|
29
|
+
export declare function hasActiveTask(key: string): boolean;
|
|
30
|
+
export declare function enqueueFeishuChatTask(params: {
|
|
31
|
+
accountId: string;
|
|
32
|
+
chatId: string;
|
|
33
|
+
threadId?: string;
|
|
34
|
+
task: () => Promise<void>;
|
|
35
|
+
}): {
|
|
36
|
+
status: QueueStatus;
|
|
37
|
+
promise: Promise<void>;
|
|
38
|
+
};
|
|
39
|
+
/** @internal Test-only: reset all queue and dispatcher state. */
|
|
40
|
+
export declare function _resetChatQueueState(): void;
|
|
41
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
5
|
+
* Process-level chat task queue.
|
|
6
|
+
*
|
|
7
|
+
* Although located in channel/, this module is intentionally shared
|
|
8
|
+
* across channel, messaging, tools, and card layers as a process-level
|
|
9
|
+
* singleton. Consumers: monitor.ts, dispatch.ts, oauth.ts, auto-auth.ts.
|
|
10
|
+
*
|
|
11
|
+
* Ensures tasks targeting the same account+chat are executed serially.
|
|
12
|
+
* Used by both websocket inbound messages and synthetic message paths.
|
|
13
|
+
*/
|
|
14
|
+
const chatQueues = new Map();
|
|
15
|
+
const activeDispatchers = new Map();
|
|
16
|
+
/**
|
|
17
|
+
* Append `:thread:{threadId}` suffix when threadId is present.
|
|
18
|
+
* Consistent with the SDK's `:thread:` separator convention.
|
|
19
|
+
*/
|
|
20
|
+
export function threadScopedKey(base, threadId) {
|
|
21
|
+
return threadId ? `${base}:thread:${threadId}` : base;
|
|
22
|
+
}
|
|
23
|
+
export function buildQueueKey(accountId, chatId, threadId) {
|
|
24
|
+
return threadScopedKey(`${accountId}:${chatId}`, threadId);
|
|
25
|
+
}
|
|
26
|
+
export function registerActiveDispatcher(key, entry) {
|
|
27
|
+
activeDispatchers.set(key, entry);
|
|
28
|
+
}
|
|
29
|
+
export function unregisterActiveDispatcher(key) {
|
|
30
|
+
activeDispatchers.delete(key);
|
|
31
|
+
}
|
|
32
|
+
export function getActiveDispatcher(key) {
|
|
33
|
+
return activeDispatchers.get(key);
|
|
34
|
+
}
|
|
35
|
+
/** Check whether the queue has an active task for the given key. */
|
|
36
|
+
export function hasActiveTask(key) {
|
|
37
|
+
return chatQueues.has(key);
|
|
38
|
+
}
|
|
39
|
+
export function enqueueFeishuChatTask(params) {
|
|
40
|
+
const { accountId, chatId, threadId, task } = params;
|
|
41
|
+
const key = buildQueueKey(accountId, chatId, threadId);
|
|
42
|
+
const prev = chatQueues.get(key) ?? Promise.resolve();
|
|
43
|
+
const status = chatQueues.has(key) ? 'queued' : 'immediate';
|
|
44
|
+
const next = prev.then(task, task); // continue queue even if previous task failed
|
|
45
|
+
chatQueues.set(key, next);
|
|
46
|
+
const cleanup = () => {
|
|
47
|
+
if (chatQueues.get(key) === next) {
|
|
48
|
+
chatQueues.delete(key);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
next.then(cleanup, cleanup);
|
|
52
|
+
return { status, promise: next };
|
|
53
|
+
}
|
|
54
|
+
/** @internal Test-only: reset all queue and dispatcher state. */
|
|
55
|
+
export function _resetChatQueueState() {
|
|
56
|
+
chatQueues.clear();
|
|
57
|
+
activeDispatchers.clear();
|
|
58
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
5
|
+
* Configuration merge helpers for Feishu account management.
|
|
6
|
+
*
|
|
7
|
+
* Centralises the pattern of merging a partial configuration patch
|
|
8
|
+
* into the Feishu section of the top-level ClawdbotConfig, handling
|
|
9
|
+
* both the default account (top-level fields) and named accounts
|
|
10
|
+
* (nested under `accounts`).
|
|
11
|
+
*/
|
|
12
|
+
import type { ClawdbotConfig } from 'openclaw/plugin-sdk';
|
|
13
|
+
/** Set the `enabled` flag on a Feishu account. */
|
|
14
|
+
export declare function setAccountEnabled(cfg: ClawdbotConfig, accountId: string, enabled: boolean): ClawdbotConfig;
|
|
15
|
+
/** Apply an arbitrary config patch to a Feishu account. */
|
|
16
|
+
export declare function applyAccountConfig(cfg: ClawdbotConfig, accountId: string, patch: Record<string, unknown>): ClawdbotConfig;
|
|
17
|
+
/** Delete a Feishu account entry from the config. */
|
|
18
|
+
export declare function deleteAccount(cfg: ClawdbotConfig, accountId: string): ClawdbotConfig;
|
|
19
|
+
/** Collect security warnings for a Feishu account. */
|
|
20
|
+
export declare function collectFeishuSecurityWarnings(params: {
|
|
21
|
+
cfg: ClawdbotConfig;
|
|
22
|
+
accountId: string;
|
|
23
|
+
}): string[];
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
5
|
+
* Configuration merge helpers for Feishu account management.
|
|
6
|
+
*
|
|
7
|
+
* Centralises the pattern of merging a partial configuration patch
|
|
8
|
+
* into the Feishu section of the top-level ClawdbotConfig, handling
|
|
9
|
+
* both the default account (top-level fields) and named accounts
|
|
10
|
+
* (nested under `accounts`).
|
|
11
|
+
*/
|
|
12
|
+
import { DEFAULT_ACCOUNT_ID } from 'openclaw/plugin-sdk';
|
|
13
|
+
import { getLarkAccount, getLarkAccountIds } from '../core/accounts';
|
|
14
|
+
import { collectIsolationWarnings } from '../core/security-check';
|
|
15
|
+
/** Generic Feishu account config merge. */
|
|
16
|
+
function mergeFeishuAccountConfig(cfg, accountId, patch) {
|
|
17
|
+
const isDefault = !accountId || accountId === DEFAULT_ACCOUNT_ID;
|
|
18
|
+
if (isDefault) {
|
|
19
|
+
return {
|
|
20
|
+
...cfg,
|
|
21
|
+
channels: {
|
|
22
|
+
...cfg.channels,
|
|
23
|
+
feishu: { ...cfg.channels?.feishu, ...patch },
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const feishuCfg = cfg.channels?.feishu;
|
|
28
|
+
return {
|
|
29
|
+
...cfg,
|
|
30
|
+
channels: {
|
|
31
|
+
...cfg.channels,
|
|
32
|
+
feishu: {
|
|
33
|
+
...feishuCfg,
|
|
34
|
+
accounts: {
|
|
35
|
+
...feishuCfg?.accounts,
|
|
36
|
+
[accountId]: { ...feishuCfg?.accounts?.[accountId], ...patch },
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/** Set the `enabled` flag on a Feishu account. */
|
|
43
|
+
export function setAccountEnabled(cfg, accountId, enabled) {
|
|
44
|
+
return mergeFeishuAccountConfig(cfg, accountId, { enabled });
|
|
45
|
+
}
|
|
46
|
+
/** Apply an arbitrary config patch to a Feishu account. */
|
|
47
|
+
export function applyAccountConfig(cfg, accountId, patch) {
|
|
48
|
+
return mergeFeishuAccountConfig(cfg, accountId, patch);
|
|
49
|
+
}
|
|
50
|
+
/** Delete a Feishu account entry from the config. */
|
|
51
|
+
export function deleteAccount(cfg, accountId) {
|
|
52
|
+
const isDefault = !accountId || accountId === DEFAULT_ACCOUNT_ID;
|
|
53
|
+
if (isDefault) {
|
|
54
|
+
// Delete entire feishu config
|
|
55
|
+
const next = { ...cfg };
|
|
56
|
+
const nextChannels = { ...cfg.channels };
|
|
57
|
+
delete nextChannels.feishu;
|
|
58
|
+
if (Object.keys(nextChannels).length > 0) {
|
|
59
|
+
next.channels = nextChannels;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
delete next.channels;
|
|
63
|
+
}
|
|
64
|
+
return next;
|
|
65
|
+
}
|
|
66
|
+
// Delete specific account from accounts
|
|
67
|
+
const feishuCfg = cfg.channels?.feishu;
|
|
68
|
+
const accounts = { ...feishuCfg?.accounts };
|
|
69
|
+
delete accounts[accountId];
|
|
70
|
+
return {
|
|
71
|
+
...cfg,
|
|
72
|
+
channels: {
|
|
73
|
+
...cfg.channels,
|
|
74
|
+
feishu: {
|
|
75
|
+
...feishuCfg,
|
|
76
|
+
accounts: Object.keys(accounts).length > 0 ? accounts : undefined,
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/** Collect security warnings for a Feishu account. */
|
|
82
|
+
export function collectFeishuSecurityWarnings(params) {
|
|
83
|
+
const { cfg, accountId } = params;
|
|
84
|
+
const warnings = [];
|
|
85
|
+
const account = getLarkAccount(cfg, accountId);
|
|
86
|
+
const feishuCfg = account.config;
|
|
87
|
+
// cfg.channels.defaults is a cross-channel defaults object (not formally typed)
|
|
88
|
+
const defaultGroupPolicy = cfg.channels?.defaults?.groupPolicy;
|
|
89
|
+
const groupPolicy = feishuCfg?.groupPolicy ?? defaultGroupPolicy ?? 'allowlist';
|
|
90
|
+
if (groupPolicy === 'open') {
|
|
91
|
+
warnings.push(`- Feishu[${account.accountId}] groups: groupPolicy="open" allows any group to interact (mention-gated). To restrict which groups are allowed, set groupPolicy="allowlist" and list group IDs in channels.feishu.groups. To restrict which senders can trigger the bot, set channels.feishu.groupAllowFrom with user open_ids (ou_xxx).`);
|
|
92
|
+
}
|
|
93
|
+
// Multi-account cross-tenant isolation check (only on first account to avoid duplicates)
|
|
94
|
+
const allIds = getLarkAccountIds(cfg);
|
|
95
|
+
if (allIds.length === 0 || accountId === allIds[0]) {
|
|
96
|
+
for (const w of collectIsolationWarnings(cfg)) {
|
|
97
|
+
warnings.push(w);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return warnings;
|
|
101
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
5
|
+
* Directory listing for Feishu peers (users) and groups.
|
|
6
|
+
*
|
|
7
|
+
* Provides both config-based (offline) and live API directory
|
|
8
|
+
* lookups so the outbound subsystem and UI can resolve targets.
|
|
9
|
+
*/
|
|
10
|
+
import type { ClawdbotConfig } from 'openclaw/plugin-sdk';
|
|
11
|
+
import type { FeishuDirectoryPeer, FeishuDirectoryGroup } from './types';
|
|
12
|
+
export type { FeishuDirectoryPeer, FeishuDirectoryGroup } from './types';
|
|
13
|
+
/**
|
|
14
|
+
* List users known from the channel config (allowFrom + dms fields).
|
|
15
|
+
*
|
|
16
|
+
* Does not make any API calls -- useful when the bot is not yet
|
|
17
|
+
* connected or when credentials are unavailable.
|
|
18
|
+
*/
|
|
19
|
+
export declare function listFeishuDirectoryPeers(params: {
|
|
20
|
+
cfg: ClawdbotConfig;
|
|
21
|
+
query?: string;
|
|
22
|
+
limit?: number;
|
|
23
|
+
accountId?: string;
|
|
24
|
+
}): Promise<FeishuDirectoryPeer[]>;
|
|
25
|
+
/**
|
|
26
|
+
* List groups known from the channel config (groups + groupAllowFrom).
|
|
27
|
+
*/
|
|
28
|
+
export declare function listFeishuDirectoryGroups(params: {
|
|
29
|
+
cfg: ClawdbotConfig;
|
|
30
|
+
query?: string;
|
|
31
|
+
limit?: number;
|
|
32
|
+
accountId?: string;
|
|
33
|
+
}): Promise<FeishuDirectoryGroup[]>;
|
|
34
|
+
/**
|
|
35
|
+
* List users via the Feishu contact/v3/users API.
|
|
36
|
+
*
|
|
37
|
+
* Falls back to config-based listing when credentials are missing or
|
|
38
|
+
* the API call fails.
|
|
39
|
+
*/
|
|
40
|
+
export declare function listFeishuDirectoryPeersLive(params: {
|
|
41
|
+
cfg: ClawdbotConfig;
|
|
42
|
+
query?: string;
|
|
43
|
+
limit?: number;
|
|
44
|
+
accountId?: string;
|
|
45
|
+
}): Promise<FeishuDirectoryPeer[]>;
|
|
46
|
+
/**
|
|
47
|
+
* List groups via the Feishu im/v1/chats API.
|
|
48
|
+
*
|
|
49
|
+
* Falls back to config-based listing when credentials are missing or
|
|
50
|
+
* the API call fails.
|
|
51
|
+
*/
|
|
52
|
+
export declare function listFeishuDirectoryGroupsLive(params: {
|
|
53
|
+
cfg: ClawdbotConfig;
|
|
54
|
+
query?: string;
|
|
55
|
+
limit?: number;
|
|
56
|
+
accountId?: string;
|
|
57
|
+
}): Promise<FeishuDirectoryGroup[]>;
|