mozi-bot 1.1.2 → 1.2.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 +251 -31
- package/dist/channels/index.d.ts +4 -0
- package/dist/channels/index.d.ts.map +1 -1
- package/dist/channels/index.js +4 -0
- package/dist/channels/index.js.map +1 -1
- package/dist/channels/qq/api.d.ts +37 -0
- package/dist/channels/qq/api.d.ts.map +1 -0
- package/dist/channels/qq/api.js +145 -0
- package/dist/channels/qq/api.js.map +1 -0
- package/dist/channels/qq/index.d.ts +36 -0
- package/dist/channels/qq/index.d.ts.map +1 -0
- package/dist/channels/qq/index.js +145 -0
- package/dist/channels/qq/index.js.map +1 -0
- package/dist/channels/qq/websocket.d.ts +67 -0
- package/dist/channels/qq/websocket.d.ts.map +1 -0
- package/dist/channels/qq/websocket.js +372 -0
- package/dist/channels/qq/websocket.js.map +1 -0
- package/dist/channels/wecom/api.d.ts +30 -0
- package/dist/channels/wecom/api.d.ts.map +1 -0
- package/dist/channels/wecom/api.js +98 -0
- package/dist/channels/wecom/api.js.map +1 -0
- package/dist/channels/wecom/crypto.d.ts +25 -0
- package/dist/channels/wecom/crypto.d.ts.map +1 -0
- package/dist/channels/wecom/crypto.js +74 -0
- package/dist/channels/wecom/crypto.js.map +1 -0
- package/dist/channels/wecom/events.d.ts +34 -0
- package/dist/channels/wecom/events.d.ts.map +1 -0
- package/dist/channels/wecom/events.js +127 -0
- package/dist/channels/wecom/events.js.map +1 -0
- package/dist/channels/wecom/index.d.ts +39 -0
- package/dist/channels/wecom/index.d.ts.map +1 -0
- package/dist/channels/wecom/index.js +184 -0
- package/dist/channels/wecom/index.js.map +1 -0
- package/dist/cli/index.js +21 -6
- package/dist/cli/index.js.map +1 -1
- package/dist/config/index.d.ts +94 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +49 -2
- package/dist/config/index.js.map +1 -1
- package/dist/gateway/server.d.ts +2 -0
- package/dist/gateway/server.d.ts.map +1 -1
- package/dist/gateway/server.js +47 -0
- package/dist/gateway/server.js.map +1 -1
- package/dist/types/index.d.ts +20 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -2,17 +2,149 @@
|
|
|
2
2
|
|
|
3
3
|
**支持国产大模型和国产通讯软件的智能助手框架**
|
|
4
4
|
|
|
5
|
-
Mozi 是一个轻量级的 AI 助手框架,专注于国产生态。它提供统一的接口对接多种国产 AI 模型(DeepSeek、Qwen、Kimi 等),支持 OpenAI Function Calling
|
|
5
|
+
Mozi 是一个轻量级的 AI 助手框架,专注于国产生态。它提供统一的接口对接多种国产 AI 模型(DeepSeek、Qwen、Kimi 等),支持 OpenAI Function Calling,并能在飞书、钉钉等平台上运行。
|
|
6
6
|
|
|
7
7
|
## 核心特性
|
|
8
8
|
|
|
9
9
|
- **多模型支持** — DeepSeek、DashScope (Qwen)、智谱AI、Kimi、阶跃星辰、MiniMax,以及 OpenAI/Anthropic 兼容格式
|
|
10
|
-
- **多平台通道** —
|
|
10
|
+
- **多平台通道** — 飞书、钉钉、QQ,统一的消息处理接口
|
|
11
11
|
- **Function Calling** — 原生支持 OpenAI tools/tool_choice 参数
|
|
12
12
|
- **17 内置工具** — 文件读写、Bash 执行、代码搜索、网页获取、图像分析、浏览器自动化等
|
|
13
13
|
- **会话管理** — 上下文压缩、会话持久化、多轮对话
|
|
14
14
|
- **可扩展** — 插件系统、Hook 事件、自定义工具、子 Agent
|
|
15
15
|
|
|
16
|
+
## 为什么选择 Mozi?
|
|
17
|
+
|
|
18
|
+
Mozi 的架构设计参考了 [Moltbot](https://github.com/moltbot/moltbot),但专注于不同的使用场景:
|
|
19
|
+
|
|
20
|
+
| 特性 | Mozi | Moltbot |
|
|
21
|
+
|------|------|---------|
|
|
22
|
+
| **定位** | 国产生态优先的轻量框架 | 全功能个人 AI 助手 |
|
|
23
|
+
| **代码量** | ~16,000 行 (64 文件) | ~516,000 行 (3,137 文件) |
|
|
24
|
+
| **国产模型** | DeepSeek、Qwen、Kimi 等 7+ 家 | 仅 Anthropic、OpenAI |
|
|
25
|
+
| **国产通讯** | 飞书、钉钉、QQ 原生支持 | WhatsApp、Telegram、Slack 等 |
|
|
26
|
+
| **Node.js 版本** | >= 18 | >= 22 |
|
|
27
|
+
| **适用场景** | 企业内部机器人、国内团队协作 | 个人多设备助手、海外平台集成 |
|
|
28
|
+
|
|
29
|
+
> **Mozi 用 3% 的代码量实现了核心功能**,专注简洁高效,易于理解和二次开发。
|
|
30
|
+
|
|
31
|
+
## 学习 Agent 原理
|
|
32
|
+
|
|
33
|
+
如果你想了解 AI Agent 的工作原理,Mozi 是一个很好的学习项目。相比动辄几十万行代码的大型框架,Mozi 只有约 16,000 行代码,但实现了完整的 Agent 核心功能:
|
|
34
|
+
|
|
35
|
+
- **消息循环** — 用户输入 → LLM 推理 → 工具调用 → 结果反馈
|
|
36
|
+
- **上下文管理** — 会话历史、Token 压缩、多轮对话
|
|
37
|
+
- **工具系统** — 函数定义、参数校验、结果处理
|
|
38
|
+
- **流式输出** — SSE/WebSocket 实时响应
|
|
39
|
+
- **失败重试** — 模型调用失败自动切换备选模型
|
|
40
|
+
|
|
41
|
+
代码结构清晰,注释完善,适合阅读源码学习 Agent 架构设计。
|
|
42
|
+
|
|
43
|
+
## 架构设计
|
|
44
|
+
|
|
45
|
+
```mermaid
|
|
46
|
+
flowchart TB
|
|
47
|
+
subgraph Input["📥 输入层"]
|
|
48
|
+
Feishu["🔵 飞书\nWebSocket 长连接"]
|
|
49
|
+
Dingtalk["🟢 钉钉\nStream 长连接"]
|
|
50
|
+
QQ["🟣 QQ\nWebSocket 长连接"]
|
|
51
|
+
WebChat["🟡 WebChat\nHTTP + WebSocket"]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
subgraph Server["🚀 服务层"]
|
|
55
|
+
Gateway["Gateway 网关\nHTTP/WebSocket 路由"]
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
subgraph Core["⚙️ 核心层"]
|
|
59
|
+
Agent["Agent 引擎"]
|
|
60
|
+
|
|
61
|
+
subgraph AgentInner[" "]
|
|
62
|
+
MsgLoop["📨 消息循环\nUser → LLM → Tool → Result"]
|
|
63
|
+
CtxMgr["📚 上下文管理\n历史压缩 / Token 控制"]
|
|
64
|
+
Session["💾 会话存储\nMemory / File"]
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
subgraph External["🔗 外部依赖"]
|
|
69
|
+
subgraph Providers["模型提供商"]
|
|
70
|
+
P1["DeepSeek"]
|
|
71
|
+
P2["DashScope"]
|
|
72
|
+
P3["智谱AI"]
|
|
73
|
+
P4["Kimi"]
|
|
74
|
+
P5["OpenAI"]
|
|
75
|
+
P6["Anthropic"]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
subgraph Tools["工具系统"]
|
|
79
|
+
T1["📁 文件操作\nread/write/edit/glob/grep"]
|
|
80
|
+
T2["⌨️ Bash 执行\n命令行 / 进程管理"]
|
|
81
|
+
T3["🌐 网络请求\nsearch/fetch"]
|
|
82
|
+
T4["🖼️ 多媒体\n图像分析 / 浏览器"]
|
|
83
|
+
T5["🤖 子 Agent\n复杂任务分解"]
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
Feishu --> Gateway
|
|
88
|
+
Dingtalk --> Gateway
|
|
89
|
+
QQ --> Gateway
|
|
90
|
+
WebChat --> Gateway
|
|
91
|
+
Gateway --> Agent
|
|
92
|
+
Agent --> MsgLoop
|
|
93
|
+
MsgLoop <--> CtxMgr
|
|
94
|
+
MsgLoop <--> Session
|
|
95
|
+
MsgLoop <-->|"调用模型"| Providers
|
|
96
|
+
MsgLoop <-->|"执行工具"| Tools
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 消息处理流程
|
|
100
|
+
|
|
101
|
+
```mermaid
|
|
102
|
+
flowchart TD
|
|
103
|
+
Start([用户发送消息]) --> Channel[Channel 接收]
|
|
104
|
+
Channel --> Gateway[Gateway 路由]
|
|
105
|
+
Gateway --> LoadCtx[加载会话上下文]
|
|
106
|
+
|
|
107
|
+
LoadCtx --> BuildCtx[构建 LLM 请求]
|
|
108
|
+
BuildCtx --> |系统提示词<br/>历史消息<br/>工具列表| CallLLM[调用 LLM]
|
|
109
|
+
|
|
110
|
+
CallLLM --> Check{返回类型?}
|
|
111
|
+
|
|
112
|
+
Check --> |纯文本| Response[返回响应]
|
|
113
|
+
Check --> |工具调用| ExecTool[执行工具]
|
|
114
|
+
|
|
115
|
+
ExecTool --> ToolResult[工具返回结果]
|
|
116
|
+
ToolResult --> |加入上下文| CallLLM
|
|
117
|
+
|
|
118
|
+
Response --> SaveCtx[保存会话]
|
|
119
|
+
SaveCtx --> Send[Channel 发送]
|
|
120
|
+
Send --> End([用户收到回复])
|
|
121
|
+
|
|
122
|
+
style Start fill:#e1f5fe
|
|
123
|
+
style End fill:#e8f5e9
|
|
124
|
+
style CallLLM fill:#fff3e0
|
|
125
|
+
style ExecTool fill:#fce4ec
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### 核心模块
|
|
129
|
+
|
|
130
|
+
| 模块 | 目录 | 职责 |
|
|
131
|
+
|------|------|------|
|
|
132
|
+
| **Agent** | `src/agents/` | 核心消息循环、上下文压缩、会话管理、模型失败重试 |
|
|
133
|
+
| **Providers** | `src/providers/` | 统一的模型调用接口,支持 OpenAI/Anthropic 兼容格式 |
|
|
134
|
+
| **Tools** | `src/tools/` | 工具注册、参数校验、执行引擎,支持自定义扩展 |
|
|
135
|
+
| **Channels** | `src/channels/` | 通道适配器,统一消息格式,支持长连接和 Webhook |
|
|
136
|
+
| **Sessions** | `src/sessions/` | 会话持久化,支持内存/文件存储,Transcript 记录 |
|
|
137
|
+
| **Gateway** | `src/gateway/` | HTTP/WebSocket 服务,路由分发 |
|
|
138
|
+
|
|
139
|
+
### 上下文压缩策略
|
|
140
|
+
|
|
141
|
+
当对话历史超过 Token 限制时,Mozi 使用智能压缩:
|
|
142
|
+
|
|
143
|
+
1. **保留策略** — 始终保留系统提示词和最近 N 轮对话
|
|
144
|
+
2. **摘要压缩** — 将早期对话压缩为摘要,保留关键信息
|
|
145
|
+
3. **工具结果裁剪** — 截断过长的工具返回结果
|
|
146
|
+
4. **配对验证** — 确保 tool_call 和 tool_result 成对出现
|
|
147
|
+
|
|
16
148
|
## 快速开始
|
|
17
149
|
|
|
18
150
|
### 环境要求
|
|
@@ -43,7 +175,7 @@ mozi onboard
|
|
|
43
175
|
- **国产模型** — DeepSeek、智谱AI、DashScope、Kimi、阶跃星辰、MiniMax、ModelScope
|
|
44
176
|
- **自定义 OpenAI 兼容接口** — 支持任意 OpenAI API 格式的服务(如 vLLM、Ollama)
|
|
45
177
|
- **自定义 Anthropic 兼容接口** — 支持任意 Claude API 格式的服务
|
|
46
|
-
- **通讯平台** —
|
|
178
|
+
- **通讯平台** — 飞书、钉钉、QQ
|
|
47
179
|
|
|
48
180
|
配置文件将保存到 `~/.mozi/config.local.json5`。
|
|
49
181
|
|
|
@@ -144,7 +276,7 @@ npm start -- start --web-only
|
|
|
144
276
|
|
|
145
277
|
## 通讯平台接入
|
|
146
278
|
|
|
147
|
-
|
|
279
|
+
飞书、钉钉和 QQ 都支持长连接模式:
|
|
148
280
|
|
|
149
281
|
| 模式 | 说明 | 适用场景 |
|
|
150
282
|
|------|------|----------|
|
|
@@ -155,13 +287,52 @@ npm start -- start --web-only
|
|
|
155
287
|
|
|
156
288
|
### 飞书
|
|
157
289
|
|
|
290
|
+
#### 1. 创建应用
|
|
291
|
+
|
|
158
292
|
1. 登录 [飞书开放平台](https://open.feishu.cn/),创建企业自建应用
|
|
159
293
|
2. 获取 App ID 和 App Secret
|
|
160
|
-
3.
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
294
|
+
3. 在应用管理页左侧导航栏,找到「应用能力」,启用「机器人」能力
|
|
295
|
+
|
|
296
|
+
#### 2. 事件配置
|
|
297
|
+
|
|
298
|
+
1. 在应用管理页左侧导航栏,找到「事件与回调」,点击进入
|
|
299
|
+
2. 订阅方式选择「长连接」,点击「保存」
|
|
300
|
+
> ⚠️ 如果提示"未建立长连接",需要先完成「Mozi 配置」并启动服务(`mozi start`),再回来保存长连接
|
|
301
|
+
3. 点击「添加事件」,在弹出列表中选择「消息与群组」分类,勾选「接收消息」(`im.message.receive_v1`),点击「确定」
|
|
302
|
+
|
|
303
|
+
#### 3. 权限配置
|
|
304
|
+
|
|
305
|
+
1. 在应用管理页左侧导航栏,找到「权限管理」,点击进入
|
|
306
|
+
2. 点击「批量导入权限」按钮,将以下 JSON 粘贴到输入框中,点击「导入」:
|
|
307
|
+
|
|
308
|
+
```json
|
|
309
|
+
{
|
|
310
|
+
"scopes": {
|
|
311
|
+
"tenant": [
|
|
312
|
+
"contact:user.base:readonly",
|
|
313
|
+
"im:chat",
|
|
314
|
+
"im:chat:read",
|
|
315
|
+
"im:chat:update",
|
|
316
|
+
"im:message",
|
|
317
|
+
"im:message.group_at_msg:readonly",
|
|
318
|
+
"im:message.p2p_msg:readonly",
|
|
319
|
+
"im:message:send_as_bot",
|
|
320
|
+
"im:resource"
|
|
321
|
+
],
|
|
322
|
+
"user": []
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
3. 页面显示「导入成功」即为完成
|
|
328
|
+
|
|
329
|
+
#### 4. 发布应用
|
|
330
|
+
|
|
331
|
+
1. 在应用管理页左侧导航栏,找到「版本管理与发布」
|
|
332
|
+
2. 点击右上角「新建版本」,填写版本号与描述
|
|
333
|
+
3. 保存并发布,等待审核通过
|
|
334
|
+
|
|
335
|
+
#### 5. Mozi 配置
|
|
165
336
|
|
|
166
337
|
```json5
|
|
167
338
|
{
|
|
@@ -175,7 +346,7 @@ npm start -- start --web-only
|
|
|
175
346
|
}
|
|
176
347
|
```
|
|
177
348
|
|
|
178
|
-
> Webhook 模式:将步骤
|
|
349
|
+
> Webhook 模式:将步骤 2 的订阅方式改为 HTTP,配置回调地址为 `http://your-server:3000/webhook/feishu`,并设置 `mode: "webhook"`。
|
|
179
350
|
|
|
180
351
|
### 钉钉
|
|
181
352
|
|
|
@@ -199,6 +370,64 @@ npm start -- start --web-only
|
|
|
199
370
|
|
|
200
371
|
> Webhook 模式:将步骤 4 改为 HTTP 模式,配置消息接收地址为 `http://your-server:3000/webhook/dingtalk`,并设置 `mode: "webhook"`。
|
|
201
372
|
|
|
373
|
+
### QQ
|
|
374
|
+
|
|
375
|
+
#### 1. 注册并创建应用
|
|
376
|
+
|
|
377
|
+
1. 访问 [QQ 开放平台](https://q.qq.com/#/apps) 并完成注册
|
|
378
|
+
2. 点击「创建机器人」,填写机器人信息
|
|
379
|
+
> 个人使用无需企业资质,可选择「指定用户、指定群聊可访问」
|
|
380
|
+
|
|
381
|
+
#### 2. 获取凭证
|
|
382
|
+
|
|
383
|
+
1. 点击机器人头像进入管理界面
|
|
384
|
+
2. 在「开发设置」页面获取 App ID 和 App Secret
|
|
385
|
+
> 管理页面地址:https://q.qq.com/qqbot/#/developer/developer-setting
|
|
386
|
+
|
|
387
|
+
#### 3. 配置 IP 白名单(重要)
|
|
388
|
+
|
|
389
|
+
1. 在「开发设置」页面找到「IP 白名单」
|
|
390
|
+
2. 添加服务器的公网 IP 地址
|
|
391
|
+
```bash
|
|
392
|
+
# 获取服务器公网 IP
|
|
393
|
+
curl -s ip.sb
|
|
394
|
+
```
|
|
395
|
+
> 未配置白名单会导致连接失败,提示 "接口访问源IP不在白名单"
|
|
396
|
+
|
|
397
|
+
#### 4. 配置沙箱(可选)
|
|
398
|
+
|
|
399
|
+
正式上线前,机器人只能在沙箱范围内使用:
|
|
400
|
+
|
|
401
|
+
1. 访问 [沙箱配置页面](https://q.qq.com/qqbot/#/developer/sandbox)
|
|
402
|
+
2. 添加测试用户或测试群
|
|
403
|
+
|
|
404
|
+
#### 5. Mozi 配置
|
|
405
|
+
|
|
406
|
+
```json5
|
|
407
|
+
{
|
|
408
|
+
channels: {
|
|
409
|
+
qq: {
|
|
410
|
+
appId: "your-app-id",
|
|
411
|
+
clientSecret: "your-app-secret",
|
|
412
|
+
sandbox: false // 沙箱环境设为 true
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
环境变量方式:
|
|
419
|
+
|
|
420
|
+
```bash
|
|
421
|
+
export QQ_APP_ID=your-app-id
|
|
422
|
+
export QQ_CLIENT_SECRET=your-app-secret
|
|
423
|
+
export QQ_SANDBOX=false # 可选,默认 false
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
#### 6. 添加机器人
|
|
427
|
+
|
|
428
|
+
1. 在机器人管理页面,扫描「添加成员」旁边的二维码
|
|
429
|
+
2. 将机器人添加到聊天界面或拉入群聊
|
|
430
|
+
|
|
202
431
|
## 配置参考
|
|
203
432
|
|
|
204
433
|
配置文件支持 `config.local.json5`、`config.json5`、`config.yaml` 等格式,优先级从高到低。存放在 `~/.mozi/` 目录下。
|
|
@@ -242,6 +471,11 @@ npm start -- start --web-only
|
|
|
242
471
|
dingtalk: {
|
|
243
472
|
appKey: "xxx",
|
|
244
473
|
appSecret: "xxx"
|
|
474
|
+
},
|
|
475
|
+
qq: {
|
|
476
|
+
appId: "xxx",
|
|
477
|
+
clientSecret: "xxx",
|
|
478
|
+
sandbox: false // 沙箱环境设为 true
|
|
245
479
|
}
|
|
246
480
|
},
|
|
247
481
|
|
|
@@ -320,17 +554,18 @@ mozi logs --level error # 只显示错误日志
|
|
|
320
554
|
|
|
321
555
|
```
|
|
322
556
|
src/
|
|
323
|
-
├── agents/ # Agent
|
|
557
|
+
├── agents/ # Agent 核心(消息循环、上下文压缩、会话管理)
|
|
324
558
|
├── channels/ # 通道适配器(飞书、钉钉)
|
|
325
|
-
├── providers/ #
|
|
326
|
-
├── tools/ #
|
|
327
|
-
├── sessions/ #
|
|
559
|
+
├── providers/ # 模型提供商(统一接口)
|
|
560
|
+
├── tools/ # 内置工具(文件、Bash、网络等)
|
|
561
|
+
├── sessions/ # 会话存储(内存、文件)
|
|
328
562
|
├── web/ # WebChat 前端
|
|
329
563
|
├── config/ # 配置加载
|
|
330
|
-
├── gateway/ # HTTP 网关
|
|
564
|
+
├── gateway/ # HTTP/WebSocket 网关
|
|
331
565
|
├── cli/ # CLI 命令行工具
|
|
566
|
+
├── hooks/ # Hook 事件系统
|
|
332
567
|
├── utils/ # 工具函数
|
|
333
|
-
└── types/ # 类型定义
|
|
568
|
+
└── types/ # TypeScript 类型定义
|
|
334
569
|
```
|
|
335
570
|
|
|
336
571
|
## API 使用
|
|
@@ -363,21 +598,6 @@ npm run build
|
|
|
363
598
|
npm test
|
|
364
599
|
```
|
|
365
600
|
|
|
366
|
-
## 与 Moltbot 对比
|
|
367
|
-
|
|
368
|
-
Mozi 的架构设计参考了 [Moltbot](https://github.com/moltbot/moltbot),但专注于不同的使用场景。
|
|
369
|
-
|
|
370
|
-
| 特性 | Mozi | Moltbot |
|
|
371
|
-
|------|------|---------|
|
|
372
|
-
| **定位** | 国产生态优先的轻量框架 | 全功能个人 AI 助手 |
|
|
373
|
-
| **代码量** | ~16,000 行 (64 文件) | ~516,000 行 (3,137 文件) |
|
|
374
|
-
| **国产模型** | DeepSeek、Qwen、Kimi 等 7+ 家 | 仅 Anthropic、OpenAI |
|
|
375
|
-
| **国产通讯** | 飞书、钉钉原生支持 | WhatsApp、Telegram、Slack 等 |
|
|
376
|
-
| **Node.js 版本** | >= 18 | >= 22 |
|
|
377
|
-
| **适用场景** | 企业内部机器人、国内团队协作 | 个人多设备助手、海外平台集成 |
|
|
378
|
-
|
|
379
|
-
> Mozi 用 3% 的代码量实现了核心功能,专注简洁高效,易于理解和二次开发。
|
|
380
|
-
|
|
381
601
|
## Star History
|
|
382
602
|
|
|
383
603
|
[](https://star-history.com/#King-Chau/mozi&Date)
|
package/dist/channels/index.d.ts
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
export * from "./common/index.js";
|
|
5
5
|
export * from "./feishu/index.js";
|
|
6
6
|
export * from "./dingtalk/index.js";
|
|
7
|
+
export * from "./qq/index.js";
|
|
8
|
+
export * from "./wecom/index.js";
|
|
7
9
|
export { FeishuApiClient } from "./feishu/api.js";
|
|
8
10
|
export { DingtalkApiClient } from "./dingtalk/api.js";
|
|
11
|
+
export { QQApiClient } from "./qq/api.js";
|
|
12
|
+
export { WeComApiClient } from "./wecom/api.js";
|
|
9
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/channels/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/channels/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AAEjC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/channels/index.js
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
export * from "./common/index.js";
|
|
5
5
|
export * from "./feishu/index.js";
|
|
6
6
|
export * from "./dingtalk/index.js";
|
|
7
|
+
export * from "./qq/index.js";
|
|
8
|
+
export * from "./wecom/index.js";
|
|
7
9
|
export { FeishuApiClient } from "./feishu/api.js";
|
|
8
10
|
export { DingtalkApiClient } from "./dingtalk/api.js";
|
|
11
|
+
export { QQApiClient } from "./qq/api.js";
|
|
12
|
+
export { WeComApiClient } from "./wecom/api.js";
|
|
9
13
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/channels/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/channels/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AAEjC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QQ 机器人 API 客户端
|
|
3
|
+
* 基于 QQ 官方机器人 API v2
|
|
4
|
+
*/
|
|
5
|
+
import type { QQConfig } from "../../types/index.js";
|
|
6
|
+
/** 发送消息响应 */
|
|
7
|
+
interface SendMessageResponse {
|
|
8
|
+
id: string;
|
|
9
|
+
timestamp: number;
|
|
10
|
+
}
|
|
11
|
+
export declare class QQApiClient {
|
|
12
|
+
private config;
|
|
13
|
+
private client;
|
|
14
|
+
private tokenCache;
|
|
15
|
+
constructor(config: QQConfig);
|
|
16
|
+
/** 获取 Access Token */
|
|
17
|
+
getAccessToken(): Promise<string>;
|
|
18
|
+
/** 获取带鉴权的请求头 */
|
|
19
|
+
private getAuthHeaders;
|
|
20
|
+
/** 获取 WebSocket 网关地址 */
|
|
21
|
+
getGatewayUrl(): Promise<string>;
|
|
22
|
+
/** 发送私聊消息 */
|
|
23
|
+
sendDirectMessage(openId: string, content: string, msgId?: string): Promise<SendMessageResponse>;
|
|
24
|
+
/** 发送群聊消息 */
|
|
25
|
+
sendGroupMessage(groupOpenId: string, content: string, msgId?: string): Promise<SendMessageResponse>;
|
|
26
|
+
/** 发送频道消息 */
|
|
27
|
+
sendChannelMessage(channelId: string, content: string, msgId?: string): Promise<SendMessageResponse>;
|
|
28
|
+
/** 发送频道私信 */
|
|
29
|
+
sendDMMessage(guildId: string, content: string, msgId?: string): Promise<SendMessageResponse>;
|
|
30
|
+
/** 获取用户信息 */
|
|
31
|
+
getUserInfo(openId: string): Promise<{
|
|
32
|
+
id: string;
|
|
33
|
+
username: string;
|
|
34
|
+
}>;
|
|
35
|
+
}
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/channels/qq/api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAiBrD,aAAa;AACb,UAAU,mBAAmB;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,UAAU,CAA2B;gBAEjC,MAAM,EAAE,QAAQ;IAY5B,sBAAsB;IAChB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IA2BvC,gBAAgB;YACF,cAAc;IAQ5B,wBAAwB;IAClB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAatC,aAAa;IACP,iBAAiB,CACrB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,mBAAmB,CAAC;IAmB/B,aAAa;IACP,gBAAgB,CACpB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,mBAAmB,CAAC;IAmB/B,aAAa;IACP,kBAAkB,CACtB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,mBAAmB,CAAC;IAmB/B,aAAa;IACP,aAAa,CACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,mBAAmB,CAAC;IAmB/B,aAAa;IACP,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAK7E"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QQ 机器人 API 客户端
|
|
3
|
+
* 基于 QQ 官方机器人 API v2
|
|
4
|
+
*/
|
|
5
|
+
import axios from "axios";
|
|
6
|
+
import { getChildLogger } from "../../utils/logger.js";
|
|
7
|
+
const logger = getChildLogger("qq-api");
|
|
8
|
+
/** QQ API 基础地址 */
|
|
9
|
+
const QQ_API_BASE = "https://api.sgroup.qq.com";
|
|
10
|
+
const QQ_SANDBOX_API_BASE = "https://sandbox.api.sgroup.qq.com";
|
|
11
|
+
/** Token 获取地址 */
|
|
12
|
+
const QQ_TOKEN_URL = "https://bots.qq.com/app/getAppAccessToken";
|
|
13
|
+
export class QQApiClient {
|
|
14
|
+
config;
|
|
15
|
+
client;
|
|
16
|
+
tokenCache = null;
|
|
17
|
+
constructor(config) {
|
|
18
|
+
this.config = config;
|
|
19
|
+
const baseURL = config.sandbox ? QQ_SANDBOX_API_BASE : QQ_API_BASE;
|
|
20
|
+
this.client = axios.create({
|
|
21
|
+
baseURL,
|
|
22
|
+
timeout: 30000,
|
|
23
|
+
headers: {
|
|
24
|
+
"Content-Type": "application/json",
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/** 获取 Access Token */
|
|
29
|
+
async getAccessToken() {
|
|
30
|
+
// 检查缓存
|
|
31
|
+
if (this.tokenCache && this.tokenCache.expiresAt > Date.now() + 60000) {
|
|
32
|
+
return this.tokenCache.accessToken;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const response = await axios.post(QQ_TOKEN_URL, {
|
|
36
|
+
appId: this.config.appId,
|
|
37
|
+
clientSecret: this.config.clientSecret,
|
|
38
|
+
});
|
|
39
|
+
const { access_token, expires_in } = response.data;
|
|
40
|
+
this.tokenCache = {
|
|
41
|
+
accessToken: access_token,
|
|
42
|
+
expiresAt: Date.now() + expires_in * 1000,
|
|
43
|
+
};
|
|
44
|
+
logger.debug("Access token refreshed");
|
|
45
|
+
return access_token;
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
logger.error({ error }, "Failed to get access token");
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** 获取带鉴权的请求头 */
|
|
53
|
+
async getAuthHeaders() {
|
|
54
|
+
const token = await this.getAccessToken();
|
|
55
|
+
return {
|
|
56
|
+
Authorization: `QQBot ${token}`,
|
|
57
|
+
"X-Union-Appid": this.config.appId,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/** 获取 WebSocket 网关地址 */
|
|
61
|
+
async getGatewayUrl() {
|
|
62
|
+
const headers = await this.getAuthHeaders();
|
|
63
|
+
// 先尝试 /gateway,再尝试 /gateway/bot
|
|
64
|
+
try {
|
|
65
|
+
const response = await this.client.get("/gateway", { headers });
|
|
66
|
+
return response.data.url;
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
// 如果 /gateway 失败,尝试 /gateway/bot
|
|
70
|
+
const response = await this.client.get("/gateway/bot", { headers });
|
|
71
|
+
return response.data.url;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/** 发送私聊消息 */
|
|
75
|
+
async sendDirectMessage(openId, content, msgId) {
|
|
76
|
+
const headers = await this.getAuthHeaders();
|
|
77
|
+
const data = {
|
|
78
|
+
content,
|
|
79
|
+
msg_type: 0,
|
|
80
|
+
};
|
|
81
|
+
if (msgId) {
|
|
82
|
+
data.msg_id = msgId;
|
|
83
|
+
}
|
|
84
|
+
const response = await this.client.post(`/v2/users/${openId}/messages`, data, {
|
|
85
|
+
headers,
|
|
86
|
+
});
|
|
87
|
+
logger.debug({ openId, messageId: response.data.id }, "Direct message sent");
|
|
88
|
+
return response.data;
|
|
89
|
+
}
|
|
90
|
+
/** 发送群聊消息 */
|
|
91
|
+
async sendGroupMessage(groupOpenId, content, msgId) {
|
|
92
|
+
const headers = await this.getAuthHeaders();
|
|
93
|
+
const data = {
|
|
94
|
+
content,
|
|
95
|
+
msg_type: 0,
|
|
96
|
+
};
|
|
97
|
+
if (msgId) {
|
|
98
|
+
data.msg_id = msgId;
|
|
99
|
+
}
|
|
100
|
+
const response = await this.client.post(`/v2/groups/${groupOpenId}/messages`, data, {
|
|
101
|
+
headers,
|
|
102
|
+
});
|
|
103
|
+
logger.debug({ groupOpenId, messageId: response.data.id }, "Group message sent");
|
|
104
|
+
return response.data;
|
|
105
|
+
}
|
|
106
|
+
/** 发送频道消息 */
|
|
107
|
+
async sendChannelMessage(channelId, content, msgId) {
|
|
108
|
+
const headers = await this.getAuthHeaders();
|
|
109
|
+
const data = {
|
|
110
|
+
content,
|
|
111
|
+
msg_type: 0,
|
|
112
|
+
};
|
|
113
|
+
if (msgId) {
|
|
114
|
+
data.msg_id = msgId;
|
|
115
|
+
}
|
|
116
|
+
const response = await this.client.post(`/channels/${channelId}/messages`, data, {
|
|
117
|
+
headers,
|
|
118
|
+
});
|
|
119
|
+
logger.debug({ channelId, messageId: response.data.id }, "Channel message sent");
|
|
120
|
+
return response.data;
|
|
121
|
+
}
|
|
122
|
+
/** 发送频道私信 */
|
|
123
|
+
async sendDMMessage(guildId, content, msgId) {
|
|
124
|
+
const headers = await this.getAuthHeaders();
|
|
125
|
+
const data = {
|
|
126
|
+
content,
|
|
127
|
+
msg_type: 0,
|
|
128
|
+
};
|
|
129
|
+
if (msgId) {
|
|
130
|
+
data.msg_id = msgId;
|
|
131
|
+
}
|
|
132
|
+
const response = await this.client.post(`/dms/${guildId}/messages`, data, {
|
|
133
|
+
headers,
|
|
134
|
+
});
|
|
135
|
+
logger.debug({ guildId, messageId: response.data.id }, "DM message sent");
|
|
136
|
+
return response.data;
|
|
137
|
+
}
|
|
138
|
+
/** 获取用户信息 */
|
|
139
|
+
async getUserInfo(openId) {
|
|
140
|
+
const headers = await this.getAuthHeaders();
|
|
141
|
+
const response = await this.client.get(`/users/${openId}`, { headers });
|
|
142
|
+
return response.data;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/channels/qq/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QQ 通道适配器
|
|
3
|
+
*
|
|
4
|
+
* 使用 WebSocket 长连接模式,无需公网部署
|
|
5
|
+
*/
|
|
6
|
+
import type { QQConfig, ChannelMeta, OutboundMessage, SendResult } from "../../types/index.js";
|
|
7
|
+
import { BaseChannelAdapter } from "../common/base.js";
|
|
8
|
+
import { QQApiClient } from "./api.js";
|
|
9
|
+
export declare class QQChannel extends BaseChannelAdapter {
|
|
10
|
+
readonly id: "qq";
|
|
11
|
+
readonly meta: ChannelMeta;
|
|
12
|
+
private config;
|
|
13
|
+
private apiClient;
|
|
14
|
+
private wsClient;
|
|
15
|
+
private initialized;
|
|
16
|
+
constructor(config: QQConfig);
|
|
17
|
+
/** 初始化通道 */
|
|
18
|
+
initialize(): Promise<void>;
|
|
19
|
+
/** 启动 WebSocket 连接 */
|
|
20
|
+
private startWebSocket;
|
|
21
|
+
/** 关闭通道 */
|
|
22
|
+
shutdown(): Promise<void>;
|
|
23
|
+
/** 发送消息 */
|
|
24
|
+
sendMessage(message: OutboundMessage): Promise<SendResult>;
|
|
25
|
+
/** 发送文本消息 */
|
|
26
|
+
sendText(chatId: string, text: string, replyToId?: string): Promise<SendResult>;
|
|
27
|
+
/** 检查通道状态 */
|
|
28
|
+
isHealthy(): Promise<boolean>;
|
|
29
|
+
/** 获取 API 客户端 */
|
|
30
|
+
getApiClient(): QQApiClient;
|
|
31
|
+
/** 检查是否使用长连接 */
|
|
32
|
+
isUsingWebSocket(): boolean;
|
|
33
|
+
}
|
|
34
|
+
/** 创建 QQ 通道 */
|
|
35
|
+
export declare function createQQChannel(config: QQConfig): QQChannel;
|
|
36
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/channels/qq/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,QAAQ,EACR,WAAW,EACX,eAAe,EACf,UAAU,EACX,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAqBvC,qBAAa,SAAU,SAAQ,kBAAkB;IAC/C,QAAQ,CAAC,EAAE,EAAG,IAAI,CAAU;IAC5B,QAAQ,CAAC,IAAI,cAAW;IAExB,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,WAAW,CAAS;gBAEhB,MAAM,EAAE,QAAQ;IAO5B,YAAY;IACN,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAyBjC,sBAAsB;YACR,cAAc;IAa5B,WAAW;IACL,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAW/B,WAAW;IACL,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC;IA8BhE,aAAa;IACP,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAIrF,aAAa;IACP,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAgBnC,iBAAiB;IACjB,YAAY,IAAI,WAAW;IAI3B,gBAAgB;IAChB,gBAAgB,IAAI,OAAO;CAG5B;AAED,eAAe;AACf,wBAAgB,eAAe,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAE3D"}
|