@zhin.js/adapter-napcat 1.0.0 → 1.0.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.
Files changed (60) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +6 -6
  3. package/client/NapCatManagement.tsx +14 -14
  4. package/dist/index.js +1 -1
  5. package/lib/adapter.d.ts +16 -15
  6. package/lib/adapter.d.ts.map +1 -1
  7. package/lib/adapter.js +46 -45
  8. package/lib/adapter.js.map +1 -1
  9. package/lib/{bot-base.d.ts → endpoint-base.d.ts} +7 -7
  10. package/lib/endpoint-base.d.ts.map +1 -0
  11. package/lib/{bot-base.js → endpoint-base.js} +7 -7
  12. package/lib/endpoint-base.js.map +1 -0
  13. package/lib/{bot-http.d.ts → endpoint-http.d.ts} +3 -3
  14. package/lib/endpoint-http.d.ts.map +1 -0
  15. package/lib/{bot-http.js → endpoint-http.js} +7 -7
  16. package/lib/endpoint-http.js.map +1 -0
  17. package/lib/{bot-ws-client.d.ts → endpoint-ws-client.d.ts} +3 -3
  18. package/lib/endpoint-ws-client.d.ts.map +1 -0
  19. package/lib/{bot-ws-client.js → endpoint-ws-client.js} +9 -9
  20. package/lib/endpoint-ws-client.js.map +1 -0
  21. package/lib/{bot-ws-server.d.ts → endpoint-ws-server.d.ts} +3 -3
  22. package/lib/endpoint-ws-server.d.ts.map +1 -0
  23. package/lib/{bot-ws-server.js → endpoint-ws-server.js} +9 -9
  24. package/lib/endpoint-ws-server.js.map +1 -0
  25. package/lib/index.d.ts +5 -5
  26. package/lib/index.d.ts.map +1 -1
  27. package/lib/index.js +6 -5
  28. package/lib/index.js.map +1 -1
  29. package/lib/routes.js +14 -14
  30. package/lib/routes.js.map +1 -1
  31. package/lib/tools.d.ts.map +1 -1
  32. package/lib/tools.js +150 -150
  33. package/lib/tools.js.map +1 -1
  34. package/lib/types.d.ts +1 -1
  35. package/lib/types.d.ts.map +1 -1
  36. package/lib/typing-indicator.d.ts +6 -6
  37. package/lib/typing-indicator.d.ts.map +1 -1
  38. package/lib/typing-indicator.js +17 -17
  39. package/lib/typing-indicator.js.map +1 -1
  40. package/package.json +11 -9
  41. package/skills/napcat/PERMITS.md +19 -0
  42. package/skills/napcat/SKILL.md +4 -4
  43. package/src/adapter.ts +42 -40
  44. package/src/{bot-base.ts → endpoint-base.ts} +9 -9
  45. package/src/{bot-http.ts → endpoint-http.ts} +6 -6
  46. package/src/{bot-ws-client.ts → endpoint-ws-client.ts} +8 -8
  47. package/src/{bot-ws-server.ts → endpoint-ws-server.ts} +8 -8
  48. package/src/index.ts +7 -5
  49. package/src/routes.ts +14 -14
  50. package/src/tools.ts +153 -153
  51. package/src/types.ts +1 -1
  52. package/src/typing-indicator.ts +20 -20
  53. package/lib/bot-base.d.ts.map +0 -1
  54. package/lib/bot-base.js.map +0 -1
  55. package/lib/bot-http.d.ts.map +0 -1
  56. package/lib/bot-http.js.map +0 -1
  57. package/lib/bot-ws-client.d.ts.map +0 -1
  58. package/lib/bot-ws-client.js.map +0 -1
  59. package/lib/bot-ws-server.d.ts.map +0 -1
  60. package/lib/bot-ws-server.js.map +0 -1
