@yanhaidao/wecom 2.3.150 → 2.3.180

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 (43) hide show
  1. package/README.md +238 -385
  2. package/SKILLS_CAL.md +895 -0
  3. package/SKILLS_DOC.md +2136 -0
  4. package/changelog/v2.3.16.md +11 -0
  5. package/changelog/v2.3.18.md +22 -0
  6. package/index.ts +39 -3
  7. package/package.json +2 -3
  8. package/src/agent/handler.event-filter.test.ts +11 -0
  9. package/src/agent/handler.ts +732 -643
  10. package/src/app/account-runtime.ts +46 -20
  11. package/src/app/index.ts +19 -1
  12. package/src/capability/calendar/SKILLS_CHECKLIST.md +251 -0
  13. package/src/capability/calendar/client.ts +815 -0
  14. package/src/capability/calendar/index.ts +3 -0
  15. package/src/capability/calendar/schema.ts +417 -0
  16. package/src/capability/calendar/tool.ts +417 -0
  17. package/src/capability/calendar/types.ts +309 -0
  18. package/src/capability/doc/client.ts +567 -62
  19. package/src/capability/doc/schema.ts +419 -318
  20. package/src/capability/doc/tool.ts +1510 -1178
  21. package/src/capability/doc/types.ts +130 -14
  22. package/src/capability/mcp/index.ts +10 -0
  23. package/src/capability/mcp/schema.ts +107 -0
  24. package/src/capability/mcp/tool.ts +170 -0
  25. package/src/capability/mcp/transport.ts +394 -0
  26. package/src/channel.ts +70 -28
  27. package/src/config/schema.ts +71 -102
  28. package/src/outbound.test.ts +91 -14
  29. package/src/outbound.ts +143 -30
  30. package/src/runtime/reply-orchestrator.test.ts +35 -2
  31. package/src/runtime/reply-orchestrator.ts +14 -2
  32. package/src/runtime/session-manager.ts +20 -6
  33. package/src/runtime/source-registry.ts +165 -0
  34. package/src/target.ts +7 -4
  35. package/src/transport/bot-ws/inbound.test.ts +46 -0
  36. package/src/transport/bot-ws/inbound.ts +23 -5
  37. package/src/transport/bot-ws/media.ts +269 -0
  38. package/src/transport/bot-ws/reply.test.ts +85 -17
  39. package/src/transport/bot-ws/reply.ts +109 -21
  40. package/src/transport/bot-ws/sdk-adapter.test.ts +64 -1
  41. package/src/transport/bot-ws/sdk-adapter.ts +88 -12
  42. package/.claude/settings.local.json +0 -11
  43. package/docs/update-content-fix.md +0 -135
