@openclaw-china/wecom-app 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +845 -0
- package/dist/index.js +6597 -0
- package/dist/index.js.map +1 -0
- package/openclaw.plugin.json +61 -0
- package/package.json +115 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,845 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 企业微信自建应用类型定义
|
|
5
|
+
*/
|
|
6
|
+
/** DM 消息策略 */
|
|
7
|
+
type WecomAppDmPolicy = "open" | "pairing" | "allowlist" | "disabled";
|
|
8
|
+
/** 群组消息策略 */
|
|
9
|
+
type WecomAppGroupPolicy = "open" | "allowlist" | "disabled";
|
|
10
|
+
/**
|
|
11
|
+
* 企业微信自建应用账户配置
|
|
12
|
+
* 相比普通 wecom 智能机器人,增加了 corpId, corpSecret, agentId 用于主动发送消息
|
|
13
|
+
*/
|
|
14
|
+
type WecomAppAccountConfig = {
|
|
15
|
+
name?: string;
|
|
16
|
+
enabled?: boolean;
|
|
17
|
+
/** Webhook 路径 */
|
|
18
|
+
webhookPath?: string;
|
|
19
|
+
/** 回调 Token */
|
|
20
|
+
token?: string;
|
|
21
|
+
/** 回调消息加密密钥 */
|
|
22
|
+
encodingAESKey?: string;
|
|
23
|
+
/** 接收者 ID (用于解密验证) */
|
|
24
|
+
receiveId?: string;
|
|
25
|
+
/** 企业 ID (用于主动发送) */
|
|
26
|
+
corpId?: string;
|
|
27
|
+
/** 应用 Secret (用于主动发送) */
|
|
28
|
+
corpSecret?: string;
|
|
29
|
+
/** 应用 AgentId (用于主动发送) */
|
|
30
|
+
agentId?: number;
|
|
31
|
+
/** 入站媒体(图片/文件)落盘设置 */
|
|
32
|
+
inboundMedia?: {
|
|
33
|
+
/** 是否启用入站媒体落盘(默认 true) */
|
|
34
|
+
enabled?: boolean;
|
|
35
|
+
/** 保存目录(默认 /root/.openclaw/media/wecom-app/inbound) */
|
|
36
|
+
dir?: string;
|
|
37
|
+
/** 单个文件最大字节数(默认 10MB) */
|
|
38
|
+
maxBytes?: number;
|
|
39
|
+
/** 保留天数(默认 7) */
|
|
40
|
+
keepDays?: number;
|
|
41
|
+
};
|
|
42
|
+
/** 媒体文件大小限制 (MB),默认 100 */
|
|
43
|
+
maxFileSizeMB?: number;
|
|
44
|
+
/** 欢迎文本 */
|
|
45
|
+
welcomeText?: string;
|
|
46
|
+
/** DM 策略 */
|
|
47
|
+
dmPolicy?: WecomAppDmPolicy;
|
|
48
|
+
/** DM 允许列表 */
|
|
49
|
+
allowFrom?: string[];
|
|
50
|
+
/** 群组策略 */
|
|
51
|
+
groupPolicy?: WecomAppGroupPolicy;
|
|
52
|
+
/** 群组允许列表 */
|
|
53
|
+
groupAllowFrom?: string[];
|
|
54
|
+
/** 是否需要 @ 提及 */
|
|
55
|
+
requireMention?: boolean;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* 企业微信自建应用配置 (顶层)
|
|
59
|
+
*/
|
|
60
|
+
type WecomAppConfig = WecomAppAccountConfig & {
|
|
61
|
+
accounts?: Record<string, WecomAppAccountConfig>;
|
|
62
|
+
defaultAccount?: string;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* 解析后的企业微信自建应用账户
|
|
66
|
+
*/
|
|
67
|
+
type ResolvedWecomAppAccount = {
|
|
68
|
+
accountId: string;
|
|
69
|
+
name?: string;
|
|
70
|
+
enabled: boolean;
|
|
71
|
+
configured: boolean;
|
|
72
|
+
/** 回调 Token */
|
|
73
|
+
token?: string;
|
|
74
|
+
/** 回调消息加密密钥 */
|
|
75
|
+
encodingAESKey?: string;
|
|
76
|
+
/** 接收者 ID */
|
|
77
|
+
receiveId: string;
|
|
78
|
+
/** 企业 ID */
|
|
79
|
+
corpId?: string;
|
|
80
|
+
/** 应用 Secret */
|
|
81
|
+
corpSecret?: string;
|
|
82
|
+
/** 应用 AgentId */
|
|
83
|
+
agentId?: number;
|
|
84
|
+
/** 是否支持主动发送 (corpId + corpSecret + agentId 均已配置) */
|
|
85
|
+
canSendActive: boolean;
|
|
86
|
+
config: WecomAppAccountConfig;
|
|
87
|
+
};
|
|
88
|
+
/** 消息发送目标 */
|
|
89
|
+
type WecomAppSendTarget = {
|
|
90
|
+
/** 用户 ID (与 chatid 二选一) */
|
|
91
|
+
userId?: string;
|
|
92
|
+
/** 群聊 ID (与 userId 二选一) */
|
|
93
|
+
chatid?: string;
|
|
94
|
+
};
|
|
95
|
+
/** Access Token 缓存条目 */
|
|
96
|
+
type AccessTokenCacheEntry = {
|
|
97
|
+
token: string;
|
|
98
|
+
expiresAt: number;
|
|
99
|
+
};
|
|
100
|
+
type WecomAppInboundBase = {
|
|
101
|
+
MsgId?: string;
|
|
102
|
+
msgid?: string;
|
|
103
|
+
aibotid?: string;
|
|
104
|
+
chattype?: "single" | "group";
|
|
105
|
+
chatid?: string;
|
|
106
|
+
response_url?: string;
|
|
107
|
+
from?: {
|
|
108
|
+
userid?: string;
|
|
109
|
+
corpid?: string;
|
|
110
|
+
};
|
|
111
|
+
FromUserName?: string;
|
|
112
|
+
ToUserName?: string;
|
|
113
|
+
CreateTime?: number;
|
|
114
|
+
MsgType?: string;
|
|
115
|
+
msgtype?: string;
|
|
116
|
+
AgentID?: number;
|
|
117
|
+
};
|
|
118
|
+
type WecomAppInboundText = WecomAppInboundBase & {
|
|
119
|
+
msgtype: "text";
|
|
120
|
+
MsgType?: "text";
|
|
121
|
+
text?: {
|
|
122
|
+
content?: string;
|
|
123
|
+
};
|
|
124
|
+
Content?: string;
|
|
125
|
+
quote?: unknown;
|
|
126
|
+
};
|
|
127
|
+
type WecomAppInboundVoice = WecomAppInboundBase & {
|
|
128
|
+
msgtype: "voice";
|
|
129
|
+
MsgType?: "voice";
|
|
130
|
+
voice?: {
|
|
131
|
+
content?: string;
|
|
132
|
+
};
|
|
133
|
+
Recognition?: string;
|
|
134
|
+
/** 语音 MediaId (用于下载原始语音文件) */
|
|
135
|
+
MediaId?: string;
|
|
136
|
+
/** 语音格式 (amr/speex) */
|
|
137
|
+
Format?: string;
|
|
138
|
+
quote?: unknown;
|
|
139
|
+
};
|
|
140
|
+
type WecomAppInboundImage = WecomAppInboundBase & {
|
|
141
|
+
msgtype: "image";
|
|
142
|
+
MsgType?: "image";
|
|
143
|
+
image?: {
|
|
144
|
+
url?: string;
|
|
145
|
+
};
|
|
146
|
+
PicUrl?: string;
|
|
147
|
+
MediaId?: string;
|
|
148
|
+
};
|
|
149
|
+
type WecomAppInboundEvent = WecomAppInboundBase & {
|
|
150
|
+
msgtype: "event";
|
|
151
|
+
MsgType?: "event";
|
|
152
|
+
create_time?: number;
|
|
153
|
+
Event?: string;
|
|
154
|
+
EventKey?: string;
|
|
155
|
+
event?: {
|
|
156
|
+
eventtype?: string;
|
|
157
|
+
[key: string]: unknown;
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
type WecomAppInboundStreamRefresh = WecomAppInboundBase & {
|
|
161
|
+
msgtype: "stream";
|
|
162
|
+
stream?: {
|
|
163
|
+
id?: string;
|
|
164
|
+
};
|
|
165
|
+
};
|
|
166
|
+
type WecomAppInboundMessage = WecomAppInboundText | WecomAppInboundVoice | WecomAppInboundImage | WecomAppInboundStreamRefresh | WecomAppInboundEvent | (WecomAppInboundBase & Record<string, unknown>);
|
|
167
|
+
|
|
168
|
+
var __createBinding = (undefined && undefined.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
169
|
+
if (k2 === undefined) k2 = k;
|
|
170
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
171
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
172
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
173
|
+
}
|
|
174
|
+
Object.defineProperty(o, k2, desc);
|
|
175
|
+
}) : (function(o, m, k, k2) {
|
|
176
|
+
if (k2 === undefined) k2 = k;
|
|
177
|
+
o[k2] = m[k];
|
|
178
|
+
}));
|
|
179
|
+
var __exportStar = (undefined && undefined.__exportStar) || function(m, exports$1) {
|
|
180
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports$1, p)) __createBinding(exports$1, m, p);
|
|
181
|
+
};
|
|
182
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
183
|
+
__exportStar(require("./errors.cjs"), exports);
|
|
184
|
+
__exportStar(require("./helpers/parseUtil.cjs"), exports);
|
|
185
|
+
__exportStar(require("./helpers/typeAliases.cjs"), exports);
|
|
186
|
+
__exportStar(require("./helpers/util.cjs"), exports);
|
|
187
|
+
__exportStar(require("./types.cjs"), exports);
|
|
188
|
+
__exportStar(require("./ZodError.cjs"), exports);
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* 企业微信自建应用配置 schema
|
|
192
|
+
*/
|
|
193
|
+
|
|
194
|
+
/** 默认账户 ID */
|
|
195
|
+
declare const DEFAULT_ACCOUNT_ID = "default";
|
|
196
|
+
interface PluginConfig {
|
|
197
|
+
session?: {
|
|
198
|
+
store?: unknown;
|
|
199
|
+
};
|
|
200
|
+
channels?: {
|
|
201
|
+
"wecom-app"?: WecomAppConfig;
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* 企业微信自建应用 ChannelPlugin 实现
|
|
207
|
+
*
|
|
208
|
+
* 与普通 wecom 智能机器人不同,自建应用支持主动发送消息
|
|
209
|
+
*/
|
|
210
|
+
|
|
211
|
+
declare const wecomAppPlugin: {
|
|
212
|
+
id: string;
|
|
213
|
+
meta: {
|
|
214
|
+
id: "wecom-app";
|
|
215
|
+
label: "WeCom App";
|
|
216
|
+
selectionLabel: "WeCom Self-built App (企微自建应用)";
|
|
217
|
+
docsPath: "/channels/wecom-app";
|
|
218
|
+
docsLabel: "wecom-app";
|
|
219
|
+
blurb: "企业微信自建应用,支持主动发送消息";
|
|
220
|
+
aliases: readonly ["qywx-app", "企微自建应用", "企业微信自建应用"];
|
|
221
|
+
order: 84;
|
|
222
|
+
};
|
|
223
|
+
capabilities: {
|
|
224
|
+
chatTypes: readonly ["direct", "group"];
|
|
225
|
+
media: boolean;
|
|
226
|
+
reactions: boolean;
|
|
227
|
+
threads: boolean;
|
|
228
|
+
edit: boolean;
|
|
229
|
+
reply: boolean;
|
|
230
|
+
polls: boolean;
|
|
231
|
+
/** 自建应用支持主动发送 */
|
|
232
|
+
activeSend: boolean;
|
|
233
|
+
};
|
|
234
|
+
configSchema: {
|
|
235
|
+
schema: {
|
|
236
|
+
type: string;
|
|
237
|
+
additionalProperties: boolean;
|
|
238
|
+
properties: {
|
|
239
|
+
name: {
|
|
240
|
+
type: string;
|
|
241
|
+
};
|
|
242
|
+
enabled: {
|
|
243
|
+
type: string;
|
|
244
|
+
};
|
|
245
|
+
webhookPath: {
|
|
246
|
+
type: string;
|
|
247
|
+
};
|
|
248
|
+
token: {
|
|
249
|
+
type: string;
|
|
250
|
+
};
|
|
251
|
+
encodingAESKey: {
|
|
252
|
+
type: string;
|
|
253
|
+
};
|
|
254
|
+
receiveId: {
|
|
255
|
+
type: string;
|
|
256
|
+
};
|
|
257
|
+
corpId: {
|
|
258
|
+
type: string;
|
|
259
|
+
};
|
|
260
|
+
corpSecret: {
|
|
261
|
+
type: string;
|
|
262
|
+
};
|
|
263
|
+
agentId: {
|
|
264
|
+
type: string;
|
|
265
|
+
};
|
|
266
|
+
inboundMedia: {
|
|
267
|
+
type: string;
|
|
268
|
+
additionalProperties: boolean;
|
|
269
|
+
properties: {
|
|
270
|
+
enabled: {
|
|
271
|
+
type: string;
|
|
272
|
+
};
|
|
273
|
+
dir: {
|
|
274
|
+
type: string;
|
|
275
|
+
};
|
|
276
|
+
maxBytes: {
|
|
277
|
+
type: string;
|
|
278
|
+
};
|
|
279
|
+
keepDays: {
|
|
280
|
+
type: string;
|
|
281
|
+
};
|
|
282
|
+
};
|
|
283
|
+
};
|
|
284
|
+
welcomeText: {
|
|
285
|
+
type: string;
|
|
286
|
+
};
|
|
287
|
+
dmPolicy: {
|
|
288
|
+
type: string;
|
|
289
|
+
enum: string[];
|
|
290
|
+
};
|
|
291
|
+
allowFrom: {
|
|
292
|
+
type: string;
|
|
293
|
+
items: {
|
|
294
|
+
type: string;
|
|
295
|
+
};
|
|
296
|
+
};
|
|
297
|
+
groupPolicy: {
|
|
298
|
+
type: string;
|
|
299
|
+
enum: string[];
|
|
300
|
+
};
|
|
301
|
+
groupAllowFrom: {
|
|
302
|
+
type: string;
|
|
303
|
+
items: {
|
|
304
|
+
type: string;
|
|
305
|
+
};
|
|
306
|
+
};
|
|
307
|
+
requireMention: {
|
|
308
|
+
type: string;
|
|
309
|
+
};
|
|
310
|
+
maxFileSizeMB: {
|
|
311
|
+
type: string;
|
|
312
|
+
};
|
|
313
|
+
defaultAccount: {
|
|
314
|
+
type: string;
|
|
315
|
+
};
|
|
316
|
+
accounts: {
|
|
317
|
+
type: string;
|
|
318
|
+
additionalProperties: {
|
|
319
|
+
type: string;
|
|
320
|
+
additionalProperties: boolean;
|
|
321
|
+
properties: {
|
|
322
|
+
name: {
|
|
323
|
+
type: string;
|
|
324
|
+
};
|
|
325
|
+
enabled: {
|
|
326
|
+
type: string;
|
|
327
|
+
};
|
|
328
|
+
webhookPath: {
|
|
329
|
+
type: string;
|
|
330
|
+
};
|
|
331
|
+
token: {
|
|
332
|
+
type: string;
|
|
333
|
+
};
|
|
334
|
+
encodingAESKey: {
|
|
335
|
+
type: string;
|
|
336
|
+
};
|
|
337
|
+
receiveId: {
|
|
338
|
+
type: string;
|
|
339
|
+
};
|
|
340
|
+
corpId: {
|
|
341
|
+
type: string;
|
|
342
|
+
};
|
|
343
|
+
corpSecret: {
|
|
344
|
+
type: string;
|
|
345
|
+
};
|
|
346
|
+
agentId: {
|
|
347
|
+
type: string;
|
|
348
|
+
};
|
|
349
|
+
inboundMedia: {
|
|
350
|
+
type: string;
|
|
351
|
+
additionalProperties: boolean;
|
|
352
|
+
properties: {
|
|
353
|
+
enabled: {
|
|
354
|
+
type: string;
|
|
355
|
+
};
|
|
356
|
+
dir: {
|
|
357
|
+
type: string;
|
|
358
|
+
};
|
|
359
|
+
maxBytes: {
|
|
360
|
+
type: string;
|
|
361
|
+
};
|
|
362
|
+
keepDays: {
|
|
363
|
+
type: string;
|
|
364
|
+
};
|
|
365
|
+
};
|
|
366
|
+
};
|
|
367
|
+
welcomeText: {
|
|
368
|
+
type: string;
|
|
369
|
+
};
|
|
370
|
+
dmPolicy: {
|
|
371
|
+
type: string;
|
|
372
|
+
enum: string[];
|
|
373
|
+
};
|
|
374
|
+
allowFrom: {
|
|
375
|
+
type: string;
|
|
376
|
+
items: {
|
|
377
|
+
type: string;
|
|
378
|
+
};
|
|
379
|
+
};
|
|
380
|
+
groupPolicy: {
|
|
381
|
+
type: string;
|
|
382
|
+
enum: string[];
|
|
383
|
+
};
|
|
384
|
+
groupAllowFrom: {
|
|
385
|
+
type: string;
|
|
386
|
+
items: {
|
|
387
|
+
type: string;
|
|
388
|
+
};
|
|
389
|
+
};
|
|
390
|
+
requireMention: {
|
|
391
|
+
type: string;
|
|
392
|
+
};
|
|
393
|
+
maxFileSizeMB: {
|
|
394
|
+
type: string;
|
|
395
|
+
};
|
|
396
|
+
};
|
|
397
|
+
};
|
|
398
|
+
};
|
|
399
|
+
};
|
|
400
|
+
};
|
|
401
|
+
};
|
|
402
|
+
reload: {
|
|
403
|
+
configPrefixes: string[];
|
|
404
|
+
};
|
|
405
|
+
config: {
|
|
406
|
+
listAccountIds: (cfg: PluginConfig) => string[];
|
|
407
|
+
resolveAccount: (cfg: PluginConfig, accountId?: string) => ResolvedWecomAppAccount;
|
|
408
|
+
defaultAccountId: (cfg: PluginConfig) => string;
|
|
409
|
+
setAccountEnabled: (params: {
|
|
410
|
+
cfg: PluginConfig;
|
|
411
|
+
accountId?: string;
|
|
412
|
+
enabled: boolean;
|
|
413
|
+
}) => PluginConfig;
|
|
414
|
+
deleteAccount: (params: {
|
|
415
|
+
cfg: PluginConfig;
|
|
416
|
+
accountId?: string;
|
|
417
|
+
}) => PluginConfig;
|
|
418
|
+
isConfigured: (account: ResolvedWecomAppAccount) => boolean;
|
|
419
|
+
describeAccount: (account: ResolvedWecomAppAccount) => {
|
|
420
|
+
accountId: string;
|
|
421
|
+
name: string | undefined;
|
|
422
|
+
enabled: boolean;
|
|
423
|
+
configured: boolean;
|
|
424
|
+
canSendActive: boolean;
|
|
425
|
+
webhookPath: string;
|
|
426
|
+
};
|
|
427
|
+
resolveAllowFrom: (params: {
|
|
428
|
+
cfg: PluginConfig;
|
|
429
|
+
accountId?: string;
|
|
430
|
+
}) => string[];
|
|
431
|
+
formatAllowFrom: (params: {
|
|
432
|
+
allowFrom: (string | number)[];
|
|
433
|
+
}) => string[];
|
|
434
|
+
};
|
|
435
|
+
groups: {
|
|
436
|
+
resolveRequireMention: (params: {
|
|
437
|
+
cfg: PluginConfig;
|
|
438
|
+
accountId?: string;
|
|
439
|
+
account?: ResolvedWecomAppAccount;
|
|
440
|
+
}) => boolean;
|
|
441
|
+
};
|
|
442
|
+
/**
|
|
443
|
+
* 目录解析 - 用于将 wecom-app:XXX 格式的 target 解析为可投递目标
|
|
444
|
+
*
|
|
445
|
+
* 支持的输入格式:
|
|
446
|
+
* - "wecom-app:user:xxx" → { channel: "wecom-app", to: "user:xxx" }
|
|
447
|
+
* - "wecom-app:group:xxx" → { channel: "wecom-app", to: "group:xxx" }
|
|
448
|
+
* - "wecom-app:xxx" → { channel: "wecom-app", to: "user:xxx" }
|
|
449
|
+
* - "user:xxx" → { channel: "wecom-app", to: "user:xxx" }
|
|
450
|
+
* - "group:xxx" → { channel: "wecom-app", to: "group:xxx" }
|
|
451
|
+
* - "xxx" (裸ID) → { channel: "wecom-app", to: "user:xxx" }
|
|
452
|
+
* - 带 accountId: "user:xxx@account1" → { channel: "wecom-app", accountId: "account1", to: "user:xxx" }
|
|
453
|
+
*/
|
|
454
|
+
directory: {
|
|
455
|
+
/**
|
|
456
|
+
* 检查此通道是否可以解析给定的目标格式
|
|
457
|
+
* 用于框架层判断是否调用 resolveTarget
|
|
458
|
+
*/
|
|
459
|
+
canResolve: (params: {
|
|
460
|
+
target: string;
|
|
461
|
+
}) => boolean;
|
|
462
|
+
/**
|
|
463
|
+
* 解析单个目标地址
|
|
464
|
+
* 将各种格式的 target 解析为可用的投递对象
|
|
465
|
+
*/
|
|
466
|
+
resolveTarget: (params: {
|
|
467
|
+
cfg: PluginConfig;
|
|
468
|
+
target: string;
|
|
469
|
+
}) => {
|
|
470
|
+
channel: string;
|
|
471
|
+
accountId?: string;
|
|
472
|
+
to: string;
|
|
473
|
+
} | null;
|
|
474
|
+
/**
|
|
475
|
+
* 批量解析多个目标地址
|
|
476
|
+
* 用于框架层批量发送消息
|
|
477
|
+
*/
|
|
478
|
+
resolveTargets: (params: {
|
|
479
|
+
cfg: PluginConfig;
|
|
480
|
+
targets: string[];
|
|
481
|
+
}) => Array<{
|
|
482
|
+
channel: string;
|
|
483
|
+
accountId?: string;
|
|
484
|
+
to: string;
|
|
485
|
+
}>;
|
|
486
|
+
/**
|
|
487
|
+
* 获取此通道支持的目标格式说明
|
|
488
|
+
* 用于帮助信息和错误提示
|
|
489
|
+
*/
|
|
490
|
+
getTargetFormats: () => string[];
|
|
491
|
+
};
|
|
492
|
+
/**
|
|
493
|
+
* 主动发送消息 (自建应用特有功能)
|
|
494
|
+
*/
|
|
495
|
+
outbound: {
|
|
496
|
+
deliveryMode: string;
|
|
497
|
+
/**
|
|
498
|
+
* 主动发送文本消息
|
|
499
|
+
*/
|
|
500
|
+
sendText: (params: {
|
|
501
|
+
cfg: PluginConfig;
|
|
502
|
+
accountId?: string;
|
|
503
|
+
to: string;
|
|
504
|
+
text: string;
|
|
505
|
+
options?: {
|
|
506
|
+
markdown?: boolean;
|
|
507
|
+
};
|
|
508
|
+
}) => Promise<{
|
|
509
|
+
channel: string;
|
|
510
|
+
ok: boolean;
|
|
511
|
+
messageId: string;
|
|
512
|
+
error?: Error;
|
|
513
|
+
}>;
|
|
514
|
+
/**
|
|
515
|
+
* 发送媒体消息(支持图片、语音、文件)
|
|
516
|
+
* OpenClaw outbound 适配器要求的接口
|
|
517
|
+
*/
|
|
518
|
+
sendMedia: (params: {
|
|
519
|
+
cfg: PluginConfig;
|
|
520
|
+
accountId?: string;
|
|
521
|
+
to: string;
|
|
522
|
+
mediaUrl: string;
|
|
523
|
+
text?: string;
|
|
524
|
+
mimeType?: string;
|
|
525
|
+
}) => Promise<{
|
|
526
|
+
channel: string;
|
|
527
|
+
ok: boolean;
|
|
528
|
+
messageId: string;
|
|
529
|
+
error?: Error;
|
|
530
|
+
}>;
|
|
531
|
+
};
|
|
532
|
+
gateway: {
|
|
533
|
+
startAccount: (ctx: {
|
|
534
|
+
cfg: PluginConfig;
|
|
535
|
+
runtime?: unknown;
|
|
536
|
+
abortSignal?: AbortSignal;
|
|
537
|
+
accountId: string;
|
|
538
|
+
setStatus?: (status: Record<string, unknown>) => void;
|
|
539
|
+
log?: {
|
|
540
|
+
info: (msg: string) => void;
|
|
541
|
+
error: (msg: string) => void;
|
|
542
|
+
};
|
|
543
|
+
}) => Promise<void>;
|
|
544
|
+
stopAccount: (ctx: {
|
|
545
|
+
accountId: string;
|
|
546
|
+
setStatus?: (status: Record<string, unknown>) => void;
|
|
547
|
+
}) => Promise<void>;
|
|
548
|
+
};
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* 企业微信自建应用插件运行时管理
|
|
553
|
+
*/
|
|
554
|
+
interface PluginRuntime {
|
|
555
|
+
log?: (msg: string) => void;
|
|
556
|
+
error?: (msg: string) => void;
|
|
557
|
+
channel?: {
|
|
558
|
+
routing?: {
|
|
559
|
+
resolveAgentRoute?: (params: {
|
|
560
|
+
cfg: unknown;
|
|
561
|
+
channel: string;
|
|
562
|
+
peer: {
|
|
563
|
+
kind: string;
|
|
564
|
+
id: string;
|
|
565
|
+
};
|
|
566
|
+
}) => {
|
|
567
|
+
sessionKey: string;
|
|
568
|
+
accountId: string;
|
|
569
|
+
agentId?: string;
|
|
570
|
+
};
|
|
571
|
+
};
|
|
572
|
+
reply?: {
|
|
573
|
+
dispatchReplyFromConfig?: (params: {
|
|
574
|
+
ctx: unknown;
|
|
575
|
+
cfg: unknown;
|
|
576
|
+
dispatcher?: unknown;
|
|
577
|
+
replyOptions?: unknown;
|
|
578
|
+
}) => Promise<{
|
|
579
|
+
queuedFinal: boolean;
|
|
580
|
+
counts: {
|
|
581
|
+
final: number;
|
|
582
|
+
};
|
|
583
|
+
}>;
|
|
584
|
+
dispatchReplyWithBufferedBlockDispatcher?: (params: {
|
|
585
|
+
ctx: unknown;
|
|
586
|
+
cfg: unknown;
|
|
587
|
+
dispatcherOptions: {
|
|
588
|
+
deliver: (payload: {
|
|
589
|
+
text?: string;
|
|
590
|
+
}) => Promise<void>;
|
|
591
|
+
onError?: (err: unknown, info: {
|
|
592
|
+
kind: string;
|
|
593
|
+
}) => void;
|
|
594
|
+
};
|
|
595
|
+
}) => Promise<void>;
|
|
596
|
+
finalizeInboundContext?: (ctx: unknown) => unknown;
|
|
597
|
+
createReplyDispatcher?: (params: unknown) => unknown;
|
|
598
|
+
createReplyDispatcherWithTyping?: (params: unknown) => {
|
|
599
|
+
dispatcher: unknown;
|
|
600
|
+
replyOptions?: unknown;
|
|
601
|
+
markDispatchIdle?: () => void;
|
|
602
|
+
};
|
|
603
|
+
resolveHumanDelayConfig?: (cfg: unknown, agentId?: string) => unknown;
|
|
604
|
+
resolveEnvelopeFormatOptions?: (cfg: unknown) => unknown;
|
|
605
|
+
formatAgentEnvelope?: (params: {
|
|
606
|
+
channel: string;
|
|
607
|
+
from: string;
|
|
608
|
+
previousTimestamp?: number;
|
|
609
|
+
envelope?: unknown;
|
|
610
|
+
body: string;
|
|
611
|
+
}) => string;
|
|
612
|
+
};
|
|
613
|
+
session?: {
|
|
614
|
+
resolveStorePath?: (store: unknown, params: {
|
|
615
|
+
agentId?: string;
|
|
616
|
+
}) => string | undefined;
|
|
617
|
+
readSessionUpdatedAt?: (params: {
|
|
618
|
+
storePath?: string;
|
|
619
|
+
sessionKey: string;
|
|
620
|
+
}) => number | null;
|
|
621
|
+
recordInboundSession?: (params: {
|
|
622
|
+
storePath: string;
|
|
623
|
+
sessionKey: string;
|
|
624
|
+
ctx: unknown;
|
|
625
|
+
onRecordError?: (err: unknown) => void;
|
|
626
|
+
}) => Promise<void>;
|
|
627
|
+
};
|
|
628
|
+
text?: {
|
|
629
|
+
resolveMarkdownTableMode?: (params: {
|
|
630
|
+
cfg: unknown;
|
|
631
|
+
channel: string;
|
|
632
|
+
accountId?: string;
|
|
633
|
+
}) => unknown;
|
|
634
|
+
convertMarkdownTables?: (text: string, mode: unknown) => string;
|
|
635
|
+
};
|
|
636
|
+
};
|
|
637
|
+
system?: {
|
|
638
|
+
enqueueSystemEvent?: (message: string, options?: unknown) => void;
|
|
639
|
+
};
|
|
640
|
+
[key: string]: unknown;
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* 设置企业微信自建应用运行时
|
|
644
|
+
*/
|
|
645
|
+
declare function setWecomAppRuntime(next: PluginRuntime): void;
|
|
646
|
+
/**
|
|
647
|
+
* 获取企业微信自建应用运行时 (必须已初始化)
|
|
648
|
+
*/
|
|
649
|
+
declare function getWecomAppRuntime(): PluginRuntime;
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* 企业微信自建应用 API
|
|
653
|
+
*
|
|
654
|
+
* 提供 Access Token 缓存和主动发送消息能力
|
|
655
|
+
*/
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* 移除 Markdown 格式,转换为纯文本
|
|
659
|
+
* 方案 C: 代码块缩进,标题用【】标记,表格简化
|
|
660
|
+
* 企业微信文本消息不支持 Markdown
|
|
661
|
+
*/
|
|
662
|
+
declare function stripMarkdown(text: string): string;
|
|
663
|
+
/**
|
|
664
|
+
* 获取 Access Token(带缓存)
|
|
665
|
+
*/
|
|
666
|
+
declare function getAccessToken(account: ResolvedWecomAppAccount): Promise<string>;
|
|
667
|
+
/**
|
|
668
|
+
* 清除指定账户的 Access Token 缓存
|
|
669
|
+
*/
|
|
670
|
+
declare function clearAccessTokenCache(account: ResolvedWecomAppAccount): void;
|
|
671
|
+
/**
|
|
672
|
+
* 清除所有 Access Token 缓存
|
|
673
|
+
*/
|
|
674
|
+
declare function clearAllAccessTokenCache(): void;
|
|
675
|
+
/** 发送消息结果 */
|
|
676
|
+
type SendMessageResult = {
|
|
677
|
+
ok: boolean;
|
|
678
|
+
errcode?: number;
|
|
679
|
+
errmsg?: string;
|
|
680
|
+
invaliduser?: string;
|
|
681
|
+
invalidparty?: string;
|
|
682
|
+
invalidtag?: string;
|
|
683
|
+
msgid?: string;
|
|
684
|
+
};
|
|
685
|
+
/**
|
|
686
|
+
* 发送企业微信应用消息
|
|
687
|
+
*
|
|
688
|
+
* @param account - 已解析的账户配置
|
|
689
|
+
* @param target - 发送目标 (userId 或 chatid)
|
|
690
|
+
* @param message - 消息内容 (会自动移除 Markdown 格式)
|
|
691
|
+
*/
|
|
692
|
+
declare function sendWecomAppMessage(account: ResolvedWecomAppAccount, target: WecomAppSendTarget, message: string): Promise<SendMessageResult>;
|
|
693
|
+
/**
|
|
694
|
+
* 发送 Markdown 格式消息 (仅企业微信客户端支持)
|
|
695
|
+
*/
|
|
696
|
+
declare function sendWecomAppMarkdownMessage(account: ResolvedWecomAppAccount, target: WecomAppSendTarget, markdownContent: string): Promise<SendMessageResult>;
|
|
697
|
+
/**
|
|
698
|
+
* 发送图片消息
|
|
699
|
+
* @param account 账户配置
|
|
700
|
+
* @param target 发送目标
|
|
701
|
+
* @param mediaId 图片 media_id
|
|
702
|
+
*/
|
|
703
|
+
declare function sendWecomAppImageMessage(account: ResolvedWecomAppAccount, target: WecomAppSendTarget, mediaId: string): Promise<SendMessageResult>;
|
|
704
|
+
/**
|
|
705
|
+
* 下载并发送图片(完整流程)
|
|
706
|
+
* @param account 账户配置
|
|
707
|
+
* @param target 发送目标
|
|
708
|
+
* @param imageUrl 图片 URL
|
|
709
|
+
*/
|
|
710
|
+
declare function downloadAndSendImage(account: ResolvedWecomAppAccount, target: WecomAppSendTarget, imageUrl: string): Promise<SendMessageResult>;
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* 企业微信自建应用发送消息封装
|
|
714
|
+
*
|
|
715
|
+
* 提供业务层简化 API,规范化 target 格式,统一调用入口
|
|
716
|
+
*
|
|
717
|
+
* 使用示例:
|
|
718
|
+
* - 私聊:sendWecomDM("caihongyu", { text: "Hello" })
|
|
719
|
+
* - 群聊:sendWecomGroup("wrkxxxxxxx", { text: "Hello" })
|
|
720
|
+
*/
|
|
721
|
+
|
|
722
|
+
/**
|
|
723
|
+
* 发送消息选项
|
|
724
|
+
*/
|
|
725
|
+
type SendMessageOptions = {
|
|
726
|
+
/** 文本内容 */
|
|
727
|
+
text?: string;
|
|
728
|
+
/** 媒体文件路径或 URL(图片) */
|
|
729
|
+
mediaPath?: string;
|
|
730
|
+
};
|
|
731
|
+
/**
|
|
732
|
+
* 发送消息结果
|
|
733
|
+
*/
|
|
734
|
+
type SendResult = {
|
|
735
|
+
ok: boolean;
|
|
736
|
+
msgid?: string;
|
|
737
|
+
error?: string;
|
|
738
|
+
};
|
|
739
|
+
/**
|
|
740
|
+
* 规范化目标格式
|
|
741
|
+
*
|
|
742
|
+
* 输入格式(用户侧传入):
|
|
743
|
+
* - 私聊:"caihongyu" 或 "user:caihongyu"
|
|
744
|
+
* - 群聊:"wrkxxxxxx" 或 "group:wrkxxxxxx"
|
|
745
|
+
* - 带 channel 前缀:"wecom-app:user:caihongyu" 或 "wecom-app:group:xxx"
|
|
746
|
+
*
|
|
747
|
+
* 输出格式(OpenClaw 标准):
|
|
748
|
+
* - 私聊:"user:caihongyu"
|
|
749
|
+
* - 群聊:"group:wrkxxxxxx"
|
|
750
|
+
*/
|
|
751
|
+
declare function normalizeTarget(target: string, type: "user" | "group"): string;
|
|
752
|
+
/**
|
|
753
|
+
* 将规范化的 target 字符串解析为 WecomAppSendTarget
|
|
754
|
+
*/
|
|
755
|
+
declare function parseTarget(target: string): WecomAppSendTarget;
|
|
756
|
+
/**
|
|
757
|
+
* 发送私聊消息
|
|
758
|
+
*
|
|
759
|
+
* @param account - 已解析的账户配置
|
|
760
|
+
* @param userId - 用户 ID(如 "caihongyu"),支持带 "user:" 前缀
|
|
761
|
+
* @param options - 消息选项
|
|
762
|
+
*
|
|
763
|
+
* @example
|
|
764
|
+
* ```ts
|
|
765
|
+
* // 发送文本
|
|
766
|
+
* await sendWecomDM(account, "caihongyu", { text: "Hello!" });
|
|
767
|
+
*
|
|
768
|
+
* // 发送图片
|
|
769
|
+
* await sendWecomDM(account, "caihongyu", { mediaPath: "/path/to/image.jpg" });
|
|
770
|
+
*
|
|
771
|
+
* // 发送文本和图片
|
|
772
|
+
* await sendWecomDM(account, "caihongyu", {
|
|
773
|
+
* text: "Check out this image!",
|
|
774
|
+
* mediaPath: "https://example.com/image.jpg"
|
|
775
|
+
* });
|
|
776
|
+
* ```
|
|
777
|
+
*/
|
|
778
|
+
declare function sendWecomDM(account: ResolvedWecomAppAccount, userId: string, options: SendMessageOptions): Promise<SendResult>;
|
|
779
|
+
/**
|
|
780
|
+
* 发送群聊消息
|
|
781
|
+
*
|
|
782
|
+
* @param account - 已解析的账户配置
|
|
783
|
+
* @param chatId - 群聊 ID(如 "wrkxxxxxx"),支持带 "group:" 前缀
|
|
784
|
+
* @param options - 消息选项
|
|
785
|
+
*
|
|
786
|
+
* @example
|
|
787
|
+
* ```ts
|
|
788
|
+
* // 发送文本
|
|
789
|
+
* await sendWecomGroup(account, "wrkxxxxxx", { text: "Hello group!" });
|
|
790
|
+
*
|
|
791
|
+
* // 发送图片
|
|
792
|
+
* await sendWecomGroup(account, "wrkxxxxxx", { mediaPath: "/path/to/image.jpg" });
|
|
793
|
+
* ```
|
|
794
|
+
*/
|
|
795
|
+
declare function sendWecomGroup(account: ResolvedWecomAppAccount, chatId: string, options: SendMessageOptions): Promise<SendResult>;
|
|
796
|
+
/**
|
|
797
|
+
* 发送消息(自动识别目标类型)
|
|
798
|
+
*
|
|
799
|
+
* 根据 target 前缀自动判断是私聊还是群聊:
|
|
800
|
+
* - "user:xxx" 或无前缀 → 私聊
|
|
801
|
+
* - "group:xxx" → 群聊
|
|
802
|
+
*
|
|
803
|
+
* @param account - 已解析的账户配置
|
|
804
|
+
* @param target - 目标(支持 "user:xxx"、"group:xxx"、"xxx" 格式)
|
|
805
|
+
* @param options - 消息选项
|
|
806
|
+
*/
|
|
807
|
+
declare function sendWecom(account: ResolvedWecomAppAccount, target: string, options: SendMessageOptions): Promise<SendResult>;
|
|
808
|
+
|
|
809
|
+
/**
|
|
810
|
+
* @openclaw-china/wecom-app
|
|
811
|
+
* 企业微信自建应用渠道插件入口
|
|
812
|
+
*
|
|
813
|
+
* 导出:
|
|
814
|
+
* - wecomAppPlugin: ChannelPlugin 实现
|
|
815
|
+
* - DEFAULT_ACCOUNT_ID: 默认账户 ID
|
|
816
|
+
* - setWecomAppRuntime: 设置 Moltbot 运行时
|
|
817
|
+
* - sendWecomAppMessage: 主动发送消息
|
|
818
|
+
* - getAccessToken: 获取 Access Token
|
|
819
|
+
*/
|
|
820
|
+
|
|
821
|
+
/**
|
|
822
|
+
* Moltbot 插件 API 接口
|
|
823
|
+
*/
|
|
824
|
+
interface MoltbotPluginApi {
|
|
825
|
+
registerChannel: (opts: {
|
|
826
|
+
plugin: unknown;
|
|
827
|
+
}) => void;
|
|
828
|
+
registerHttpHandler?: (handler: (req: IncomingMessage, res: ServerResponse) => Promise<boolean> | boolean) => void;
|
|
829
|
+
runtime?: unknown;
|
|
830
|
+
[key: string]: unknown;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
declare const plugin: {
|
|
834
|
+
id: string;
|
|
835
|
+
name: string;
|
|
836
|
+
description: string;
|
|
837
|
+
configSchema: {
|
|
838
|
+
type: string;
|
|
839
|
+
additionalProperties: boolean;
|
|
840
|
+
properties: {};
|
|
841
|
+
};
|
|
842
|
+
register(api: MoltbotPluginApi): void;
|
|
843
|
+
};
|
|
844
|
+
|
|
845
|
+
export { type AccessTokenCacheEntry, DEFAULT_ACCOUNT_ID, type MoltbotPluginApi, type ResolvedWecomAppAccount, type SendMessageOptions, type SendResult, type WecomAppConfig, type WecomAppDmPolicy, type WecomAppGroupPolicy, type WecomAppInboundMessage, type WecomAppSendTarget, clearAccessTokenCache, clearAllAccessTokenCache, plugin as default, downloadAndSendImage, getAccessToken, getWecomAppRuntime, normalizeTarget, parseTarget, sendWecom, sendWecomAppImageMessage, sendWecomAppMarkdownMessage, sendWecomAppMessage, sendWecomDM, sendWecomGroup, setWecomAppRuntime, stripMarkdown, wecomAppPlugin };
|