package/lib/tools.js CHANGED
@@ -1,8 +1,8 @@
1
- function getBot(adapter, botId) {
2
- const bot = adapter.bots.get(botId);
3
- if (!bot)
4
- throw new Error(`Bot ${botId} not found`);
5
- return bot;
1
+ function getEndpoint(adapter, endpointId) {
2
+ const endpoint = adapter.endpoints.get(endpointId);
3
+ if (!endpoint)
4
+ throw new Error(`Endpoint ${endpointId} not found`);
5
+ return endpoint;
6
6
  }
7
7
  const NAPCAT_TOOL_SPECS = [
8
8
  // ── 消息与社交 ──────────────────────────────────────────────────
@@ -10,15 +10,15 @@ const NAPCAT_TOOL_SPECS = [
10
10
  name: 'napcat_send_poke',
11
11
  description: '戳一戳(群聊或私聊)。group_id 不传时为私聊戳一戳。',
12
12
  params: {
13
- bot: { type: 'string', description: 'Bot 名称' },
13
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
14
14
  user_id: { type: 'number', description: '目标用户 QQ 号' },
15
15
  group_id: { type: 'number', description: '群号(不传则为私聊戳一戳)' },
16
16
  },
17
- required: ['bot', 'user_id'],
17
+ required: ['endpoint_id', 'user_id'],
18
18
  keywords: ['戳一戳', 'poke', '戳', '拍一拍'],
19
19
  execute: async (adapter, args) => {
20
- const bot = getBot(adapter, args.bot);
21
- await bot.sendPoke(args.user_id, args.group_id);
20
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
21
+ await endpoint.sendPoke(args.user_id, args.group_id);
22
22
  return { success: true, message: `已戳 ${args.user_id}` };
23
23
  },
24
24
  },
@@ -26,15 +26,15 @@ const NAPCAT_TOOL_SPECS = [
26
26
  name: 'napcat_set_emoji_reaction',
27
27
  description: '为消息添加表情回应(贴表情)。',
28
28
  params: {
29
- bot: { type: 'string', description: 'Bot 名称' },
29
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
30
30
  message_id: { type: 'number', description: '消息 ID' },
31
31
  emoji_id: { type: 'string', description: '表情 ID' },
32
32
  },
33
- required: ['bot', 'message_id', 'emoji_id'],
33
+ required: ['endpoint_id', 'message_id', 'emoji_id'],
34
34
  keywords: ['表情回应', 'reaction', '贴表情', 'emoji'],
35
35
  execute: async (adapter, args) => {
36
- const bot = getBot(adapter, args.bot);
37
- await bot.setMsgEmojiLike(args.message_id, args.emoji_id);
36
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
37
+ await endpoint.setMsgEmojiLike(args.message_id, args.emoji_id);
38
38
  return { success: true };
39
39
  },
40
40
  },
@@ -42,17 +42,17 @@ const NAPCAT_TOOL_SPECS = [
42
42
  name: 'napcat_send_forward_msg',
43
43
  description: '发送合并转发消息(群聊或私聊)。messages 为转发节点数组。',
44
44
  params: {
45
- bot: { type: 'string', description: 'Bot 名称' },
45
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
46
46
  message_type: { type: 'string', description: 'private 或 group', enum: ['private', 'group'] },
47
47
  id: { type: 'number', description: '群号或 QQ 号' },
48
48
  messages: { type: 'string', description: '转发节点 JSON(node 数组)' },
49
49
  },
50
- required: ['bot', 'message_type', 'id', 'messages'],
50
+ required: ['endpoint_id', 'message_type', 'id', 'messages'],
51
51
  keywords: ['合并转发', 'forward', '转发消息'],
52
52
  execute: async (adapter, args) => {
53
- const bot = getBot(adapter, args.bot);
53
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
54
54
  const messages = typeof args.messages === 'string' ? JSON.parse(args.messages) : args.messages;
55
- const result = await bot.sendForwardMsg(args.message_type, args.id, messages);
55
+ const result = await endpoint.sendForwardMsg(args.message_type, args.id, messages);
56
56
  return result;
57
57
  },
58
58
  },
@@ -60,19 +60,19 @@ const NAPCAT_TOOL_SPECS = [
60
60
  name: 'napcat_forward_single_msg',
61
61
  description: '转发单条消息到指定好友或群。',
62
62
  params: {
63
- bot: { type: 'string', description: 'Bot 名称' },
63
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
64
64
  target_type: { type: 'string', description: 'friend 或 group', enum: ['friend', 'group'] },
65
65
  target_id: { type: 'number', description: '目标好友 QQ 号或群号' },
66
66
  message_id: { type: 'number', description: '要转发的消息 ID' },
67
67
  },
68
- required: ['bot', 'target_type', 'target_id', 'message_id'],
68
+ required: ['endpoint_id', 'target_type', 'target_id', 'message_id'],
69
69
  keywords: ['转发', 'forward', '单条转发'],
70
70
  execute: async (adapter, args) => {
71
- const bot = getBot(adapter, args.bot);
71
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
72
72
  if (args.target_type === 'friend')
73
- await bot.forwardFriendSingleMsg(args.target_id, args.message_id);
73
+ await endpoint.forwardFriendSingleMsg(args.target_id, args.message_id);
74
74
  else
75
- await bot.forwardGroupSingleMsg(args.target_id, args.message_id);
75
+ await endpoint.forwardGroupSingleMsg(args.target_id, args.message_id);
76
76
  return { success: true };
77
77
  },
78
78
  },
@@ -80,15 +80,15 @@ const NAPCAT_TOOL_SPECS = [
80
80
  name: 'napcat_send_like',
81
81
  description: '给好友点赞(每人每天最多 10 次)。',
82
82
  params: {
83
- bot: { type: 'string', description: 'Bot 名称' },
83
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
84
84
  user_id: { type: 'number', description: '目标 QQ 号' },
85
85
  times: { type: 'number', description: '点赞次数(1-10)', default: 1 },
86
86
  },
87
- required: ['bot', 'user_id'],
87
+ required: ['endpoint_id', 'user_id'],
88
88
  keywords: ['点赞', 'like', '赞', '好友赞'],
89
89
  execute: async (adapter, args) => {
90
- const bot = getBot(adapter, args.bot);
91
- await bot.sendLike(args.user_id, args.times || 1);
90
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
91
+ await endpoint.sendLike(args.user_id, args.times || 1);
92
92
  return { success: true, message: `已给 ${args.user_id} 点赞 ${args.times || 1} 次` };
93
93
  },
94
94
  },
@@ -97,16 +97,16 @@ const NAPCAT_TOOL_SPECS = [
97
97
  name: 'napcat_set_essence_msg',
98
98
  description: '设置群精华消息。',
99
99
  params: {
100
- bot: { type: 'string', description: 'Bot 名称' },
100
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
101
101
  message_id: { type: 'number', description: '消息 ID' },
102
102
  },
103
- required: ['bot', 'message_id'],
103
+ required: ['endpoint_id', 'message_id'],
104
104
  keywords: ['精华', 'essence', '设精', '加精'],
105
- requiredAnyRole: ['group_admin'],
105
+ permit: 'platform(napcat,group_admin)',
106
106
  scopes: ['group'],
107
107
  execute: async (adapter, args) => {
108
- const bot = getBot(adapter, args.bot);
109
- await bot.setEssenceMsg(args.message_id);
108
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
109
+ await endpoint.setEssenceMsg(args.message_id);
110
110
  return { success: true };
111
111
  },
112
112
  },
@@ -114,16 +114,16 @@ const NAPCAT_TOOL_SPECS = [
114
114
  name: 'napcat_delete_essence_msg',
115
115
  description: '移除群精华消息。',
116
116
  params: {
117
- bot: { type: 'string', description: 'Bot 名称' },
117
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
118
118
  message_id: { type: 'number', description: '消息 ID' },
119
119
  },
120
- required: ['bot', 'message_id'],
120
+ required: ['endpoint_id', 'message_id'],
121
121
  keywords: ['取消精华', '移除精华', 'delete essence'],
122
- requiredAnyRole: ['group_admin'],
122
+ permit: 'platform(napcat,group_admin)',
123
123
  scopes: ['group'],
124
124
  execute: async (adapter, args) => {
125
- const bot = getBot(adapter, args.bot);
126
- await bot.deleteEssenceMsg(args.message_id);
125
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
126
+ await endpoint.deleteEssenceMsg(args.message_id);
127
127
  return { success: true };
128
128
  },
129
129
  },
@@ -131,16 +131,16 @@ const NAPCAT_TOOL_SPECS = [
131
131
  name: 'napcat_get_essence_list',
132
132
  description: '获取群精华消息列表。',
133
133
  params: {
134
- bot: { type: 'string', description: 'Bot 名称' },
134
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
135
135
  group_id: { type: 'number', description: '群号' },
136
136
  },
137
- required: ['bot', 'group_id'],
137
+ required: ['endpoint_id', 'group_id'],
138
138
  keywords: ['精华列表', 'essence list'],
139
139
  preExecutable: true,
140
140
  scopes: ['group'],
141
141
  execute: async (adapter, args) => {
142
- const bot = getBot(adapter, args.bot);
143
- return bot.getEssenceMsgList(args.group_id);
142
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
143
+ return endpoint.getEssenceMsgList(args.group_id);
144
144
  },
145
145
  },
146
146
  // ── 群公告 ──────────────────────────────────────────────────────
@@ -148,18 +148,18 @@ const NAPCAT_TOOL_SPECS = [
148
148
  name: 'napcat_send_group_notice',
149
149
  description: '发送群公告。',
150
150
  params: {
151
- bot: { type: 'string', description: 'Bot 名称' },
151
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
152
152
  group_id: { type: 'number', description: '群号' },
153
153
  content: { type: 'string', description: '公告内容' },
154
154
  image: { type: 'string', description: '图片(URL 或 base64,可选)' },
155
155
  },
156
- required: ['bot', 'group_id', 'content'],
156
+ required: ['endpoint_id', 'group_id', 'content'],
157
157
  keywords: ['群公告', 'notice', '公告', '发公告'],
158
- requiredAnyRole: ['group_admin'],
158
+ permit: 'platform(napcat,group_admin)',
159
159
  scopes: ['group'],
160
160
  execute: async (adapter, args) => {
161
- const bot = getBot(adapter, args.bot);
162
- await bot.sendGroupNotice(args.group_id, args.content, args.image);
161
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
162
+ await endpoint.sendGroupNotice(args.group_id, args.content, args.image);
163
163
  return { success: true };
164
164
  },
165
165
  },
@@ -167,33 +167,33 @@ const NAPCAT_TOOL_SPECS = [
167
167
  name: 'napcat_get_group_notice',
168
168
  description: '获取群公告列表。',
169
169
  params: {
170
- bot: { type: 'string', description: 'Bot 名称' },
170
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
171
171
  group_id: { type: 'number', description: '群号' },
172
172
  },
173
- required: ['bot', 'group_id'],
173
+ required: ['endpoint_id', 'group_id'],
174
174
  keywords: ['群公告', '获取公告', 'get notice'],
175
175
  preExecutable: true,
176
176
  scopes: ['group'],
177
177
  execute: async (adapter, args) => {
178
- const bot = getBot(adapter, args.bot);
179
- return bot.getGroupNotice(args.group_id);
178
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
179
+ return endpoint.getGroupNotice(args.group_id);
180
180
  },
181
181
  },
182
182
  {
183
183
  name: 'napcat_del_group_notice',
184
184
  description: '删除群公告。',
185
185
  params: {
186
- bot: { type: 'string', description: 'Bot 名称' },
186
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
187
187
  group_id: { type: 'number', description: '群号' },
188
188
  notice_id: { type: 'string', description: '公告 ID' },
189
189
  },
190
- required: ['bot', 'group_id', 'notice_id'],
190
+ required: ['endpoint_id', 'group_id', 'notice_id'],
191
191
  keywords: ['删除公告', 'delete notice'],
192
- requiredAnyRole: ['group_admin'],
192
+ permit: 'platform(napcat,group_admin)',
193
193
  scopes: ['group'],
194
194
  execute: async (adapter, args) => {
195
- const bot = getBot(adapter, args.bot);
196
- await bot.deleteGroupNotice(args.group_id, args.notice_id);
195
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
196
+ await endpoint.deleteGroupNotice(args.group_id, args.notice_id);
197
197
  return { success: true };
198
198
  },
199
199
  },
@@ -202,18 +202,18 @@ const NAPCAT_TOOL_SPECS = [
202
202
  name: 'napcat_upload_group_file',
203
203
  description: '上传文件到群。file 为本地路径或 URL。',
204
204
  params: {
205
- bot: { type: 'string', description: 'Bot 名称' },
205
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
206
206
  group_id: { type: 'number', description: '群号' },
207
207
  file: { type: 'string', description: '文件路径或 URL' },
208
208
  name: { type: 'string', description: '文件名' },
209
209
  folder: { type: 'string', description: '目标文件夹 ID(可选)' },
210
210
  },
211
- required: ['bot', 'group_id', 'file', 'name'],
211
+ required: ['endpoint_id', 'group_id', 'file', 'name'],
212
212
  keywords: ['上传文件', 'upload file', '群文件'],
213
213
  scopes: ['group'],
214
214
  execute: async (adapter, args) => {
215
- const bot = getBot(adapter, args.bot);
216
- await bot.uploadGroupFile(args.group_id, args.file, args.name, args.folder);
215
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
216
+ await endpoint.uploadGroupFile(args.group_id, args.file, args.name, args.folder);
217
217
  return { success: true };
218
218
  },
219
219
  },
@@ -221,34 +221,34 @@ const NAPCAT_TOOL_SPECS = [
221
221
  name: 'napcat_get_group_file_url',
222
222
  description: '获取群文件下载链接。',
223
223
  params: {
224
- bot: { type: 'string', description: 'Bot 名称' },
224
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
225
225
  group_id: { type: 'number', description: '群号' },
226
226
  file_id: { type: 'string', description: '文件 ID' },
227
227
  busid: { type: 'number', description: '文件类型 ID' },
228
228
  },
229
- required: ['bot', 'group_id', 'file_id', 'busid'],
229
+ required: ['endpoint_id', 'group_id', 'file_id', 'busid'],
230
230
  keywords: ['文件链接', 'file url', '下载文件'],
231
231
  preExecutable: true,
232
232
  scopes: ['group'],
233
233
  execute: async (adapter, args) => {
234
- const bot = getBot(adapter, args.bot);
235
- return bot.getGroupFileUrl(args.group_id, args.file_id, args.busid);
234
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
235
+ return endpoint.getGroupFileUrl(args.group_id, args.file_id, args.busid);
236
236
  },
237
237
  },
238
238
  {
239
239
  name: 'napcat_get_group_root_files',
240
240
  description: '获取群根目录文件列表。',
241
241
  params: {
242
- bot: { type: 'string', description: 'Bot 名称' },
242
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
243
243
  group_id: { type: 'number', description: '群号' },
244
244
  },
245
- required: ['bot', 'group_id'],
245
+ required: ['endpoint_id', 'group_id'],
246
246
  keywords: ['群文件列表', 'group files'],
247
247
  preExecutable: true,
248
248
  scopes: ['group'],
249
249
  execute: async (adapter, args) => {
250
- const bot = getBot(adapter, args.bot);
251
- return bot.getGroupRootFiles(args.group_id);
250
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
251
+ return endpoint.getGroupRootFiles(args.group_id);
252
252
  },
253
253
  },
254
254
  // ── 群管理增强 ──────────────────────────────────────────────────
@@ -256,33 +256,33 @@ const NAPCAT_TOOL_SPECS = [
256
256
  name: 'napcat_get_group_shut_list',
257
257
  description: '获取群禁言列表。',
258
258
  params: {
259
- bot: { type: 'string', description: 'Bot 名称' },
259
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
260
260
  group_id: { type: 'number', description: '群号' },
261
261
  },
262
- required: ['bot', 'group_id'],
262
+ required: ['endpoint_id', 'group_id'],
263
263
  keywords: ['禁言列表', 'shut list', '被禁言'],
264
264
  preExecutable: true,
265
265
  scopes: ['group'],
266
266
  execute: async (adapter, args) => {
267
- const bot = getBot(adapter, args.bot);
268
- return bot.getGroupShutList(args.group_id);
267
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
268
+ return endpoint.getGroupShutList(args.group_id);
269
269
  },
270
270
  },
271
271
  {
272
272
  name: 'napcat_set_group_portrait',
273
273
  description: '设置群头像。file 为图片 URL 或 base64。',
274
274
  params: {
275
- bot: { type: 'string', description: 'Bot 名称' },
275
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
276
276
  group_id: { type: 'number', description: '群号' },
277
277
  file: { type: 'string', description: '图片(URL 或 base64)' },
278
278
  },
279
- required: ['bot', 'group_id', 'file'],
279
+ required: ['endpoint_id', 'group_id', 'file'],
280
280
  keywords: ['群头像', 'group portrait', '设置群头像'],
281
- requiredAnyRole: ['group_admin'],
281
+ permit: 'platform(napcat,group_admin)',
282
282
  scopes: ['group'],
283
283
  execute: async (adapter, args) => {
284
- const bot = getBot(adapter, args.bot);
285
- await bot.setGroupPortrait(args.group_id, args.file);
284
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
285
+ await endpoint.setGroupPortrait(args.group_id, args.file);
286
286
  return { success: true };
287
287
  },
288
288
  },
@@ -290,18 +290,18 @@ const NAPCAT_TOOL_SPECS = [
290
290
  name: 'napcat_set_title',
291
291
  description: '设置群成员专属头衔。需要群主权限。',
292
292
  params: {
293
- bot: { type: 'string', description: 'Bot 名称' },
293
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
294
294
  group_id: { type: 'number', description: '群号' },
295
295
  user_id: { type: 'number', description: '目标成员 QQ 号' },
296
296
  title: { type: 'string', description: '头衔文字' },
297
297
  },
298
- required: ['bot', 'group_id', 'user_id', 'title'],
298
+ required: ['endpoint_id', 'group_id', 'user_id', 'title'],
299
299
  keywords: ['头衔', 'title', '专属头衔', '设置头衔'],
300
- requiredAnyRole: ['group_owner'],
300
+ permit: 'platform(napcat,group_owner)',
301
301
  scopes: ['group'],
302
302
  execute: async (adapter, args) => {
303
- const bot = getBot(adapter, args.bot);
304
- await bot.setTitle(args.group_id, args.user_id, args.title);
303
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
304
+ await endpoint.setTitle(args.group_id, args.user_id, args.title);
305
305
  return { success: true, message: `已设置 ${args.user_id} 头衔为 "${args.title}"` };
306
306
  },
307
307
  },
@@ -309,15 +309,15 @@ const NAPCAT_TOOL_SPECS = [
309
309
  name: 'napcat_group_sign',
310
310
  description: '群签到/群打卡。',
311
311
  params: {
312
- bot: { type: 'string', description: 'Bot 名称' },
312
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
313
313
  group_id: { type: 'number', description: '群号' },
314
314
  },
315
- required: ['bot', 'group_id'],
315
+ required: ['endpoint_id', 'group_id'],
316
316
  keywords: ['签到', '打卡', 'sign', 'check in'],
317
317
  scopes: ['group'],
318
318
  execute: async (adapter, args) => {
319
- const bot = getBot(adapter, args.bot);
320
- await bot.sendGroupSign(args.group_id);
319
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
320
+ await endpoint.sendGroupSign(args.group_id);
321
321
  return { success: true };
322
322
  },
323
323
  },
@@ -326,66 +326,66 @@ const NAPCAT_TOOL_SPECS = [
326
326
  name: 'napcat_ai_tts',
327
327
  description: 'AI 文字转语音,在群聊中发送 AI 语音消息。',
328
328
  params: {
329
- bot: { type: 'string', description: 'Bot 名称' },
329
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
330
330
  group_id: { type: 'number', description: '群号' },
331
331
  character: { type: 'string', description: 'AI 语音角色 ID(可先用 napcat_get_ai_characters 查询)' },
332
332
  text: { type: 'string', description: '要转为语音的文字' },
333
333
  },
334
- required: ['bot', 'group_id', 'character', 'text'],
334
+ required: ['endpoint_id', 'group_id', 'character', 'text'],
335
335
  keywords: ['AI语音', 'TTS', '文字转语音', 'ai record'],
336
336
  scopes: ['group'],
337
337
  execute: async (adapter, args) => {
338
- const bot = getBot(adapter, args.bot);
339
- return bot.sendGroupAiRecord(args.group_id, args.character, args.text);
338
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
339
+ return endpoint.sendGroupAiRecord(args.group_id, args.character, args.text);
340
340
  },
341
341
  },
342
342
  {
343
343
  name: 'napcat_get_ai_characters',
344
344
  description: '获取 AI 语音角色列表,用于 napcat_ai_tts 的 character 参数。',
345
345
  params: {
346
- bot: { type: 'string', description: 'Bot 名称' },
346
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
347
347
  group_id: { type: 'number', description: '群号' },
348
348
  },
349
- required: ['bot', 'group_id'],
349
+ required: ['endpoint_id', 'group_id'],
350
350
  keywords: ['AI角色', 'ai characters', '语音角色'],
351
351
  preExecutable: true,
352
352
  scopes: ['group'],
353
353
  execute: async (adapter, args) => {
354
- const bot = getBot(adapter, args.bot);
355
- return bot.getAiCharacters(args.group_id);
354
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
355
+ return endpoint.getAiCharacters(args.group_id);
356
356
  },
357
357
  },
358
358
  {
359
359
  name: 'napcat_ocr_image',
360
360
  description: '图片 OCR 文字识别。',
361
361
  params: {
362
- bot: { type: 'string', description: 'Bot 名称' },
362
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
363
363
  image: { type: 'string', description: '图片 file 参数(收到消息中的 file 字段或 URL)' },
364
364
  },
365
- required: ['bot', 'image'],
365
+ required: ['endpoint_id', 'image'],
366
366
  keywords: ['OCR', '文字识别', '图片识别', 'ocr'],
367
367
  preExecutable: true,
368
368
  execute: async (adapter, args) => {
369
- const bot = getBot(adapter, args.bot);
370
- return bot.ocrImage(args.image);
369
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
370
+ return endpoint.ocrImage(args.image);
371
371
  },
372
372
  },
373
373
  {
374
374
  name: 'napcat_get_mini_app_ark',
375
375
  description: '签名小程序卡片(如 B 站分享卡片等)。',
376
376
  params: {
377
- bot: { type: 'string', description: 'Bot 名称' },
377
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
378
378
  type: { type: 'string', description: '卡片类型' },
379
379
  title: { type: 'string', description: '标题' },
380
380
  desc: { type: 'string', description: '描述' },
381
381
  pic_url: { type: 'string', description: '图片 URL' },
382
382
  jump_url: { type: 'string', description: '跳转 URL' },
383
383
  },
384
- required: ['bot', 'type', 'title', 'desc', 'pic_url', 'jump_url'],
384
+ required: ['endpoint_id', 'type', 'title', 'desc', 'pic_url', 'jump_url'],
385
385
  keywords: ['小程序', 'mini app', '卡片', 'ark'],
386
386
  execute: async (adapter, args) => {
387
- const bot = getBot(adapter, args.bot);
388
- return bot.getMiniAppArk(args.type, args.title, args.desc, args.pic_url, args.jump_url);
387
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
388
+ return endpoint.getMiniAppArk(args.type, args.title, args.desc, args.pic_url, args.jump_url);
389
389
  },
390
390
  },
391
391
  // ── 消息历史 ────────────────────────────────────────────────────
@@ -393,35 +393,35 @@ const NAPCAT_TOOL_SPECS = [
393
393
  name: 'napcat_get_group_msg_history',
394
394
  description: '获取群消息历史记录。',
395
395
  params: {
396
- bot: { type: 'string', description: 'Bot 名称' },
396
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
397
397
  group_id: { type: 'number', description: '群号' },
398
398
  message_seq: { type: 'number', description: '起始消息序号(可选,不传从最新开始)' },
399
399
  count: { type: 'number', description: '获取条数(可选)' },
400
400
  },
401
- required: ['bot', 'group_id'],
401
+ required: ['endpoint_id', 'group_id'],
402
402
  keywords: ['群消息历史', '聊天记录', 'message history'],
403
403
  preExecutable: true,
404
404
  scopes: ['group'],
405
405
  execute: async (adapter, args) => {
406
- const bot = getBot(adapter, args.bot);
407
- return bot.getGroupMsgHistory(args.group_id, args.message_seq, args.count);
406
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
407
+ return endpoint.getGroupMsgHistory(args.group_id, args.message_seq, args.count);
408
408
  },
409
409
  },
410
410
  {
411
411
  name: 'napcat_get_friend_msg_history',
412
412
  description: '获取私聊消息历史记录。',
413
413
  params: {
414
- bot: { type: 'string', description: 'Bot 名称' },
414
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
415
415
  user_id: { type: 'number', description: 'QQ 号' },
416
416
  message_seq: { type: 'number', description: '起始消息序号(可选)' },
417
417
  count: { type: 'number', description: '获取条数(可选)' },
418
418
  },
419
- required: ['bot', 'user_id'],
419
+ required: ['endpoint_id', 'user_id'],
420
420
  keywords: ['私聊记录', '好友聊天记录', 'friend history'],
421
421
  preExecutable: true,
422
422
  execute: async (adapter, args) => {
423
- const bot = getBot(adapter, args.bot);
424
- return bot.getFriendMsgHistory(args.user_id, args.message_seq, args.count);
423
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
424
+ return endpoint.getFriendMsgHistory(args.user_id, args.message_seq, args.count);
425
425
  },
426
426
  },
427
427
  // ── 信息查询 ────────────────────────────────────────────────────
@@ -429,31 +429,31 @@ const NAPCAT_TOOL_SPECS = [
429
429
  name: 'napcat_get_user_status',
430
430
  description: '获取用户在线状态。',
431
431
  params: {
432
- bot: { type: 'string', description: 'Bot 名称' },
432
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
433
433
  user_id: { type: 'number', description: '目标 QQ 号' },
434
434
  },
435
- required: ['bot', 'user_id'],
435
+ required: ['endpoint_id', 'user_id'],
436
436
  keywords: ['在线状态', '用户状态', 'online status'],
437
437
  preExecutable: true,
438
438
  execute: async (adapter, args) => {
439
- const bot = getBot(adapter, args.bot);
440
- return bot.ncGetUserStatus(args.user_id);
439
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
440
+ return endpoint.ncGetUserStatus(args.user_id);
441
441
  },
442
442
  },
443
443
  {
444
444
  name: 'napcat_get_group_info_ex',
445
445
  description: '获取群组额外详细信息。',
446
446
  params: {
447
- bot: { type: 'string', description: 'Bot 名称' },
447
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
448
448
  group_id: { type: 'number', description: '群号' },
449
449
  },
450
- required: ['bot', 'group_id'],
450
+ required: ['endpoint_id', 'group_id'],
451
451
  keywords: ['群详情', '群额外信息', 'group info ex'],
452
452
  preExecutable: true,
453
453
  scopes: ['group'],
454
454
  execute: async (adapter, args) => {
455
- const bot = getBot(adapter, args.bot);
456
- return bot.getGroupInfoEx(args.group_id);
455
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
456
+ return endpoint.getGroupInfoEx(args.group_id);
457
457
  },
458
458
  },
459
459
  // ── 个人设置 ────────────────────────────────────────────────────
@@ -461,18 +461,18 @@ const NAPCAT_TOOL_SPECS = [
461
461
  name: 'napcat_set_profile',
462
462
  description: '修改 QQ 资料(昵称等)。',
463
463
  params: {
464
- bot: { type: 'string', description: 'Bot 名称' },
464
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
465
465
  nickname: { type: 'string', description: '昵称' },
466
466
  company: { type: 'string', description: '公司(可选)' },
467
467
  email: { type: 'string', description: '邮箱(可选)' },
468
468
  college: { type: 'string', description: '学校(可选)' },
469
469
  personal_note: { type: 'string', description: '个人说明(可选)' },
470
470
  },
471
- required: ['bot', 'nickname'],
471
+ required: ['endpoint_id', 'nickname'],
472
472
  keywords: ['修改资料', '设置昵称', 'profile', 'set profile'],
473
473
  execute: async (adapter, args) => {
474
- const bot = getBot(adapter, args.bot);
475
- await bot.setQQProfile(args.nickname, args.company, args.email, args.college, args.personal_note);
474
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
475
+ await endpoint.setQQProfile(args.nickname, args.company, args.email, args.college, args.personal_note);
476
476
  return { success: true };
477
477
  },
478
478
  },
@@ -480,14 +480,14 @@ const NAPCAT_TOOL_SPECS = [
480
480
  name: 'napcat_set_avatar',
481
481
  description: '修改 QQ 头像。',
482
482
  params: {
483
- bot: { type: 'string', description: 'Bot 名称' },
483
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
484
484
  file: { type: 'string', description: '图片(URL 或 base64)' },
485
485
  },
486
- required: ['bot', 'file'],
486
+ required: ['endpoint_id', 'file'],
487
487
  keywords: ['头像', 'avatar', '设置头像', '换头像'],
488
488
  execute: async (adapter, args) => {
489
- const bot = getBot(adapter, args.bot);
490
- await bot.setQQAvatar(args.file);
489
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
490
+ await endpoint.setQQAvatar(args.file);
491
491
  return { success: true };
492
492
  },
493
493
  },
@@ -495,15 +495,15 @@ const NAPCAT_TOOL_SPECS = [
495
495
  name: 'napcat_set_online_status',
496
496
  description: '设置在线状态(在线、隐身、忙碌等)。',
497
497
  params: {
498
- bot: { type: 'string', description: 'Bot 名称' },
498
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
499
499
  status: { type: 'number', description: '状态码(11=在线, 21=离开, 31=隐身, 41=忙碌, 50=请勿打扰, 60=Q我吧)' },
500
500
  ext_status: { type: 'number', description: '扩展状态码', default: 0 },
501
501
  },
502
- required: ['bot', 'status'],
502
+ required: ['endpoint_id', 'status'],
503
503
  keywords: ['在线状态', '隐身', '忙碌', 'online', 'status'],
504
504
  execute: async (adapter, args) => {
505
- const bot = getBot(adapter, args.bot);
506
- await bot.setOnlineStatus(args.status, args.ext_status || 0);
505
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
506
+ await endpoint.setOnlineStatus(args.status, args.ext_status || 0);
507
507
  return { success: true };
508
508
  },
509
509
  },
@@ -511,14 +511,14 @@ const NAPCAT_TOOL_SPECS = [
511
511
  name: 'napcat_set_signature',
512
512
  description: '设置个人签名(个性签名)。',
513
513
  params: {
514
- bot: { type: 'string', description: 'Bot 名称' },
514
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
515
515
  signature: { type: 'string', description: '签名内容' },
516
516
  },
517
- required: ['bot', 'signature'],
517
+ required: ['endpoint_id', 'signature'],
518
518
  keywords: ['签名', '个性签名', 'signature', 'longnick'],
519
519
  execute: async (adapter, args) => {
520
- const bot = getBot(adapter, args.bot);
521
- await bot.setSelfLongnick(args.signature);
520
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
521
+ await endpoint.setSelfLongnick(args.signature);
522
522
  return { success: true };
523
523
  },
524
524
  },
@@ -526,29 +526,29 @@ const NAPCAT_TOOL_SPECS = [
526
526
  name: 'napcat_translate',
527
527
  description: '英译中翻译。',
528
528
  params: {
529
- bot: { type: 'string', description: 'Bot 名称' },
529
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
530
530
  text: { type: 'string', description: '要翻译的英文文本' },
531
531
  },
532
- required: ['bot', 'text'],
532
+ required: ['endpoint_id', 'text'],
533
533
  keywords: ['翻译', 'translate', '英译中'],
534
534
  preExecutable: true,
535
535
  execute: async (adapter, args) => {
536
- const bot = getBot(adapter, args.bot);
537
- return bot.translateEn2Zh(args.text);
536
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
537
+ return endpoint.translateEn2Zh(args.text);
538
538
  },
539
539
  },
540
540
  {
541
541
  name: 'napcat_mark_msg_as_read',
542
542
  description: '标记消息为已读。',
543
543
  params: {
544
- bot: { type: 'string', description: 'Bot 名称' },
544
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
545
545
  message_id: { type: 'number', description: '消息 ID' },
546
546
  },
547
- required: ['bot', 'message_id'],
547
+ required: ['endpoint_id', 'message_id'],
548
548
  keywords: ['已读', 'mark read', '标记已读'],
549
549
  execute: async (adapter, args) => {
550
- const bot = getBot(adapter, args.bot);
551
- await bot.markMsgAsRead(args.message_id);
550
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
551
+ await endpoint.markMsgAsRead(args.message_id);
552
552
  return { success: true };
553
553
  },
554
554
  },
@@ -556,30 +556,30 @@ const NAPCAT_TOOL_SPECS = [
556
556
  name: 'napcat_download_file',
557
557
  description: '下载文件到 NapCat 缓存目录,返回本地路径。',
558
558
  params: {
559
- bot: { type: 'string', description: 'Bot 名称' },
559
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
560
560
  url: { type: 'string', description: '文件 URL' },
561
561
  thread_count: { type: 'number', description: '下载线程数(可选,默认 1)', default: 1 },
562
562
  },
563
- required: ['bot', 'url'],
563
+ required: ['endpoint_id', 'url'],
564
564
  keywords: ['下载', 'download', '下载文件'],
565
565
  execute: async (adapter, args) => {
566
- const bot = getBot(adapter, args.bot);
567
- return bot.downloadFile(args.url, args.thread_count || 1);
566
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
567
+ return endpoint.downloadFile(args.url, args.thread_count || 1);
568
568
  },
569
569
  },
570
570
  {
571
571
  name: 'napcat_delete_friend',
572
572
  description: '删除好友。',
573
573
  params: {
574
- bot: { type: 'string', description: 'Bot 名称' },
574
+ endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
575
575
  user_id: { type: 'number', description: '好友 QQ 号' },
576
576
  },
577
- required: ['bot', 'user_id'],
577
+ required: ['endpoint_id', 'user_id'],
578
578
  keywords: ['删除好友', 'delete friend', '删好友'],
579
- requiredAnyRole: ['group_admin'],
579
+ permit: 'platform(napcat,group_admin)',
580
580
  execute: async (adapter, args) => {
581
- const bot = getBot(adapter, args.bot);
582
- await bot.deleteFriend(args.user_id);
581
+ const endpoint = getEndpoint(adapter, args.endpoint_id);
582
+ await endpoint.deleteFriend(args.user_id);
583
583
  return { success: true };
584
584
  },
585
585
  },
@@ -597,7 +597,7 @@ export function createNapCatTools(adapter) {
597
597
  tags: ['napcat', 'qq'],
598
598
  keywords: spec.keywords,
599
599
  platforms: ['napcat'],
600
- ...(spec.requiredAnyRole?.length ? { requiredAnyRole: spec.requiredAnyRole } : {}),
600
+ ...(spec.permit ? { permissions: [spec.permit] } : {}),
601
601
  scopes: spec.scopes || ['group', 'private'],
602
602
  preExecutable: spec.preExecutable,
603
603
  }));