@yanhaidao/wecom 2.4.120 → 2.5.110
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/README.md +4 -5
- package/dist/index.js +68 -0
- package/dist/src/accounts.js +20 -0
- package/dist/src/agent/handler.js +895 -0
- package/dist/src/agent/index.js +5 -0
- package/dist/src/app/account-runtime.js +216 -0
- package/dist/src/app/bootstrap.js +19 -0
- package/dist/src/app/index.js +118 -0
- package/dist/src/capability/agent/delivery-service.js +63 -0
- package/dist/src/capability/agent/fallback-policy.js +6 -0
- package/dist/src/capability/agent/ingress-service.js +33 -0
- package/dist/src/capability/agent/upstream-delivery-service.js +71 -0
- package/dist/src/capability/bot/dispatch-config.js +45 -0
- package/dist/src/capability/bot/fallback-delivery.js +147 -0
- package/dist/src/capability/bot/local-path-delivery.js +178 -0
- package/dist/src/capability/bot/sandbox-media.js +138 -0
- package/dist/src/capability/bot/service.js +49 -0
- package/dist/src/capability/bot/stream-delivery.js +321 -0
- package/dist/src/capability/bot/stream-finalizer.js +81 -0
- package/dist/src/capability/bot/stream-orchestrator.js +318 -0
- package/dist/src/capability/bot/types.js +1 -0
- package/{src/capability/calendar/client.ts → dist/src/capability/calendar/client.js} +118 -241
- package/{src/capability/calendar/schema.ts → dist/src/capability/calendar/schema.js} +0 -38
- package/dist/src/capability/calendar/tool.js +365 -0
- package/dist/src/capability/calendar/types.js +12 -0
- package/{src/capability/doc/client.ts → dist/src/capability/doc/client.js} +370 -605
- package/{src/capability/doc/schema.ts → dist/src/capability/doc/schema.js} +345 -394
- package/dist/src/capability/doc/tool.js +1556 -0
- package/dist/src/capability/doc/types.js +113 -0
- package/dist/src/capability/mcp/index.js +3 -0
- package/dist/src/capability/mcp/schema.js +102 -0
- package/dist/src/capability/mcp/tool.js +146 -0
- package/dist/src/capability/mcp/transport.js +293 -0
- package/dist/src/channel.js +224 -0
- package/dist/src/config/accounts.js +236 -0
- package/dist/src/config/derived-paths.js +31 -0
- package/dist/src/config/index.js +7 -0
- package/dist/src/config/media.js +110 -0
- package/dist/src/config/network.js +32 -0
- package/dist/src/config/routing.js +20 -0
- package/dist/src/config/runtime-config.js +25 -0
- package/dist/src/config/schema.js +4 -0
- package/{src/config-schema.ts → dist/src/config-schema.js} +1 -1
- package/dist/src/context-store.js +219 -0
- package/{src/crypto/aes.ts → dist/src/crypto/aes.js} +11 -28
- package/dist/src/crypto/index.js +9 -0
- package/{src/crypto/signature.ts → dist/src/crypto/signature.js} +3 -18
- package/{src/crypto/xml.ts → dist/src/crypto/xml.js} +3 -11
- package/dist/src/crypto.js +145 -0
- package/dist/src/domain/models.js +1 -0
- package/dist/src/domain/policies.js +32 -0
- package/{src/dynamic-agent.ts → dist/src/dynamic-agent.js} +36 -73
- package/dist/src/gateway-monitor.js +139 -0
- package/dist/src/http.js +114 -0
- package/{src/media.ts → dist/src/media.js} +21 -40
- package/dist/src/monitor/limits.js +7 -0
- package/dist/src/monitor/state.js +28 -0
- package/dist/src/monitor.js +84 -0
- package/dist/src/observability/audit-log.js +30 -0
- package/dist/src/observability/legacy-operational-event-store.js +22 -0
- package/dist/src/observability/raw-envelope-log.js +24 -0
- package/dist/src/observability/status-registry.js +9 -0
- package/dist/src/observability/transport-session-view.js +14 -0
- package/dist/src/onboarding.js +546 -0
- package/dist/src/outbound.js +557 -0
- package/dist/src/runtime/dispatcher.js +57 -0
- package/{src/runtime/index.ts → dist/src/runtime/index.js} +0 -1
- package/dist/src/runtime/outbound-intent.js +1 -0
- package/dist/src/runtime/reply-orchestrator.js +38 -0
- package/dist/src/runtime/routing-bridge.js +26 -0
- package/dist/src/runtime/session-manager.js +112 -0
- package/dist/src/runtime/source-registry.js +174 -0
- package/dist/src/runtime.js +1 -0
- package/dist/src/shared/command-auth.js +57 -0
- package/{src/shared/index.ts → dist/src/shared/index.js} +0 -1
- package/dist/src/shared/media-asset.js +65 -0
- package/dist/src/shared/media-service.js +59 -0
- package/dist/src/shared/media-types.js +1 -0
- package/{src/shared/xml-parser.ts → dist/src/shared/xml-parser.js} +72 -63
- package/dist/src/store/active-reply-store.js +41 -0
- package/dist/src/store/interfaces.js +1 -0
- package/dist/src/store/memory-store.js +33 -0
- package/dist/src/store/stream-batch-store.js +319 -0
- package/{src/target.ts → dist/src/target.js} +15 -48
- package/dist/src/transport/agent-api/client.js +168 -0
- package/dist/src/transport/agent-api/core.js +337 -0
- package/dist/src/transport/agent-api/delivery.js +28 -0
- package/dist/src/transport/agent-api/media-upload.js +4 -0
- package/dist/src/transport/agent-api/reply.js +24 -0
- package/dist/src/transport/agent-api/upstream-delivery.js +30 -0
- package/dist/src/transport/agent-api/upstream-media-upload.js +46 -0
- package/dist/src/transport/agent-api/upstream-reply.js +26 -0
- package/dist/src/transport/agent-callback/http-handler.js +30 -0
- package/dist/src/transport/agent-callback/inbound.js +4 -0
- package/dist/src/transport/agent-callback/reply.js +8 -0
- package/dist/src/transport/agent-callback/request-handler.js +189 -0
- package/dist/src/transport/agent-callback/session.js +15 -0
- package/dist/src/transport/bot-webhook/active-reply.js +27 -0
- package/dist/src/transport/bot-webhook/http-handler.js +31 -0
- package/dist/src/transport/bot-webhook/inbound-normalizer.js +496 -0
- package/dist/src/transport/bot-webhook/inbound.js +4 -0
- package/dist/src/transport/bot-webhook/message-shape.js +98 -0
- package/dist/src/transport/bot-webhook/protocol.js +124 -0
- package/dist/src/transport/bot-webhook/reply.js +9 -0
- package/dist/src/transport/bot-webhook/request-handler.js +285 -0
- package/dist/src/transport/bot-webhook/session.js +15 -0
- package/dist/src/transport/bot-ws/inbound.js +147 -0
- package/dist/src/transport/bot-ws/media.js +236 -0
- package/dist/src/transport/bot-ws/reply.js +310 -0
- package/dist/src/transport/bot-ws/sdk-adapter.js +257 -0
- package/dist/src/transport/bot-ws/session.js +15 -0
- package/dist/src/transport/http/common.js +78 -0
- package/dist/src/transport/http/registry.js +71 -0
- package/dist/src/transport/http/request-handler.js +51 -0
- package/{src/transport/index.ts → dist/src/transport/index.js} +2 -10
- package/dist/src/types/account.js +1 -0
- package/dist/src/types/config.js +1 -0
- package/dist/src/types/constants.js +28 -0
- package/dist/src/types/events.js +1 -0
- package/dist/src/types/index.js +1 -0
- package/dist/src/types/legacy-stream.js +1 -0
- package/dist/src/types/message.js +5 -0
- package/dist/src/types/runtime-context.js +1 -0
- package/dist/src/types/runtime.js +1 -0
- package/dist/src/types.js +1 -0
- package/dist/src/upstream/index.js +111 -0
- package/dist/src/wecom_msg_adapter/markdown_adapter.js +280 -0
- package/openclaw.plugin.json +15 -0
- package/package.json +18 -1
- package/.github/workflows/release.yml +0 -143
- package/GOVERNANCE.md +0 -26
- package/MENU_EVENT_CONF.md +0 -500
- package/MENU_EVENT_PLAN.md +0 -440
- package/SKILLS_CAL.md +0 -895
- package/SKILLS_DOC.md +0 -2288
- package/UPSTREAM_CONFIG.md +0 -170
- package/UPSTREAM_PLAN.md +0 -175
- package/assets/01.bot-add.png +0 -0
- package/assets/01.bot-setp2.png +0 -0
- package/assets/01.image.jpg +0 -0
- package/assets/02.agent.add.png +0 -0
- package/assets/02.agent.api-set.png +0 -0
- package/assets/02.image.jpg +0 -0
- package/assets/03.agent.page.png +0 -0
- package/assets/03.bot.page.png +0 -0
- package/assets/link-me.jpg +0 -0
- package/assets/register.png +0 -0
- package/changelog/v2.2.28.md +0 -70
- package/changelog/v2.3.10.md +0 -17
- package/changelog/v2.3.11.md +0 -19
- package/changelog/v2.3.12.md +0 -25
- package/changelog/v2.3.13.md +0 -19
- package/changelog/v2.3.14.md +0 -48
- package/changelog/v2.3.15.md +0 -15
- package/changelog/v2.3.16.md +0 -11
- package/changelog/v2.3.18.md +0 -22
- package/changelog/v2.3.19.md +0 -73
- package/changelog/v2.3.2.md +0 -28
- package/changelog/v2.3.26.md +0 -21
- package/changelog/v2.3.27.md +0 -33
- package/changelog/v2.3.4.md +0 -20
- package/changelog/v2.3.9.md +0 -22
- package/changelog/v2.4.12.md +0 -37
- package/compat-single-account.md +0 -148
- package/index.test.ts +0 -38
- package/scripts/test-proxy.ts +0 -70
- package/scripts/wecom/README.md +0 -123
- package/scripts/wecom/menu-click-help.js +0 -59
- package/scripts/wecom/menu-click-help.py +0 -55
- package/src/accounts.ts +0 -34
- package/src/agent/api-client.upload.test.ts +0 -109
- package/src/agent/event-router.test.ts +0 -421
- package/src/agent/event-router.ts +0 -272
- package/src/agent/handler.event-filter.test.ts +0 -135
- package/src/agent/handler.ts +0 -1250
- package/src/agent/index.ts +0 -12
- package/src/agent/script-runner.ts +0 -186
- package/src/agent/test-fixtures/invalid-json-script.mjs +0 -1
- package/src/agent/test-fixtures/reply-event-script.mjs +0 -29
- package/src/agent/test-fixtures/reply-event-script.py +0 -17
- package/src/app/account-runtime.ts +0 -276
- package/src/app/bootstrap.ts +0 -29
- package/src/app/index.ts +0 -192
- package/src/capability/agent/delivery-service.ts +0 -87
- package/src/capability/agent/fallback-policy.ts +0 -13
- package/src/capability/agent/ingress-service.ts +0 -38
- package/src/capability/agent/upstream-delivery-service.ts +0 -96
- package/src/capability/bot/dispatch-config.ts +0 -47
- package/src/capability/bot/fallback-delivery.ts +0 -178
- package/src/capability/bot/local-path-delivery.ts +0 -215
- package/src/capability/bot/sandbox-media.test.ts +0 -221
- package/src/capability/bot/sandbox-media.ts +0 -176
- package/src/capability/bot/service.ts +0 -56
- package/src/capability/bot/stream-delivery.ts +0 -379
- package/src/capability/bot/stream-finalizer.ts +0 -120
- package/src/capability/bot/stream-orchestrator.ts +0 -371
- package/src/capability/bot/types.ts +0 -8
- package/src/capability/calendar/SKILLS_CHECKLIST.md +0 -251
- package/src/capability/calendar/tool.ts +0 -417
- package/src/capability/calendar/types.ts +0 -309
- package/src/capability/doc/tool.ts +0 -1629
- package/src/capability/doc/types.ts +0 -792
- package/src/capability/mcp/index.ts +0 -10
- package/src/capability/mcp/schema.ts +0 -107
- package/src/capability/mcp/tool.ts +0 -174
- package/src/capability/mcp/transport.ts +0 -394
- package/src/channel.config.test.ts +0 -180
- package/src/channel.lifecycle.test.ts +0 -255
- package/src/channel.meta.test.ts +0 -26
- package/src/channel.ts +0 -256
- package/src/config/accounts.resolve.test.ts +0 -75
- package/src/config/accounts.ts +0 -312
- package/src/config/derived-paths.test.ts +0 -111
- package/src/config/derived-paths.ts +0 -41
- package/src/config/index.ts +0 -22
- package/src/config/media.test.ts +0 -113
- package/src/config/media.ts +0 -139
- package/src/config/network.ts +0 -20
- package/src/config/routing.test.ts +0 -88
- package/src/config/routing.ts +0 -26
- package/src/config/runtime-config.ts +0 -46
- package/src/config/schema.ts +0 -144
- package/src/context-store.ts +0 -297
- package/src/crypto/index.ts +0 -24
- package/src/crypto.test.ts +0 -32
- package/src/crypto.ts +0 -176
- package/src/domain/models.ts +0 -7
- package/src/domain/policies.ts +0 -36
- package/src/dynamic-agent.account-scope.test.ts +0 -17
- package/src/gateway-monitor.ts +0 -181
- package/src/http.ts +0 -137
- package/src/media.test.ts +0 -82
- package/src/monitor/limits.ts +0 -7
- package/src/monitor/state.queue.test.ts +0 -185
- package/src/monitor/state.ts +0 -34
- package/src/monitor.active.test.ts +0 -245
- package/src/monitor.inbound-filter.test.ts +0 -63
- package/src/monitor.integration.test.ts +0 -208
- package/src/monitor.ts +0 -121
- package/src/monitor.webhook.test.ts +0 -774
- package/src/observability/audit-log.ts +0 -48
- package/src/observability/legacy-operational-event-store.ts +0 -36
- package/src/observability/raw-envelope-log.ts +0 -28
- package/src/observability/status-registry.ts +0 -13
- package/src/observability/transport-session-view.ts +0 -14
- package/src/onboarding.test.ts +0 -336
- package/src/onboarding.ts +0 -704
- package/src/outbound.test.ts +0 -1271
- package/src/outbound.ts +0 -746
- package/src/runtime/dispatcher.ts +0 -71
- package/src/runtime/outbound-intent.ts +0 -4
- package/src/runtime/reply-orchestrator.test.ts +0 -71
- package/src/runtime/reply-orchestrator.ts +0 -67
- package/src/runtime/routing-bridge.test.ts +0 -115
- package/src/runtime/routing-bridge.ts +0 -44
- package/src/runtime/session-manager.test.ts +0 -174
- package/src/runtime/session-manager.ts +0 -139
- package/src/runtime/source-registry.ts +0 -249
- package/src/runtime.ts +0 -14
- package/src/shared/command-auth.ts +0 -87
- package/src/shared/media-asset.ts +0 -78
- package/src/shared/media-service.test.ts +0 -111
- package/src/shared/media-service.ts +0 -84
- package/src/shared/media-types.ts +0 -5
- package/src/shared/xml-parser.test.ts +0 -50
- package/src/store/active-reply-store.ts +0 -42
- package/src/store/interfaces.ts +0 -11
- package/src/store/memory-store.ts +0 -43
- package/src/store/stream-batch-store.ts +0 -350
- package/src/transport/agent-api/client.ts +0 -277
- package/src/transport/agent-api/core.ts +0 -463
- package/src/transport/agent-api/delivery.ts +0 -41
- package/src/transport/agent-api/media-upload.ts +0 -11
- package/src/transport/agent-api/reply.ts +0 -39
- package/src/transport/agent-api/upstream-delivery.ts +0 -45
- package/src/transport/agent-api/upstream-media-upload.ts +0 -70
- package/src/transport/agent-api/upstream-reply.ts +0 -43
- package/src/transport/agent-callback/http-handler.ts +0 -47
- package/src/transport/agent-callback/inbound.ts +0 -5
- package/src/transport/agent-callback/reply.ts +0 -13
- package/src/transport/agent-callback/request-handler.ts +0 -244
- package/src/transport/agent-callback/session.ts +0 -23
- package/src/transport/bot-webhook/active-reply.ts +0 -39
- package/src/transport/bot-webhook/http-handler.ts +0 -48
- package/src/transport/bot-webhook/inbound-normalizer.ts +0 -371
- package/src/transport/bot-webhook/inbound.ts +0 -5
- package/src/transport/bot-webhook/message-shape.ts +0 -89
- package/src/transport/bot-webhook/protocol.ts +0 -148
- package/src/transport/bot-webhook/reply.ts +0 -15
- package/src/transport/bot-webhook/request-handler.ts +0 -394
- package/src/transport/bot-webhook/session.ts +0 -23
- package/src/transport/bot-ws/inbound.test.ts +0 -96
- package/src/transport/bot-ws/inbound.ts +0 -116
- package/src/transport/bot-ws/media.test.ts +0 -44
- package/src/transport/bot-ws/media.ts +0 -321
- package/src/transport/bot-ws/reply.test.ts +0 -450
- package/src/transport/bot-ws/reply.ts +0 -365
- package/src/transport/bot-ws/sdk-adapter.test.ts +0 -187
- package/src/transport/bot-ws/sdk-adapter.ts +0 -314
- package/src/transport/bot-ws/session.ts +0 -28
- package/src/transport/http/common.ts +0 -109
- package/src/transport/http/registry.ts +0 -92
- package/src/transport/http/request-handler.ts +0 -84
- package/src/types/account.ts +0 -72
- package/src/types/config.ts +0 -166
- package/src/types/constants.ts +0 -31
- package/src/types/events.ts +0 -21
- package/src/types/global.d.ts +0 -9
- package/src/types/index.ts +0 -17
- package/src/types/legacy-stream.ts +0 -50
- package/src/types/message.ts +0 -187
- package/src/types/runtime-context.ts +0 -28
- package/src/types/runtime.ts +0 -165
- package/src/types.ts +0 -41
- package/src/upstream/index.ts +0 -150
- package/src/upstream.test.ts +0 -84
- package/src/wecom_msg_adapter/markdown_adapter.ts +0 -331
- package/tsconfig.json +0 -22
- package/vitest.config.ts +0 -26
- /package/{src/capability/agent/index.ts → dist/src/capability/agent/index.js} +0 -0
- /package/{src/capability/bot/index.ts → dist/src/capability/bot/index.js} +0 -0
- /package/{src/capability/calendar/index.ts → dist/src/capability/calendar/index.js} +0 -0
- /package/{src/capability/index.ts → dist/src/capability/index.js} +0 -0
|
@@ -1,371 +0,0 @@
|
|
|
1
|
-
import { pathToFileURL } from "node:url";
|
|
2
|
-
|
|
3
|
-
import type { PluginRuntime } from "openclaw/plugin-sdk";
|
|
4
|
-
|
|
5
|
-
import { resolveWecomMediaMaxBytes, shouldRejectWecomDefaultRoute } from "../../config/index.js";
|
|
6
|
-
import { ensureDynamicAgentListed, generateAgentId, shouldUseDynamicAgent } from "../../dynamic-agent.js";
|
|
7
|
-
import { LIMITS, type StreamStore } from "../../monitor/state.js";
|
|
8
|
-
import { getWecomRuntime } from "../../runtime.js";
|
|
9
|
-
import { buildWecomUnauthorizedCommandPrompt, resolveWecomCommandAuthorization } from "../../shared/command-auth.js";
|
|
10
|
-
import type { PendingInbound } from "../../types/legacy-stream.js";
|
|
11
|
-
import type { WecomBotInboundMessage as WecomInboundMessage } from "../../types/index.js";
|
|
12
|
-
import type { WecomWebhookTarget } from "../../types/runtime-context.js";
|
|
13
|
-
import { looksLikeSendLocalFileIntent, processBotInboundMessage } from "../../transport/bot-webhook/inbound-normalizer.js";
|
|
14
|
-
import { resolveWecomSenderUserId } from "../../transport/bot-webhook/message-shape.js";
|
|
15
|
-
import { buildWecomBotDispatchConfig } from "./dispatch-config.js";
|
|
16
|
-
import { sendBotFallbackPromptNow } from "./fallback-delivery.js";
|
|
17
|
-
import { finalizeBotStream } from "./stream-finalizer.js";
|
|
18
|
-
import { handleDirectLocalPathIntent } from "./local-path-delivery.js";
|
|
19
|
-
import { stageWecomInboundMediaForSession } from "./sandbox-media.js";
|
|
20
|
-
import { createBotReplyDispatcher } from "./stream-delivery.js";
|
|
21
|
-
import type { BotRuntimeLogger, RecordBotOperationalEvent } from "./types.js";
|
|
22
|
-
|
|
23
|
-
export type StartBotAgentStreamParams = {
|
|
24
|
-
target: WecomWebhookTarget;
|
|
25
|
-
accountId: string;
|
|
26
|
-
msg: WecomInboundMessage;
|
|
27
|
-
streamId: string;
|
|
28
|
-
mergedContents?: string[] | string;
|
|
29
|
-
mergedMsgids?: string[];
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export function createBotStreamOrchestrator(params: {
|
|
33
|
-
streamStore: StreamStore;
|
|
34
|
-
recordBotOperationalEvent: RecordBotOperationalEvent;
|
|
35
|
-
}) {
|
|
36
|
-
const { streamStore, recordBotOperationalEvent } = params;
|
|
37
|
-
|
|
38
|
-
const logVerbose: BotRuntimeLogger = (target, message) => {
|
|
39
|
-
const should =
|
|
40
|
-
target.core.logging?.shouldLogVerbose?.() ??
|
|
41
|
-
(() => {
|
|
42
|
-
try {
|
|
43
|
-
return getWecomRuntime().logging.shouldLogVerbose();
|
|
44
|
-
} catch {
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
})();
|
|
48
|
-
if (!should) return;
|
|
49
|
-
target.runtime.log?.(`[wecom] ${message}`);
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
const logInfo: BotRuntimeLogger = (target, message) => {
|
|
53
|
-
target.runtime.log?.(`[wecom] ${message}`);
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const truncateUtf8Bytes = (text: string, maxBytes: number): string => {
|
|
57
|
-
const buf = Buffer.from(text, "utf8");
|
|
58
|
-
if (buf.length <= maxBytes) return text;
|
|
59
|
-
return buf.subarray(buf.length - maxBytes).toString("utf8");
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
const computeTaskKey = (target: WecomWebhookTarget, msg: WecomInboundMessage): string | undefined => {
|
|
63
|
-
const msgid = msg.msgid ? String(msg.msgid) : "";
|
|
64
|
-
if (!msgid) return undefined;
|
|
65
|
-
const aibotid = String((msg as any).aibotid ?? "unknown").trim() || "unknown";
|
|
66
|
-
return `bot:${target.account.accountId}:${aibotid}:${msgid}`;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
async function flushPending(pending: PendingInbound): Promise<void> {
|
|
70
|
-
const { streamId, target, msg, contents, msgids, conversationKey, batchKey } = pending;
|
|
71
|
-
const mergedContents = contents.filter((c) => c.trim()).join("\n").trim();
|
|
72
|
-
|
|
73
|
-
let core: PluginRuntime | null = null;
|
|
74
|
-
try {
|
|
75
|
-
core = getWecomRuntime();
|
|
76
|
-
} catch (err) {
|
|
77
|
-
logVerbose(target, `flush pending: runtime not ready: ${String(err)}`);
|
|
78
|
-
streamStore.markFinished(streamId);
|
|
79
|
-
logInfo(target, `queue: runtime not ready,结束批次并推进 streamId=${streamId}`);
|
|
80
|
-
streamStore.onStreamFinished(streamId);
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (!core) return;
|
|
85
|
-
|
|
86
|
-
streamStore.markStarted(streamId);
|
|
87
|
-
const enrichedTarget: WecomWebhookTarget = { ...target, core };
|
|
88
|
-
logInfo(
|
|
89
|
-
target,
|
|
90
|
-
`flush pending: start batch streamId=${streamId} batchKey=${batchKey} conversationKey=${conversationKey} mergedCount=${contents.length}`,
|
|
91
|
-
);
|
|
92
|
-
logVerbose(target, `防抖结束: 开始处理聚合消息 数量=${contents.length} streamId=${streamId}`);
|
|
93
|
-
|
|
94
|
-
startAgentForStream({
|
|
95
|
-
target: enrichedTarget,
|
|
96
|
-
accountId: target.account.accountId,
|
|
97
|
-
msg,
|
|
98
|
-
streamId,
|
|
99
|
-
mergedContents: contents.length > 1 ? mergedContents : undefined,
|
|
100
|
-
mergedMsgids: msgids.length > 1 ? msgids : undefined,
|
|
101
|
-
}).catch((err) => {
|
|
102
|
-
streamStore.updateStream(streamId, (state) => {
|
|
103
|
-
state.error = err instanceof Error ? err.message : String(err);
|
|
104
|
-
state.content = state.content || `Error: ${state.error}`;
|
|
105
|
-
state.finished = true;
|
|
106
|
-
});
|
|
107
|
-
target.runtime.error?.(`[${target.account.accountId}] wecom agent failed (处理失败): ${String(err)}`);
|
|
108
|
-
streamStore.onStreamFinished(streamId);
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
async function startAgentForStream(params: StartBotAgentStreamParams): Promise<void> {
|
|
113
|
-
const { target, msg, streamId } = params;
|
|
114
|
-
const core = target.core;
|
|
115
|
-
const config = target.config;
|
|
116
|
-
const account = target.account;
|
|
117
|
-
|
|
118
|
-
const userId = resolveWecomSenderUserId(msg) || "unknown";
|
|
119
|
-
const chatType = msg.chattype === "group" ? "group" : "direct";
|
|
120
|
-
const chatId = msg.chattype === "group" ? (msg.chatid?.trim() || "unknown") : userId;
|
|
121
|
-
const taskKey = computeTaskKey(target, msg);
|
|
122
|
-
const aibotid = String((msg as any).aibotid ?? "").trim() || undefined;
|
|
123
|
-
|
|
124
|
-
streamStore.updateStream(streamId, (s) => {
|
|
125
|
-
s.userId = userId;
|
|
126
|
-
s.chatType = chatType;
|
|
127
|
-
s.chatId = chatId;
|
|
128
|
-
s.taskKey = taskKey;
|
|
129
|
-
s.aibotid = aibotid;
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
let { body: rawBody, media } = await processBotInboundMessage({
|
|
133
|
-
target,
|
|
134
|
-
msg,
|
|
135
|
-
recordOperationalIssue: (event) => recordBotOperationalEvent(target, event),
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
if (params.mergedContents) {
|
|
139
|
-
rawBody = Array.isArray(params.mergedContents) ? params.mergedContents.join("\n") : params.mergedContents;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
const handledLocalPath = await handleDirectLocalPathIntent({
|
|
143
|
-
streamStore,
|
|
144
|
-
target,
|
|
145
|
-
streamId,
|
|
146
|
-
rawBody,
|
|
147
|
-
userId,
|
|
148
|
-
chatType,
|
|
149
|
-
logVerbose,
|
|
150
|
-
looksLikeSendLocalFileIntent,
|
|
151
|
-
});
|
|
152
|
-
if (handledLocalPath) return;
|
|
153
|
-
|
|
154
|
-
let mediaPath: string | undefined;
|
|
155
|
-
let mediaType: string | undefined;
|
|
156
|
-
const mediaFilename = media?.filename;
|
|
157
|
-
if (media) {
|
|
158
|
-
try {
|
|
159
|
-
const maxBytes = resolveWecomMediaMaxBytes(target.config, target.account.accountId);
|
|
160
|
-
const saved = await core.channel.media.saveMediaBuffer(media.buffer, media.contentType, "inbound", maxBytes, media.filename);
|
|
161
|
-
mediaPath = saved.path;
|
|
162
|
-
mediaType = saved.contentType;
|
|
163
|
-
logVerbose(target, `saved inbound media to ${mediaPath} (${mediaType})`);
|
|
164
|
-
} catch (err) {
|
|
165
|
-
target.runtime.error?.(`Failed to save inbound media: ${String(err)}`);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const route = core.channel.routing.resolveAgentRoute({
|
|
170
|
-
cfg: config,
|
|
171
|
-
channel: "wecom",
|
|
172
|
-
accountId: account.accountId,
|
|
173
|
-
peer: { kind: chatType === "group" ? "group" : "direct", id: chatId },
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
const useDynamicAgent = shouldUseDynamicAgent({
|
|
177
|
-
chatType: chatType === "group" ? "group" : "dm",
|
|
178
|
-
senderId: userId,
|
|
179
|
-
config,
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
if (shouldRejectWecomDefaultRoute({ cfg: config, matchedBy: route.matchedBy, useDynamicAgent })) {
|
|
183
|
-
const prompt =
|
|
184
|
-
`当前账号(${account.accountId})未绑定 OpenClaw Agent,已拒绝回退到默认主智能体。` +
|
|
185
|
-
`请在 bindings 中添加:{"agentId":"你的Agent","match":{"channel":"wecom","accountId":"${account.accountId}"}}`;
|
|
186
|
-
target.runtime.error?.(
|
|
187
|
-
`[wecom] routing guard: blocked default fallback accountId=${account.accountId} matchedBy=${route.matchedBy} streamId=${streamId}`,
|
|
188
|
-
);
|
|
189
|
-
streamStore.updateStream(streamId, (s) => {
|
|
190
|
-
s.finished = true;
|
|
191
|
-
s.content = prompt;
|
|
192
|
-
});
|
|
193
|
-
try {
|
|
194
|
-
await sendBotFallbackPromptNow({ streamId, text: prompt });
|
|
195
|
-
} catch (err) {
|
|
196
|
-
target.runtime.error?.(`routing guard prompt push failed streamId=${streamId}: ${String(err)}`);
|
|
197
|
-
}
|
|
198
|
-
streamStore.onStreamFinished(streamId);
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
if (useDynamicAgent) {
|
|
203
|
-
const targetAgentId = generateAgentId(chatType === "group" ? "group" : "dm", chatId, account.accountId);
|
|
204
|
-
route.agentId = targetAgentId;
|
|
205
|
-
route.sessionKey = `agent:${targetAgentId}:wecom:${account.accountId}:${chatType === "group" ? "group" : "dm"}:${chatId}`;
|
|
206
|
-
ensureDynamicAgentListed(targetAgentId, core).catch(() => { });
|
|
207
|
-
logVerbose(target, `dynamic agent routing: ${targetAgentId}, sessionKey=${route.sessionKey}`);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (mediaPath) {
|
|
211
|
-
try {
|
|
212
|
-
const stagedSessionPath = await stageWecomInboundMediaForSession({
|
|
213
|
-
cfg: target.config,
|
|
214
|
-
accountId: target.account.accountId,
|
|
215
|
-
agentId: route.agentId,
|
|
216
|
-
sessionKey: route.sessionKey,
|
|
217
|
-
mediaPath,
|
|
218
|
-
filename: mediaFilename,
|
|
219
|
-
});
|
|
220
|
-
mediaPath = stagedSessionPath;
|
|
221
|
-
logVerbose(target, `session media staged to ${mediaPath}`);
|
|
222
|
-
} catch (err) {
|
|
223
|
-
target.runtime.error?.(`Failed to stage inbound media for session workspace: ${String(err)}`);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
logVerbose(target, `starting agent processing (streamId=${streamId}, agentId=${route.agentId}, peerKind=${chatType}, peerId=${chatId})`);
|
|
228
|
-
logVerbose(target, `启动 Agent 处理: streamId=${streamId} 路由=${route.agentId} 类型=${chatType} ID=${chatId}`);
|
|
229
|
-
|
|
230
|
-
const fromLabel = chatType === "group" ? `group:${chatId}` : `user:${userId}`;
|
|
231
|
-
const storePath = core.channel.session.resolveStorePath(config.session?.store, { agentId: route.agentId });
|
|
232
|
-
const envelopeOptions = core.channel.reply.resolveEnvelopeFormatOptions(config);
|
|
233
|
-
const previousTimestamp = core.channel.session.readSessionUpdatedAt({
|
|
234
|
-
storePath,
|
|
235
|
-
sessionKey: route.sessionKey,
|
|
236
|
-
});
|
|
237
|
-
const body = core.channel.reply.formatAgentEnvelope({
|
|
238
|
-
channel: "WeCom",
|
|
239
|
-
from: fromLabel,
|
|
240
|
-
previousTimestamp,
|
|
241
|
-
envelope: envelopeOptions,
|
|
242
|
-
body: rawBody,
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
const authz = await resolveWecomCommandAuthorization({
|
|
246
|
-
core,
|
|
247
|
-
cfg: config,
|
|
248
|
-
accountConfig: account.config,
|
|
249
|
-
rawBody,
|
|
250
|
-
senderUserId: userId,
|
|
251
|
-
});
|
|
252
|
-
const commandAuthorized = authz.commandAuthorized;
|
|
253
|
-
logVerbose(
|
|
254
|
-
target,
|
|
255
|
-
`authz: dmPolicy=${authz.dmPolicy} shouldCompute=${authz.shouldComputeAuth} sender=${userId.toLowerCase()} senderAllowed=${authz.senderAllowed} authorizerConfigured=${authz.authorizerConfigured} commandAuthorized=${String(authz.commandAuthorized)}`,
|
|
256
|
-
);
|
|
257
|
-
|
|
258
|
-
if (authz.shouldComputeAuth && authz.commandAuthorized !== true) {
|
|
259
|
-
const prompt = buildWecomUnauthorizedCommandPrompt({ senderUserId: userId, dmPolicy: authz.dmPolicy, scope: "bot" });
|
|
260
|
-
streamStore.updateStream(streamId, (s) => {
|
|
261
|
-
s.finished = true;
|
|
262
|
-
s.content = prompt;
|
|
263
|
-
});
|
|
264
|
-
try {
|
|
265
|
-
await sendBotFallbackPromptNow({ streamId, text: prompt });
|
|
266
|
-
logInfo(target, `authz: 未授权命令已提示用户 streamId=${streamId}`);
|
|
267
|
-
} catch (err) {
|
|
268
|
-
target.runtime.error?.(`authz: 未授权命令提示推送失败 streamId=${streamId}: ${String(err)}`);
|
|
269
|
-
}
|
|
270
|
-
streamStore.onStreamFinished(streamId);
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
const attachments = mediaPath
|
|
275
|
-
? [
|
|
276
|
-
{
|
|
277
|
-
name: media?.filename || "file",
|
|
278
|
-
mimeType: mediaType,
|
|
279
|
-
url: pathToFileURL(mediaPath).href,
|
|
280
|
-
},
|
|
281
|
-
]
|
|
282
|
-
: undefined;
|
|
283
|
-
|
|
284
|
-
const ctxPayload = core.channel.reply.finalizeInboundContext({
|
|
285
|
-
Body: body,
|
|
286
|
-
RawBody: rawBody,
|
|
287
|
-
CommandBody: rawBody,
|
|
288
|
-
Attachments: attachments,
|
|
289
|
-
From: chatType === "group" ? `wecom:group:${chatId}` : `wecom:user:${userId}`,
|
|
290
|
-
To: chatType === "group" ? `wecom:group:${chatId}` : `wecom:user:${chatId}`,
|
|
291
|
-
SessionKey: route.sessionKey,
|
|
292
|
-
AccountId: route.accountId,
|
|
293
|
-
ChatType: chatType,
|
|
294
|
-
ConversationLabel: fromLabel,
|
|
295
|
-
SenderName: userId,
|
|
296
|
-
SenderId: userId,
|
|
297
|
-
Provider: "wecom",
|
|
298
|
-
Surface: "wecom",
|
|
299
|
-
MessageSid: msg.msgid,
|
|
300
|
-
CommandAuthorized: commandAuthorized,
|
|
301
|
-
OriginatingChannel: "wecom",
|
|
302
|
-
OriginatingTo: chatType === "group" ? `wecom:group:${chatId}` : `wecom:user:${chatId}`,
|
|
303
|
-
MediaPath: mediaPath,
|
|
304
|
-
MediaType: mediaType,
|
|
305
|
-
MediaUrl: mediaPath,
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
await core.channel.session.recordInboundSession({
|
|
309
|
-
storePath,
|
|
310
|
-
sessionKey: ctxPayload.SessionKey ?? route.sessionKey,
|
|
311
|
-
ctx: ctxPayload,
|
|
312
|
-
onRecordError: (err) => {
|
|
313
|
-
target.runtime.error?.(`wecom: failed updating session meta: ${String(err)}`);
|
|
314
|
-
},
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
const tableMode = core.channel.text.resolveMarkdownTableMode({
|
|
318
|
-
cfg: config,
|
|
319
|
-
channel: "wecom",
|
|
320
|
-
accountId: account.accountId,
|
|
321
|
-
});
|
|
322
|
-
const cfgForDispatch = buildWecomBotDispatchConfig(config);
|
|
323
|
-
logVerbose(target, "tool-policy: WeCom Bot 会话已禁用 message 工具(tools.deny += message;并同步到 tools.sandbox.tools.deny,防止绕过 Bot 交付)");
|
|
324
|
-
|
|
325
|
-
await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
|
|
326
|
-
ctx: ctxPayload,
|
|
327
|
-
cfg: cfgForDispatch,
|
|
328
|
-
replyOptions: { disableBlockStreaming: false },
|
|
329
|
-
dispatcherOptions: createBotReplyDispatcher({
|
|
330
|
-
streamStore,
|
|
331
|
-
target,
|
|
332
|
-
accountId: account.accountId,
|
|
333
|
-
config,
|
|
334
|
-
msg,
|
|
335
|
-
streamId,
|
|
336
|
-
rawBody,
|
|
337
|
-
chatType,
|
|
338
|
-
userId,
|
|
339
|
-
core,
|
|
340
|
-
tableMode,
|
|
341
|
-
logVerbose,
|
|
342
|
-
truncateUtf8Bytes,
|
|
343
|
-
recordBotOperationalEvent,
|
|
344
|
-
}),
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
const rawBodyNormalized = rawBody.trim();
|
|
348
|
-
const isResetCommand = /^\/(new|reset)(?:\s|$)/i.test(rawBodyNormalized);
|
|
349
|
-
const resetCommandKind = isResetCommand ? (rawBodyNormalized.match(/^\/(new|reset)/i)?.[1]?.toLowerCase() ?? "new") : null;
|
|
350
|
-
|
|
351
|
-
await finalizeBotStream({
|
|
352
|
-
streamStore,
|
|
353
|
-
target,
|
|
354
|
-
streamId,
|
|
355
|
-
chatType,
|
|
356
|
-
core,
|
|
357
|
-
config,
|
|
358
|
-
accountId: account.accountId,
|
|
359
|
-
isResetCommand,
|
|
360
|
-
resetCommandKind,
|
|
361
|
-
logInfo,
|
|
362
|
-
logVerbose,
|
|
363
|
-
recordBotOperationalEvent,
|
|
364
|
-
});
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
return {
|
|
368
|
-
flushPending,
|
|
369
|
-
startAgentForStream,
|
|
370
|
-
};
|
|
371
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { WecomRuntimeAuditEvent, WecomWebhookTarget } from "../../types/runtime-context.js";
|
|
2
|
-
|
|
3
|
-
export type BotRuntimeLogger = (target: WecomWebhookTarget, message: string) => void;
|
|
4
|
-
|
|
5
|
-
export type RecordBotOperationalEvent = (
|
|
6
|
-
target: Pick<WecomWebhookTarget, "account" | "auditSink">,
|
|
7
|
-
event: Omit<WecomRuntimeAuditEvent, "transport">,
|
|
8
|
-
) => void;
|
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
# WeCom Calendar Skills 技能清单
|
|
2
|
-
|
|
3
|
-
## 技能列表
|
|
4
|
-
|
|
5
|
-
### wecom_calendar - 企业微信日历工具
|
|
6
|
-
|
|
7
|
-
**技能 ID**: `wecom_calendar`
|
|
8
|
-
**标签**: `WeCom Calendar`
|
|
9
|
-
**描述**: 企业微信日历工具。支持创建/更新/删除日历和日程,管理日程参与者,获取日历详情等功能。
|
|
10
|
-
|
|
11
|
-
## 支持的 Actions (13 个)
|
|
12
|
-
|
|
13
|
-
### 日历管理 (4 个)
|
|
14
|
-
|
|
15
|
-
#### 1. calendar_create - 创建日历
|
|
16
|
-
**参数**:
|
|
17
|
-
- `summary` (必填): 日历标题,1-128 字符
|
|
18
|
-
- `color` (必填): RGB 颜色编码,如 #FF3030
|
|
19
|
-
- `description` (可选): 日历描述,0-512 字符
|
|
20
|
-
- `admins` (可选): 日历管理员 userid 列表,最多 3 人
|
|
21
|
-
- `set_as_default` (可选): 是否设为默认日历,0-否,1-是(第三方应用不支持)
|
|
22
|
-
- `shares` (可选): 通知范围成员列表,最多 2000 人
|
|
23
|
-
- `is_public` (可选): 是否公共日历,0-否,1-是
|
|
24
|
-
- `public_range` (可选): 公开范围
|
|
25
|
-
- `userids`: 公开的成员列表,最多 1000 个
|
|
26
|
-
- `partyids`: 公开的部门列表,最多 100 个
|
|
27
|
-
- `is_corp_calendar` (可选): 是否全员日历,0-否,1-是
|
|
28
|
-
|
|
29
|
-
**返回**: `{ ok: true, action: "calendar_create", calId: string, raw: object }`
|
|
30
|
-
|
|
31
|
-
#### 2. calendar_update - 更新日历
|
|
32
|
-
**参数**:
|
|
33
|
-
- `cal_id` (必填): 日历 ID
|
|
34
|
-
- `summary` (必填): 日历标题,1-128 字符
|
|
35
|
-
- `color` (必填): RGB 颜色编码
|
|
36
|
-
- `description` (可选): 日历描述,0-512 字符
|
|
37
|
-
- `admins` (可选): 日历管理员,最多 3 人
|
|
38
|
-
- `shares` (可选): 通知范围成员,最多 2000 人
|
|
39
|
-
- `public_range` (可选): 公开范围
|
|
40
|
-
- `skip_public_range` (可选): 是否不更新可订阅范围,0-否,1-是
|
|
41
|
-
|
|
42
|
-
**返回**: `{ ok: true, action: "calendar_update", calId: string, raw: object }`
|
|
43
|
-
|
|
44
|
-
#### 3. calendar_get - 获取日历详情
|
|
45
|
-
**参数**:
|
|
46
|
-
- `cal_id_list` (必填): 日历 ID 列表,一次最多 1000 条
|
|
47
|
-
|
|
48
|
-
**返回**: `{ ok: true, action: "calendar_get", calendarList: array, raw: object }`
|
|
49
|
-
|
|
50
|
-
#### 4. calendar_delete - 删除日历
|
|
51
|
-
**参数**:
|
|
52
|
-
- `cal_id` (必填): 日历 ID
|
|
53
|
-
|
|
54
|
-
**返回**: `{ ok: true, action: "calendar_delete", calId: string, raw: object }`
|
|
55
|
-
|
|
56
|
-
### 日程管理 (7 个)
|
|
57
|
-
|
|
58
|
-
#### 5. schedule_create - 创建日程
|
|
59
|
-
**参数**:
|
|
60
|
-
- `start_time` (必填): 日程开始时间,Unix 时间戳(秒)
|
|
61
|
-
- `end_time` (必填): 日程结束时间,Unix 时间戳(秒)
|
|
62
|
-
- `is_whole_day` (可选): 是否全天日程,0-否,1-是
|
|
63
|
-
- `summary` (可选): 日程标题,0-128 字符
|
|
64
|
-
- `description` (可选): 日程描述,不多于 1000 字符
|
|
65
|
-
- `location` (可选): 日程地址,不多于 128 字符
|
|
66
|
-
- `attendees` (可选): 日程参与者列表,最多 1000 人
|
|
67
|
-
- `admins` (可选): 日程管理员,最多 3 人
|
|
68
|
-
- `reminders` (可选): 提醒相关信息
|
|
69
|
-
- `is_remind`: 是否需要提醒,0-否,1-是
|
|
70
|
-
- `is_repeat`: 是否重复日程,0-否,1-是
|
|
71
|
-
- `remind_before_event_secs`: 日程开始前多少秒提醒 [0,300,900,3600,86400]
|
|
72
|
-
- `remind_time_diffs`: 提醒时间与日程开始时间的差值数组
|
|
73
|
-
- `repeat_type`: 重复类型 [0-每日,1-每周,2-每月,5-每年,7-工作日]
|
|
74
|
-
- `repeat_until`: 重复结束时刻,Unix 时间戳
|
|
75
|
-
- `is_custom_repeat`: 是否自定义重复,0-否,1-是
|
|
76
|
-
- `repeat_interval`: 重复间隔
|
|
77
|
-
- `repeat_day_of_week`: 每周周几重复 [1-7]
|
|
78
|
-
- `repeat_day_of_month`: 每月哪几天重复 [1-31]
|
|
79
|
-
- `timezone`: 时区 [-12 到 +12]
|
|
80
|
-
- `cal_id` (可选): 日程所属日历 ID(第三方应用必须指定)
|
|
81
|
-
|
|
82
|
-
**返回**: `{ ok: true, action: "schedule_create", scheduleId: string, raw: object }`
|
|
83
|
-
|
|
84
|
-
#### 6. schedule_update - 更新日程
|
|
85
|
-
**参数**:
|
|
86
|
-
- `schedule_id` (必填): 日程 ID
|
|
87
|
-
- `start_time` (必填): 日程开始时间
|
|
88
|
-
- `end_time` (必填): 日程结束时间
|
|
89
|
-
- `is_whole_day` (可选): 是否全天日程
|
|
90
|
-
- `summary` (可选): 日程标题
|
|
91
|
-
- `description` (可选): 日程描述
|
|
92
|
-
- `location` (可选): 日程地址
|
|
93
|
-
- `attendees` (可选): 日程参与者
|
|
94
|
-
- `admins` (可选): 日程管理员
|
|
95
|
-
- `reminders` (可选): 提醒相关信息
|
|
96
|
-
- `skip_attendees` (可选): 是否不更新参与人,0-否,1-是
|
|
97
|
-
- `op_mode` (可选): 操作模式 [0-全部修改,1-仅修改此日程,2-修改将来的所有日程]
|
|
98
|
-
- `op_start_time` (可选): 操作起始时间
|
|
99
|
-
|
|
100
|
-
**返回**: `{ ok: true, action: "schedule_update", scheduleId: string, raw: object }`
|
|
101
|
-
|
|
102
|
-
#### 7. schedule_add_attendees - 新增日程参与者
|
|
103
|
-
**参数**:
|
|
104
|
-
- `schedule_id` (必填): 日程 ID
|
|
105
|
-
- `attendees` (必填): 日程参与者列表,累计最多 1000 人
|
|
106
|
-
|
|
107
|
-
**返回**: `{ ok: true, action: "schedule_add_attendees", scheduleId: string, raw: object }`
|
|
108
|
-
|
|
109
|
-
#### 8. schedule_del_attendees - 删除日程参与者
|
|
110
|
-
**参数**:
|
|
111
|
-
- `schedule_id` (必填): 日程 ID
|
|
112
|
-
- `attendees` (必填): 日程参与者列表,最多 1000 人
|
|
113
|
-
|
|
114
|
-
**返回**: `{ ok: true, action: "schedule_del_attendees", scheduleId: string, raw: object }`
|
|
115
|
-
|
|
116
|
-
#### 9. schedule_get_by_calendar - 获取日历下的日程列表
|
|
117
|
-
**参数**:
|
|
118
|
-
- `cal_id` (必填): 日历 ID
|
|
119
|
-
- `offset` (可选): 分页偏移量,默认 0
|
|
120
|
-
- `limit` (可选): 分页大小,默认 500,范围 1-1000
|
|
121
|
-
|
|
122
|
-
**返回**: `{ ok: true, action: "schedule_get_by_calendar", scheduleList: array, raw: object }`
|
|
123
|
-
|
|
124
|
-
#### 10. schedule_get - 获取日程详情
|
|
125
|
-
**参数**:
|
|
126
|
-
- `schedule_id_list` (必填): 日程 ID 列表,一次最多 1000 条
|
|
127
|
-
|
|
128
|
-
**返回**: `{ ok: true, action: "schedule_get", scheduleList: array, meetingCode: string, meetingLink: string, raw: object }`
|
|
129
|
-
|
|
130
|
-
#### 11. schedule_delete - 取消日程
|
|
131
|
-
**参数**:
|
|
132
|
-
- `schedule_id` (必填): 日程 ID
|
|
133
|
-
- `op_mode` (可选): 操作模式 [0-删除所有,1-仅删除此日程,2-删除本次及后续]
|
|
134
|
-
- `op_start_time` (可选): 操作起始时间
|
|
135
|
-
|
|
136
|
-
**返回**: `{ ok: true, action: "schedule_delete", scheduleId: string, raw: object }`
|
|
137
|
-
|
|
138
|
-
### 默认日历管理 (2 个)
|
|
139
|
-
|
|
140
|
-
#### 12. schedule_get_system_calid - 获取默认日历本 ID
|
|
141
|
-
**参数**:
|
|
142
|
-
- `userid` (必填): 指定成员的 userid
|
|
143
|
-
|
|
144
|
-
**返回**: `{ ok: true, action: "schedule_get_system_calid", calId: string, raw: object }`
|
|
145
|
-
|
|
146
|
-
#### 13. schedule_create_in_system - 在默认日历创建日程
|
|
147
|
-
**参数**:
|
|
148
|
-
- `organizer` (必填): 日程创建者 userid
|
|
149
|
-
- `start_time` (必填): 日程开始时间
|
|
150
|
-
- `end_time` (必填): 日程结束时间
|
|
151
|
-
- `is_whole_day` (可选): 是否全天日程
|
|
152
|
-
- `summary` (可选): 日程标题
|
|
153
|
-
- `description` (可选): 日程描述
|
|
154
|
-
- `location` (可选): 日程地址
|
|
155
|
-
- `attendees` (可选): 日程参与者
|
|
156
|
-
- `reminders` (可选): 提醒相关信息
|
|
157
|
-
|
|
158
|
-
**返回**: `{ ok: true, action: "schedule_create_in_system", scheduleId: string, raw: object }`
|
|
159
|
-
|
|
160
|
-
## 与官方文档对比验证
|
|
161
|
-
|
|
162
|
-
### 接口完整性 ✓
|
|
163
|
-
- [x] 创建日历 (calendar/add) - 完整实现
|
|
164
|
-
- [x] 更新日历 (calendar/update) - 完整实现
|
|
165
|
-
- [x] 获取日历 (calendar/get) - 完整实现
|
|
166
|
-
- [x] 删除日历 (calendar/del) - 完整实现
|
|
167
|
-
- [x] 创建日程 (schedule/add) - 完整实现
|
|
168
|
-
- [x] 更新日程 (schedule/update) - 完整实现
|
|
169
|
-
- [x] 新增参与者 (schedule/add_attendees) - 完整实现
|
|
170
|
-
- [x] 删除参与者 (schedule/del_attendees) - 完整实现
|
|
171
|
-
- [x] 获取日程列表 (schedule/get_by_calendar) - 完整实现
|
|
172
|
-
- [x] 获取日程详情 (schedule/get) - 完整实现
|
|
173
|
-
- [x] 取消日程 (schedule/del) - 完整实现
|
|
174
|
-
- [x] 获取默认日历 ID (calendar/get_system_calid) - 完整实现
|
|
175
|
-
- [x] 创建默认日历日程 (schedule/add_schedule_in_system_cal) - 完整实现
|
|
176
|
-
- [x] 更新日程回执 (schedule/respond) - 已实现(client.ts)
|
|
177
|
-
- [x] 同步日程 (schedule/sync) - 已实现(client.ts)
|
|
178
|
-
|
|
179
|
-
### 参数验证 ✓
|
|
180
|
-
- [x] 所有必填参数都有 required 声明
|
|
181
|
-
- [x] 所有参数的类型、格式、取值范围都正确
|
|
182
|
-
- [x] 所有接口限制都有验证(数量、字符)
|
|
183
|
-
- [x] 所有枚举值都正确定义
|
|
184
|
-
|
|
185
|
-
### 返回值处理 ✓
|
|
186
|
-
- [x] 所有接口返回结果结构正确
|
|
187
|
-
- [x] 错误处理完善(HTTP 错误、JSON 错误、业务错误)
|
|
188
|
-
- [x] 重试机制实现(3 次)
|
|
189
|
-
|
|
190
|
-
### 特殊功能 ✓
|
|
191
|
-
- [x] op_mode 操作模式支持(0/1/2)
|
|
192
|
-
- [x] op_start_time 重复日程操作
|
|
193
|
-
- [x] 提醒时间枚举值验证
|
|
194
|
-
- [x] 时区范围验证(-12 到 +12)
|
|
195
|
-
- [x] 重复日程自定义设置
|
|
196
|
-
|
|
197
|
-
## 已知限制和注意事项
|
|
198
|
-
|
|
199
|
-
1. **第三方应用**:不支持 `set_as_default` 参数
|
|
200
|
-
2. **全员日历**:每个企业最多 20 个,不支持指定颜色
|
|
201
|
-
3. **公共日历**:每人最多创建或订阅 100 个
|
|
202
|
-
4. **日程数量**:每个应用每天最多 2 万个
|
|
203
|
-
5. **重复日程修改**:需指定 op_mode 和 op_start_time
|
|
204
|
-
6. **会议室关联**:已预约会议室的日程更新时间受限
|
|
205
|
-
|
|
206
|
-
## 待实现功能
|
|
207
|
-
|
|
208
|
-
1. **回调事件处理** - 需要在 webhook 中添加以下事件处理:
|
|
209
|
-
- delete_calendar
|
|
210
|
-
- modify_calendar
|
|
211
|
-
- modify_schedule
|
|
212
|
-
- delete_schedule
|
|
213
|
-
- respond_schedule
|
|
214
|
-
- add_schedule
|
|
215
|
-
|
|
216
|
-
2. **完整实现** - client.ts 和 tool.ts 需要完善所有方法的具体实现
|
|
217
|
-
|
|
218
|
-
## 使用示例
|
|
219
|
-
|
|
220
|
-
```json
|
|
221
|
-
// 创建日历
|
|
222
|
-
{
|
|
223
|
-
"action": "calendar_create",
|
|
224
|
-
"summary": "团队日历",
|
|
225
|
-
"color": "#FF3030",
|
|
226
|
-
"description": "团队共享日历",
|
|
227
|
-
"admins": ["zhangsan", "lisi"],
|
|
228
|
-
"shares": [{"userid": "wangwu", "permission": 1}]
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// 创建日程
|
|
232
|
-
{
|
|
233
|
-
"action": "schedule_create",
|
|
234
|
-
"start_time": 1679011200,
|
|
235
|
-
"end_time": 1679014800,
|
|
236
|
-
"summary": "项目评审会议",
|
|
237
|
-
"location": "10 楼会议室",
|
|
238
|
-
"attendees": [{"userid": "user1"}, {"userid": "user2"}],
|
|
239
|
-
"reminders": {
|
|
240
|
-
"is_remind": 1,
|
|
241
|
-
"remind_before_event_secs": 3600,
|
|
242
|
-
"timezone": 8
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// 获取日程详情
|
|
247
|
-
{
|
|
248
|
-
"action": "schedule_get",
|
|
249
|
-
"schedule_id_list": ["schedule_id_1", "schedule_id_2"]
|
|
250
|
-
}
|
|
251
|
-
```
|