@yanhaidao/wecom 2.4.160 → 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/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/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/changelog/v2.4.16.md +0 -19
- package/compat-single-account.md +0 -148
- package/index.test.ts +0 -38
- package/scripts/test-proxy.ts +0 -70
- package/src/accounts.ts +0 -34
- package/src/agent/api-client.upload.test.ts +0 -109
- package/src/agent/handler.event-filter.test.ts +0 -100
- package/src/agent/handler.ts +0 -1105
- package/src/agent/index.ts +0 -12
- 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 -147
- 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 -296
- package/src/config/derived-paths.test.ts +0 -111
- package/src/config/derived-paths.ts +0 -41
- package/src/config/index.ts +0 -26
- package/src/config/media.test.ts +0 -113
- package/src/config/media.ts +0 -139
- package/src/config/network.ts +0 -53
- 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 -90
- 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 -145
- 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.test.ts +0 -433
- package/src/transport/bot-webhook/inbound-normalizer.ts +0 -558
- package/src/transport/bot-webhook/inbound.ts +0 -5
- package/src/transport/bot-webhook/message-shape.ts +0 -92
- 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 -290
- package/src/transport/bot-ws/inbound.ts +0 -163
- 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 -70
- package/src/types/config.ts +0 -114
- 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 -189
- 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,30 +1,10 @@
|
|
|
1
|
-
// ============================================================================
|
|
2
|
-
// Calendar Client - Complete Implementation
|
|
3
|
-
// 严格遵循企业微信官方 API 文档:https://developer.work.weixin.qq.com/document/path/93329
|
|
4
|
-
// ============================================================================
|
|
5
|
-
import type { ResolvedAgentAccount } from "../../types/index.js";
|
|
6
1
|
import { getAccessToken } from "../../transport/agent-api/core.js";
|
|
7
2
|
import { wecomFetch } from "../../http.js";
|
|
8
3
|
import { resolveWecomEgressProxyUrlFromNetwork } from "../../config/index.js";
|
|
9
4
|
import { LIMITS } from "../../types/constants.js";
|
|
10
|
-
import type {
|
|
11
|
-
CreateCalendarRequest, CreateCalendarResponse, UpdateCalendarRequest, UpdateCalendarResponse,
|
|
12
|
-
GetCalendarRequest, GetCalendarResponse, DeleteCalendarResponse,
|
|
13
|
-
CreateScheduleRequest, CreateScheduleResponse, UpdateScheduleRequest, UpdateScheduleResponse,
|
|
14
|
-
AddScheduleAttendeesRequest, AddScheduleAttendeesResponse,
|
|
15
|
-
DeleteScheduleAttendeesRequest, DeleteScheduleAttendeesResponse,
|
|
16
|
-
GetScheduleByCalendarRequest, GetScheduleByCalendarResponse,
|
|
17
|
-
GetScheduleRequest, GetScheduleResponse, DeleteScheduleRequest, DeleteScheduleResponse,
|
|
18
|
-
GetSystemCalendarIdRequest, GetSystemCalendarIdResponse,
|
|
19
|
-
CreateSystemScheduleRequest, RespondScheduleRequest, RespondScheduleResponse,
|
|
20
|
-
SyncScheduleRequest, SyncScheduleResponse, CalendarInfo, ScheduleInfo,
|
|
21
|
-
ScheduleReminders,
|
|
22
|
-
} from "./types.js";
|
|
23
|
-
|
|
24
5
|
// ============================================================================
|
|
25
6
|
// Constants - 官方 API 限定值
|
|
26
7
|
// ============================================================================
|
|
27
|
-
|
|
28
8
|
const CALENDAR_LIMITS = {
|
|
29
9
|
ADMINS_MAX: 3,
|
|
30
10
|
SHARES_MAX: 2000,
|
|
@@ -50,13 +30,11 @@ const CALENDAR_LIMITS = {
|
|
|
50
30
|
OP_MODE_VALUES: [0, 1, 2],
|
|
51
31
|
PERMISSION_VALUES: [1, 3],
|
|
52
32
|
RESPONSE_STATUS_VALUES: [1, 2, 4],
|
|
53
|
-
}
|
|
54
|
-
|
|
33
|
+
};
|
|
55
34
|
// ============================================================================
|
|
56
35
|
// Validation Functions
|
|
57
36
|
// ============================================================================
|
|
58
|
-
|
|
59
|
-
function validateString(value: unknown, fieldName: string, opts?: { min?: number; max?: number; pattern?: RegExp; allowEmpty?: boolean }): string {
|
|
37
|
+
function validateString(value, fieldName, opts) {
|
|
60
38
|
const str = String(value ?? "");
|
|
61
39
|
if (!opts?.allowEmpty && !str.trim()) {
|
|
62
40
|
throw new Error(`${fieldName} 不能为空`);
|
|
@@ -72,22 +50,25 @@ function validateString(value: unknown, fieldName: string, opts?: { min?: number
|
|
|
72
50
|
}
|
|
73
51
|
return str;
|
|
74
52
|
}
|
|
75
|
-
|
|
76
|
-
function validateNumber(value: unknown, fieldName: string, opts?: { min?: number; max?: number; required?: boolean }): number {
|
|
53
|
+
function validateNumber(value, fieldName, opts) {
|
|
77
54
|
if (value === undefined || value === null) {
|
|
78
|
-
if (opts?.required)
|
|
55
|
+
if (opts?.required)
|
|
56
|
+
throw new Error(`${fieldName} 是必填项`);
|
|
79
57
|
return 0;
|
|
80
58
|
}
|
|
81
59
|
const num = Number(value);
|
|
82
|
-
if (isNaN(num))
|
|
83
|
-
|
|
84
|
-
if (opts?.
|
|
60
|
+
if (isNaN(num))
|
|
61
|
+
throw new Error(`${fieldName} 必须是数字`);
|
|
62
|
+
if (opts?.min !== undefined && num < opts.min)
|
|
63
|
+
throw new Error(`${fieldName} 不能小于 ${opts.min}`);
|
|
64
|
+
if (opts?.max !== undefined && num > opts.max)
|
|
65
|
+
throw new Error(`${fieldName} 不能大于 ${opts.max}`);
|
|
85
66
|
return num;
|
|
86
67
|
}
|
|
87
|
-
|
|
88
|
-
function validateArray<T>(value: unknown, fieldName: string, opts?: { min?: number; max?: number; required?: boolean }): any[] {
|
|
68
|
+
function validateArray(value, fieldName, opts) {
|
|
89
69
|
if (!Array.isArray(value)) {
|
|
90
|
-
if (opts?.required)
|
|
70
|
+
if (opts?.required)
|
|
71
|
+
throw new Error(`${fieldName} 必须是数组`);
|
|
91
72
|
return [];
|
|
92
73
|
}
|
|
93
74
|
if (opts?.min !== undefined && value.length < opts.min) {
|
|
@@ -98,15 +79,15 @@ function validateArray<T>(value: unknown, fieldName: string, opts?: { min?: numb
|
|
|
98
79
|
}
|
|
99
80
|
return value;
|
|
100
81
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
82
|
+
function validateCalendarAdmins(admins) {
|
|
83
|
+
if (!admins)
|
|
84
|
+
return undefined;
|
|
104
85
|
validateArray(admins, "admins", { max: CALENDAR_LIMITS.ADMINS_MAX });
|
|
105
86
|
return admins.map((id, i) => validateString(id, `admins[${i}]`, { allowEmpty: false }));
|
|
106
87
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
88
|
+
function validateCalendarShares(shares) {
|
|
89
|
+
if (!shares)
|
|
90
|
+
return undefined;
|
|
110
91
|
validateArray(shares, "shares", { max: CALENDAR_LIMITS.SHARES_MAX });
|
|
111
92
|
return shares.map((s, i) => {
|
|
112
93
|
const userid = validateString(s.userid, `shares[${i}].userid`, { allowEmpty: false });
|
|
@@ -116,10 +97,10 @@ function validateCalendarShares(shares?: Array<{ userid: string; permission?: 1
|
|
|
116
97
|
return { userid, permission: s.permission };
|
|
117
98
|
});
|
|
118
99
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const result
|
|
100
|
+
function validatePublicRange(publicRange) {
|
|
101
|
+
if (!publicRange)
|
|
102
|
+
return undefined;
|
|
103
|
+
const result = {};
|
|
123
104
|
if (publicRange.userids) {
|
|
124
105
|
validateArray(publicRange.userids, "public_range.userids", { max: CALENDAR_LIMITS.PUBLIC_USERS_MAX });
|
|
125
106
|
result.userids = publicRange.userids.map((id, i) => validateString(id, `public_range.userids[${i}]`, { allowEmpty: false }));
|
|
@@ -130,29 +111,28 @@ function validatePublicRange(publicRange?: { userids?: string[]; partyids?: numb
|
|
|
130
111
|
}
|
|
131
112
|
return result;
|
|
132
113
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
114
|
+
function validateScheduleAttendees(attendees) {
|
|
115
|
+
if (!attendees)
|
|
116
|
+
return undefined;
|
|
136
117
|
validateArray(attendees, "attendees", { max: CALENDAR_LIMITS.SCHEDULE_ATTENDEES_MAX });
|
|
137
118
|
return attendees.map((a, i) => ({
|
|
138
119
|
userid: validateString(a.userid, `attendees[${i}].userid`, { allowEmpty: false, max: 64 })
|
|
139
120
|
}));
|
|
140
121
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const result
|
|
145
|
-
|
|
122
|
+
function validateReminders(reminders) {
|
|
123
|
+
if (!reminders)
|
|
124
|
+
return undefined;
|
|
125
|
+
const result = {};
|
|
146
126
|
if (reminders.is_remind !== undefined) {
|
|
147
|
-
if (![0, 1].includes(reminders.is_remind))
|
|
127
|
+
if (![0, 1].includes(reminders.is_remind))
|
|
128
|
+
throw new Error("reminders.is_remind 必须是 0 或 1");
|
|
148
129
|
result.is_remind = reminders.is_remind;
|
|
149
130
|
}
|
|
150
|
-
|
|
151
131
|
if (reminders.is_repeat !== undefined) {
|
|
152
|
-
if (![0, 1].includes(reminders.is_repeat))
|
|
132
|
+
if (![0, 1].includes(reminders.is_repeat))
|
|
133
|
+
throw new Error("reminders.is_repeat 必须是 0 或 1");
|
|
153
134
|
result.is_repeat = reminders.is_repeat;
|
|
154
135
|
}
|
|
155
|
-
|
|
156
136
|
if (reminders.remind_before_event_secs !== undefined) {
|
|
157
137
|
const val = reminders.remind_before_event_secs;
|
|
158
138
|
if (!CALENDAR_LIMITS.REMINDER_BEFORE_EVENT_VALUES.includes(val)) {
|
|
@@ -160,143 +140,123 @@ function validateReminders(reminders?: any): any | undefined {
|
|
|
160
140
|
}
|
|
161
141
|
result.remind_before_event_secs = val;
|
|
162
142
|
}
|
|
163
|
-
|
|
164
143
|
if (reminders.remind_time_diffs !== undefined) {
|
|
165
144
|
validateArray(reminders.remind_time_diffs, "reminders.remind_time_diffs");
|
|
166
|
-
result.remind_time_diffs = reminders.remind_time_diffs.map((v
|
|
167
|
-
if (!CALENDAR_LIMITS.REMINDER_TIME_DIFFS_VALUES.includes(v
|
|
145
|
+
result.remind_time_diffs = reminders.remind_time_diffs.map((v, i) => {
|
|
146
|
+
if (!CALENDAR_LIMITS.REMINDER_TIME_DIFFS_VALUES.includes(v)) {
|
|
168
147
|
throw new Error(`reminders.remind_time_diffs[${i}] 必须是 ${CALENDAR_LIMITS.REMINDER_TIME_DIFFS_VALUES.join(",")}`);
|
|
169
148
|
}
|
|
170
|
-
return v
|
|
149
|
+
return v;
|
|
171
150
|
});
|
|
172
151
|
}
|
|
173
|
-
|
|
174
152
|
if (reminders.repeat_type !== undefined) {
|
|
175
153
|
if (!CALENDAR_LIMITS.REPEAT_TYPE_VALUES.includes(reminders.repeat_type)) {
|
|
176
154
|
throw new Error(`reminders.repeat_type 必须是 ${CALENDAR_LIMITS.REPEAT_TYPE_VALUES.join(",")}`);
|
|
177
155
|
}
|
|
178
156
|
result.repeat_type = reminders.repeat_type;
|
|
179
157
|
}
|
|
180
|
-
|
|
181
158
|
if (reminders.repeat_until !== undefined) {
|
|
182
159
|
result.repeat_until = validateNumber(reminders.repeat_until, "reminders.repeat_until", { min: 0 });
|
|
183
160
|
}
|
|
184
|
-
|
|
185
161
|
if (reminders.is_custom_repeat !== undefined) {
|
|
186
162
|
if (![0, 1].includes(reminders.is_custom_repeat)) {
|
|
187
163
|
throw new Error("reminders.is_custom_repeat 必须是 0 或 1");
|
|
188
164
|
}
|
|
189
165
|
result.is_custom_repeat = reminders.is_custom_repeat;
|
|
190
166
|
}
|
|
191
|
-
|
|
192
167
|
if (reminders.repeat_interval !== undefined) {
|
|
193
168
|
result.repeat_interval = validateNumber(reminders.repeat_interval, "reminders.repeat_interval", { min: 1 });
|
|
194
169
|
}
|
|
195
|
-
|
|
196
170
|
if (reminders.repeat_day_of_week !== undefined) {
|
|
197
171
|
validateArray(reminders.repeat_day_of_week, "reminders.repeat_day_of_week");
|
|
198
|
-
result.repeat_day_of_week = reminders.repeat_day_of_week.map((v
|
|
199
|
-
if (v < 1 || v > 7)
|
|
172
|
+
result.repeat_day_of_week = reminders.repeat_day_of_week.map((v, i) => {
|
|
173
|
+
if (v < 1 || v > 7)
|
|
174
|
+
throw new Error(`reminders.repeat_day_of_week[${i}] 必须是 1-7`);
|
|
200
175
|
return v;
|
|
201
176
|
});
|
|
202
177
|
}
|
|
203
|
-
|
|
204
178
|
if (reminders.repeat_day_of_month !== undefined) {
|
|
205
179
|
validateArray(reminders.repeat_day_of_month, "reminders.repeat_day_of_month");
|
|
206
|
-
result.repeat_day_of_month = reminders.repeat_day_of_month.map((v
|
|
207
|
-
if (v < 1 || v > 31)
|
|
180
|
+
result.repeat_day_of_month = reminders.repeat_day_of_month.map((v, i) => {
|
|
181
|
+
if (v < 1 || v > 31)
|
|
182
|
+
throw new Error(`reminders.repeat_day_of_month[${i}] 必须是 1-31`);
|
|
208
183
|
return v;
|
|
209
184
|
});
|
|
210
185
|
}
|
|
211
|
-
|
|
212
186
|
if (reminders.timezone !== undefined) {
|
|
213
187
|
result.timezone = validateNumber(reminders.timezone, "reminders.timezone", {
|
|
214
188
|
min: CALENDAR_LIMITS.TIMEZONE_MIN,
|
|
215
189
|
max: CALENDAR_LIMITS.TIMEZONE_MAX
|
|
216
190
|
});
|
|
217
191
|
}
|
|
218
|
-
|
|
219
192
|
if (reminders.exclude_time_list !== undefined) {
|
|
220
193
|
validateArray(reminders.exclude_time_list, "reminders.exclude_time_list");
|
|
221
|
-
result.exclude_time_list = reminders.exclude_time_list.map((item
|
|
194
|
+
result.exclude_time_list = reminders.exclude_time_list.map((item, i) => ({
|
|
222
195
|
start_time: validateNumber(item.start_time, `reminders.exclude_time_list[${i}].start_time`, { min: 0, required: true })
|
|
223
196
|
}));
|
|
224
197
|
}
|
|
225
|
-
|
|
226
198
|
return result;
|
|
227
199
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
if (!CALENDAR_LIMITS.OP_MODE_VALUES.includes(opMode
|
|
200
|
+
function validateOpMode(opMode) {
|
|
201
|
+
if (opMode === undefined)
|
|
202
|
+
return undefined;
|
|
203
|
+
if (!CALENDAR_LIMITS.OP_MODE_VALUES.includes(opMode)) {
|
|
232
204
|
throw new Error(`op_mode 必须是 ${CALENDAR_LIMITS.OP_MODE_VALUES.join(",")}`);
|
|
233
205
|
}
|
|
234
|
-
return opMode
|
|
206
|
+
return opMode;
|
|
235
207
|
}
|
|
236
|
-
|
|
237
208
|
// ============================================================================
|
|
238
209
|
// Helper Functions
|
|
239
210
|
// ============================================================================
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
let json: any;
|
|
211
|
+
async function parseResponse(res, label) {
|
|
212
|
+
let json;
|
|
243
213
|
try {
|
|
244
214
|
json = await res.json();
|
|
245
|
-
}
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
246
217
|
throw new Error(`${label}: 无效的 JSON 响应`);
|
|
247
218
|
}
|
|
248
|
-
|
|
249
219
|
if (!json || typeof json !== "object") {
|
|
250
220
|
throw new Error(`${label}: 空响应`);
|
|
251
221
|
}
|
|
252
|
-
|
|
253
222
|
if (Array.isArray(json)) {
|
|
254
|
-
const failed = json.find((i
|
|
255
|
-
if (failed)
|
|
256
|
-
|
|
223
|
+
const failed = json.find((i) => Number(i?.errcode ?? 0) !== 0);
|
|
224
|
+
if (failed)
|
|
225
|
+
throw new Error(`${label}: ${failed?.errmsg || "failed"} (${failed?.errcode})`);
|
|
226
|
+
return json;
|
|
257
227
|
}
|
|
258
|
-
|
|
259
228
|
const errCode = Number(json.errcode ?? 0);
|
|
260
229
|
if (errCode !== 0) {
|
|
261
230
|
throw new Error(`${label}: ${json.errmsg || "failed"} (${errCode})`);
|
|
262
231
|
}
|
|
263
|
-
|
|
264
|
-
return json as T;
|
|
232
|
+
return json;
|
|
265
233
|
}
|
|
266
|
-
|
|
267
|
-
function normalizeColor(color: string): string {
|
|
234
|
+
function normalizeColor(color) {
|
|
268
235
|
const trimmed = color.trim();
|
|
269
236
|
return trimmed.startsWith("#") ? trimmed : `#${trimmed}`;
|
|
270
237
|
}
|
|
271
|
-
|
|
272
238
|
// ============================================================================
|
|
273
239
|
// WecomCalendarClient Class
|
|
274
240
|
// ============================================================================
|
|
275
|
-
|
|
276
241
|
export class WecomCalendarClient {
|
|
277
|
-
|
|
242
|
+
async post(path, label, agent, body) {
|
|
278
243
|
if (!agent?.corpId || !agent?.corpSecret) {
|
|
279
244
|
throw new Error(`${label}: 账号配置不完整,需要 corpId 和 corpSecret`);
|
|
280
245
|
}
|
|
281
|
-
|
|
282
246
|
const token = await getAccessToken(agent);
|
|
283
247
|
const url = `https://qyapi.weixin.qq.com${path}?access_token=${encodeURIComponent(token)}`;
|
|
284
248
|
const proxyUrl = resolveWecomEgressProxyUrlFromNetwork(agent.network);
|
|
285
|
-
|
|
286
|
-
let lastError: Error | undefined;
|
|
249
|
+
let lastError;
|
|
287
250
|
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
288
251
|
try {
|
|
289
|
-
const res = await wecomFetch(
|
|
290
|
-
|
|
291
|
-
{
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
);
|
|
298
|
-
return await parseResponse<T>(res, label);
|
|
299
|
-
} catch (e) {
|
|
252
|
+
const res = await wecomFetch(url, {
|
|
253
|
+
method: "POST",
|
|
254
|
+
headers: { "content-type": "application/json" },
|
|
255
|
+
body: JSON.stringify(body || {}),
|
|
256
|
+
}, { proxyUrl, timeoutMs: LIMITS.REQUEST_TIMEOUT_MS });
|
|
257
|
+
return await parseResponse(res, label);
|
|
258
|
+
}
|
|
259
|
+
catch (e) {
|
|
300
260
|
lastError = e instanceof Error ? e : new Error(String(e));
|
|
301
261
|
if (attempt < 3) {
|
|
302
262
|
await new Promise(r => setTimeout(r, 1000 * attempt));
|
|
@@ -305,34 +265,28 @@ export class WecomCalendarClient {
|
|
|
305
265
|
}
|
|
306
266
|
throw lastError || new Error(`${label}: 请求失败`);
|
|
307
267
|
}
|
|
308
|
-
|
|
309
268
|
// ========================================================================
|
|
310
269
|
// Calendar APIs
|
|
311
270
|
// ========================================================================
|
|
312
|
-
|
|
313
271
|
/**
|
|
314
272
|
* 创建日历
|
|
315
273
|
* POST /cgi-bin/oa/calendar/add
|
|
316
274
|
*/
|
|
317
|
-
async createCalendar(p
|
|
275
|
+
async createCalendar(p) {
|
|
318
276
|
const calendar = p.request.calendar;
|
|
319
|
-
|
|
320
277
|
// 验证必填字段
|
|
321
278
|
const summary = validateString(calendar.summary, "calendar.summary", {
|
|
322
279
|
min: CALENDAR_LIMITS.SUMMARY_MIN_LENGTH,
|
|
323
280
|
max: CALENDAR_LIMITS.SUMMARY_MAX_LENGTH
|
|
324
281
|
});
|
|
325
282
|
const color = validateString(calendar.color, "calendar.color", { pattern: CALENDAR_LIMITS.COLOR_PATTERN });
|
|
326
|
-
|
|
327
283
|
// 验证可选字段
|
|
328
284
|
const description = calendar.description !== undefined
|
|
329
285
|
? validateString(calendar.description, "calendar.description", { max: CALENDAR_LIMITS.DESCRIPTION_MAX_LENGTH, allowEmpty: true })
|
|
330
286
|
: undefined;
|
|
331
|
-
|
|
332
287
|
const admins = validateCalendarAdmins(calendar.admins);
|
|
333
288
|
const shares = validateCalendarShares(calendar.shares);
|
|
334
289
|
const publicRange = validatePublicRange(calendar.public_range);
|
|
335
|
-
|
|
336
290
|
if (calendar.set_as_default !== undefined && ![0, 1].includes(calendar.set_as_default)) {
|
|
337
291
|
throw new Error("calendar.set_as_default 必须是 0 或 1");
|
|
338
292
|
}
|
|
@@ -342,7 +296,6 @@ export class WecomCalendarClient {
|
|
|
342
296
|
if (calendar.is_corp_calendar !== undefined && ![0, 1].includes(calendar.is_corp_calendar)) {
|
|
343
297
|
throw new Error("calendar.is_corp_calendar 必须是 0 或 1");
|
|
344
298
|
}
|
|
345
|
-
|
|
346
299
|
// 全员日历必须是公共日历且必须指定 public_range
|
|
347
300
|
if (calendar.is_corp_calendar === 1) {
|
|
348
301
|
if (calendar.is_public !== 1) {
|
|
@@ -352,8 +305,7 @@ export class WecomCalendarClient {
|
|
|
352
305
|
throw new Error("全员日历必须指定 public_range");
|
|
353
306
|
}
|
|
354
307
|
}
|
|
355
|
-
|
|
356
|
-
const request: CreateCalendarRequest = {
|
|
308
|
+
const request = {
|
|
357
309
|
calendar: {
|
|
358
310
|
summary,
|
|
359
311
|
color: normalizeColor(color),
|
|
@@ -366,23 +318,19 @@ export class WecomCalendarClient {
|
|
|
366
318
|
is_corp_calendar: calendar.is_corp_calendar,
|
|
367
319
|
},
|
|
368
320
|
};
|
|
369
|
-
|
|
370
321
|
if (p.request.agentid !== undefined) {
|
|
371
322
|
request.agentid = p.request.agentid;
|
|
372
323
|
}
|
|
373
|
-
|
|
374
|
-
const json = await this.post<CreateCalendarResponse>("/cgi-bin/oa/calendar/add", "create_calendar", p.agent, request);
|
|
324
|
+
const json = await this.post("/cgi-bin/oa/calendar/add", "create_calendar", p.agent, request);
|
|
375
325
|
return { raw: json, calId: json.cal_id };
|
|
376
326
|
}
|
|
377
|
-
|
|
378
327
|
/**
|
|
379
328
|
* 更新日历
|
|
380
329
|
* POST /cgi-bin/oa/calendar/update
|
|
381
330
|
* 注意:更新操作是覆盖式,不是增量式
|
|
382
331
|
*/
|
|
383
|
-
async updateCalendar(p
|
|
332
|
+
async updateCalendar(p) {
|
|
384
333
|
const calendar = p.request.calendar;
|
|
385
|
-
|
|
386
334
|
const calId = validateString(calendar.cal_id, "calendar.cal_id", { allowEmpty: false });
|
|
387
335
|
const summary = validateString(calendar.summary, "calendar.summary", {
|
|
388
336
|
min: CALENDAR_LIMITS.SUMMARY_MIN_LENGTH,
|
|
@@ -392,16 +340,13 @@ export class WecomCalendarClient {
|
|
|
392
340
|
const description = calendar.description !== undefined
|
|
393
341
|
? validateString(calendar.description, "calendar.description", { max: CALENDAR_LIMITS.DESCRIPTION_MAX_LENGTH, allowEmpty: true })
|
|
394
342
|
: undefined;
|
|
395
|
-
|
|
396
343
|
const admins = validateCalendarAdmins(calendar.admins);
|
|
397
344
|
const shares = validateCalendarShares(calendar.shares);
|
|
398
345
|
const publicRange = validatePublicRange(calendar.public_range);
|
|
399
|
-
|
|
400
346
|
if (p.request.skip_public_range !== undefined && ![0, 1].includes(p.request.skip_public_range)) {
|
|
401
347
|
throw new Error("skip_public_range 必须是 0 或 1");
|
|
402
348
|
}
|
|
403
|
-
|
|
404
|
-
const request: UpdateCalendarRequest = {
|
|
349
|
+
const request = {
|
|
405
350
|
calendar: {
|
|
406
351
|
cal_id: calId,
|
|
407
352
|
summary,
|
|
@@ -413,80 +358,65 @@ export class WecomCalendarClient {
|
|
|
413
358
|
},
|
|
414
359
|
skip_public_range: p.request.skip_public_range,
|
|
415
360
|
};
|
|
416
|
-
|
|
417
|
-
const json = await this.post<UpdateCalendarResponse>("/cgi-bin/oa/calendar/update", "update_calendar", p.agent, request);
|
|
361
|
+
const json = await this.post("/cgi-bin/oa/calendar/update", "update_calendar", p.agent, request);
|
|
418
362
|
return { raw: json, calId: calId };
|
|
419
363
|
}
|
|
420
|
-
|
|
421
364
|
/**
|
|
422
365
|
* 获取日历详情
|
|
423
366
|
* POST /cgi-bin/oa/calendar/get
|
|
424
367
|
*/
|
|
425
|
-
async getCalendar(p
|
|
368
|
+
async getCalendar(p) {
|
|
426
369
|
const calIdList = validateArray(p.request.cal_id_list, "cal_id_list", {
|
|
427
370
|
min: 1,
|
|
428
371
|
max: CALENDAR_LIMITS.CAL_ID_LIST_MAX,
|
|
429
372
|
required: true
|
|
430
373
|
}).map((id, i) => validateString(id, `cal_id_list[${i}]`, { allowEmpty: false }));
|
|
431
|
-
|
|
432
|
-
const
|
|
433
|
-
const json = await this.post<GetCalendarResponse>("/cgi-bin/oa/calendar/get", "get_calendar", p.agent, request);
|
|
374
|
+
const request = { cal_id_list: calIdList };
|
|
375
|
+
const json = await this.post("/cgi-bin/oa/calendar/get", "get_calendar", p.agent, request);
|
|
434
376
|
return { raw: json, calendarList: json.calendar_list || [] };
|
|
435
377
|
}
|
|
436
|
-
|
|
437
378
|
/**
|
|
438
379
|
* 删除日历
|
|
439
380
|
* POST /cgi-bin/oa/calendar/del
|
|
440
381
|
*/
|
|
441
|
-
async deleteCalendar(p
|
|
382
|
+
async deleteCalendar(p) {
|
|
442
383
|
const calId = validateString(p.calId, "calId", { allowEmpty: false });
|
|
443
|
-
const json = await this.post
|
|
384
|
+
const json = await this.post("/cgi-bin/oa/calendar/del", "delete_calendar", p.agent, { cal_id: calId });
|
|
444
385
|
return { raw: json, calId: calId };
|
|
445
386
|
}
|
|
446
|
-
|
|
447
387
|
// ========================================================================
|
|
448
388
|
// Schedule APIs
|
|
449
389
|
// ========================================================================
|
|
450
|
-
|
|
451
390
|
/**
|
|
452
391
|
* 创建日程
|
|
453
392
|
* POST /cgi-bin/oa/schedule/add
|
|
454
393
|
*/
|
|
455
|
-
async createSchedule(p
|
|
394
|
+
async createSchedule(p) {
|
|
456
395
|
const schedule = p.request.schedule;
|
|
457
|
-
|
|
458
396
|
const startTime = validateNumber(schedule.start_time, "schedule.start_time", { min: 0, required: true });
|
|
459
397
|
const endTime = validateNumber(schedule.end_time, "schedule.end_time", { min: 0, required: true });
|
|
460
|
-
|
|
461
398
|
if (endTime <= startTime) {
|
|
462
399
|
throw new Error("schedule.end_time 必须大于 schedule.start_time");
|
|
463
400
|
}
|
|
464
|
-
|
|
465
401
|
if (schedule.is_whole_day !== undefined && ![0, 1].includes(schedule.is_whole_day)) {
|
|
466
402
|
throw new Error("schedule.is_whole_day 必须是 0 或 1");
|
|
467
403
|
}
|
|
468
|
-
|
|
469
404
|
const summary = schedule.summary !== undefined
|
|
470
405
|
? validateString(schedule.summary, "schedule.summary", { max: CALENDAR_LIMITS.SCHEDULE_SUMMARY_MAX_LENGTH, allowEmpty: true })
|
|
471
406
|
: undefined;
|
|
472
|
-
|
|
473
407
|
const description = schedule.description !== undefined
|
|
474
408
|
? validateString(schedule.description, "schedule.description", { max: CALENDAR_LIMITS.SCHEDULE_DESCRIPTION_MAX_LENGTH, allowEmpty: true })
|
|
475
409
|
: undefined;
|
|
476
|
-
|
|
477
410
|
const location = schedule.location !== undefined
|
|
478
411
|
? validateString(schedule.location, "schedule.location", { max: CALENDAR_LIMITS.SCHEDULE_LOCATION_MAX_LENGTH, allowEmpty: true })
|
|
479
412
|
: undefined;
|
|
480
|
-
|
|
481
413
|
const admins = validateCalendarAdmins(schedule.admins);
|
|
482
414
|
const attendees = validateScheduleAttendees(schedule.attendees);
|
|
483
415
|
const reminders = validateReminders(schedule.reminders);
|
|
484
|
-
|
|
485
416
|
const calId = schedule.cal_id !== undefined
|
|
486
417
|
? validateString(schedule.cal_id, "schedule.cal_id", { max: 64, allowEmpty: true })
|
|
487
418
|
: undefined;
|
|
488
|
-
|
|
489
|
-
const request: CreateScheduleRequest = {
|
|
419
|
+
const request = {
|
|
490
420
|
schedule: {
|
|
491
421
|
start_time: startTime,
|
|
492
422
|
end_time: endTime,
|
|
@@ -500,61 +430,48 @@ export class WecomCalendarClient {
|
|
|
500
430
|
cal_id: calId,
|
|
501
431
|
},
|
|
502
432
|
};
|
|
503
|
-
|
|
504
433
|
if (p.request.agentid !== undefined) {
|
|
505
434
|
request.agentid = p.request.agentid;
|
|
506
435
|
}
|
|
507
|
-
|
|
508
|
-
const json = await this.post<CreateScheduleResponse>("/cgi-bin/oa/schedule/add", "create_schedule", p.agent, request);
|
|
436
|
+
const json = await this.post("/cgi-bin/oa/schedule/add", "create_schedule", p.agent, request);
|
|
509
437
|
return { raw: json, scheduleId: json.schedule_id };
|
|
510
438
|
}
|
|
511
|
-
|
|
512
439
|
/**
|
|
513
440
|
* 更新日程
|
|
514
441
|
* POST /cgi-bin/oa/schedule/update
|
|
515
442
|
* 注意:更新操作是覆盖式,不是增量式
|
|
516
443
|
*/
|
|
517
|
-
async updateSchedule(p
|
|
444
|
+
async updateSchedule(p) {
|
|
518
445
|
const schedule = p.request.schedule;
|
|
519
|
-
|
|
520
446
|
const scheduleId = validateString(schedule.schedule_id, "schedule.schedule_id", { allowEmpty: false });
|
|
521
447
|
const startTime = validateNumber(schedule.start_time, "schedule.start_time", { min: 0, required: true });
|
|
522
448
|
const endTime = validateNumber(schedule.end_time, "schedule.end_time", { min: 0, required: true });
|
|
523
|
-
|
|
524
449
|
if (endTime <= startTime) {
|
|
525
450
|
throw new Error("schedule.end_time 必须大于 schedule.start_time");
|
|
526
451
|
}
|
|
527
|
-
|
|
528
452
|
if (schedule.is_whole_day !== undefined && ![0, 1].includes(schedule.is_whole_day)) {
|
|
529
453
|
throw new Error("schedule.is_whole_day 必须是 0 或 1");
|
|
530
454
|
}
|
|
531
|
-
|
|
532
455
|
const summary = schedule.summary !== undefined
|
|
533
456
|
? validateString(schedule.summary, "schedule.summary", { max: CALENDAR_LIMITS.SCHEDULE_SUMMARY_MAX_LENGTH, allowEmpty: true })
|
|
534
457
|
: undefined;
|
|
535
|
-
|
|
536
458
|
const description = schedule.description !== undefined
|
|
537
459
|
? validateString(schedule.description, "schedule.description", { max: CALENDAR_LIMITS.SCHEDULE_DESCRIPTION_MAX_LENGTH, allowEmpty: true })
|
|
538
460
|
: undefined;
|
|
539
|
-
|
|
540
461
|
const location = schedule.location !== undefined
|
|
541
462
|
? validateString(schedule.location, "schedule.location", { max: CALENDAR_LIMITS.SCHEDULE_LOCATION_MAX_LENGTH, allowEmpty: true })
|
|
542
463
|
: undefined;
|
|
543
|
-
|
|
544
464
|
const admins = validateCalendarAdmins(schedule.admins);
|
|
545
465
|
const attendees = validateScheduleAttendees(schedule.attendees);
|
|
546
466
|
const reminders = validateReminders(schedule.reminders);
|
|
547
|
-
|
|
548
467
|
if (p.request.skip_attendees !== undefined && ![0, 1].includes(p.request.skip_attendees)) {
|
|
549
468
|
throw new Error("skip_attendees 必须是 0 或 1");
|
|
550
469
|
}
|
|
551
|
-
|
|
552
470
|
const opMode = validateOpMode(p.request.op_mode);
|
|
553
471
|
const opStartTime = p.request.op_start_time !== undefined
|
|
554
472
|
? validateNumber(p.request.op_start_time, "op_start_time", { min: 0 })
|
|
555
473
|
: undefined;
|
|
556
|
-
|
|
557
|
-
const request: UpdateScheduleRequest = {
|
|
474
|
+
const request = {
|
|
558
475
|
schedule: {
|
|
559
476
|
schedule_id: scheduleId,
|
|
560
477
|
start_time: startTime,
|
|
@@ -567,100 +484,84 @@ export class WecomCalendarClient {
|
|
|
567
484
|
attendees,
|
|
568
485
|
reminders,
|
|
569
486
|
},
|
|
570
|
-
skip_attendees: p.request.skip_attendees
|
|
571
|
-
op_mode: opMode
|
|
487
|
+
skip_attendees: p.request.skip_attendees,
|
|
488
|
+
op_mode: opMode,
|
|
572
489
|
op_start_time: opStartTime,
|
|
573
490
|
};
|
|
574
|
-
|
|
575
|
-
const json = await this.post<UpdateScheduleResponse>("/cgi-bin/oa/schedule/update", "update_schedule", p.agent, request);
|
|
491
|
+
const json = await this.post("/cgi-bin/oa/schedule/update", "update_schedule", p.agent, request);
|
|
576
492
|
return { raw: json, scheduleId: json.schedule_id || scheduleId };
|
|
577
493
|
}
|
|
578
|
-
|
|
579
494
|
/**
|
|
580
495
|
* 新增日程参与者
|
|
581
496
|
* POST /cgi-bin/oa/schedule/add_attendees
|
|
582
497
|
* 注意:该接口是增量式
|
|
583
498
|
*/
|
|
584
|
-
async addScheduleAttendees(p
|
|
499
|
+
async addScheduleAttendees(p) {
|
|
585
500
|
const scheduleId = validateString(p.request.schedule_id, "schedule_id", { allowEmpty: false });
|
|
586
501
|
const attendees = validateScheduleAttendees(p.request.attendees);
|
|
587
|
-
|
|
588
502
|
if (!attendees || attendees.length === 0) {
|
|
589
503
|
throw new Error("attendees 不能为空");
|
|
590
504
|
}
|
|
591
|
-
|
|
592
|
-
const request: AddScheduleAttendeesRequest = {
|
|
505
|
+
const request = {
|
|
593
506
|
schedule_id: scheduleId,
|
|
594
507
|
attendees,
|
|
595
508
|
};
|
|
596
|
-
|
|
597
|
-
const json = await this.post<AddScheduleAttendeesResponse>("/cgi-bin/oa/schedule/add_attendees", "add_attendees", p.agent, request);
|
|
509
|
+
const json = await this.post("/cgi-bin/oa/schedule/add_attendees", "add_attendees", p.agent, request);
|
|
598
510
|
return { raw: json, scheduleId: scheduleId };
|
|
599
511
|
}
|
|
600
|
-
|
|
601
512
|
/**
|
|
602
513
|
* 删除日程参与者
|
|
603
514
|
* POST /cgi-bin/oa/schedule/del_attendees
|
|
604
515
|
* 注意:该接口是增量式
|
|
605
516
|
*/
|
|
606
|
-
async deleteScheduleAttendees(p
|
|
517
|
+
async deleteScheduleAttendees(p) {
|
|
607
518
|
const scheduleId = validateString(p.request.schedule_id, "schedule_id", { allowEmpty: false });
|
|
608
519
|
const attendees = validateScheduleAttendees(p.request.attendees);
|
|
609
|
-
|
|
610
520
|
if (!attendees || attendees.length === 0) {
|
|
611
521
|
throw new Error("attendees 不能为空");
|
|
612
522
|
}
|
|
613
|
-
|
|
614
|
-
const request: DeleteScheduleAttendeesRequest = {
|
|
523
|
+
const request = {
|
|
615
524
|
schedule_id: scheduleId,
|
|
616
525
|
attendees,
|
|
617
526
|
};
|
|
618
|
-
|
|
619
|
-
const json = await this.post<DeleteScheduleAttendeesResponse>("/cgi-bin/oa/schedule/del_attendees", "del_attendees", p.agent, request);
|
|
527
|
+
const json = await this.post("/cgi-bin/oa/schedule/del_attendees", "del_attendees", p.agent, request);
|
|
620
528
|
return { raw: json, scheduleId: scheduleId };
|
|
621
529
|
}
|
|
622
|
-
|
|
623
530
|
/**
|
|
624
531
|
* 获取日历下的日程列表
|
|
625
532
|
* POST /cgi-bin/oa/schedule/get_by_calendar
|
|
626
533
|
*/
|
|
627
|
-
async getScheduleByCalendar(p
|
|
534
|
+
async getScheduleByCalendar(p) {
|
|
628
535
|
const calId = validateString(p.request.cal_id, "cal_id", { allowEmpty: false });
|
|
629
|
-
|
|
630
536
|
if (p.request.offset !== undefined && p.request.offset < 0) {
|
|
631
537
|
throw new Error("offset 不能小于 0");
|
|
632
538
|
}
|
|
633
|
-
|
|
634
539
|
let limit = p.request.limit;
|
|
635
540
|
if (limit !== undefined) {
|
|
636
541
|
if (limit < CALENDAR_LIMITS.GET_SCHEDULE_LIMIT_MIN || limit > CALENDAR_LIMITS.GET_SCHEDULE_LIMIT_MAX) {
|
|
637
542
|
throw new Error(`limit 必须在 ${CALENDAR_LIMITS.GET_SCHEDULE_LIMIT_MIN}-${CALENDAR_LIMITS.GET_SCHEDULE_LIMIT_MAX} 之间`);
|
|
638
543
|
}
|
|
639
544
|
}
|
|
640
|
-
|
|
641
|
-
const request: GetScheduleByCalendarRequest = {
|
|
545
|
+
const request = {
|
|
642
546
|
cal_id: calId,
|
|
643
547
|
offset: p.request.offset,
|
|
644
548
|
limit: limit,
|
|
645
549
|
};
|
|
646
|
-
|
|
647
|
-
const json = await this.post<GetScheduleByCalendarResponse>("/cgi-bin/oa/schedule/get_by_calendar", "get_by_calendar", p.agent, request);
|
|
550
|
+
const json = await this.post("/cgi-bin/oa/schedule/get_by_calendar", "get_by_calendar", p.agent, request);
|
|
648
551
|
return { raw: json, scheduleList: json.schedule_list || [] };
|
|
649
552
|
}
|
|
650
|
-
|
|
651
553
|
/**
|
|
652
554
|
* 获取日程详情
|
|
653
555
|
* POST /cgi-bin/oa/schedule/get
|
|
654
556
|
*/
|
|
655
|
-
async getSchedule(p
|
|
557
|
+
async getSchedule(p) {
|
|
656
558
|
const scheduleIdList = validateArray(p.request.schedule_id_list, "schedule_id_list", {
|
|
657
559
|
min: 1,
|
|
658
560
|
max: CALENDAR_LIMITS.SCHEDULE_ID_LIST_MAX,
|
|
659
561
|
required: true
|
|
660
562
|
}).map((id, i) => validateString(id, `schedule_id_list[${i}]`, { allowEmpty: false }));
|
|
661
|
-
|
|
662
|
-
const
|
|
663
|
-
const json = await this.post<GetScheduleResponse>("/cgi-bin/oa/schedule/get", "get_schedule", p.agent, request);
|
|
563
|
+
const request = { schedule_id_list: scheduleIdList };
|
|
564
|
+
const json = await this.post("/cgi-bin/oa/schedule/get", "get_schedule", p.agent, request);
|
|
664
565
|
return {
|
|
665
566
|
raw: json,
|
|
666
567
|
scheduleList: json.schedule_list || [],
|
|
@@ -668,77 +569,63 @@ export class WecomCalendarClient {
|
|
|
668
569
|
meetingLink: json.meeting_link,
|
|
669
570
|
};
|
|
670
571
|
}
|
|
671
|
-
|
|
672
572
|
/**
|
|
673
573
|
* 取消日程
|
|
674
574
|
* POST /cgi-bin/oa/schedule/del
|
|
675
575
|
*/
|
|
676
|
-
async deleteSchedule(p
|
|
576
|
+
async deleteSchedule(p) {
|
|
677
577
|
const scheduleId = validateString(p.request.schedule_id, "schedule_id", { allowEmpty: false });
|
|
678
578
|
const opMode = validateOpMode(p.request.op_mode);
|
|
679
579
|
const opStartTime = p.request.op_start_time !== undefined
|
|
680
580
|
? validateNumber(p.request.op_start_time, "op_start_time", { min: 0 })
|
|
681
581
|
: undefined;
|
|
682
|
-
|
|
683
|
-
const request: DeleteScheduleRequest = {
|
|
582
|
+
const request = {
|
|
684
583
|
schedule_id: scheduleId,
|
|
685
|
-
op_mode: opMode
|
|
584
|
+
op_mode: opMode,
|
|
686
585
|
op_start_time: opStartTime,
|
|
687
586
|
};
|
|
688
|
-
|
|
689
|
-
const json = await this.post<DeleteScheduleResponse>("/cgi-bin/oa/schedule/del", "delete_schedule", p.agent, request);
|
|
587
|
+
const json = await this.post("/cgi-bin/oa/schedule/del", "delete_schedule", p.agent, request);
|
|
690
588
|
return { raw: json, scheduleId: scheduleId };
|
|
691
589
|
}
|
|
692
|
-
|
|
693
590
|
// ========================================================================
|
|
694
591
|
// System Calendar APIs
|
|
695
592
|
// ========================================================================
|
|
696
|
-
|
|
697
593
|
/**
|
|
698
594
|
* 获取默认日历本 ID
|
|
699
595
|
* POST /cgi-bin/oa/calendar/get_system_calid
|
|
700
596
|
*/
|
|
701
|
-
async getSystemCalendarId(p
|
|
597
|
+
async getSystemCalendarId(p) {
|
|
702
598
|
const userid = validateString(p.userid, "userid", { allowEmpty: false });
|
|
703
|
-
const json = await this.post
|
|
599
|
+
const json = await this.post("/cgi-bin/oa/calendar/get_system_calid", "get_system_calid", p.agent, { userid });
|
|
704
600
|
return { raw: json, calId: json.cal_id };
|
|
705
601
|
}
|
|
706
|
-
|
|
707
602
|
/**
|
|
708
603
|
* 在默认日历本中创建日程
|
|
709
604
|
* POST /cgi-bin/oa/schedule/add_schedule_in_system_cal
|
|
710
605
|
*/
|
|
711
|
-
async createSystemSchedule(p
|
|
606
|
+
async createSystemSchedule(p) {
|
|
712
607
|
const schedule = p.request.schedule;
|
|
713
|
-
|
|
714
608
|
const organizer = validateString(schedule.organizer, "schedule.organizer", { allowEmpty: false });
|
|
715
609
|
const startTime = validateNumber(schedule.start_time, "schedule.start_time", { min: 0, required: true });
|
|
716
610
|
const endTime = validateNumber(schedule.end_time, "schedule.end_time", { min: 0, required: true });
|
|
717
|
-
|
|
718
611
|
if (endTime <= startTime) {
|
|
719
612
|
throw new Error("schedule.end_time 必须大于 schedule.start_time");
|
|
720
613
|
}
|
|
721
|
-
|
|
722
614
|
if (schedule.is_whole_day !== undefined && ![0, 1].includes(schedule.is_whole_day)) {
|
|
723
615
|
throw new Error("schedule.is_whole_day 必须是 0 或 1");
|
|
724
616
|
}
|
|
725
|
-
|
|
726
617
|
const summary = schedule.summary !== undefined
|
|
727
618
|
? validateString(schedule.summary, "schedule.summary", { max: CALENDAR_LIMITS.SCHEDULE_SUMMARY_MAX_LENGTH, allowEmpty: true })
|
|
728
619
|
: undefined;
|
|
729
|
-
|
|
730
620
|
const description = schedule.description !== undefined
|
|
731
621
|
? validateString(schedule.description, "schedule.description", { max: CALENDAR_LIMITS.SCHEDULE_DESCRIPTION_MAX_LENGTH, allowEmpty: true })
|
|
732
622
|
: undefined;
|
|
733
|
-
|
|
734
623
|
const location = schedule.location !== undefined
|
|
735
624
|
? validateString(schedule.location, "schedule.location", { max: CALENDAR_LIMITS.SCHEDULE_LOCATION_MAX_LENGTH, allowEmpty: true })
|
|
736
625
|
: undefined;
|
|
737
|
-
|
|
738
626
|
const attendees = validateScheduleAttendees(schedule.attendees);
|
|
739
627
|
const reminders = validateReminders(schedule.reminders);
|
|
740
|
-
|
|
741
|
-
const request: CreateSystemScheduleRequest = {
|
|
628
|
+
const request = {
|
|
742
629
|
schedule: {
|
|
743
630
|
organizer,
|
|
744
631
|
start_time: startTime,
|
|
@@ -751,61 +638,51 @@ export class WecomCalendarClient {
|
|
|
751
638
|
reminders,
|
|
752
639
|
},
|
|
753
640
|
};
|
|
754
|
-
|
|
755
|
-
const json = await this.post<CreateScheduleResponse>("/cgi-bin/oa/schedule/add_schedule_in_system_cal", "create_system_schedule", p.agent, request);
|
|
641
|
+
const json = await this.post("/cgi-bin/oa/schedule/add_schedule_in_system_cal", "create_system_schedule", p.agent, request);
|
|
756
642
|
return { raw: json, scheduleId: json.schedule_id };
|
|
757
643
|
}
|
|
758
|
-
|
|
759
644
|
/**
|
|
760
645
|
* 日程回执
|
|
761
646
|
* POST /cgi-bin/oa/schedule/respond
|
|
762
647
|
*/
|
|
763
|
-
async respondSchedule(p
|
|
648
|
+
async respondSchedule(p) {
|
|
764
649
|
const scheduleId = validateString(p.request.schedule_id, "schedule_id", { allowEmpty: false });
|
|
765
650
|
const opMode = validateOpMode(p.request.op_mode);
|
|
766
651
|
const opStartTime = p.request.op_start_time !== undefined
|
|
767
652
|
? validateNumber(p.request.op_start_time, "op_start_time", { min: 0 })
|
|
768
653
|
: undefined;
|
|
769
|
-
|
|
770
654
|
const attendee = validateString(p.request.attendee, "attendee", { allowEmpty: false });
|
|
771
|
-
|
|
772
655
|
if (!CALENDAR_LIMITS.RESPONSE_STATUS_VALUES.includes(p.request.response_status)) {
|
|
773
656
|
throw new Error(`response_status 必须是 ${CALENDAR_LIMITS.RESPONSE_STATUS_VALUES.join(",")}`);
|
|
774
657
|
}
|
|
775
|
-
|
|
776
|
-
const request: RespondScheduleRequest = {
|
|
658
|
+
const request = {
|
|
777
659
|
schedule_id: scheduleId,
|
|
778
|
-
op_mode: opMode
|
|
660
|
+
op_mode: opMode,
|
|
779
661
|
op_start_time: opStartTime,
|
|
780
662
|
attendee,
|
|
781
|
-
response_status: p.request.response_status
|
|
663
|
+
response_status: p.request.response_status,
|
|
782
664
|
};
|
|
783
|
-
|
|
784
|
-
const json = await this.post<RespondScheduleResponse>("/cgi-bin/oa/schedule/respond", "respond_schedule", p.agent, request);
|
|
665
|
+
const json = await this.post("/cgi-bin/oa/schedule/respond", "respond_schedule", p.agent, request);
|
|
785
666
|
return { raw: json, scheduleId: scheduleId };
|
|
786
667
|
}
|
|
787
|
-
|
|
788
668
|
/**
|
|
789
669
|
* 同步日程
|
|
790
670
|
* POST /cgi-bin/oa/schedule/sync
|
|
791
671
|
*/
|
|
792
|
-
async syncSchedule(p
|
|
672
|
+
async syncSchedule(p) {
|
|
793
673
|
const calId = validateString(p.request.cal_id, "cal_id", { allowEmpty: false });
|
|
794
|
-
|
|
795
674
|
let limit = p.request.limit;
|
|
796
675
|
if (limit !== undefined) {
|
|
797
676
|
if (limit < CALENDAR_LIMITS.GET_SCHEDULE_LIMIT_MIN || limit > CALENDAR_LIMITS.GET_SCHEDULE_LIMIT_MAX) {
|
|
798
677
|
throw new Error(`limit 必须在 ${CALENDAR_LIMITS.GET_SCHEDULE_LIMIT_MIN}-${CALENDAR_LIMITS.GET_SCHEDULE_LIMIT_MAX} 之间`);
|
|
799
678
|
}
|
|
800
679
|
}
|
|
801
|
-
|
|
802
|
-
const request: SyncScheduleRequest = {
|
|
680
|
+
const request = {
|
|
803
681
|
cal_id: calId,
|
|
804
682
|
cursor: p.request.cursor,
|
|
805
683
|
limit: limit,
|
|
806
684
|
};
|
|
807
|
-
|
|
808
|
-
const json = await this.post<SyncScheduleResponse>("/cgi-bin/oa/schedule/sync", "sync_schedule", p.agent, request);
|
|
685
|
+
const json = await this.post("/cgi-bin/oa/schedule/sync", "sync_schedule", p.agent, request);
|
|
809
686
|
return {
|
|
810
687
|
raw: json,
|
|
811
688
|
nextCursor: json.next_cursor,
|