@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.
Files changed (323) hide show
  1. package/README.md +4 -5
  2. package/dist/index.js +68 -0
  3. package/dist/src/accounts.js +20 -0
  4. package/dist/src/agent/handler.js +895 -0
  5. package/dist/src/agent/index.js +5 -0
  6. package/dist/src/app/account-runtime.js +216 -0
  7. package/dist/src/app/bootstrap.js +19 -0
  8. package/dist/src/app/index.js +118 -0
  9. package/dist/src/capability/agent/delivery-service.js +63 -0
  10. package/dist/src/capability/agent/fallback-policy.js +6 -0
  11. package/dist/src/capability/agent/ingress-service.js +33 -0
  12. package/dist/src/capability/agent/upstream-delivery-service.js +71 -0
  13. package/dist/src/capability/bot/dispatch-config.js +45 -0
  14. package/dist/src/capability/bot/fallback-delivery.js +147 -0
  15. package/dist/src/capability/bot/local-path-delivery.js +178 -0
  16. package/dist/src/capability/bot/sandbox-media.js +138 -0
  17. package/dist/src/capability/bot/service.js +49 -0
  18. package/dist/src/capability/bot/stream-delivery.js +321 -0
  19. package/dist/src/capability/bot/stream-finalizer.js +81 -0
  20. package/dist/src/capability/bot/stream-orchestrator.js +318 -0
  21. package/dist/src/capability/bot/types.js +1 -0
  22. package/{src/capability/calendar/client.ts → dist/src/capability/calendar/client.js} +118 -241
  23. package/{src/capability/calendar/schema.ts → dist/src/capability/calendar/schema.js} +0 -38
  24. package/dist/src/capability/calendar/tool.js +365 -0
  25. package/dist/src/capability/calendar/types.js +12 -0
  26. package/{src/capability/doc/client.ts → dist/src/capability/doc/client.js} +370 -605
  27. package/{src/capability/doc/schema.ts → dist/src/capability/doc/schema.js} +345 -394
  28. package/dist/src/capability/doc/tool.js +1556 -0
  29. package/dist/src/capability/doc/types.js +113 -0
  30. package/dist/src/capability/mcp/index.js +3 -0
  31. package/dist/src/capability/mcp/schema.js +102 -0
  32. package/dist/src/capability/mcp/tool.js +146 -0
  33. package/dist/src/capability/mcp/transport.js +293 -0
  34. package/dist/src/channel.js +224 -0
  35. package/dist/src/config/accounts.js +236 -0
  36. package/dist/src/config/derived-paths.js +31 -0
  37. package/dist/src/config/index.js +7 -0
  38. package/dist/src/config/media.js +110 -0
  39. package/dist/src/config/network.js +32 -0
  40. package/dist/src/config/routing.js +20 -0
  41. package/dist/src/config/runtime-config.js +25 -0
  42. package/dist/src/config/schema.js +4 -0
  43. package/{src/config-schema.ts → dist/src/config-schema.js} +1 -1
  44. package/dist/src/context-store.js +219 -0
  45. package/{src/crypto/aes.ts → dist/src/crypto/aes.js} +11 -28
  46. package/dist/src/crypto/index.js +9 -0
  47. package/{src/crypto/signature.ts → dist/src/crypto/signature.js} +3 -18
  48. package/{src/crypto/xml.ts → dist/src/crypto/xml.js} +3 -11
  49. package/dist/src/crypto.js +145 -0
  50. package/dist/src/domain/models.js +1 -0
  51. package/dist/src/domain/policies.js +32 -0
  52. package/{src/dynamic-agent.ts → dist/src/dynamic-agent.js} +36 -73
  53. package/dist/src/gateway-monitor.js +139 -0
  54. package/dist/src/http.js +114 -0
  55. package/{src/media.ts → dist/src/media.js} +21 -40
  56. package/dist/src/monitor/limits.js +7 -0
  57. package/dist/src/monitor/state.js +28 -0
  58. package/dist/src/monitor.js +84 -0
  59. package/dist/src/observability/audit-log.js +30 -0
  60. package/dist/src/observability/legacy-operational-event-store.js +22 -0
  61. package/dist/src/observability/raw-envelope-log.js +24 -0
  62. package/dist/src/observability/status-registry.js +9 -0
  63. package/dist/src/observability/transport-session-view.js +14 -0
  64. package/dist/src/onboarding.js +546 -0
  65. package/dist/src/outbound.js +557 -0
  66. package/dist/src/runtime/dispatcher.js +57 -0
  67. package/{src/runtime/index.ts → dist/src/runtime/index.js} +0 -1
  68. package/dist/src/runtime/outbound-intent.js +1 -0
  69. package/dist/src/runtime/reply-orchestrator.js +38 -0
  70. package/dist/src/runtime/routing-bridge.js +26 -0
  71. package/dist/src/runtime/session-manager.js +112 -0
  72. package/dist/src/runtime/source-registry.js +174 -0
  73. package/dist/src/runtime.js +1 -0
  74. package/dist/src/shared/command-auth.js +57 -0
  75. package/{src/shared/index.ts → dist/src/shared/index.js} +0 -1
  76. package/dist/src/shared/media-asset.js +65 -0
  77. package/dist/src/shared/media-service.js +59 -0
  78. package/dist/src/shared/media-types.js +1 -0
  79. package/{src/shared/xml-parser.ts → dist/src/shared/xml-parser.js} +72 -63
  80. package/dist/src/store/active-reply-store.js +41 -0
  81. package/dist/src/store/interfaces.js +1 -0
  82. package/dist/src/store/memory-store.js +33 -0
  83. package/dist/src/store/stream-batch-store.js +319 -0
  84. package/{src/target.ts → dist/src/target.js} +15 -48
  85. package/dist/src/transport/agent-api/client.js +168 -0
  86. package/dist/src/transport/agent-api/core.js +337 -0
  87. package/dist/src/transport/agent-api/delivery.js +28 -0
  88. package/dist/src/transport/agent-api/media-upload.js +4 -0
  89. package/dist/src/transport/agent-api/reply.js +24 -0
  90. package/dist/src/transport/agent-api/upstream-delivery.js +30 -0
  91. package/dist/src/transport/agent-api/upstream-media-upload.js +46 -0
  92. package/dist/src/transport/agent-api/upstream-reply.js +26 -0
  93. package/dist/src/transport/agent-callback/http-handler.js +30 -0
  94. package/dist/src/transport/agent-callback/inbound.js +4 -0
  95. package/dist/src/transport/agent-callback/reply.js +8 -0
  96. package/dist/src/transport/agent-callback/request-handler.js +189 -0
  97. package/dist/src/transport/agent-callback/session.js +15 -0
  98. package/dist/src/transport/bot-webhook/active-reply.js +27 -0
  99. package/dist/src/transport/bot-webhook/http-handler.js +31 -0
  100. package/dist/src/transport/bot-webhook/inbound-normalizer.js +496 -0
  101. package/dist/src/transport/bot-webhook/inbound.js +4 -0
  102. package/dist/src/transport/bot-webhook/message-shape.js +98 -0
  103. package/dist/src/transport/bot-webhook/protocol.js +124 -0
  104. package/dist/src/transport/bot-webhook/reply.js +9 -0
  105. package/dist/src/transport/bot-webhook/request-handler.js +285 -0
  106. package/dist/src/transport/bot-webhook/session.js +15 -0
  107. package/dist/src/transport/bot-ws/inbound.js +147 -0
  108. package/dist/src/transport/bot-ws/media.js +236 -0
  109. package/dist/src/transport/bot-ws/reply.js +310 -0
  110. package/dist/src/transport/bot-ws/sdk-adapter.js +257 -0
  111. package/dist/src/transport/bot-ws/session.js +15 -0
  112. package/dist/src/transport/http/common.js +78 -0
  113. package/dist/src/transport/http/registry.js +71 -0
  114. package/dist/src/transport/http/request-handler.js +51 -0
  115. package/{src/transport/index.ts → dist/src/transport/index.js} +2 -10
  116. package/dist/src/types/account.js +1 -0
  117. package/dist/src/types/config.js +1 -0
  118. package/dist/src/types/constants.js +28 -0
  119. package/dist/src/types/events.js +1 -0
  120. package/dist/src/types/index.js +1 -0
  121. package/dist/src/types/legacy-stream.js +1 -0
  122. package/dist/src/types/message.js +5 -0
  123. package/dist/src/types/runtime-context.js +1 -0
  124. package/dist/src/types/runtime.js +1 -0
  125. package/dist/src/types.js +1 -0
  126. package/dist/src/upstream/index.js +111 -0
  127. package/dist/src/wecom_msg_adapter/markdown_adapter.js +280 -0
  128. package/openclaw.plugin.json +15 -0
  129. package/package.json +18 -1
  130. package/.github/workflows/release.yml +0 -143
  131. package/GOVERNANCE.md +0 -26
  132. package/MENU_EVENT_CONF.md +0 -500
  133. package/MENU_EVENT_PLAN.md +0 -440
  134. package/SKILLS_CAL.md +0 -895
  135. package/SKILLS_DOC.md +0 -2288
  136. package/UPSTREAM_CONFIG.md +0 -170
  137. package/UPSTREAM_PLAN.md +0 -175
  138. package/assets/01.bot-add.png +0 -0
  139. package/assets/01.bot-setp2.png +0 -0
  140. package/assets/01.image.jpg +0 -0
  141. package/assets/02.agent.add.png +0 -0
  142. package/assets/02.agent.api-set.png +0 -0
  143. package/assets/02.image.jpg +0 -0
  144. package/assets/03.agent.page.png +0 -0
  145. package/assets/03.bot.page.png +0 -0
  146. package/assets/link-me.jpg +0 -0
  147. package/assets/register.png +0 -0
  148. package/changelog/v2.2.28.md +0 -70
  149. package/changelog/v2.3.10.md +0 -17
  150. package/changelog/v2.3.11.md +0 -19
  151. package/changelog/v2.3.12.md +0 -25
  152. package/changelog/v2.3.13.md +0 -19
  153. package/changelog/v2.3.14.md +0 -48
  154. package/changelog/v2.3.15.md +0 -15
  155. package/changelog/v2.3.16.md +0 -11
  156. package/changelog/v2.3.18.md +0 -22
  157. package/changelog/v2.3.19.md +0 -73
  158. package/changelog/v2.3.2.md +0 -28
  159. package/changelog/v2.3.26.md +0 -21
  160. package/changelog/v2.3.27.md +0 -33
  161. package/changelog/v2.3.4.md +0 -20
  162. package/changelog/v2.3.9.md +0 -22
  163. package/changelog/v2.4.12.md +0 -37
  164. package/compat-single-account.md +0 -148
  165. package/index.test.ts +0 -38
  166. package/scripts/test-proxy.ts +0 -70
  167. package/scripts/wecom/README.md +0 -123
  168. package/scripts/wecom/menu-click-help.js +0 -59
  169. package/scripts/wecom/menu-click-help.py +0 -55
  170. package/src/accounts.ts +0 -34
  171. package/src/agent/api-client.upload.test.ts +0 -109
  172. package/src/agent/event-router.test.ts +0 -421
  173. package/src/agent/event-router.ts +0 -272
  174. package/src/agent/handler.event-filter.test.ts +0 -135
  175. package/src/agent/handler.ts +0 -1250
  176. package/src/agent/index.ts +0 -12
  177. package/src/agent/script-runner.ts +0 -186
  178. package/src/agent/test-fixtures/invalid-json-script.mjs +0 -1
  179. package/src/agent/test-fixtures/reply-event-script.mjs +0 -29
  180. package/src/agent/test-fixtures/reply-event-script.py +0 -17
  181. package/src/app/account-runtime.ts +0 -276
  182. package/src/app/bootstrap.ts +0 -29
  183. package/src/app/index.ts +0 -192
  184. package/src/capability/agent/delivery-service.ts +0 -87
  185. package/src/capability/agent/fallback-policy.ts +0 -13
  186. package/src/capability/agent/ingress-service.ts +0 -38
  187. package/src/capability/agent/upstream-delivery-service.ts +0 -96
  188. package/src/capability/bot/dispatch-config.ts +0 -47
  189. package/src/capability/bot/fallback-delivery.ts +0 -178
  190. package/src/capability/bot/local-path-delivery.ts +0 -215
  191. package/src/capability/bot/sandbox-media.test.ts +0 -221
  192. package/src/capability/bot/sandbox-media.ts +0 -176
  193. package/src/capability/bot/service.ts +0 -56
  194. package/src/capability/bot/stream-delivery.ts +0 -379
  195. package/src/capability/bot/stream-finalizer.ts +0 -120
  196. package/src/capability/bot/stream-orchestrator.ts +0 -371
  197. package/src/capability/bot/types.ts +0 -8
  198. package/src/capability/calendar/SKILLS_CHECKLIST.md +0 -251
  199. package/src/capability/calendar/tool.ts +0 -417
  200. package/src/capability/calendar/types.ts +0 -309
  201. package/src/capability/doc/tool.ts +0 -1629
  202. package/src/capability/doc/types.ts +0 -792
  203. package/src/capability/mcp/index.ts +0 -10
  204. package/src/capability/mcp/schema.ts +0 -107
  205. package/src/capability/mcp/tool.ts +0 -174
  206. package/src/capability/mcp/transport.ts +0 -394
  207. package/src/channel.config.test.ts +0 -180
  208. package/src/channel.lifecycle.test.ts +0 -255
  209. package/src/channel.meta.test.ts +0 -26
  210. package/src/channel.ts +0 -256
  211. package/src/config/accounts.resolve.test.ts +0 -75
  212. package/src/config/accounts.ts +0 -312
  213. package/src/config/derived-paths.test.ts +0 -111
  214. package/src/config/derived-paths.ts +0 -41
  215. package/src/config/index.ts +0 -22
  216. package/src/config/media.test.ts +0 -113
  217. package/src/config/media.ts +0 -139
  218. package/src/config/network.ts +0 -20
  219. package/src/config/routing.test.ts +0 -88
  220. package/src/config/routing.ts +0 -26
  221. package/src/config/runtime-config.ts +0 -46
  222. package/src/config/schema.ts +0 -144
  223. package/src/context-store.ts +0 -297
  224. package/src/crypto/index.ts +0 -24
  225. package/src/crypto.test.ts +0 -32
  226. package/src/crypto.ts +0 -176
  227. package/src/domain/models.ts +0 -7
  228. package/src/domain/policies.ts +0 -36
  229. package/src/dynamic-agent.account-scope.test.ts +0 -17
  230. package/src/gateway-monitor.ts +0 -181
  231. package/src/http.ts +0 -137
  232. package/src/media.test.ts +0 -82
  233. package/src/monitor/limits.ts +0 -7
  234. package/src/monitor/state.queue.test.ts +0 -185
  235. package/src/monitor/state.ts +0 -34
  236. package/src/monitor.active.test.ts +0 -245
  237. package/src/monitor.inbound-filter.test.ts +0 -63
  238. package/src/monitor.integration.test.ts +0 -208
  239. package/src/monitor.ts +0 -121
  240. package/src/monitor.webhook.test.ts +0 -774
  241. package/src/observability/audit-log.ts +0 -48
  242. package/src/observability/legacy-operational-event-store.ts +0 -36
  243. package/src/observability/raw-envelope-log.ts +0 -28
  244. package/src/observability/status-registry.ts +0 -13
  245. package/src/observability/transport-session-view.ts +0 -14
  246. package/src/onboarding.test.ts +0 -336
  247. package/src/onboarding.ts +0 -704
  248. package/src/outbound.test.ts +0 -1271
  249. package/src/outbound.ts +0 -746
  250. package/src/runtime/dispatcher.ts +0 -71
  251. package/src/runtime/outbound-intent.ts +0 -4
  252. package/src/runtime/reply-orchestrator.test.ts +0 -71
  253. package/src/runtime/reply-orchestrator.ts +0 -67
  254. package/src/runtime/routing-bridge.test.ts +0 -115
  255. package/src/runtime/routing-bridge.ts +0 -44
  256. package/src/runtime/session-manager.test.ts +0 -174
  257. package/src/runtime/session-manager.ts +0 -139
  258. package/src/runtime/source-registry.ts +0 -249
  259. package/src/runtime.ts +0 -14
  260. package/src/shared/command-auth.ts +0 -87
  261. package/src/shared/media-asset.ts +0 -78
  262. package/src/shared/media-service.test.ts +0 -111
  263. package/src/shared/media-service.ts +0 -84
  264. package/src/shared/media-types.ts +0 -5
  265. package/src/shared/xml-parser.test.ts +0 -50
  266. package/src/store/active-reply-store.ts +0 -42
  267. package/src/store/interfaces.ts +0 -11
  268. package/src/store/memory-store.ts +0 -43
  269. package/src/store/stream-batch-store.ts +0 -350
  270. package/src/transport/agent-api/client.ts +0 -277
  271. package/src/transport/agent-api/core.ts +0 -463
  272. package/src/transport/agent-api/delivery.ts +0 -41
  273. package/src/transport/agent-api/media-upload.ts +0 -11
  274. package/src/transport/agent-api/reply.ts +0 -39
  275. package/src/transport/agent-api/upstream-delivery.ts +0 -45
  276. package/src/transport/agent-api/upstream-media-upload.ts +0 -70
  277. package/src/transport/agent-api/upstream-reply.ts +0 -43
  278. package/src/transport/agent-callback/http-handler.ts +0 -47
  279. package/src/transport/agent-callback/inbound.ts +0 -5
  280. package/src/transport/agent-callback/reply.ts +0 -13
  281. package/src/transport/agent-callback/request-handler.ts +0 -244
  282. package/src/transport/agent-callback/session.ts +0 -23
  283. package/src/transport/bot-webhook/active-reply.ts +0 -39
  284. package/src/transport/bot-webhook/http-handler.ts +0 -48
  285. package/src/transport/bot-webhook/inbound-normalizer.ts +0 -371
  286. package/src/transport/bot-webhook/inbound.ts +0 -5
  287. package/src/transport/bot-webhook/message-shape.ts +0 -89
  288. package/src/transport/bot-webhook/protocol.ts +0 -148
  289. package/src/transport/bot-webhook/reply.ts +0 -15
  290. package/src/transport/bot-webhook/request-handler.ts +0 -394
  291. package/src/transport/bot-webhook/session.ts +0 -23
  292. package/src/transport/bot-ws/inbound.test.ts +0 -96
  293. package/src/transport/bot-ws/inbound.ts +0 -116
  294. package/src/transport/bot-ws/media.test.ts +0 -44
  295. package/src/transport/bot-ws/media.ts +0 -321
  296. package/src/transport/bot-ws/reply.test.ts +0 -450
  297. package/src/transport/bot-ws/reply.ts +0 -365
  298. package/src/transport/bot-ws/sdk-adapter.test.ts +0 -187
  299. package/src/transport/bot-ws/sdk-adapter.ts +0 -314
  300. package/src/transport/bot-ws/session.ts +0 -28
  301. package/src/transport/http/common.ts +0 -109
  302. package/src/transport/http/registry.ts +0 -92
  303. package/src/transport/http/request-handler.ts +0 -84
  304. package/src/types/account.ts +0 -72
  305. package/src/types/config.ts +0 -166
  306. package/src/types/constants.ts +0 -31
  307. package/src/types/events.ts +0 -21
  308. package/src/types/global.d.ts +0 -9
  309. package/src/types/index.ts +0 -17
  310. package/src/types/legacy-stream.ts +0 -50
  311. package/src/types/message.ts +0 -187
  312. package/src/types/runtime-context.ts +0 -28
  313. package/src/types/runtime.ts +0 -165
  314. package/src/types.ts +0 -41
  315. package/src/upstream/index.ts +0 -150
  316. package/src/upstream.test.ts +0 -84
  317. package/src/wecom_msg_adapter/markdown_adapter.ts +0 -331
  318. package/tsconfig.json +0 -22
  319. package/vitest.config.ts +0 -26
  320. /package/{src/capability/agent/index.ts → dist/src/capability/agent/index.js} +0 -0
  321. /package/{src/capability/bot/index.ts → dist/src/capability/bot/index.js} +0 -0
  322. /package/{src/capability/calendar/index.ts → dist/src/capability/calendar/index.js} +0 -0
  323. /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
