openclaw-remote-skills 1.0.2 → 1.0.3
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/package.json
CHANGED
|
@@ -1,612 +0,0 @@
|
|
|
1
|
-
// WPS365 远程技能调用 - 核心实现
|
|
2
|
-
// 提供远程调用 Windows 节点上 wps365-skill 的统一接口
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* WPS365 远程技能调用器
|
|
6
|
-
*/
|
|
7
|
-
class Wps365Remote {
|
|
8
|
-
constructor() {
|
|
9
|
-
this.nodeId = null
|
|
10
|
-
this.wpsSid = null
|
|
11
|
-
this.cache = {
|
|
12
|
-
nodeId: null,
|
|
13
|
-
wpsSid: null,
|
|
14
|
-
lastUpdate: 0,
|
|
15
|
-
ttl: 300000 // 5分钟缓存
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* 获取 Windows 节点 ID
|
|
21
|
-
* @returns {string} 节点ID
|
|
22
|
-
*/
|
|
23
|
-
getWindowsNodeId() {
|
|
24
|
-
const status = nodes(action="status")
|
|
25
|
-
const windowsNode = status.nodes.find(node =>
|
|
26
|
-
node.platform === "win32" && node.connected === true
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
if (!windowsNode) {
|
|
30
|
-
throw new Error("未找到已连接的 Windows 节点")
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return windowsNode.nodeId
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* 读取 wps_sid 配置
|
|
38
|
-
* @param {string} nodeId - 节点ID
|
|
39
|
-
* @returns {string} wps_sid
|
|
40
|
-
*/
|
|
41
|
-
async getWpsSid(nodeId) {
|
|
42
|
-
const command = `
|
|
43
|
-
$config = Get-Content 'C:\\Users\\KSG\\.openclaw\\openclaw.json' -Encoding UTF8 | ConvertFrom-Json
|
|
44
|
-
$config.channels.agentspace.accounts.default.wps_sid
|
|
45
|
-
`
|
|
46
|
-
|
|
47
|
-
const result = nodes(
|
|
48
|
-
action="invoke",
|
|
49
|
-
node=nodeId,
|
|
50
|
-
invokeCommand="system.run",
|
|
51
|
-
invokeParamsJson={
|
|
52
|
-
"command": ["powershell.exe", "-Command", command]
|
|
53
|
-
}
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
if (!result.ok || !result.payload.success) {
|
|
57
|
-
throw new Error("读取 wps_sid 失败: " + (result.payload.error || result.payload.stderr))
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return result.payload.stdout.trim()
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* 获取缓存的配置
|
|
65
|
-
* @returns {Promise<{nodeId: string, wpsSid: string}>}
|
|
66
|
-
*/
|
|
67
|
-
async getCachedConfig() {
|
|
68
|
-
const now = Date.now()
|
|
69
|
-
|
|
70
|
-
if (!this.cache.nodeId || (now - this.cache.lastUpdate) > this.cache.ttl) {
|
|
71
|
-
this.cache.nodeId = this.getWindowsNodeId()
|
|
72
|
-
this.cache.wpsSid = await this.getWpsSid(this.cache.nodeId)
|
|
73
|
-
this.cache.lastUpdate = now
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return {
|
|
77
|
-
nodeId: this.cache.nodeId,
|
|
78
|
-
wpsSid: this.cache.wpsSid
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* 执行 wps365 命令
|
|
84
|
-
* @param {string} subcommand - 子命令(im, calendar, contacts, drive, dbsheet, meeting, user-current)
|
|
85
|
-
* @param {string} action - 动作
|
|
86
|
-
* @param {object} args - 参数
|
|
87
|
-
* @returns {Promise<any>} 执行结果
|
|
88
|
-
*/
|
|
89
|
-
async runCommand(subcommand, action, args = {}) {
|
|
90
|
-
const { nodeId, wpsSid } = await this.getCachedConfig()
|
|
91
|
-
|
|
92
|
-
// 构建命令
|
|
93
|
-
let cmdArgs = []
|
|
94
|
-
|
|
95
|
-
switch (subcommand) {
|
|
96
|
-
case "im":
|
|
97
|
-
cmdArgs = this.buildImCommand(action, args)
|
|
98
|
-
break
|
|
99
|
-
case "calendar":
|
|
100
|
-
cmdArgs = this.buildCalendarCommand(action, args)
|
|
101
|
-
break
|
|
102
|
-
case "contacts":
|
|
103
|
-
cmdArgs = this.buildContactsCommand(action, args)
|
|
104
|
-
break
|
|
105
|
-
case "drive":
|
|
106
|
-
cmdArgs = this.buildDriveCommand(action, args)
|
|
107
|
-
break
|
|
108
|
-
case "dbsheet":
|
|
109
|
-
cmdArgs = this.buildDbsheetCommand(action, args)
|
|
110
|
-
break
|
|
111
|
-
case "meeting":
|
|
112
|
-
cmdArgs = this.buildMeetingCommand(action, args)
|
|
113
|
-
break
|
|
114
|
-
case "user-current":
|
|
115
|
-
cmdArgs = this.buildUserCurrentCommand(action, args)
|
|
116
|
-
break
|
|
117
|
-
default:
|
|
118
|
-
throw new Error(`不支持的子命令: ${subcommand}`)
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// 执行命令
|
|
122
|
-
const command = `$env:WPS_SID='${wpsSid}'; cd C:\\Users\\KSG\\.openclaw\\skills\\wps365-skill; python skills/${subcommand}/run.py ${cmdArgs.join(' ')}`
|
|
123
|
-
|
|
124
|
-
const result = nodes(
|
|
125
|
-
action="invoke",
|
|
126
|
-
node=nodeId,
|
|
127
|
-
invokeCommand="system.run",
|
|
128
|
-
invokeParamsJson={
|
|
129
|
-
"command": ["powershell.exe", "-Command", command],
|
|
130
|
-
"timeout": 30000
|
|
131
|
-
}
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
if (!result.ok || !result.payload.success) {
|
|
135
|
-
throw new Error(`${subcommand} ${action} 执行失败: ${result.payload.stderr || result.payload.error}`)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return this.parseOutput(result.payload.stdout)
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* 构建即时消息命令
|
|
143
|
-
*/
|
|
144
|
-
buildImCommand(action, args) {
|
|
145
|
-
const cmdArgs = []
|
|
146
|
-
|
|
147
|
-
switch (action) {
|
|
148
|
-
case "search":
|
|
149
|
-
cmdArgs.push("search", `"${args.keyword}"`)
|
|
150
|
-
if (args.page_size) cmdArgs.push("--page-size", args.page_size.toString())
|
|
151
|
-
break
|
|
152
|
-
|
|
153
|
-
case "send":
|
|
154
|
-
cmdArgs.push("send", args.chat_id)
|
|
155
|
-
if (args.message) {
|
|
156
|
-
// 转义引号
|
|
157
|
-
const escapedMessage = args.message.replace(/"/g, '\\"')
|
|
158
|
-
cmdArgs.push(`"${escapedMessage}"`)
|
|
159
|
-
}
|
|
160
|
-
if (args.plain) cmdArgs.push("--plain")
|
|
161
|
-
if (args.mention) {
|
|
162
|
-
if (Array.isArray(args.mention)) {
|
|
163
|
-
args.mention.forEach(userId => {
|
|
164
|
-
cmdArgs.push("--mention", userId)
|
|
165
|
-
})
|
|
166
|
-
} else {
|
|
167
|
-
cmdArgs.push("--mention", args.mention)
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
if (args.type && args.type !== "text") {
|
|
171
|
-
cmdArgs.push("--type", args.type)
|
|
172
|
-
if (args[args.type]) {
|
|
173
|
-
cmdArgs.push(`--${args.type}`, `'${JSON.stringify(args[args.type])}'`)
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
break
|
|
177
|
-
|
|
178
|
-
case "list":
|
|
179
|
-
cmdArgs.push("list")
|
|
180
|
-
if (args.page_size) cmdArgs.push("--page-size", args.page_size.toString())
|
|
181
|
-
break
|
|
182
|
-
|
|
183
|
-
case "history":
|
|
184
|
-
cmdArgs.push("history", args.chat_id)
|
|
185
|
-
if (args.start_time) cmdArgs.push("--start-time", args.start_time)
|
|
186
|
-
if (args.end_time) cmdArgs.push("--end-time", args.end_time)
|
|
187
|
-
if (args.page_size) cmdArgs.push("--page-size", args.page_size.toString())
|
|
188
|
-
break
|
|
189
|
-
|
|
190
|
-
case "recall":
|
|
191
|
-
cmdArgs.push("recall", args.chat_id, args.message_id)
|
|
192
|
-
break
|
|
193
|
-
|
|
194
|
-
case "recent":
|
|
195
|
-
cmdArgs.push("recent")
|
|
196
|
-
if (args.filter_unread) cmdArgs.push("--filter-unread")
|
|
197
|
-
if (args.filter_mention_me) cmdArgs.push("--filter-mention-me")
|
|
198
|
-
if (args.page_size) cmdArgs.push("--page-size", args.page_size.toString())
|
|
199
|
-
break
|
|
200
|
-
|
|
201
|
-
case "search-messages":
|
|
202
|
-
cmdArgs.push("search-messages")
|
|
203
|
-
if (args.keyword) cmdArgs.push("--keyword", `"${args.keyword}"`)
|
|
204
|
-
if (args.chat_ids) cmdArgs.push("--chat-ids", args.chat_ids)
|
|
205
|
-
if (args.start_time) cmdArgs.push("--start-time", args.start_time)
|
|
206
|
-
if (args.end_time) cmdArgs.push("--end-time", args.end_time)
|
|
207
|
-
if (args.page_size) cmdArgs.push("--page-size", args.page_size.toString())
|
|
208
|
-
break
|
|
209
|
-
|
|
210
|
-
default:
|
|
211
|
-
throw new Error(`不支持的 IM 动作: ${action}`)
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return cmdArgs
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* 构建日历命令(简化版)
|
|
219
|
-
*/
|
|
220
|
-
buildCalendarCommand(action, args) {
|
|
221
|
-
const cmdArgs = [action]
|
|
222
|
-
|
|
223
|
-
switch (action) {
|
|
224
|
-
case "create":
|
|
225
|
-
if (args.summary) cmdArgs.push("--summary", `"${args.summary}"`)
|
|
226
|
-
if (args.start) cmdArgs.push("--start", args.start)
|
|
227
|
-
if (args.end) cmdArgs.push("--end", args.end)
|
|
228
|
-
if (args.description) cmdArgs.push("--description", `"${args.description}"`)
|
|
229
|
-
break
|
|
230
|
-
|
|
231
|
-
case "list":
|
|
232
|
-
if (args.start_time) cmdArgs.push("--start-time", args.start_time)
|
|
233
|
-
if (args.end_time) cmdArgs.push("--end-time", args.end_time)
|
|
234
|
-
if (args.page_size) cmdArgs.push("--page-size", args.page_size.toString())
|
|
235
|
-
break
|
|
236
|
-
|
|
237
|
-
default:
|
|
238
|
-
// 直接传递其他参数
|
|
239
|
-
Object.keys(args).forEach(key => {
|
|
240
|
-
if (key.startsWith("--")) {
|
|
241
|
-
cmdArgs.push(key, args[key])
|
|
242
|
-
}
|
|
243
|
-
})
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
return cmdArgs
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* 构建联系人命令(简化版)
|
|
251
|
-
*/
|
|
252
|
-
buildContactsCommand(action, args) {
|
|
253
|
-
const cmdArgs = [action]
|
|
254
|
-
|
|
255
|
-
if (action === "search" && args.keyword) {
|
|
256
|
-
cmdArgs.push(`"${args.keyword}"`)
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
if (args.page_size) {
|
|
260
|
-
cmdArgs.push("--page-size", args.page_size.toString())
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
return cmdArgs
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* 构建云盘命令(简化版)
|
|
268
|
-
*/
|
|
269
|
-
buildDriveCommand(action, args) {
|
|
270
|
-
const cmdArgs = [action]
|
|
271
|
-
|
|
272
|
-
switch (action) {
|
|
273
|
-
case "upload":
|
|
274
|
-
if (args.file_path) cmdArgs.push("--file", `"${args.file_path}"`)
|
|
275
|
-
if (args.folder_token) cmdArgs.push("--folder-token", args.folder_token)
|
|
276
|
-
break
|
|
277
|
-
|
|
278
|
-
case "list":
|
|
279
|
-
if (args.folder_token) cmdArgs.push("--folder-token", args.folder_token)
|
|
280
|
-
if (args.page_size) cmdArgs.push("--page-size", args.page_size.toString())
|
|
281
|
-
break
|
|
282
|
-
|
|
283
|
-
case "search":
|
|
284
|
-
if (args.keyword) cmdArgs.push("--keyword", `"${args.keyword}"`)
|
|
285
|
-
if (args.page_size) cmdArgs.push("--page-size", args.page_size.toString())
|
|
286
|
-
break
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
return cmdArgs
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* 构建数据表命令(简化版)
|
|
294
|
-
*/
|
|
295
|
-
buildDbsheetCommand(action, args) {
|
|
296
|
-
const cmdArgs = [action]
|
|
297
|
-
|
|
298
|
-
if (args.table_id) {
|
|
299
|
-
cmdArgs.push("--table", args.table_id)
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
if (args.view_id) {
|
|
303
|
-
cmdArgs.push("--view", args.view_id)
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
if (args.page_size) {
|
|
307
|
-
cmdArgs.push("--page-size", args.page_size.toString())
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
return cmdArgs
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* 构建会议命令(简化版)
|
|
315
|
-
*/
|
|
316
|
-
buildMeetingCommand(action, args) {
|
|
317
|
-
const cmdArgs = [action]
|
|
318
|
-
|
|
319
|
-
if (args.meeting_id) {
|
|
320
|
-
cmdArgs.push(args.meeting_id)
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
if (action === "create") {
|
|
324
|
-
if (args.topic) cmdArgs.push("--topic", `"${args.topic}"`)
|
|
325
|
-
if (args.start_time) cmdArgs.push("--start-time", args.start_time)
|
|
326
|
-
if (args.duration) cmdArgs.push("--duration", args.duration.toString())
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
return cmdArgs
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* 构建用户信息命令
|
|
334
|
-
*/
|
|
335
|
-
buildUserCurrentCommand(action, args) {
|
|
336
|
-
const cmdArgs = [action]
|
|
337
|
-
return cmdArgs
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
/**
|
|
341
|
-
* 解析命令输出
|
|
342
|
-
*/
|
|
343
|
-
parseOutput(output) {
|
|
344
|
-
try {
|
|
345
|
-
// 尝试从输出中提取 JSON
|
|
346
|
-
const jsonMatch = output.match(/```json\s*([\s\S]*?)\s*```/)
|
|
347
|
-
if (jsonMatch) {
|
|
348
|
-
return JSON.parse(jsonMatch[1])
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
// 尝试解析整个输出为 JSON(某些命令直接输出 JSON)
|
|
352
|
-
try {
|
|
353
|
-
const jsonStart = output.indexOf('{')
|
|
354
|
-
const jsonEnd = output.lastIndexOf('}') + 1
|
|
355
|
-
if (jsonStart >= 0 && jsonEnd > jsonStart) {
|
|
356
|
-
const jsonStr = output.substring(jsonStart, jsonEnd)
|
|
357
|
-
return JSON.parse(jsonStr)
|
|
358
|
-
}
|
|
359
|
-
} catch (e) {
|
|
360
|
-
// 忽略 JSON 解析错误
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// 返回原始输出
|
|
364
|
-
return { raw_output: output.trim() }
|
|
365
|
-
} catch (e) {
|
|
366
|
-
return {
|
|
367
|
-
raw_output: output.trim(),
|
|
368
|
-
parse_error: e.message
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
// ========== 高级 API 方法 ==========
|
|
374
|
-
|
|
375
|
-
/**
|
|
376
|
-
* 搜索会话并发送消息
|
|
377
|
-
* @param {string} groupName - 群名关键词
|
|
378
|
-
* @param {string} message - 消息内容
|
|
379
|
-
* @param {object} options - 选项
|
|
380
|
-
*/
|
|
381
|
-
async sendMessageToGroup(groupName, message, options = {}) {
|
|
382
|
-
// 搜索群聊
|
|
383
|
-
const searchResult = await this.runCommand("im", "search", {
|
|
384
|
-
keyword: groupName
|
|
385
|
-
})
|
|
386
|
-
|
|
387
|
-
if (!searchResult.items || searchResult.items.length === 0) {
|
|
388
|
-
throw new Error(`未找到包含"${groupName}"的群聊`)
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
// 发送消息
|
|
392
|
-
const sendResult = await this.runCommand("im", "send", {
|
|
393
|
-
chat_id: searchResult.items[0].chat.id,
|
|
394
|
-
message: message,
|
|
395
|
-
plain: options.plain || false,
|
|
396
|
-
mention: options.mention
|
|
397
|
-
})
|
|
398
|
-
|
|
399
|
-
return {
|
|
400
|
-
chat_id: searchResult.items[0].chat.id,
|
|
401
|
-
chat_name: searchResult.items[0].chat.name,
|
|
402
|
-
message_id: sendResult.id,
|
|
403
|
-
result: sendResult
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
/**
|
|
408
|
-
* 批量发送消息
|
|
409
|
-
* @param {Array} messages - 消息列表 [{groupName, message, options}]
|
|
410
|
-
*/
|
|
411
|
-
async batchSendMessages(messages) {
|
|
412
|
-
const results = []
|
|
413
|
-
|
|
414
|
-
for (const msg of messages) {
|
|
415
|
-
try {
|
|
416
|
-
const result = await this.sendMessageToGroup(
|
|
417
|
-
msg.groupName,
|
|
418
|
-
msg.message,
|
|
419
|
-
msg.options || {}
|
|
420
|
-
)
|
|
421
|
-
results.push({
|
|
422
|
-
success: true,
|
|
423
|
-
group: msg.groupName,
|
|
424
|
-
result: result
|
|
425
|
-
})
|
|
426
|
-
} catch (error) {
|
|
427
|
-
results.push({
|
|
428
|
-
success: false,
|
|
429
|
-
group: msg.groupName,
|
|
430
|
-
error: error.message
|
|
431
|
-
})
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
// 避免频繁请求
|
|
435
|
-
await this.sleep(500)
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
return results
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
/**
|
|
442
|
-
* 创建日历事件并通知
|
|
443
|
-
*/
|
|
444
|
-
async createEventAndNotify(event, groupName) {
|
|
445
|
-
// 创建日历事件
|
|
446
|
-
const eventResult = await this.runCommand("calendar", "create", {
|
|
447
|
-
summary: event.summary,
|
|
448
|
-
description: event.description,
|
|
449
|
-
start: event.start_time,
|
|
450
|
-
end: event.end_time,
|
|
451
|
-
location: event.location
|
|
452
|
-
})
|
|
453
|
-
|
|
454
|
-
// 发送通知
|
|
455
|
-
const message = `📅 新日历事件\n\n**事件**: ${event.summary}\n**时间**: ${event.start_time}\n**地点**: ${event.location || "未指定"}\n**描述**: ${event.description || "无"}`
|
|
456
|
-
|
|
457
|
-
const notifyResult = await this.sendMessageToGroup(groupName, message)
|
|
458
|
-
|
|
459
|
-
return {
|
|
460
|
-
event: eventResult,
|
|
461
|
-
notification: notifyResult
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
/**
|
|
466
|
-
* 上传文件并分享
|
|
467
|
-
*/
|
|
468
|
-
async uploadAndShare(filePath, groupName, options = {}) {
|
|
469
|
-
// 上传文件
|
|
470
|
-
const uploadResult = await this.runCommand("drive", "upload", {
|
|
471
|
-
file_path: filePath,
|
|
472
|
-
folder_token: options.folder_token,
|
|
473
|
-
file_name: options.file_name
|
|
474
|
-
})
|
|
475
|
-
|
|
476
|
-
// 获取文件信息
|
|
477
|
-
const fileInfo = this.parseOutput(uploadResult.raw_output)
|
|
478
|
-
|
|
479
|
-
// 发送文件消息
|
|
480
|
-
if (fileInfo.link_id) {
|
|
481
|
-
const sendResult = await this.runCommand("im", "send", {
|
|
482
|
-
chat_id: await this.getChatIdByName(groupName),
|
|
483
|
-
type: "file",
|
|
484
|
-
file: JSON.stringify({
|
|
485
|
-
type: "cloud",
|
|
486
|
-
cloud: {
|
|
487
|
-
id: fileInfo.link_id,
|
|
488
|
-
link_url: fileInfo.url || `https://www.kdocs.cn/l/${fileInfo.link_id}`,
|
|
489
|
-
link_id: fileInfo.link_id
|
|
490
|
-
}
|
|
491
|
-
})
|
|
492
|
-
})
|
|
493
|
-
|
|
494
|
-
return {
|
|
495
|
-
upload: uploadResult,
|
|
496
|
-
share: sendResult
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
throw new Error("上传文件后未获取到 link_id")
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
/**
|
|
504
|
-
* 根据群名获取 chat_id
|
|
505
|
-
*/
|
|
506
|
-
async getChatIdByName(groupName) {
|
|
507
|
-
const result = await this.runCommand("im", "search", {
|
|
508
|
-
keyword: groupName
|
|
509
|
-
})
|
|
510
|
-
|
|
511
|
-
if (result.items && result.items.length > 0) {
|
|
512
|
-
return result.items[0].chat.id
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
throw new Error(`未找到群聊: ${groupName}`)
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
/**
|
|
519
|
-
* 等待函数
|
|
520
|
-
*/
|
|
521
|
-
sleep(ms) {
|
|
522
|
-
return new Promise(resolve => setTimeout(resolve, ms))
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
// ========== 导出和使用示例 ==========
|
|
527
|
-
|
|
528
|
-
// 创建全局实例
|
|
529
|
-
const wps365 = new Wps365Remote()
|
|
530
|
-
|
|
531
|
-
// 示例:发送消息到个人测试告警群
|
|
532
|
-
async function demoSendMessage() {
|
|
533
|
-
try {
|
|
534
|
-
console.log("开始发送测试消息...")
|
|
535
|
-
|
|
536
|
-
const result = await wps365.sendMessageToGroup(
|
|
537
|
-
"个人测试告警群",
|
|
538
|
-
"**远程技能调用测试**\n\n这是一条通过远程 WPS365 技能发送的测试消息。\n时间: " + new Date().toLocaleString(),
|
|
539
|
-
{ plain: false }
|
|
540
|
-
)
|
|
541
|
-
|
|
542
|
-
console.log("消息发送成功:")
|
|
543
|
-
console.log(`- 群聊: ${result.chat_name} (${result.chat_id})`)
|
|
544
|
-
console.log(`- 消息ID: ${result.message_id}`)
|
|
545
|
-
|
|
546
|
-
return result
|
|
547
|
-
} catch (error) {
|
|
548
|
-
console.error("发送消息失败:", error.message)
|
|
549
|
-
throw error
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
// 示例:批量发送消息
|
|
554
|
-
async function demoBatchSend() {
|
|
555
|
-
const messages = [
|
|
556
|
-
{
|
|
557
|
-
groupName: "个人测试告警群",
|
|
558
|
-
message: "系统监控正常,所有服务运行良好。",
|
|
559
|
-
options: { plain: false }
|
|
560
|
-
}
|
|
561
|
-
]
|
|
562
|
-
|
|
563
|
-
return await wps365.batchSendMessages(messages)
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
// 示例:搜索会话
|
|
567
|
-
async function demoSearchChats() {
|
|
568
|
-
const result = await wps365.runCommand("im", "search", {
|
|
569
|
-
keyword: "测试",
|
|
570
|
-
page_size: 10
|
|
571
|
-
})
|
|
572
|
-
|
|
573
|
-
console.log(`找到 ${result.total} 个相关会话:`)
|
|
574
|
-
result.items.forEach((item, index) => {
|
|
575
|
-
console.log(`${index + 1}. [${item.chat.type}] ${item.chat.name} | ID: ${item.chat.id}`)
|
|
576
|
-
})
|
|
577
|
-
|
|
578
|
-
return result
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
// 导入 agentspace 安装器
|
|
582
|
-
const { AgentspaceInstaller, quickInstallAgentspace, checkAgentspaceStatus } = require('./agentspace-installer')
|
|
583
|
-
|
|
584
|
-
/**
|
|
585
|
-
* 安装和配置 agentspace
|
|
586
|
-
* 一键完成下载安装器、获取Windows节点配置、合并配置、重启OpenClaw
|
|
587
|
-
*/
|
|
588
|
-
async function installAgentspace() {
|
|
589
|
-
console.log('🔧 开始安装和配置 agentspace...')
|
|
590
|
-
const installer = new AgentspaceInstaller()
|
|
591
|
-
return await installer.installAndConfigure()
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
/**
|
|
595
|
-
* 检查 agentspace 安装状态
|
|
596
|
-
*/
|
|
597
|
-
function getAgentspaceStatus() {
|
|
598
|
-
return checkAgentspaceStatus()
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
// 导出
|
|
602
|
-
module.exports = {
|
|
603
|
-
Wps365Remote,
|
|
604
|
-
wps365,
|
|
605
|
-
installAgentspace,
|
|
606
|
-
getAgentspaceStatus,
|
|
607
|
-
demo: {
|
|
608
|
-
sendMessage: demoSendMessage,
|
|
609
|
-
batchSend: demoBatchSend,
|
|
610
|
-
searchChats: demoSearchChats
|
|
611
|
-
}
|
|
612
|
-
}
|