@@ -0,0 +1,417 @@
1
+ // ============================================================================
2
+ // Calendar Tool - Complete Implementation
3
+ // 严格遵循企业微信官方 API 文档:https://developer.work.weixin.qq.com/document/path/93329
4
+ // ============================================================================
5
+ import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
6
+ import { isWecomAgentSource } from "../../runtime/source-registry.js";
7
+ import type { ResolvedAgentAccount } from "../../types/index.js";
8
+ import { resolveAgentAccountOrUndefined } from "../bot/fallback-delivery.js";
9
+ import { WecomCalendarClient } from "./client.js";
10
+ import { wecomCalendarToolSchema } from "./schema.js";
11
+
12
+ // ============================================================================
13
+ // Helper Functions
14
+ // ============================================================================
15
+
16
+ function readString(v: unknown): string {
17
+ return String(v ?? "").trim();
18
+ }
19
+
20
+ function readNumber(v: unknown): number {
21
+ const num = Number(v);
22
+ return isNaN(num) ? 0 : num;
23
+ }
24
+
25
+ function readArray(v: unknown): any[] {
26
+ return Array.isArray(v) ? v : [];
27
+ }
28
+
29
+ function buildResult(payload: any) {
30
+ return {
31
+ content: [{ type: "text" as const, text: JSON.stringify(payload, null, 2) }],
32
+ details: payload,
33
+ };
34
+ }
35
+
36
+ function resolveAccount(
37
+ api: OpenClawPluginApi,
38
+ paramsAccountId?: string,
39
+ toolContext?: any,
40
+ ): ResolvedAgentAccount | undefined {
41
+ const accountId =
42
+ paramsAccountId || toolContext?.agentAccountId || toolContext?.accountId || "default";
43
+ return resolveAgentAccountOrUndefined(api.config, accountId);
44
+ }
45
+
46
+ // ============================================================================
47
+ // Tool Registration
48
+ // ============================================================================
49
+
50
+ export function registerWecomCalendarTools(api: OpenClawPluginApi): void {
51
+ if (typeof api?.registerTool !== "function") {
52
+ return;
53
+ }
54
+
55
+ const client = new WecomCalendarClient();
56
+
57
+ api.registerTool((toolContext: any) => {
58
+ if (
59
+ toolContext?.messageChannel !== "wecom" ||
60
+ !isWecomAgentSource({
61
+ accountId: toolContext?.agentAccountId || toolContext?.accountId,
62
+ sessionKey: toolContext?.sessionKey,
63
+ sessionId: toolContext?.sessionId,
64
+ })
65
+ ) {
66
+ return null;
67
+ }
68
+
69
+ return {
70
+ name: "wecom_calendar",
71
+ label: "WeCom Calendar",
72
+ description: "企业微信日历工具,支持创建/更新/删除日历和日程,获取日程详情等功能",
73
+ parameters: wecomCalendarToolSchema,
74
+ async execute(_toolCallId: string, params: any) {
75
+ try {
76
+ const account = resolveAccount(api, params.accountId, toolContext);
77
+
78
+ if (!account || !account.configured) {
79
+ return buildResult({
80
+ ok: false,
81
+ action: params.action,
82
+ error: "账号未配置或不存在",
83
+ accountId: params.accountId,
84
+ });
85
+ }
86
+
87
+ switch (params.action) {
88
+ // ========================================================================
89
+ // Calendar APIs
90
+ // ========================================================================
91
+
92
+ case "calendar_create": {
93
+ const r = await client.createCalendar({
94
+ agent: account,
95
+ request: {
96
+ calendar: {
97
+ summary: readString(params.summary),
98
+ color: readString(params.color),
99
+ description:
100
+ params.description !== undefined ? readString(params.description) : undefined,
101
+ admins: readArray(params.admins),
102
+ set_as_default: params.set_as_default,
103
+ shares: readArray(params.shares),
104
+ is_public: params.is_public,
105
+ public_range: params.public_range,
106
+ is_corp_calendar: params.is_corp_calendar,
107
+ },
108
+ agentid: params.agentid,
109
+ },
110
+ });
111
+ return buildResult({
112
+ ok: true,
113
+ action: "calendar_create",
114
+ calId: r.calId,
115
+ raw: r.raw,
116
+ });
117
+ }
118
+
119
+ case "calendar_update": {
120
+ const r = await client.updateCalendar({
121
+ agent: account,
122
+ request: {
123
+ skip_public_range: params.skip_public_range,
124
+ calendar: {
125
+ cal_id: readString(params.cal_id),
126
+ summary: readString(params.summary),
127
+ color: readString(params.color),
128
+ description:
129
+ params.description !== undefined ? readString(params.description) : undefined,
130
+ admins: readArray(params.admins),
131
+ shares: readArray(params.shares),
132
+ public_range: params.public_range,
133
+ },
134
+ },
135
+ });
136
+ return buildResult({
137
+ ok: true,
138
+ action: "calendar_update",
139
+ calId: r.calId,
140
+ raw: r.raw,
141
+ });
142
+ }
143
+
144
+ case "calendar_get": {
145
+ const r = await client.getCalendar({
146
+ agent: account,
147
+ request: {
148
+ cal_id_list: readArray(params.cal_id_list),
149
+ },
150
+ });
151
+ return buildResult({
152
+ ok: true,
153
+ action: "calendar_get",
154
+ calendarList: r.calendarList,
155
+ raw: r.raw,
156
+ });
157
+ }
158
+
159
+ case "calendar_delete": {
160
+ const r = await client.deleteCalendar({
161
+ agent: account,
162
+ calId: readString(params.cal_id),
163
+ });
164
+ return buildResult({
165
+ ok: true,
166
+ action: "calendar_delete",
167
+ calId: r.calId,
168
+ raw: r.raw,
169
+ });
170
+ }
171
+
172
+ // ========================================================================
173
+ // Schedule APIs
174
+ // ========================================================================
175
+
176
+ case "schedule_create": {
177
+ const r = await client.createSchedule({
178
+ agent: account,
179
+ request: {
180
+ schedule: {
181
+ start_time: readNumber(params.start_time),
182
+ end_time: readNumber(params.end_time),
183
+ is_whole_day: params.is_whole_day,
184
+ summary: params.summary !== undefined ? readString(params.summary) : undefined,
185
+ description:
186
+ params.description !== undefined ? readString(params.description) : undefined,
187
+ location:
188
+ params.location !== undefined ? readString(params.location) : undefined,
189
+ attendees: readArray(params.attendees),
190
+ admins: readArray(params.admins),
191
+ reminders: params.reminders,
192
+ cal_id: params.cal_id !== undefined ? readString(params.cal_id) : undefined,
193
+ },
194
+ agentid: params.agentid,
195
+ },
196
+ });
197
+ return buildResult({
198
+ ok: true,
199
+ action: "schedule_create",
200
+ scheduleId: r.scheduleId,
201
+ raw: r.raw,
202
+ });
203
+ }
204
+
205
+ case "schedule_update": {
206
+ const r = await client.updateSchedule({
207
+ agent: account,
208
+ request: {
209
+ skip_attendees: params.skip_attendees,
210
+ op_mode: params.op_mode,
211
+ op_start_time: params.op_start_time,
212
+ schedule: {
213
+ schedule_id: readString(params.schedule_id),
214
+ start_time: readNumber(params.start_time),
215
+ end_time: readNumber(params.end_time),
216
+ is_whole_day: params.is_whole_day,
217
+ summary: params.summary !== undefined ? readString(params.summary) : undefined,
218
+ description:
219
+ params.description !== undefined ? readString(params.description) : undefined,
220
+ location:
221
+ params.location !== undefined ? readString(params.location) : undefined,
222
+ attendees: readArray(params.attendees),
223
+ admins: readArray(params.admins),
224
+ reminders: params.reminders,
225
+ },
226
+ },
227
+ });
228
+ return buildResult({
229
+ ok: true,
230
+ action: "schedule_update",
231
+ scheduleId: r.scheduleId,
232
+ raw: r.raw,
233
+ });
234
+ }
235
+
236
+ case "schedule_add_attendees": {
237
+ const r = await client.addScheduleAttendees({
238
+ agent: account,
239
+ request: {
240
+ schedule_id: readString(params.schedule_id),
241
+ attendees: readArray(params.attendees),
242
+ },
243
+ });
244
+ return buildResult({
245
+ ok: true,
246
+ action: "schedule_add_attendees",
247
+ scheduleId: r.scheduleId,
248
+ raw: r.raw,
249
+ });
250
+ }
251
+
252
+ case "schedule_del_attendees": {
253
+ const r = await client.deleteScheduleAttendees({
254
+ agent: account,
255
+ request: {
256
+ schedule_id: readString(params.schedule_id),
257
+ attendees: readArray(params.attendees),
258
+ },
259
+ });
260
+ return buildResult({
261
+ ok: true,
262
+ action: "schedule_del_attendees",
263
+ scheduleId: r.scheduleId,
264
+ raw: r.raw,
265
+ });
266
+ }
267
+
268
+ case "schedule_get_by_calendar": {
269
+ const r = await client.getScheduleByCalendar({
270
+ agent: account,
271
+ request: {
272
+ cal_id: readString(params.cal_id),
273
+ offset: params.offset,
274
+ limit: params.limit,
275
+ },
276
+ });
277
+ return buildResult({
278
+ ok: true,
279
+ action: "schedule_get_by_calendar",
280
+ scheduleList: r.scheduleList,
281
+ raw: r.raw,
282
+ });
283
+ }
284
+
285
+ case "schedule_get": {
286
+ const r = await client.getSchedule({
287
+ agent: account,
288
+ request: {
289
+ schedule_id_list: readArray(params.schedule_id_list),
290
+ },
291
+ });
292
+ return buildResult({
293
+ ok: true,
294
+ action: "schedule_get",
295
+ scheduleList: r.scheduleList,
296
+ meetingCode: r.meetingCode,
297
+ meetingLink: r.meetingLink,
298
+ raw: r.raw,
299
+ });
300
+ }
301
+
302
+ case "schedule_delete": {
303
+ const r = await client.deleteSchedule({
304
+ agent: account,
305
+ request: {
306
+ schedule_id: readString(params.schedule_id),
307
+ op_mode: params.op_mode,
308
+ op_start_time: params.op_start_time,
309
+ },
310
+ });
311
+ return buildResult({
312
+ ok: true,
313
+ action: "schedule_delete",
314
+ scheduleId: r.scheduleId,
315
+ raw: r.raw,
316
+ });
317
+ }
318
+
319
+ // ========================================================================
320
+ // System Calendar APIs
321
+ // ========================================================================
322
+
323
+ case "schedule_get_system_calid": {
324
+ const r = await client.getSystemCalendarId({
325
+ agent: account,
326
+ userid: readString(params.userid),
327
+ });
328
+ return buildResult({
329
+ ok: true,
330
+ action: "schedule_get_system_calid",
331
+ calId: r.calId,
332
+ raw: r.raw,
333
+ });
334
+ }
335
+
336
+ case "schedule_create_in_system": {
337
+ const r = await client.createSystemSchedule({
338
+ agent: account,
339
+ request: {
340
+ schedule: {
341
+ organizer: readString(params.organizer),
342
+ start_time: readNumber(params.start_time),
343
+ end_time: readNumber(params.end_time),
344
+ is_whole_day: params.is_whole_day,
345
+ summary: params.summary !== undefined ? readString(params.summary) : undefined,
346
+ description:
347
+ params.description !== undefined ? readString(params.description) : undefined,
348
+ location:
349
+ params.location !== undefined ? readString(params.location) : undefined,
350
+ attendees: readArray(params.attendees),
351
+ reminders: params.reminders,
352
+ },
353
+ },
354
+ });
355
+ return buildResult({
356
+ ok: true,
357
+ action: "schedule_create_in_system",
358
+ scheduleId: r.scheduleId,
359
+ raw: r.raw,
360
+ });
361
+ }
362
+
363
+ case "schedule_respond": {
364
+ const r = await client.respondSchedule({
365
+ agent: account,
366
+ request: {
367
+ schedule_id: readString(params.schedule_id),
368
+ op_mode: params.op_mode,
369
+ op_start_time: params.op_start_time,
370
+ attendee: readString(params.attendee),
371
+ response_status: params.response_status,
372
+ },
373
+ });
374
+ return buildResult({
375
+ ok: true,
376
+ action: "schedule_respond",
377
+ scheduleId: r.scheduleId,
378
+ raw: r.raw,
379
+ });
380
+ }
381
+
382
+ case "schedule_sync": {
383
+ const r = await client.syncSchedule({
384
+ agent: account,
385
+ request: {
386
+ cal_id: readString(params.cal_id),
387
+ cursor: params.cursor,
388
+ limit: params.limit,
389
+ },
390
+ });
391
+ return buildResult({
392
+ ok: true,
393
+ action: "schedule_sync",
394
+ nextCursor: r.nextCursor,
395
+ scheduleList: r.scheduleList,
396
+ raw: r.raw,
397
+ });
398
+ }
399
+
400
+ // ========================================================================
401
+ // Default: Unknown Action
402
+ // ========================================================================
403
+
404
+ default:
405
+ throw new Error(`未知操作:${params.action}`);
406
+ }
407
+ } catch (err) {
408
+ return buildResult({
409
+ ok: false,
410
+ action: params.action,
411
+ error: err instanceof Error ? err.message : String(err),
412
+ });
413
+ }
414
+ },
415
+ };
416
+ });
417
+ }