- } as const;
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) throw new Error(`${fieldName} 是必填项`);
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)) throw new Error(`${fieldName} 必须是数字`);
83
- if (opts?.min !== undefined && num < opts.min) throw new Error(`${fieldName} 不能小于 ${opts.min}`);
84
- if (opts?.max !== undefined && num > opts.max) throw new Error(`${fieldName} 不能大于 ${opts.max}`);
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) throw new Error(`${fieldName} 必须是数组`);
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
- function validateCalendarAdmins(admins?: string[]): string[] | undefined {
103
- if (!admins) return undefined;
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
- function validateCalendarShares(shares?: Array<{ userid: string; permission?: 1 | 3 }>): Array<{ userid: string; permission?: 1 | 3 }> | undefined {
109
- if (!shares) return undefined;
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
- function validatePublicRange(publicRange?: { userids?: string[]; partyids?: number[] }): { userids?: string[]; partyids?: number[] } | undefined {
121
- if (!publicRange) return undefined;
122
- const result: { userids?: string[]; partyids?: number[] } = {};
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
- function validateScheduleAttendees(attendees?: Array<{ userid: string }>): Array<{ userid: string }> | undefined {
135
- if (!attendees) return undefined;
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
- function validateReminders(reminders?: any): any | undefined {
143
- if (!reminders) return undefined;
144
- const result: any = {};
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)) throw new Error("reminders.is_remind 必须是 0 或 1");
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)) throw new Error("reminders.is_repeat 必须是 0 或 1");
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: number, i: number) => {
167
- if (!CALENDAR_LIMITS.REMINDER_TIME_DIFFS_VALUES.includes(v as any)) {
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 as any;
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: number, i: number) => {
199
- if (v < 1 || v > 7) throw new Error(`reminders.repeat_day_of_week[${i}] 必须是 1-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: number, i: number) => {
207
- if (v < 1 || v > 31) throw new Error(`reminders.repeat_day_of_month[${i}] 必须是 1-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: any, i: number) => ({
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
- function validateOpMode(opMode?: number): 0 | 1 | 2 | undefined {
230
- if (opMode === undefined) return undefined;
231
- if (!CALENDAR_LIMITS.OP_MODE_VALUES.includes(opMode as any)) {
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 as 0 | 1 | 2;
206
+ return opMode;
235
207
  }
236
-
237
208
  // ============================================================================
238
209
  // Helper Functions
239
210
  // ============================================================================
240
-
241
- async function parseResponse<T>(res: Response, label: string): Promise<T> {
242
- let json: any;
211
+ async function parseResponse(res, label) {
212
+ let json;
243
213
  try {
244
214
  json = await res.json();
245
- } catch {
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: any) => Number(i?.errcode ?? 0) !== 0);
255
- if (failed) throw new Error(`${label}: ${failed?.errmsg || "failed"} (${failed?.errcode})`);
256
- return json as T;
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
- private async post<T>(path: string, label: string, agent: ResolvedAgentAccount, body: any): Promise<T> {
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
- url,
291
- {
292
- method: "POST",
293
- headers: { "content-type": "application/json" },
294
- body: JSON.stringify(body || {}),
295
- },
296
- { proxyUrl, timeoutMs: LIMITS.REQUEST_TIMEOUT_MS }
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: { agent: ResolvedAgentAccount; request: CreateCalendarRequest }): Promise<{ raw: CreateCalendarResponse; calId: string }> {
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: { agent: ResolvedAgentAccount; request: UpdateCalendarRequest }): Promise<{ raw: UpdateCalendarResponse; calId: string }> {
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: { agent: ResolvedAgentAccount; request: GetCalendarRequest }): Promise<{ raw: GetCalendarResponse; calendarList: CalendarInfo[] }> {
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 request: GetCalendarRequest = { cal_id_list: calIdList };
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: { agent: ResolvedAgentAccount; calId: string }): Promise<{ raw: DeleteCalendarResponse; calId: string }> {
382
+ async deleteCalendar(p) {
442
383
  const calId = validateString(p.calId, "calId", { allowEmpty: false });
443
- const json = await this.post<DeleteCalendarResponse>("/cgi-bin/oa/calendar/del", "delete_calendar", p.agent, { cal_id: calId });
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: { agent: ResolvedAgentAccount; request: CreateScheduleRequest }): Promise<{ raw: CreateScheduleResponse; scheduleId: string }> {
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: { agent: ResolvedAgentAccount; request: UpdateScheduleRequest }): Promise<{ raw: UpdateScheduleResponse; scheduleId: string }> {
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 as any,
571
- op_mode: opMode as any,
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: { agent: ResolvedAgentAccount; request: AddScheduleAttendeesRequest }): Promise<{ raw: AddScheduleAttendeesResponse; scheduleId: string }> {
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: { agent: ResolvedAgentAccount; request: DeleteScheduleAttendeesRequest }): Promise<{ raw: DeleteScheduleAttendeesResponse; scheduleId: string }> {
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: { agent: ResolvedAgentAccount; request: GetScheduleByCalendarRequest }): Promise<{ raw: GetScheduleByCalendarResponse; scheduleList: ScheduleInfo[] }> {
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: { agent: ResolvedAgentAccount; request: GetScheduleRequest }): Promise<{ raw: GetScheduleResponse; scheduleList: ScheduleInfo[]; meetingCode?: string; meetingLink?: string }> {
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 request: GetScheduleRequest = { schedule_id_list: scheduleIdList };
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: { agent: ResolvedAgentAccount; request: DeleteScheduleRequest }): Promise<{ raw: DeleteScheduleResponse; scheduleId: string }> {
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 as any,
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: { agent: ResolvedAgentAccount; userid: string }): Promise<{ raw: GetSystemCalendarIdResponse; calId: string }> {
597
+ async getSystemCalendarId(p) {
702
598
  const userid = validateString(p.userid, "userid", { allowEmpty: false });
703
- const json = await this.post<GetSystemCalendarIdResponse>("/cgi-bin/oa/calendar/get_system_calid", "get_system_calid", p.agent, { userid });
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: { agent: ResolvedAgentAccount; request: CreateSystemScheduleRequest }): Promise<{ raw: CreateScheduleResponse; scheduleId: string }> {
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: { agent: ResolvedAgentAccount; request: RespondScheduleRequest }): Promise<{ raw: RespondScheduleResponse; scheduleId: string }> {
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 as any,
660
+ op_mode: opMode,
779
661
  op_start_time: opStartTime,
780
662
  attendee,
781
- response_status: p.request.response_status as any,
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: { agent: ResolvedAgentAccount; request: SyncScheduleRequest }): Promise<{ raw: SyncScheduleResponse; nextCursor: string; scheduleList: ScheduleInfo[] }> {
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,