@wu529778790/open-im 1.8.3-beta.8 → 1.9.0
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/README.md +22 -2
- package/README.zh-CN.md +22 -2
- package/dist/channels/capabilities.js +0 -5
- package/dist/channels/capabilities.test.js +1 -1
- package/dist/commands/handler.d.ts +2 -2
- package/dist/config-web.js +0 -1
- package/dist/config.d.ts +2 -15
- package/dist/config.js +20 -53
- package/dist/index.js +0 -22
- package/dist/setup.js +113 -67
- package/dist/workbuddy/centrifuge-client.d.ts +8 -1
- package/dist/workbuddy/centrifuge-client.js +35 -18
- package/dist/workbuddy/client.d.ts +4 -16
- package/dist/workbuddy/client.js +180 -93
- package/dist/workbuddy/message-sender.js +2 -2
- package/dist/workbuddy/oauth.js +3 -2
- package/package.json +1 -1
- package/dist/wechat/client.d.ts +0 -29
- package/dist/wechat/client.js +0 -136
- package/dist/wechat/client.test.d.ts +0 -1
- package/dist/wechat/client.test.js +0 -30
- package/dist/wechat/event-handler.d.ts +0 -11
- package/dist/wechat/event-handler.js +0 -286
- package/dist/wechat/message-sender.d.ts +0 -11
- package/dist/wechat/message-sender.js +0 -151
- package/dist/wechat/message-sender.test.d.ts +0 -1
- package/dist/wechat/message-sender.test.js +0 -35
- package/dist/wechat/transport.d.ts +0 -39
- package/dist/wechat/transport.js +0 -4
- package/dist/wechat/types.d.ts +0 -94
- package/dist/wechat/types.js +0 -5
- package/dist/wechat/workbuddy-transport.d.ts +0 -39
- package/dist/wechat/workbuddy-transport.js +0 -223
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Multi-platform IM bridge for AI CLI tools. Connect Telegram, Feishu, WeCom, Ding
|
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
-
- Multi-platform support: Telegram, Feishu, WeCom, DingTalk, QQ,
|
|
9
|
+
- Multi-platform support: Telegram, Feishu, WeCom, DingTalk, QQ, WeChat (experimental), and WorkBuddy (WeChat KF via CodeBuddy), with multiple platforms enabled at the same time
|
|
10
10
|
- Multiple AI tools: Claude, Codex, and CodeBuddy
|
|
11
11
|
- Per-platform AI routing: each IM platform can use a different AI tool, with `aiCommand` as the global default and `platforms.<name>.aiCommand` as the override
|
|
12
12
|
- Streaming replies: relay AI output and tool execution progress in real time (DingTalk streaming is not fully supported yet)
|
|
@@ -56,7 +56,7 @@ Open the config page at [`http://127.0.0.1:39282`](http://127.0.0.1:39282) (or t
|
|
|
56
56
|
- **AI Tooling** – **General**: default AI tool (Claude / Codex / CodeBuddy), work directory, hook port, log level. **Per-tool tabs**: Claude (CLI path, timeout, proxy, config path, ANTHROPIC\_\* fields), Codex (CLI path, timeout, proxy), CodeBuddy (CLI path, timeout).
|
|
57
57
|
- **Service control** – Validate config, Save, Start bridge, Stop bridge.
|
|
58
58
|
|
|
59
|
-
WeChat
|
|
59
|
+
WeChat and WorkBuddy are not in the web UI; configure them in `~/.open-im/config.json` or via `open-im init`.
|
|
60
60
|
|
|
61
61
|
- `open-im start` serves both the config page and the bridge on your local machine.
|
|
62
62
|
- `open-im dev` opens the page automatically only when setup is incomplete.
|
|
@@ -240,6 +240,14 @@ The following is valid JSON and can be saved directly as `~/.open-im/config.json
|
|
|
240
240
|
"allowedUserIds": [],
|
|
241
241
|
"appId": "YOUR_WECHAT_APP_ID",
|
|
242
242
|
"appSecret": "YOUR_WECHAT_APP_SECRET"
|
|
243
|
+
},
|
|
244
|
+
"workbuddy": {
|
|
245
|
+
"enabled": false,
|
|
246
|
+
"aiCommand": "claude",
|
|
247
|
+
"allowedUserIds": [],
|
|
248
|
+
"accessToken": "",
|
|
249
|
+
"refreshToken": "",
|
|
250
|
+
"userId": ""
|
|
243
251
|
}
|
|
244
252
|
}
|
|
245
253
|
}
|
|
@@ -287,6 +295,13 @@ The following is valid JSON and can be saved directly as `~/.open-im/config.json
|
|
|
287
295
|
| `WECHAT_USER_ID` | WeChat AGP mode user ID |
|
|
288
296
|
| `WECHAT_WS_URL` | WeChat WebSocket URL |
|
|
289
297
|
| `WECHAT_ALLOWED_USER_IDS` | WeChat allowlist |
|
|
298
|
+
| `WORKBUDDY_ACCESS_TOKEN` | WorkBuddy OAuth access token (auto-generated by `open-im init`) |
|
|
299
|
+
| `WORKBUDDY_REFRESH_TOKEN` | WorkBuddy OAuth refresh token (auto-generated by `open-im init`) |
|
|
300
|
+
| `WORKBUDDY_USER_ID` | WorkBuddy user ID |
|
|
301
|
+
| `WORKBUDDY_BASE_URL` | WorkBuddy API base URL, defaults to `https://copilot.tencent.com` |
|
|
302
|
+
| `WORKBUDDY_GUID` | WorkBuddy connection GUID (optional) |
|
|
303
|
+
| `WORKBUDDY_WORKSPACE_PATH` | WorkBuddy workspace path (optional) |
|
|
304
|
+
| `WORKBUDDY_ALLOWED_USER_IDS` | WorkBuddy allowlist |
|
|
290
305
|
|
|
291
306
|
### Platform Setup Sources
|
|
292
307
|
|
|
@@ -296,6 +311,7 @@ The following is valid JSON and can be saved directly as `~/.open-im/config.json
|
|
|
296
311
|
- DingTalk: create an internal enterprise app in DingTalk Open Platform, enable bot Stream Mode, and get the `Client ID` and `Client Secret`
|
|
297
312
|
- WeCom: get the bot ID and secret from the [WeCom admin console](https://work.weixin.qq.com/)
|
|
298
313
|
- WeChat: experimental, supports both standard mode and AGP/Qclaw-related settings
|
|
314
|
+
- WorkBuddy: connects via CodeBuddy (copilot.tencent.com) Centrifuge WebSocket; run `open-im init` and select "WorkBuddy 微信客服 (WeChat KF)" to complete OAuth login and WeChat KF binding
|
|
299
315
|
|
|
300
316
|
Notes on DingTalk: the current implementation uses a hybrid model of "Stream Mode for receiving messages + OpenAPI for sending messages".
|
|
301
317
|
|
|
@@ -337,6 +353,10 @@ DingTalk AI card templates are already compatible with the official "Search Resu
|
|
|
337
353
|
|
|
338
354
|
**CodeBuddy prompts for login**: run `codebuddy login` first. `open-im` does not read CodeBuddy login state from `~/.open-im/config.json`.
|
|
339
355
|
|
|
356
|
+
**WorkBuddy cannot connect**: run `open-im init` to re-authenticate. Tokens may expire — the client will attempt auto-reconnect, but if the refresh token is invalid, a fresh login is required.
|
|
357
|
+
|
|
358
|
+
**WorkBuddy WeChat KF not receiving messages**: ensure the WeChat KF binding was completed during `open-im init`. You can re-run init to generate a new binding link.
|
|
359
|
+
|
|
340
360
|
## License
|
|
341
361
|
|
|
342
362
|
[MIT](LICENSE)
|
package/README.zh-CN.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
## 功能特性
|
|
8
8
|
|
|
9
|
-
- 多平台:支持 Telegram、飞书、企业微信、钉钉、QQ
|
|
9
|
+
- 多平台:支持 Telegram、飞书、企业微信、钉钉、QQ、微信(测试中)、WorkBuddy(通过 CodeBuddy 接入微信客服),可同时启用
|
|
10
10
|
- 多 AI 工具:支持 Claude、Codex、CodeBuddy
|
|
11
11
|
- 按平台分配 AI:根级 `aiCommand` 作为默认值,`platforms.<name>.aiCommand` 可为不同 IM 单独指定 AI 工具
|
|
12
12
|
- 流式输出:实时回传 AI 回复与工具执行进度(目前钉钉暂未实现流式传输)
|
|
@@ -62,7 +62,7 @@ open-im start
|
|
|
62
62
|
- **AI 工具配置** – **公共**:默认 AI 工具(Claude / Codex / CodeBuddy)、工作目录、Hook 端口、日志级别。**分工具**:Claude(CLI 路径、超时、代理、配置路径、ANTHROPIC\_\* 等)、Codex(CLI 路径、超时、代理)、CodeBuddy(CLI 路径、超时)
|
|
63
63
|
- **服务控制** – 校验配置、保存、启动桥接、停止桥接
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
微信和 WorkBuddy 暂不在网页中配置,如需使用请在 `~/.open-im/config.json` 中手动配置或通过 `open-im init` 引导。
|
|
66
66
|
|
|
67
67
|
- `open-im start` 会同时启动桥接服务并提供该配置页(本机场景)。
|
|
68
68
|
- `open-im dev` 仅在未完成配置时自动打开页面。
|
|
@@ -246,6 +246,14 @@ codebuddy login
|
|
|
246
246
|
"allowedUserIds": [],
|
|
247
247
|
"appId": "YOUR_WECHAT_APP_ID",
|
|
248
248
|
"appSecret": "YOUR_WECHAT_APP_SECRET"
|
|
249
|
+
},
|
|
250
|
+
"workbuddy": {
|
|
251
|
+
"enabled": false,
|
|
252
|
+
"aiCommand": "claude",
|
|
253
|
+
"allowedUserIds": [],
|
|
254
|
+
"accessToken": "",
|
|
255
|
+
"refreshToken": "",
|
|
256
|
+
"userId": ""
|
|
249
257
|
}
|
|
250
258
|
}
|
|
251
259
|
}
|
|
@@ -293,6 +301,13 @@ codebuddy login
|
|
|
293
301
|
| `WECHAT_USER_ID` | 微信 AGP 模式 User ID |
|
|
294
302
|
| `WECHAT_WS_URL` | 微信 WebSocket 地址 |
|
|
295
303
|
| `WECHAT_ALLOWED_USER_IDS` | 微信白名单 |
|
|
304
|
+
| `WORKBUDDY_ACCESS_TOKEN` | WorkBuddy OAuth 访问令牌(由 `open-im init` 自动生成) |
|
|
305
|
+
| `WORKBUDDY_REFRESH_TOKEN` | WorkBuddy OAuth 刷新令牌(由 `open-im init` 自动生成) |
|
|
306
|
+
| `WORKBUDDY_USER_ID` | WorkBuddy 用户 ID |
|
|
307
|
+
| `WORKBUDDY_BASE_URL` | WorkBuddy API 地址,默认 `https://copilot.tencent.com` |
|
|
308
|
+
| `WORKBUDDY_GUID` | WorkBuddy 连接 GUID(可选) |
|
|
309
|
+
| `WORKBUDDY_WORKSPACE_PATH` | WorkBuddy 工作区路径(可选) |
|
|
310
|
+
| `WORKBUDDY_ALLOWED_USER_IDS` | WorkBuddy 白名单 |
|
|
296
311
|
|
|
297
312
|
### 平台配置来源
|
|
298
313
|
|
|
@@ -302,6 +317,7 @@ codebuddy login
|
|
|
302
317
|
- 钉钉:从钉钉开放平台创建企业内部应用,启用机器人 Stream Mode,获取 `Client ID` 和 `Client Secret`
|
|
303
318
|
- 企业微信:从 [企业微信管理后台](https://work.weixin.qq.com/) 获取 Bot ID 和 Secret
|
|
304
319
|
- 微信:测试中,支持标准模式和 AGP/Qclaw 相关配置
|
|
320
|
+
- WorkBuddy:通过 CodeBuddy(copilot.tencent.com)Centrifuge WebSocket 接入微信客服;运行 `open-im init` 并选择 "WorkBuddy 微信客服 (WeChat KF)" 完成 OAuth 登录和微信客服绑定
|
|
305
321
|
|
|
306
322
|
说明:钉钉当前采用“Stream Mode 收消息 + OpenAPI 发送消息”的混合模式。
|
|
307
323
|
|
|
@@ -343,6 +359,10 @@ codebuddy login
|
|
|
343
359
|
|
|
344
360
|
**CodeBuddy 提示需要登录**:先执行 `codebuddy login`。`open-im` 不会从 `~/.open-im/config.json` 读取 CodeBuddy 的登录态。
|
|
345
361
|
|
|
362
|
+
**WorkBuddy 无法连接**:重新运行 `open-im init` 登录。Token 可能过期——客户端会尝试自动重连,但如果 refresh token 失效,需要重新登录。
|
|
363
|
+
|
|
364
|
+
**WorkBuddy 微信客服收不到消息**:确认在 `open-im init` 中完成了微信客服绑定。可重新运行 init 生成新的绑定链接。
|
|
365
|
+
|
|
346
366
|
## License
|
|
347
367
|
|
|
348
368
|
[MIT](LICENSE)
|
|
@@ -2,7 +2,6 @@ const PLATFORM_LABELS = {
|
|
|
2
2
|
telegram: "Telegram",
|
|
3
3
|
feishu: "Feishu",
|
|
4
4
|
qq: "QQ",
|
|
5
|
-
wechat: "微信",
|
|
6
5
|
wework: "企业微信",
|
|
7
6
|
dingtalk: "钉钉",
|
|
8
7
|
workbuddy: "WorkBuddy",
|
|
@@ -20,10 +19,6 @@ export const CHANNEL_CAPABILITIES = {
|
|
|
20
19
|
inbound: { text: "native", image: "fallback", file: "fallback", voice: "fallback", video: "fallback" },
|
|
21
20
|
outbound: { streamEdit: "none", streamPush: "none", image: "fallback", card: "fallback", typing: "fallback" },
|
|
22
21
|
},
|
|
23
|
-
wechat: {
|
|
24
|
-
inbound: { text: "native", image: "fallback", file: "fallback", voice: "fallback", video: "fallback" },
|
|
25
|
-
outbound: { streamEdit: "native", streamPush: "fallback", image: "fallback", card: "native", typing: "native" },
|
|
26
|
-
},
|
|
27
22
|
wework: {
|
|
28
23
|
inbound: { text: "native", image: "fallback", file: "fallback", voice: "fallback", video: "fallback" },
|
|
29
24
|
outbound: { streamEdit: "native", streamPush: "fallback", image: "native", card: "native", typing: "native" },
|
|
@@ -10,7 +10,7 @@ describe("channel capabilities", () => {
|
|
|
10
10
|
expect(CHANNEL_CAPABILITIES.qq.inbound.video).toBe("fallback");
|
|
11
11
|
expect(CHANNEL_CAPABILITIES.qq.outbound.streamEdit).toBe("none");
|
|
12
12
|
expect(CHANNEL_CAPABILITIES.qq.outbound.streamPush).toBe("none");
|
|
13
|
-
expect(CHANNEL_CAPABILITIES.
|
|
13
|
+
expect(CHANNEL_CAPABILITIES.wework.inbound.image).toBe("fallback");
|
|
14
14
|
expect(CHANNEL_CAPABILITIES.wework.inbound.video).toBe("fallback");
|
|
15
15
|
expect(CHANNEL_CAPABILITIES.wework.outbound.image).toBe("native");
|
|
16
16
|
expect(CHANNEL_CAPABILITIES.dingtalk.inbound.file).toBe("fallback");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Config } from '../config.js';
|
|
1
|
+
import { type Config, type Platform } from '../config.js';
|
|
2
2
|
import type { SessionManager } from '../session/session-manager.js';
|
|
3
3
|
import type { RequestQueue } from '../queue/request-queue.js';
|
|
4
4
|
import type { ThreadContext } from '../shared/types.js';
|
|
@@ -18,7 +18,7 @@ export type ClaudeRequestHandler = (userId: string, chatId: string, prompt: stri
|
|
|
18
18
|
export declare class CommandHandler {
|
|
19
19
|
private deps;
|
|
20
20
|
constructor(deps: CommandHandlerDeps);
|
|
21
|
-
dispatch(text: string, chatId: string, userId: string, platform:
|
|
21
|
+
dispatch(text: string, chatId: string, userId: string, platform: Platform, handleClaudeRequest: ClaudeRequestHandler): Promise<boolean>;
|
|
22
22
|
private handleHelp;
|
|
23
23
|
private handleNew;
|
|
24
24
|
private handlePwd;
|
package/dist/config-web.js
CHANGED
package/dist/config.d.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { type LogLevel } from './logger.js';
|
|
2
|
-
export type Platform = 'dingtalk' | 'feishu' | 'qq' | 'telegram' | '
|
|
2
|
+
export type Platform = 'dingtalk' | 'feishu' | 'qq' | 'telegram' | 'wework' | 'workbuddy';
|
|
3
3
|
export type AiCommand = 'claude' | 'codex' | 'codebuddy';
|
|
4
4
|
export interface Config {
|
|
5
5
|
enabledPlatforms: Platform[];
|
|
6
6
|
telegramBotToken?: string;
|
|
7
7
|
feishuAppId?: string;
|
|
8
8
|
feishuAppSecret?: string;
|
|
9
|
-
/** WorkBuddy 用户 ID(可选,与 platforms.wechat.userId 二选一,环境变量 WECHAT_USER_ID) */
|
|
10
|
-
wechatUserId?: string;
|
|
11
9
|
weworkCorpId?: string;
|
|
12
10
|
weworkSecret?: string;
|
|
13
11
|
weworkWsUrl?: string;
|
|
@@ -20,7 +18,6 @@ export interface Config {
|
|
|
20
18
|
telegramAllowedUserIds: string[];
|
|
21
19
|
feishuAllowedUserIds: string[];
|
|
22
20
|
qqAllowedUserIds: string[];
|
|
23
|
-
wechatAllowedUserIds: string[];
|
|
24
21
|
weworkAllowedUserIds: string[];
|
|
25
22
|
dingtalkAllowedUserIds: string[];
|
|
26
23
|
workbuddyAllowedUserIds: string[];
|
|
@@ -55,16 +52,6 @@ export interface Config {
|
|
|
55
52
|
aiCommand?: AiCommand;
|
|
56
53
|
allowedUserIds: string[];
|
|
57
54
|
};
|
|
58
|
-
wechat?: {
|
|
59
|
-
enabled: boolean;
|
|
60
|
-
aiCommand?: AiCommand;
|
|
61
|
-
userId?: string;
|
|
62
|
-
allowedUserIds: string[];
|
|
63
|
-
workbuddyAccessToken?: string;
|
|
64
|
-
workbuddyRefreshToken?: string;
|
|
65
|
-
workbuddyBaseUrl?: string;
|
|
66
|
-
workbuddyHostId?: string;
|
|
67
|
-
};
|
|
68
55
|
wework?: {
|
|
69
56
|
enabled: boolean;
|
|
70
57
|
aiCommand?: AiCommand;
|
|
@@ -206,7 +193,7 @@ export declare function hasClaudeCredentials(): boolean;
|
|
|
206
193
|
/** 检测是否需要交互式配置(无 token 且无环境变量) */
|
|
207
194
|
export declare function needsSetup(): boolean;
|
|
208
195
|
export declare function loadConfig(): Config;
|
|
209
|
-
/**
|
|
196
|
+
/** 获取已配置凭证的平台列表 */
|
|
210
197
|
export declare function getPlatformsWithCredentials(config: Config): Platform[];
|
|
211
198
|
export declare function resolvePlatformAiCommand(config: Config, platform: Platform): AiCommand;
|
|
212
199
|
export declare function getConfiguredAiCommands(config: Config): AiCommand[];
|
package/dist/config.js
CHANGED
|
@@ -191,17 +191,19 @@ export function needsSetup() {
|
|
|
191
191
|
const tg = file.platforms?.telegram;
|
|
192
192
|
const fs = file.platforms?.feishu;
|
|
193
193
|
const qq = file.platforms?.qq;
|
|
194
|
-
const wc = file.platforms?.wechat;
|
|
195
194
|
const ww = file.platforms?.wework;
|
|
196
195
|
const dt = file.platforms?.dingtalk;
|
|
196
|
+
const wb = file.platforms?.workbuddy;
|
|
197
|
+
// Also check legacy platforms.wechat for migration path
|
|
198
|
+
const legacyWc = file.platforms?.wechat;
|
|
197
199
|
const hasTelegram = !!tg?.botToken;
|
|
198
200
|
const hasFeishu = !!(fs?.appId && fs?.appSecret);
|
|
199
201
|
const hasQQ = !!(qq?.appId && qq?.secret);
|
|
200
|
-
const hasWechat = !!(wc?.workbuddyAccessToken && wc?.workbuddyRefreshToken);
|
|
201
|
-
// 企业微信只需要 corpId 和 secret
|
|
202
202
|
const hasWework = !!(ww?.corpId && ww?.secret);
|
|
203
203
|
const hasDingtalk = !!(dt?.clientId && dt?.clientSecret);
|
|
204
|
-
|
|
204
|
+
const hasWorkBuddy = !!(wb?.accessToken && wb?.refreshToken && wb?.userId);
|
|
205
|
+
const hasLegacyWechat = !!(legacyWc?.workbuddyAccessToken && legacyWc?.workbuddyRefreshToken);
|
|
206
|
+
return !hasTelegram && !hasFeishu && !hasQQ && !hasWework && !hasDingtalk && !hasWorkBuddy && !hasLegacyWechat;
|
|
205
207
|
}
|
|
206
208
|
function parseCommaSeparated(value) {
|
|
207
209
|
return value.split(',').map((s) => s.trim()).filter(Boolean);
|
|
@@ -229,10 +231,18 @@ export function loadConfig() {
|
|
|
229
231
|
const fileTelegram = file.platforms?.telegram;
|
|
230
232
|
const fileFeishu = file.platforms?.feishu;
|
|
231
233
|
const fileQQ = file.platforms?.qq;
|
|
232
|
-
const fileWechat = file.platforms?.wechat;
|
|
233
234
|
const fileWework = file.platforms?.wework;
|
|
234
235
|
const fileDingtalk = file.platforms?.dingtalk;
|
|
235
|
-
|
|
236
|
+
// Auto-migrate legacy platforms.wechat WorkBuddy credentials → platforms.workbuddy
|
|
237
|
+
const legacyWechat = file.platforms?.wechat;
|
|
238
|
+
const fileWorkBuddy = file.platforms?.workbuddy ?? (legacyWechat?.workbuddyAccessToken && legacyWechat?.workbuddyRefreshToken
|
|
239
|
+
? {
|
|
240
|
+
accessToken: legacyWechat.workbuddyAccessToken,
|
|
241
|
+
refreshToken: legacyWechat.workbuddyRefreshToken,
|
|
242
|
+
userId: legacyWechat.userId,
|
|
243
|
+
baseUrl: legacyWechat.workbuddyBaseUrl,
|
|
244
|
+
}
|
|
245
|
+
: undefined);
|
|
236
246
|
// 1. 加载各平台凭证(env 优先,其次新结构,最后旧字段)
|
|
237
247
|
const telegramBotToken = process.env.TELEGRAM_BOT_TOKEN ??
|
|
238
248
|
fileTelegram?.botToken ??
|
|
@@ -247,16 +257,6 @@ export function loadConfig() {
|
|
|
247
257
|
fileQQ?.appId;
|
|
248
258
|
const qqSecret = process.env.QQ_BOT_SECRET ??
|
|
249
259
|
fileQQ?.secret;
|
|
250
|
-
const wechatUserId = process.env.WECHAT_USER_ID ??
|
|
251
|
-
fileWechat?.userId;
|
|
252
|
-
const wechatWorkbuddyAccessToken = process.env.WECHAT_WORKBUDDY_ACCESS_TOKEN ??
|
|
253
|
-
fileWechat?.workbuddyAccessToken;
|
|
254
|
-
const wechatWorkbuddyRefreshToken = process.env.WECHAT_WORKBUDDY_REFRESH_TOKEN ??
|
|
255
|
-
fileWechat?.workbuddyRefreshToken;
|
|
256
|
-
const wechatWorkbuddyBaseUrl = process.env.WECHAT_WORKBUDDY_BASE_URL ??
|
|
257
|
-
fileWechat?.workbuddyBaseUrl;
|
|
258
|
-
const wechatWorkbuddyHostId = process.env.WECHAT_WORKBUDDY_HOST_ID ??
|
|
259
|
-
fileWechat?.workbuddyHostId;
|
|
260
260
|
const weworkCorpId = process.env.WEWORK_CORP_ID ??
|
|
261
261
|
fileWework?.corpId;
|
|
262
262
|
const weworkSecret = process.env.WEWORK_SECRET ??
|
|
@@ -287,19 +287,14 @@ export function loadConfig() {
|
|
|
287
287
|
const telegramEnabledFlag = fileTelegram?.enabled;
|
|
288
288
|
const feishuEnabledFlag = fileFeishu?.enabled;
|
|
289
289
|
const qqEnabledFlag = fileQQ?.enabled;
|
|
290
|
-
const wechatEnabledFlag = fileWechat?.enabled;
|
|
291
290
|
const weworkEnabledFlag = fileWework?.enabled;
|
|
292
291
|
const dingtalkEnabledFlag = fileDingtalk?.enabled;
|
|
293
292
|
const workbuddyEnabledFlag = fileWorkBuddy?.enabled;
|
|
294
293
|
const telegramEnabled = !!telegramBotToken && (telegramEnabledFlag !== false);
|
|
295
294
|
const feishuEnabled = !!(feishuAppId && feishuAppSecret) && (feishuEnabledFlag !== false);
|
|
296
295
|
const qqEnabled = !!(qqAppId && qqSecret) && (qqEnabledFlag !== false);
|
|
297
|
-
const hasWechatWorkbuddyCreds = !!(wechatWorkbuddyAccessToken && wechatWorkbuddyRefreshToken);
|
|
298
|
-
const wechatEnabled = hasWechatWorkbuddyCreds && (wechatEnabledFlag !== false);
|
|
299
|
-
// 企业微信只需要 corpId (botId) 和 secret
|
|
300
296
|
const weworkEnabled = !!(weworkCorpId && weworkSecret) && (weworkEnabledFlag !== false);
|
|
301
297
|
const dingtalkEnabled = !!(dingtalkClientId && dingtalkClientSecret) && (dingtalkEnabledFlag !== false);
|
|
302
|
-
// WorkBuddy 需要 OAuth 凭证
|
|
303
298
|
const workbuddyEnabled = !!(workbuddyAccessToken && workbuddyRefreshToken && workbuddyUserId) && (workbuddyEnabledFlag !== false);
|
|
304
299
|
if (telegramEnabled)
|
|
305
300
|
enabledPlatforms.push('telegram');
|
|
@@ -307,8 +302,6 @@ export function loadConfig() {
|
|
|
307
302
|
enabledPlatforms.push('feishu');
|
|
308
303
|
if (qqEnabled)
|
|
309
304
|
enabledPlatforms.push('qq');
|
|
310
|
-
if (wechatEnabled)
|
|
311
|
-
enabledPlatforms.push('wechat');
|
|
312
305
|
if (weworkEnabled)
|
|
313
306
|
enabledPlatforms.push('wework');
|
|
314
307
|
if (dingtalkEnabled)
|
|
@@ -332,9 +325,6 @@ export function loadConfig() {
|
|
|
332
325
|
const qqAllowedUserIds = process.env.QQ_ALLOWED_USER_IDS !== undefined
|
|
333
326
|
? parseCommaSeparated(process.env.QQ_ALLOWED_USER_IDS)
|
|
334
327
|
: fileQQ?.allowedUserIds ?? allowedUserIds;
|
|
335
|
-
const wechatAllowedUserIds = process.env.WECHAT_ALLOWED_USER_IDS !== undefined
|
|
336
|
-
? parseCommaSeparated(process.env.WECHAT_ALLOWED_USER_IDS)
|
|
337
|
-
: fileWechat?.allowedUserIds ?? allowedUserIds;
|
|
338
328
|
const weworkAllowedUserIds = process.env.WEWORK_ALLOWED_USER_IDS !== undefined
|
|
339
329
|
? parseCommaSeparated(process.env.WEWORK_ALLOWED_USER_IDS)
|
|
340
330
|
: fileWework?.allowedUserIds ?? allowedUserIds;
|
|
@@ -544,27 +534,6 @@ export function loadConfig() {
|
|
|
544
534
|
aiCommand: normalizeAiCommand(file.platforms?.qq?.aiCommand, aiCommand),
|
|
545
535
|
allowedUserIds: qqAllowedUserIds,
|
|
546
536
|
},
|
|
547
|
-
wechat: wechatEnabled
|
|
548
|
-
? {
|
|
549
|
-
enabled: true,
|
|
550
|
-
aiCommand: normalizeAiCommand(file.platforms?.wechat?.aiCommand, aiCommand),
|
|
551
|
-
userId: wechatUserId,
|
|
552
|
-
allowedUserIds: wechatAllowedUserIds,
|
|
553
|
-
workbuddyAccessToken: wechatWorkbuddyAccessToken,
|
|
554
|
-
workbuddyRefreshToken: wechatWorkbuddyRefreshToken,
|
|
555
|
-
workbuddyBaseUrl: wechatWorkbuddyBaseUrl,
|
|
556
|
-
workbuddyHostId: wechatWorkbuddyHostId,
|
|
557
|
-
}
|
|
558
|
-
: {
|
|
559
|
-
enabled: false,
|
|
560
|
-
aiCommand: normalizeAiCommand(file.platforms?.wechat?.aiCommand, aiCommand),
|
|
561
|
-
userId: wechatUserId,
|
|
562
|
-
allowedUserIds: wechatAllowedUserIds,
|
|
563
|
-
workbuddyAccessToken: wechatWorkbuddyAccessToken,
|
|
564
|
-
workbuddyRefreshToken: wechatWorkbuddyRefreshToken,
|
|
565
|
-
workbuddyBaseUrl: wechatWorkbuddyBaseUrl,
|
|
566
|
-
workbuddyHostId: wechatWorkbuddyHostId,
|
|
567
|
-
},
|
|
568
537
|
wework: weworkEnabled
|
|
569
538
|
? {
|
|
570
539
|
enabled: true,
|
|
@@ -620,7 +589,6 @@ export function loadConfig() {
|
|
|
620
589
|
feishuAppSecret: feishuAppSecret ?? '',
|
|
621
590
|
qqAppId: qqAppId ?? '',
|
|
622
591
|
qqSecret: qqSecret ?? '',
|
|
623
|
-
wechatUserId: wechatUserId,
|
|
624
592
|
weworkCorpId: weworkCorpId ?? '',
|
|
625
593
|
weworkSecret: weworkSecret ?? '',
|
|
626
594
|
weworkWsUrl: weworkWsUrl,
|
|
@@ -631,7 +599,6 @@ export function loadConfig() {
|
|
|
631
599
|
telegramAllowedUserIds,
|
|
632
600
|
feishuAllowedUserIds,
|
|
633
601
|
qqAllowedUserIds,
|
|
634
|
-
wechatAllowedUserIds,
|
|
635
602
|
weworkAllowedUserIds,
|
|
636
603
|
dingtalkAllowedUserIds,
|
|
637
604
|
workbuddyAllowedUserIds,
|
|
@@ -650,7 +617,7 @@ export function loadConfig() {
|
|
|
650
617
|
platforms,
|
|
651
618
|
};
|
|
652
619
|
}
|
|
653
|
-
/**
|
|
620
|
+
/** 获取已配置凭证的平台列表 */
|
|
654
621
|
export function getPlatformsWithCredentials(config) {
|
|
655
622
|
const r = [];
|
|
656
623
|
if (config.telegramBotToken)
|
|
@@ -663,9 +630,9 @@ export function getPlatformsWithCredentials(config) {
|
|
|
663
630
|
r.push('wework');
|
|
664
631
|
if (config.dingtalkClientId && config.dingtalkClientSecret)
|
|
665
632
|
r.push('dingtalk');
|
|
666
|
-
const
|
|
667
|
-
if (
|
|
668
|
-
r.push('
|
|
633
|
+
const wb = config.platforms.workbuddy;
|
|
634
|
+
if (wb?.accessToken && wb?.refreshToken)
|
|
635
|
+
r.push('workbuddy');
|
|
669
636
|
return r;
|
|
670
637
|
}
|
|
671
638
|
export function resolvePlatformAiCommand(config, platform) {
|
package/dist/index.js
CHANGED
|
@@ -15,9 +15,6 @@ import { sendTextReply as sendFeishuTextReply } from "./feishu/message-sender.js
|
|
|
15
15
|
import { initQQ, stopQQ } from "./qq/client.js";
|
|
16
16
|
import { setupQQHandlers } from "./qq/event-handler.js";
|
|
17
17
|
import { sendTextReply as sendQQTextReply } from "./qq/message-sender.js";
|
|
18
|
-
import { initWeChat, stopWeChat } from "./wechat/client.js";
|
|
19
|
-
import { setupWeChatHandlers } from "./wechat/event-handler.js";
|
|
20
|
-
import { sendTextReply as sendWeChatTextReply } from "./wechat/message-sender.js";
|
|
21
18
|
import { initWeWork, stopWeWork } from "./wework/client.js";
|
|
22
19
|
import { setupWeWorkHandlers } from "./wework/event-handler.js";
|
|
23
20
|
import { sendProactiveTextReply as sendWeWorkTextReply } from "./wework/message-sender.js";
|
|
@@ -42,7 +39,6 @@ async function sendLifecycleNotification(platform, message) {
|
|
|
42
39
|
const telegramChatId = getActiveChatId("telegram");
|
|
43
40
|
const feishuChatId = getActiveChatId("feishu");
|
|
44
41
|
const qqChatId = getActiveChatId("qq");
|
|
45
|
-
const wechatChatId = getActiveChatId("wechat");
|
|
46
42
|
const weworkChatId = getActiveChatId("wework");
|
|
47
43
|
const sendPromises = [];
|
|
48
44
|
if (platform === "telegram" && telegramChatId) {
|
|
@@ -60,11 +56,6 @@ async function sendLifecycleNotification(platform, message) {
|
|
|
60
56
|
log.debug("Failed to send QQ notification:", err);
|
|
61
57
|
}));
|
|
62
58
|
}
|
|
63
|
-
if (platform === "wechat" && wechatChatId) {
|
|
64
|
-
sendPromises.push(sendWeChatTextReply(wechatChatId, message).catch((err) => {
|
|
65
|
-
log.debug("Failed to send WeChat notification:", err);
|
|
66
|
-
}));
|
|
67
|
-
}
|
|
68
59
|
if (platform === "wework" && weworkChatId) {
|
|
69
60
|
sendPromises.push(sendWeWorkTextReply(weworkChatId, message).catch((err) => {
|
|
70
61
|
log.debug("Failed to send WeWork notification:", err);
|
|
@@ -173,7 +164,6 @@ export async function main() {
|
|
|
173
164
|
let telegramHandle = null;
|
|
174
165
|
let feishuHandle = null;
|
|
175
166
|
let qqHandle = null;
|
|
176
|
-
let wechatHandle = null;
|
|
177
167
|
let weworkHandle = null;
|
|
178
168
|
let dingtalkHandle = null;
|
|
179
169
|
let workbuddyHandle = null;
|
|
@@ -210,16 +200,6 @@ export async function main() {
|
|
|
210
200
|
log.error("Failed to initialize QQ:", err);
|
|
211
201
|
}
|
|
212
202
|
}
|
|
213
|
-
if (config.enabledPlatforms.includes("wechat")) {
|
|
214
|
-
try {
|
|
215
|
-
wechatHandle = setupWeChatHandlers(config, sessionManager);
|
|
216
|
-
await initWeChat(config, wechatHandle.handleEvent);
|
|
217
|
-
successfulPlatforms.push("wechat");
|
|
218
|
-
}
|
|
219
|
-
catch (err) {
|
|
220
|
-
log.error("Failed to initialize WeChat:", err);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
203
|
if (config.enabledPlatforms.includes("wework")) {
|
|
224
204
|
try {
|
|
225
205
|
weworkHandle = setupWeWorkHandlers(config, sessionManager);
|
|
@@ -290,8 +270,6 @@ export async function main() {
|
|
|
290
270
|
stopFeishu();
|
|
291
271
|
qqHandle?.stop();
|
|
292
272
|
await stopQQ();
|
|
293
|
-
wechatHandle?.stop();
|
|
294
|
-
stopWeChat();
|
|
295
273
|
weworkHandle?.stop();
|
|
296
274
|
stopWeWork();
|
|
297
275
|
dingtalkHandle?.stop();
|