@aalis/plugin-tool-onebot 0.9.2 → 0.10.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/dist/index.d.ts +15 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +228 -203
- package/dist/index.js.map +1 -1
- package/package.json +18 -9
package/dist/index.js
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { media } from '@aalis/api-media';
|
|
2
|
+
import { getPlatformAdapters, getPlatformNames, platform } from '@aalis/api-platform';
|
|
3
|
+
import { createStorageGateway, storage } from '@aalis/api-storage';
|
|
4
|
+
import { sessionHistory } from '@aalis/api-tool-session';
|
|
5
|
+
import { tools, withToolGroups } from '@aalis/api-tools';
|
|
6
|
+
import { config, definePlugin, events, lifecycle, logger, optional } from '@aalis/core';
|
|
4
7
|
// ===== 插件元数据 =====
|
|
5
|
-
|
|
6
|
-
export const displayName = 'OneBot 工具';
|
|
7
|
-
export const subsystem = 'tools';
|
|
8
|
-
export const inject = {
|
|
9
|
-
optional: ['platform', 'session-history'],
|
|
10
|
-
};
|
|
11
|
-
export const configSchema = {
|
|
8
|
+
const configSchema = {
|
|
12
9
|
groupManagement: {
|
|
13
10
|
label: '群管理工具',
|
|
14
11
|
fields: {
|
|
@@ -86,6 +83,18 @@ export const configSchema = {
|
|
|
86
83
|
},
|
|
87
84
|
},
|
|
88
85
|
};
|
|
86
|
+
// ===== 能力声明 =====
|
|
87
|
+
const uses = {
|
|
88
|
+
tools: optional(tools),
|
|
89
|
+
platform: optional(platform),
|
|
90
|
+
storage: optional(storage),
|
|
91
|
+
media: optional(media),
|
|
92
|
+
sessionHistory: optional(sessionHistory),
|
|
93
|
+
events,
|
|
94
|
+
logger,
|
|
95
|
+
lifecycle,
|
|
96
|
+
config,
|
|
97
|
+
};
|
|
89
98
|
// ===== 辅助函数 =====
|
|
90
99
|
/** 从 sessionId 解析 OneBot 连接信息 */
|
|
91
100
|
function parseOneBotSession(sessionId) {
|
|
@@ -98,13 +107,13 @@ function parseOneBotSession(sessionId) {
|
|
|
98
107
|
targetId: parts.slice(3).join(':'),
|
|
99
108
|
};
|
|
100
109
|
}
|
|
101
|
-
/**
|
|
102
|
-
function findOneBotAdapter(
|
|
103
|
-
return getPlatformAdapters(
|
|
110
|
+
/** 在已注册的平台适配器里找出支持 callAction 的 OneBot 适配器 */
|
|
111
|
+
function findOneBotAdapter(platform) {
|
|
112
|
+
return getPlatformAdapters(platform).find(a => a.platform === 'onebot' && typeof a.callAction === 'function');
|
|
104
113
|
}
|
|
105
114
|
/** 从已连接的 OneBot 适配器中找出任意一个 selfId(优先 online) */
|
|
106
|
-
function getAnyOneBotSelfId(
|
|
107
|
-
for (const a of getPlatformAdapters(
|
|
115
|
+
function getAnyOneBotSelfId(platform) {
|
|
116
|
+
for (const a of getPlatformAdapters(platform)) {
|
|
108
117
|
if (a.platform !== 'onebot')
|
|
109
118
|
continue;
|
|
110
119
|
const conns = a.getConnections?.() ?? [];
|
|
@@ -122,14 +131,14 @@ function getAnyOneBotSelfId(ctx) {
|
|
|
122
131
|
* 优先级:args.self_id → 当前 callCtx 是 OneBot 会话时取它的 selfId → 任意可用 adapter 的第一个 selfId。
|
|
123
132
|
* 找不到则抛错(无可用 OneBot 连接)。
|
|
124
133
|
*/
|
|
125
|
-
function resolveSelfId(
|
|
134
|
+
function resolveSelfId(platform, callCtx, args) {
|
|
126
135
|
const fromArgs = args.self_id != null && String(args.self_id).trim() ? String(args.self_id).trim() : '';
|
|
127
136
|
if (fromArgs)
|
|
128
137
|
return fromArgs;
|
|
129
138
|
const parsed = parseOneBotSession(callCtx.sessionId);
|
|
130
139
|
if (parsed?.selfId)
|
|
131
140
|
return parsed.selfId;
|
|
132
|
-
const fallback = getAnyOneBotSelfId(
|
|
141
|
+
const fallback = getAnyOneBotSelfId(platform);
|
|
133
142
|
if (fallback)
|
|
134
143
|
return fallback;
|
|
135
144
|
throw new Error('未找到可用的 OneBot 连接');
|
|
@@ -138,9 +147,9 @@ function resolveSelfId(ctx, callCtx, args) {
|
|
|
138
147
|
* 解析"目标群":args.group_id 优先;否则当前会话必须在 OneBot 群里。
|
|
139
148
|
* 不再限制工具必须在群会话上下文中调用。
|
|
140
149
|
*/
|
|
141
|
-
function resolveGroupTarget(
|
|
150
|
+
function resolveGroupTarget(platform, callCtx, args) {
|
|
142
151
|
const argGroupId = args.group_id != null && String(args.group_id).trim() ? String(args.group_id).trim() : '';
|
|
143
|
-
const selfId = resolveSelfId(
|
|
152
|
+
const selfId = resolveSelfId(platform, callCtx, args);
|
|
144
153
|
if (argGroupId)
|
|
145
154
|
return { selfId, groupId: argGroupId };
|
|
146
155
|
const parsed = parseOneBotSession(callCtx.sessionId);
|
|
@@ -152,9 +161,9 @@ function resolveGroupTarget(ctx, callCtx, args) {
|
|
|
152
161
|
/**
|
|
153
162
|
* 解析"目标用户":args.user_id 优先;否则当前会话必须是 OneBot 私聊。
|
|
154
163
|
*/
|
|
155
|
-
function _resolveUserTarget(
|
|
164
|
+
function _resolveUserTarget(platform, callCtx, args) {
|
|
156
165
|
const argUserId = args.user_id != null && String(args.user_id).trim() ? String(args.user_id).trim() : '';
|
|
157
|
-
const selfId = resolveSelfId(
|
|
166
|
+
const selfId = resolveSelfId(platform, callCtx, args);
|
|
158
167
|
if (argUserId)
|
|
159
168
|
return { selfId, userId: argUserId };
|
|
160
169
|
const parsed = parseOneBotSession(callCtx.sessionId);
|
|
@@ -171,8 +180,8 @@ function buildOneBotSessionId(selfId, detailType, targetId) {
|
|
|
171
180
|
* adapter 内部只用 sessionId 解析 selfId 来定位 WebSocket 连接,
|
|
172
181
|
* 因此这里用合成 sessionId("onebot:<selfId>:internal:0")即可,与目标会话类型无关。
|
|
173
182
|
*/
|
|
174
|
-
async function callAction(
|
|
175
|
-
const adapter = findOneBotAdapter(
|
|
183
|
+
async function callAction(platform, selfId, action, params) {
|
|
184
|
+
const adapter = findOneBotAdapter(platform);
|
|
176
185
|
if (!adapter?.callAction)
|
|
177
186
|
throw new Error('OneBot 适配器不可用或不支持 callAction');
|
|
178
187
|
return adapter.callAction(buildOneBotSessionId(selfId, 'internal', '0'), action, params);
|
|
@@ -287,11 +296,12 @@ function collectForwardImageRefs(data, limit) {
|
|
|
287
296
|
.slice(0, limit)
|
|
288
297
|
.flatMap(item => extractImageRefsFromContent(getForwardNodeContent(item)));
|
|
289
298
|
}
|
|
290
|
-
async function resolveForwardImageSource(
|
|
299
|
+
async function resolveForwardImageSource(caps, storage, selfId, ref) {
|
|
291
300
|
if (/^(https?:|data:)/i.test(ref.source))
|
|
292
301
|
return ref.source;
|
|
302
|
+
const { platform, logger } = caps;
|
|
293
303
|
try {
|
|
294
|
-
const imageData = (await callAction(
|
|
304
|
+
const imageData = (await callAction(platform, selfId, 'get_image', { file: ref.source }));
|
|
295
305
|
const resolvedSource = imageData.url ?? imageData.file ?? ref.source;
|
|
296
306
|
if (typeof resolvedSource === 'string') {
|
|
297
307
|
if (/^(https?:|data:)/i.test(resolvedSource))
|
|
@@ -303,19 +313,20 @@ async function resolveForwardImageSource(ctx, storage, selfId, ref) {
|
|
|
303
313
|
}
|
|
304
314
|
}
|
|
305
315
|
catch (err) {
|
|
306
|
-
|
|
316
|
+
logger.debug(`get_image 解析转发图片失败 (${ref.source}): ${err}`);
|
|
307
317
|
}
|
|
308
318
|
const dataUri = await localImageToDataUri(storage, ref.source);
|
|
309
319
|
return dataUri ?? ref.source;
|
|
310
320
|
}
|
|
311
|
-
async function recognizeForwardImages(
|
|
321
|
+
async function recognizeForwardImages(caps, storage, selfId, data, limit) {
|
|
312
322
|
const refs = collectForwardImageRefs(data, limit);
|
|
313
323
|
const imageDescriptions = new Map();
|
|
314
324
|
if (refs.length === 0)
|
|
315
325
|
return { imageDescriptions };
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
|
|
326
|
+
const { logger, media } = caps;
|
|
327
|
+
const mediaService = media.current;
|
|
328
|
+
if (!mediaService?.describeImage) {
|
|
329
|
+
logger.debug(`合并转发包含 ${refs.length} 张图片,但 media 服务不可用`);
|
|
319
330
|
return { imageDescriptions };
|
|
320
331
|
}
|
|
321
332
|
const seen = new Set();
|
|
@@ -325,13 +336,13 @@ async function recognizeForwardImages(ctx, storage, selfId, data, limit) {
|
|
|
325
336
|
continue;
|
|
326
337
|
seen.add(key);
|
|
327
338
|
try {
|
|
328
|
-
const imageSource = await resolveForwardImageSource(
|
|
329
|
-
const description = await
|
|
339
|
+
const imageSource = await resolveForwardImageSource(caps, storage, selfId, ref);
|
|
340
|
+
const description = await mediaService.describeImage(imageSource);
|
|
330
341
|
if (description)
|
|
331
342
|
imageDescriptions.set(key, description);
|
|
332
343
|
}
|
|
333
344
|
catch (err) {
|
|
334
|
-
|
|
345
|
+
logger.debug(`合并转发图片识别失败 (${ref.source}): ${err}`);
|
|
335
346
|
}
|
|
336
347
|
}
|
|
337
348
|
return { imageDescriptions };
|
|
@@ -423,9 +434,9 @@ function roleLevel(role) {
|
|
|
423
434
|
return ROLE_LEVEL[role] ?? 0;
|
|
424
435
|
}
|
|
425
436
|
/** 查询群成员信息(失败返回 null) */
|
|
426
|
-
async function getGroupMemberInfo(
|
|
437
|
+
async function getGroupMemberInfo(platform, selfId, groupId, userId) {
|
|
427
438
|
try {
|
|
428
|
-
return (await callAction(
|
|
439
|
+
return (await callAction(platform, selfId, 'get_group_member_info', {
|
|
429
440
|
group_id: Number(groupId),
|
|
430
441
|
user_id: Number(userId),
|
|
431
442
|
no_cache: true,
|
|
@@ -436,8 +447,8 @@ async function getGroupMemberInfo(ctx, selfId, groupId, userId) {
|
|
|
436
447
|
}
|
|
437
448
|
}
|
|
438
449
|
/** 检查管理操作权限,返回错误消息(null 表示通过或无法验证) */
|
|
439
|
-
async function checkAdminPermission(
|
|
440
|
-
const selfInfo = await getGroupMemberInfo(
|
|
450
|
+
async function checkAdminPermission(platform, selfId, groupId, targetUserId, requireOwner) {
|
|
451
|
+
const selfInfo = await getGroupMemberInfo(platform, selfId, groupId, selfId);
|
|
441
452
|
if (!selfInfo)
|
|
442
453
|
return null; // 无法获取自身信息,跳过权限检查
|
|
443
454
|
const selfRole = String(selfInfo.role ?? 'member');
|
|
@@ -448,7 +459,7 @@ async function checkAdminPermission(ctx, selfId, groupId, targetUserId, requireO
|
|
|
448
459
|
return `操作失败:机器人不是管理员(当前角色:${selfRole}),无法执行管理操作`;
|
|
449
460
|
}
|
|
450
461
|
if (targetUserId) {
|
|
451
|
-
const targetInfo = await getGroupMemberInfo(
|
|
462
|
+
const targetInfo = await getGroupMemberInfo(platform, selfId, groupId, targetUserId);
|
|
452
463
|
if (!targetInfo) {
|
|
453
464
|
return `操作失败:无法获取用户 ${targetUserId} 的信息,该用户可能不在群中`;
|
|
454
465
|
}
|
|
@@ -460,81 +471,89 @@ async function checkAdminPermission(ctx, selfId, groupId, targetUserId, requireO
|
|
|
460
471
|
}
|
|
461
472
|
return null;
|
|
462
473
|
}
|
|
463
|
-
export
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
return;
|
|
477
|
-
}
|
|
478
|
-
ctx.logger.info('检测到 OneBot 平台,开始注册 OneBot 工具');
|
|
479
|
-
// 注册工具分组:按职责语义切分,彼此不重叠
|
|
480
|
-
tools.registerGroup({
|
|
481
|
-
name: 'onebot-daily',
|
|
482
|
-
label: 'OneBot 只读与日常',
|
|
483
|
-
description: '只读查询(群信息/成员/好友列表/历史/登录信息)+ 日常低风险互动(戳一戳、好友赞)',
|
|
484
|
-
});
|
|
485
|
-
tools.registerGroup({
|
|
486
|
-
name: 'onebot-group',
|
|
487
|
-
label: 'OneBot 群务',
|
|
488
|
-
description: '群务管理:禁言/全员禁言/踢人/撤回消息/设置群名片/改群名/设管理员/群打卡/审批加群申请 等',
|
|
489
|
-
});
|
|
490
|
-
tools.registerGroup({
|
|
491
|
-
name: 'onebot-personal',
|
|
492
|
-
label: 'OneBot 个人/私聊',
|
|
493
|
-
description: '影响 bot 账号本身的人际关系:退群、删好友、处理好友申请、接受/拒绝入群邀请',
|
|
494
|
-
});
|
|
495
|
-
const cfg = {
|
|
496
|
-
groupManagement: { enabled: true, ...(config.groupManagement ?? {}) },
|
|
497
|
-
groupInfo: { enabled: true, ...(config.groupInfo ?? {}) },
|
|
498
|
-
account: { enabled: true, ...(config.account ?? {}) },
|
|
499
|
-
interaction: { enabled: true, ...(config.interaction ?? {}) },
|
|
500
|
-
sessionHistory: {
|
|
501
|
-
enabled: true,
|
|
502
|
-
maxLimit: 100,
|
|
503
|
-
defaultLimit: 20,
|
|
504
|
-
allowGroupReadPrivate: false,
|
|
505
|
-
allowCrossSelf: false,
|
|
506
|
-
allowCrossGroup: true,
|
|
507
|
-
allowCrossPrivate: false,
|
|
508
|
-
...(config.sessionHistory ?? {}),
|
|
509
|
-
},
|
|
474
|
+
export default definePlugin({
|
|
475
|
+
name: '@aalis/plugin-tool-onebot',
|
|
476
|
+
displayName: 'OneBot 工具',
|
|
477
|
+
subsystem: 'tools',
|
|
478
|
+
configSchema,
|
|
479
|
+
uses,
|
|
480
|
+
apply(caps) {
|
|
481
|
+
const { tools, events, logger, platform, config } = caps;
|
|
482
|
+
const storage = createStorageGateway(caps.storage);
|
|
483
|
+
const bundle = {
|
|
484
|
+
daily: withToolGroups(tools, ['onebot-daily']),
|
|
485
|
+
group: withToolGroups(tools, ['onebot-group']),
|
|
486
|
+
personal: withToolGroups(tools, ['onebot-personal']),
|
|
510
487
|
};
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
488
|
+
// 仅当 OneBot 平台可用时才注册工具
|
|
489
|
+
// 使用 app:ready 事件确保平台已加载
|
|
490
|
+
events.on('app:ready', () => {
|
|
491
|
+
if (!getPlatformNames(platform).includes('onebot')) {
|
|
492
|
+
logger.info('未检测到 OneBot 平台,跳过 OneBot 工具注册');
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
logger.info('检测到 OneBot 平台,开始注册 OneBot 工具');
|
|
496
|
+
// 注册工具分组:按职责语义切分,彼此不重叠
|
|
497
|
+
tools.registerGroup({
|
|
498
|
+
name: 'onebot-daily',
|
|
499
|
+
label: 'OneBot 只读与日常',
|
|
500
|
+
description: '只读查询(群信息/成员/好友列表/历史/登录信息)+ 日常低风险互动(戳一戳、好友赞)',
|
|
501
|
+
});
|
|
502
|
+
tools.registerGroup({
|
|
503
|
+
name: 'onebot-group',
|
|
504
|
+
label: 'OneBot 群务',
|
|
505
|
+
description: '群务管理:禁言/全员禁言/踢人/撤回消息/设置群名片/改群名/设管理员/群打卡/审批加群申请 等',
|
|
506
|
+
});
|
|
507
|
+
tools.registerGroup({
|
|
508
|
+
name: 'onebot-personal',
|
|
509
|
+
label: 'OneBot 个人/私聊',
|
|
510
|
+
description: '影响 bot 账号本身的人际关系:退群、删好友、处理好友申请、接受/拒绝入群邀请',
|
|
511
|
+
});
|
|
512
|
+
const cfg = {
|
|
513
|
+
groupManagement: { enabled: true, ...(config.groupManagement ?? {}) },
|
|
514
|
+
groupInfo: { enabled: true, ...(config.groupInfo ?? {}) },
|
|
515
|
+
account: { enabled: true, ...(config.account ?? {}) },
|
|
516
|
+
interaction: { enabled: true, ...(config.interaction ?? {}) },
|
|
517
|
+
sessionHistory: {
|
|
518
|
+
enabled: true,
|
|
519
|
+
maxLimit: 100,
|
|
520
|
+
defaultLimit: 20,
|
|
521
|
+
allowGroupReadPrivate: false,
|
|
522
|
+
allowCrossSelf: false,
|
|
523
|
+
allowCrossGroup: true,
|
|
524
|
+
allowCrossPrivate: false,
|
|
525
|
+
...(config.sessionHistory ?? {}),
|
|
526
|
+
},
|
|
529
527
|
};
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
528
|
+
if (cfg.groupManagement.enabled)
|
|
529
|
+
registerGroupManagementTools(caps, bundle);
|
|
530
|
+
if (cfg.groupInfo.enabled)
|
|
531
|
+
registerGroupInfoTools(caps, storage, bundle);
|
|
532
|
+
if (cfg.account.enabled)
|
|
533
|
+
registerAccountTools(caps, bundle);
|
|
534
|
+
if (cfg.interaction.enabled)
|
|
535
|
+
registerInteractionTools(caps, bundle);
|
|
536
|
+
if (cfg.sessionHistory.enabled) {
|
|
537
|
+
const maxLimit = Math.max(1, Math.min(1000, Number(cfg.sessionHistory.maxLimit) || 100));
|
|
538
|
+
const defaultLimitRaw = Math.max(1, Math.floor(Number(cfg.sessionHistory.defaultLimit) || 20));
|
|
539
|
+
const historyCfg = {
|
|
540
|
+
maxLimit,
|
|
541
|
+
defaultLimit: Math.min(defaultLimitRaw, maxLimit),
|
|
542
|
+
allowGroupReadPrivate: cfg.sessionHistory.allowGroupReadPrivate === true,
|
|
543
|
+
allowCrossSelf: cfg.sessionHistory.allowCrossSelf === true,
|
|
544
|
+
allowCrossGroup: cfg.sessionHistory.allowCrossGroup !== false,
|
|
545
|
+
allowCrossPrivate: cfg.sessionHistory.allowCrossPrivate === true,
|
|
546
|
+
};
|
|
547
|
+
registerSessionHistoryTools(caps, bundle, historyCfg);
|
|
548
|
+
registerOneBotHistoryAccessChecker(caps, historyCfg);
|
|
549
|
+
}
|
|
550
|
+
registerRequestTools(caps, bundle);
|
|
551
|
+
});
|
|
552
|
+
},
|
|
553
|
+
});
|
|
536
554
|
// ===== 群管理工具 =====
|
|
537
|
-
function registerGroupManagementTools(
|
|
555
|
+
function registerGroupManagementTools(caps, bundle) {
|
|
556
|
+
const { platform, logger } = caps;
|
|
538
557
|
const { group, personal } = bundle;
|
|
539
558
|
// ---- 群禁言(单人)----
|
|
540
559
|
group.register({
|
|
@@ -555,18 +574,18 @@ function registerGroupManagementTools(ctx, bundle) {
|
|
|
555
574
|
},
|
|
556
575
|
},
|
|
557
576
|
handler: async (args, callCtx) => {
|
|
558
|
-
const { selfId, groupId } = resolveGroupTarget(
|
|
577
|
+
const { selfId, groupId } = resolveGroupTarget(platform, callCtx, args);
|
|
559
578
|
const duration = typeof args.duration === 'number' ? args.duration : 60;
|
|
560
|
-
const permError = await checkAdminPermission(
|
|
579
|
+
const permError = await checkAdminPermission(platform, selfId, groupId, String(args.user_id));
|
|
561
580
|
if (permError)
|
|
562
581
|
return permError;
|
|
563
|
-
await callAction(
|
|
582
|
+
await callAction(platform, selfId, 'set_group_ban', {
|
|
564
583
|
group_id: Number(groupId),
|
|
565
584
|
user_id: Number(args.user_id),
|
|
566
585
|
duration,
|
|
567
586
|
});
|
|
568
587
|
// 验证禁言是否生效
|
|
569
|
-
const info = await getGroupMemberInfo(
|
|
588
|
+
const info = await getGroupMemberInfo(platform, selfId, groupId, String(args.user_id));
|
|
570
589
|
if (info && 'shut_up_timestamp' in info) {
|
|
571
590
|
const shutUp = Number(info.shut_up_timestamp);
|
|
572
591
|
const now = Math.floor(Date.now() / 1000);
|
|
@@ -602,11 +621,11 @@ function registerGroupManagementTools(ctx, bundle) {
|
|
|
602
621
|
},
|
|
603
622
|
},
|
|
604
623
|
handler: async (args, callCtx) => {
|
|
605
|
-
const { selfId, groupId } = resolveGroupTarget(
|
|
606
|
-
const permError = await checkAdminPermission(
|
|
624
|
+
const { selfId, groupId } = resolveGroupTarget(platform, callCtx, args);
|
|
625
|
+
const permError = await checkAdminPermission(platform, selfId, groupId);
|
|
607
626
|
if (permError)
|
|
608
627
|
return permError;
|
|
609
|
-
await callAction(
|
|
628
|
+
await callAction(platform, selfId, 'set_group_whole_ban', {
|
|
610
629
|
group_id: Number(groupId),
|
|
611
630
|
enable: !!args.enable,
|
|
612
631
|
});
|
|
@@ -632,11 +651,11 @@ function registerGroupManagementTools(ctx, bundle) {
|
|
|
632
651
|
},
|
|
633
652
|
},
|
|
634
653
|
handler: async (args, callCtx) => {
|
|
635
|
-
const { selfId, groupId } = resolveGroupTarget(
|
|
636
|
-
const permError = await checkAdminPermission(
|
|
654
|
+
const { selfId, groupId } = resolveGroupTarget(platform, callCtx, args);
|
|
655
|
+
const permError = await checkAdminPermission(platform, selfId, groupId, String(args.user_id));
|
|
637
656
|
if (permError)
|
|
638
657
|
return permError;
|
|
639
|
-
await callAction(
|
|
658
|
+
await callAction(platform, selfId, 'set_group_kick', {
|
|
640
659
|
group_id: Number(groupId),
|
|
641
660
|
user_id: Number(args.user_id),
|
|
642
661
|
reject_add_request: !!args.reject_add_request,
|
|
@@ -662,12 +681,12 @@ function registerGroupManagementTools(ctx, bundle) {
|
|
|
662
681
|
},
|
|
663
682
|
handler: async (args, callCtx) => {
|
|
664
683
|
const argGroupId = args.group_id != null && String(args.group_id).trim() ? String(args.group_id).trim() : '';
|
|
665
|
-
const selfId = resolveSelfId(
|
|
684
|
+
const selfId = resolveSelfId(platform, callCtx, args);
|
|
666
685
|
const parsed = parseOneBotSession(callCtx.sessionId);
|
|
667
686
|
const groupId = argGroupId || (parsed?.detailType === 'group' ? parsed.targetId : '');
|
|
668
687
|
if (!groupId)
|
|
669
688
|
return '请提供 group_id,或在要退出的群聊中调用此工具';
|
|
670
|
-
await callAction(
|
|
689
|
+
await callAction(platform, selfId, 'set_group_leave', {
|
|
671
690
|
group_id: Number(groupId),
|
|
672
691
|
is_dismiss: false,
|
|
673
692
|
});
|
|
@@ -693,11 +712,11 @@ function registerGroupManagementTools(ctx, bundle) {
|
|
|
693
712
|
},
|
|
694
713
|
},
|
|
695
714
|
handler: async (args, callCtx) => {
|
|
696
|
-
const { selfId, groupId } = resolveGroupTarget(
|
|
697
|
-
const permError = await checkAdminPermission(
|
|
715
|
+
const { selfId, groupId } = resolveGroupTarget(platform, callCtx, args);
|
|
716
|
+
const permError = await checkAdminPermission(platform, selfId, groupId);
|
|
698
717
|
if (permError)
|
|
699
718
|
return permError;
|
|
700
|
-
await callAction(
|
|
719
|
+
await callAction(platform, selfId, 'set_group_card', {
|
|
701
720
|
group_id: Number(groupId),
|
|
702
721
|
user_id: Number(args.user_id),
|
|
703
722
|
card: String(args.card ?? ''),
|
|
@@ -723,11 +742,11 @@ function registerGroupManagementTools(ctx, bundle) {
|
|
|
723
742
|
},
|
|
724
743
|
},
|
|
725
744
|
handler: async (args, callCtx) => {
|
|
726
|
-
const { selfId, groupId } = resolveGroupTarget(
|
|
727
|
-
const permError = await checkAdminPermission(
|
|
745
|
+
const { selfId, groupId } = resolveGroupTarget(platform, callCtx, args);
|
|
746
|
+
const permError = await checkAdminPermission(platform, selfId, groupId);
|
|
728
747
|
if (permError)
|
|
729
748
|
return permError;
|
|
730
|
-
await callAction(
|
|
749
|
+
await callAction(platform, selfId, 'set_group_name', {
|
|
731
750
|
group_id: Number(groupId),
|
|
732
751
|
group_name: String(args.group_name),
|
|
733
752
|
});
|
|
@@ -753,11 +772,11 @@ function registerGroupManagementTools(ctx, bundle) {
|
|
|
753
772
|
},
|
|
754
773
|
},
|
|
755
774
|
handler: async (args, callCtx) => {
|
|
756
|
-
const { selfId, groupId } = resolveGroupTarget(
|
|
757
|
-
const permError = await checkAdminPermission(
|
|
775
|
+
const { selfId, groupId } = resolveGroupTarget(platform, callCtx, args);
|
|
776
|
+
const permError = await checkAdminPermission(platform, selfId, groupId, undefined, true);
|
|
758
777
|
if (permError)
|
|
759
778
|
return permError;
|
|
760
|
-
await callAction(
|
|
779
|
+
await callAction(platform, selfId, 'set_group_special_title', {
|
|
761
780
|
group_id: Number(groupId),
|
|
762
781
|
user_id: Number(args.user_id),
|
|
763
782
|
special_title: String(args.special_title ?? ''),
|
|
@@ -785,11 +804,11 @@ function registerGroupManagementTools(ctx, bundle) {
|
|
|
785
804
|
},
|
|
786
805
|
},
|
|
787
806
|
handler: async (args, callCtx) => {
|
|
788
|
-
const { selfId, groupId } = resolveGroupTarget(
|
|
789
|
-
const permError = await checkAdminPermission(
|
|
807
|
+
const { selfId, groupId } = resolveGroupTarget(platform, callCtx, args);
|
|
808
|
+
const permError = await checkAdminPermission(platform, selfId, groupId, undefined, true);
|
|
790
809
|
if (permError)
|
|
791
810
|
return permError;
|
|
792
|
-
await callAction(
|
|
811
|
+
await callAction(platform, selfId, 'set_group_admin', {
|
|
793
812
|
group_id: Number(groupId),
|
|
794
813
|
user_id: Number(args.user_id),
|
|
795
814
|
enable: !!args.enable,
|
|
@@ -815,8 +834,8 @@ function registerGroupManagementTools(ctx, bundle) {
|
|
|
815
834
|
},
|
|
816
835
|
handler: async (args, callCtx) => {
|
|
817
836
|
// 不限制必须是群聊;只要能找到可用的 OneBot 账号即可
|
|
818
|
-
const selfId = resolveSelfId(
|
|
819
|
-
await callAction(
|
|
837
|
+
const selfId = resolveSelfId(platform, callCtx, args);
|
|
838
|
+
await callAction(platform, selfId, 'delete_msg', {
|
|
820
839
|
message_id: Number(args.message_id),
|
|
821
840
|
});
|
|
822
841
|
return `已撤回消息 ${args.message_id}`;
|
|
@@ -844,7 +863,7 @@ function registerGroupManagementTools(ctx, bundle) {
|
|
|
844
863
|
},
|
|
845
864
|
},
|
|
846
865
|
handler: async (args, callCtx) => {
|
|
847
|
-
const selfId = resolveSelfId(
|
|
866
|
+
const selfId = resolveSelfId(platform, callCtx, args);
|
|
848
867
|
const argGroupId = args.group_id != null && String(args.group_id).trim() ? String(args.group_id).trim() : '';
|
|
849
868
|
const argUserId = args.user_id != null && String(args.user_id).trim() ? String(args.user_id).trim() : '';
|
|
850
869
|
let targetSessionId;
|
|
@@ -858,7 +877,7 @@ function registerGroupManagementTools(ctx, bundle) {
|
|
|
858
877
|
return '当前不在 OneBot 会话中,请用 group_id 或 user_id 指定要撤回的目标会话。';
|
|
859
878
|
targetSessionId = callCtx.sessionId;
|
|
860
879
|
}
|
|
861
|
-
const adapter = findOneBotAdapter(
|
|
880
|
+
const adapter = findOneBotAdapter(platform);
|
|
862
881
|
if (!adapter?.getSentMessages) {
|
|
863
882
|
return '当前 OneBot 适配器版本未记录机器人发出的消息(不支持 getSentMessages)。如已知 message_id 可改用 onebot_delete_msg。';
|
|
864
883
|
}
|
|
@@ -872,7 +891,7 @@ function registerGroupManagementTools(ctx, bundle) {
|
|
|
872
891
|
const failed = [];
|
|
873
892
|
for (const t of targets) {
|
|
874
893
|
try {
|
|
875
|
-
await callAction(
|
|
894
|
+
await callAction(platform, selfId, 'delete_msg', { message_id: Number(t.messageId) || t.messageId });
|
|
876
895
|
adapter.forgetSentMessage?.(targetSessionId, t.messageId);
|
|
877
896
|
recalled.push(t.preview ? `「${t.preview}」` : `msg=${t.messageId}`);
|
|
878
897
|
}
|
|
@@ -889,10 +908,11 @@ function registerGroupManagementTools(ctx, bundle) {
|
|
|
889
908
|
return msg;
|
|
890
909
|
},
|
|
891
910
|
});
|
|
892
|
-
|
|
911
|
+
logger.info('OneBot 群管理工具已注册');
|
|
893
912
|
}
|
|
894
913
|
// ===== 群信息查询工具 =====
|
|
895
|
-
function registerGroupInfoTools(
|
|
914
|
+
function registerGroupInfoTools(caps, storage, bundle) {
|
|
915
|
+
const { platform, logger } = caps;
|
|
896
916
|
const { daily } = bundle;
|
|
897
917
|
// ---- 查看合并转发 ----
|
|
898
918
|
daily.register({
|
|
@@ -915,7 +935,7 @@ function registerGroupInfoTools(ctx, storage, bundle) {
|
|
|
915
935
|
},
|
|
916
936
|
},
|
|
917
937
|
handler: async (args, callCtx) => {
|
|
918
|
-
const selfId = resolveSelfId(
|
|
938
|
+
const selfId = resolveSelfId(platform, callCtx, args);
|
|
919
939
|
if (!args.id)
|
|
920
940
|
return '参数错误:缺少 id(合并转发 ID)。请使用 <forward id="..."> 中的 id 字符串,不要使用 message_id。';
|
|
921
941
|
const forwardId = String(args.id);
|
|
@@ -924,7 +944,7 @@ function registerGroupInfoTools(ctx, storage, bundle) {
|
|
|
924
944
|
// 并维护了一份接收时即抓取并展开(含摘要与图像识别)的缓存。
|
|
925
945
|
let data;
|
|
926
946
|
try {
|
|
927
|
-
data = await callAction(
|
|
947
|
+
data = await callAction(platform, selfId, 'get_forward_msg', { id: forwardId });
|
|
928
948
|
}
|
|
929
949
|
catch (err) {
|
|
930
950
|
return `合并转发读取失败:${err instanceof Error ? err.message : String(err)}。该转发可能已在协议端过期,或当前 OneBot 实现不支持跨会话读取。`;
|
|
@@ -937,7 +957,7 @@ function registerGroupInfoTools(ctx, storage, bundle) {
|
|
|
937
957
|
const summaryLine = entry.summary ? `\n摘要:${entry.summary}\n` : '\n';
|
|
938
958
|
return `${header}${summaryLine}\n原文:\n${entry.fullText}`;
|
|
939
959
|
}
|
|
940
|
-
const formatContext = await recognizeForwardImages(
|
|
960
|
+
const formatContext = await recognizeForwardImages(caps, storage, selfId, data, limit);
|
|
941
961
|
return formatForwardMessage(data, limit, formatContext);
|
|
942
962
|
},
|
|
943
963
|
});
|
|
@@ -958,8 +978,8 @@ function registerGroupInfoTools(ctx, storage, bundle) {
|
|
|
958
978
|
},
|
|
959
979
|
},
|
|
960
980
|
handler: async (args, callCtx) => {
|
|
961
|
-
const { selfId, groupId } = resolveGroupTarget(
|
|
962
|
-
const data = await callAction(
|
|
981
|
+
const { selfId, groupId } = resolveGroupTarget(platform, callCtx, args);
|
|
982
|
+
const data = await callAction(platform, selfId, 'get_group_info', {
|
|
963
983
|
group_id: Number(groupId),
|
|
964
984
|
});
|
|
965
985
|
return JSON.stringify(data);
|
|
@@ -983,9 +1003,9 @@ function registerGroupInfoTools(ctx, storage, bundle) {
|
|
|
983
1003
|
},
|
|
984
1004
|
},
|
|
985
1005
|
handler: async (args, callCtx) => {
|
|
986
|
-
const { selfId, groupId } = resolveGroupTarget(
|
|
1006
|
+
const { selfId, groupId } = resolveGroupTarget(platform, callCtx, args);
|
|
987
1007
|
const userId = args.user_id ? String(args.user_id) : selfId;
|
|
988
|
-
const data = await callAction(
|
|
1008
|
+
const data = await callAction(platform, selfId, 'get_group_member_info', {
|
|
989
1009
|
group_id: Number(groupId),
|
|
990
1010
|
user_id: Number(userId),
|
|
991
1011
|
no_cache: true,
|
|
@@ -1014,8 +1034,8 @@ function registerGroupInfoTools(ctx, storage, bundle) {
|
|
|
1014
1034
|
},
|
|
1015
1035
|
},
|
|
1016
1036
|
handler: async (args, callCtx) => {
|
|
1017
|
-
const { selfId, groupId } = resolveGroupTarget(
|
|
1018
|
-
const data = await callAction(
|
|
1037
|
+
const { selfId, groupId } = resolveGroupTarget(platform, callCtx, args);
|
|
1038
|
+
const data = await callAction(platform, selfId, 'get_group_member_list', {
|
|
1019
1039
|
group_id: Number(groupId),
|
|
1020
1040
|
});
|
|
1021
1041
|
const list = Array.isArray(data) ? data : [];
|
|
@@ -1078,7 +1098,7 @@ function registerGroupInfoTools(ctx, storage, bundle) {
|
|
|
1078
1098
|
},
|
|
1079
1099
|
handler: async (args, callCtx) => {
|
|
1080
1100
|
const argGroupId = args.group_id != null && String(args.group_id).trim() ? String(args.group_id).trim() : '';
|
|
1081
|
-
const selfId = resolveSelfId(
|
|
1101
|
+
const selfId = resolveSelfId(platform, callCtx, args);
|
|
1082
1102
|
const parsed = parseOneBotSession(callCtx.sessionId);
|
|
1083
1103
|
let groupId = argGroupId;
|
|
1084
1104
|
if (!groupId) {
|
|
@@ -1087,12 +1107,12 @@ function registerGroupInfoTools(ctx, storage, bundle) {
|
|
|
1087
1107
|
}
|
|
1088
1108
|
groupId = parsed.targetId;
|
|
1089
1109
|
}
|
|
1090
|
-
const adapter = findOneBotAdapter(
|
|
1110
|
+
const adapter = findOneBotAdapter(platform);
|
|
1091
1111
|
if (!adapter?.callAction)
|
|
1092
1112
|
return JSON.stringify({ available: false, reason: 'OneBot 适配器不可用' });
|
|
1093
1113
|
let info = null;
|
|
1094
1114
|
try {
|
|
1095
|
-
info = (await callAction(
|
|
1115
|
+
info = (await callAction(platform, selfId, 'get_group_member_info', {
|
|
1096
1116
|
group_id: Number(groupId),
|
|
1097
1117
|
user_id: Number(selfId),
|
|
1098
1118
|
no_cache: true,
|
|
@@ -1141,7 +1161,7 @@ function registerGroupInfoTools(ctx, storage, bundle) {
|
|
|
1141
1161
|
},
|
|
1142
1162
|
},
|
|
1143
1163
|
handler: async (args) => {
|
|
1144
|
-
const adapter = findOneBotAdapter(
|
|
1164
|
+
const adapter = findOneBotAdapter(platform);
|
|
1145
1165
|
if (!adapter?.getSelfMutes) {
|
|
1146
1166
|
return JSON.stringify({ supported: false, reason: '当前 OneBot 适配器版本不支持 getSelfMutes' });
|
|
1147
1167
|
}
|
|
@@ -1186,11 +1206,11 @@ function registerGroupInfoTools(ctx, storage, bundle) {
|
|
|
1186
1206
|
},
|
|
1187
1207
|
},
|
|
1188
1208
|
handler: async (args, callCtx) => {
|
|
1189
|
-
const selfId = resolveSelfId(
|
|
1209
|
+
const selfId = resolveSelfId(platform, callCtx, args);
|
|
1190
1210
|
if (!args.message_id)
|
|
1191
1211
|
return '参数错误:缺少 message_id';
|
|
1192
1212
|
try {
|
|
1193
|
-
const data = await callAction(
|
|
1213
|
+
const data = await callAction(platform, selfId, 'get_msg', {
|
|
1194
1214
|
message_id: Number(args.message_id),
|
|
1195
1215
|
});
|
|
1196
1216
|
return JSON.stringify(data);
|
|
@@ -1222,19 +1242,20 @@ function registerGroupInfoTools(ctx, storage, bundle) {
|
|
|
1222
1242
|
},
|
|
1223
1243
|
},
|
|
1224
1244
|
handler: async (args, callCtx) => {
|
|
1225
|
-
const { selfId, groupId } = resolveGroupTarget(
|
|
1245
|
+
const { selfId, groupId } = resolveGroupTarget(platform, callCtx, args);
|
|
1226
1246
|
const honorType = typeof args.type === 'string' ? args.type : 'all';
|
|
1227
|
-
const data = await callAction(
|
|
1247
|
+
const data = await callAction(platform, selfId, 'get_group_honor_info', {
|
|
1228
1248
|
group_id: Number(groupId),
|
|
1229
1249
|
type: honorType,
|
|
1230
1250
|
});
|
|
1231
1251
|
return JSON.stringify(data);
|
|
1232
1252
|
},
|
|
1233
1253
|
});
|
|
1234
|
-
|
|
1254
|
+
logger.info('OneBot 群信息查询工具已注册');
|
|
1235
1255
|
}
|
|
1236
1256
|
// ===== 账号 / 好友 / 群列表查询工具 =====
|
|
1237
|
-
function registerAccountTools(
|
|
1257
|
+
function registerAccountTools(caps, bundle) {
|
|
1258
|
+
const { platform, logger } = caps;
|
|
1238
1259
|
const { daily, personal } = bundle;
|
|
1239
1260
|
// ---- 群列表 ----
|
|
1240
1261
|
daily.register({
|
|
@@ -1258,8 +1279,8 @@ function registerAccountTools(ctx, bundle) {
|
|
|
1258
1279
|
},
|
|
1259
1280
|
},
|
|
1260
1281
|
handler: async (args, callCtx) => {
|
|
1261
|
-
const selfId = resolveSelfId(
|
|
1262
|
-
const data = await callAction(
|
|
1282
|
+
const selfId = resolveSelfId(platform, callCtx, args);
|
|
1283
|
+
const data = await callAction(platform, selfId, 'get_group_list', {});
|
|
1263
1284
|
const list = Array.isArray(data) ? data : [];
|
|
1264
1285
|
const keyword = typeof args.keyword === 'string' ? args.keyword.trim().toLowerCase() : '';
|
|
1265
1286
|
// 上限封顶,避免超大 limit 把整张列表灌进 LLM 上下文(token 浪费)。
|
|
@@ -1307,8 +1328,8 @@ function registerAccountTools(ctx, bundle) {
|
|
|
1307
1328
|
},
|
|
1308
1329
|
},
|
|
1309
1330
|
handler: async (args, callCtx) => {
|
|
1310
|
-
const selfId = resolveSelfId(
|
|
1311
|
-
const data = await callAction(
|
|
1331
|
+
const selfId = resolveSelfId(platform, callCtx, args);
|
|
1332
|
+
const data = await callAction(platform, selfId, 'get_friend_list', {});
|
|
1312
1333
|
const list = Array.isArray(data) ? data : [];
|
|
1313
1334
|
const keyword = typeof args.keyword === 'string' ? args.keyword.trim().toLowerCase() : '';
|
|
1314
1335
|
// 上限封顶,避免超大 limit 把整张列表灌进 LLM 上下文(token 浪费)。
|
|
@@ -1355,8 +1376,8 @@ function registerAccountTools(ctx, bundle) {
|
|
|
1355
1376
|
},
|
|
1356
1377
|
},
|
|
1357
1378
|
handler: async (args, callCtx) => {
|
|
1358
|
-
const selfId = resolveSelfId(
|
|
1359
|
-
const data = await callAction(
|
|
1379
|
+
const selfId = resolveSelfId(platform, callCtx, args);
|
|
1380
|
+
const data = await callAction(platform, selfId, 'get_stranger_info', {
|
|
1360
1381
|
user_id: Number(args.user_id),
|
|
1361
1382
|
no_cache: !!args.no_cache,
|
|
1362
1383
|
});
|
|
@@ -1374,8 +1395,8 @@ function registerAccountTools(ctx, bundle) {
|
|
|
1374
1395
|
},
|
|
1375
1396
|
},
|
|
1376
1397
|
handler: async (_args, callCtx) => {
|
|
1377
|
-
const selfId = resolveSelfId(
|
|
1378
|
-
const data = await callAction(
|
|
1398
|
+
const selfId = resolveSelfId(platform, callCtx, _args);
|
|
1399
|
+
const data = await callAction(platform, selfId, 'get_login_info', {});
|
|
1379
1400
|
return JSON.stringify(data);
|
|
1380
1401
|
},
|
|
1381
1402
|
});
|
|
@@ -1397,21 +1418,22 @@ function registerAccountTools(ctx, bundle) {
|
|
|
1397
1418
|
},
|
|
1398
1419
|
handler: async (args, callCtx) => {
|
|
1399
1420
|
const argUserId = args.user_id != null && String(args.user_id).trim() ? String(args.user_id).trim() : '';
|
|
1400
|
-
const selfId = resolveSelfId(
|
|
1421
|
+
const selfId = resolveSelfId(platform, callCtx, args);
|
|
1401
1422
|
const parsed = parseOneBotSession(callCtx.sessionId);
|
|
1402
1423
|
const userId = argUserId || (parsed?.detailType === 'private' ? parsed.targetId : '');
|
|
1403
1424
|
if (!userId)
|
|
1404
1425
|
return '请提供 user_id,或在要删除的好友私聊中调用此工具';
|
|
1405
|
-
await callAction(
|
|
1426
|
+
await callAction(platform, selfId, 'delete_friend', {
|
|
1406
1427
|
user_id: Number(userId),
|
|
1407
1428
|
});
|
|
1408
1429
|
return `已删除好友 ${userId}`;
|
|
1409
1430
|
},
|
|
1410
1431
|
});
|
|
1411
|
-
|
|
1432
|
+
logger.info('OneBot 账号 / 好友 / 群列表查询工具已注册');
|
|
1412
1433
|
}
|
|
1413
1434
|
// ===== 特殊交互工具 =====
|
|
1414
|
-
function registerInteractionTools(
|
|
1435
|
+
function registerInteractionTools(caps, bundle) {
|
|
1436
|
+
const { platform, logger } = caps;
|
|
1415
1437
|
const { daily, group } = bundle;
|
|
1416
1438
|
// ---- 戳一戳 ----
|
|
1417
1439
|
daily.register({
|
|
@@ -1436,7 +1458,7 @@ function registerInteractionTools(ctx, bundle) {
|
|
|
1436
1458
|
},
|
|
1437
1459
|
},
|
|
1438
1460
|
handler: async (args, callCtx) => {
|
|
1439
|
-
const selfId = resolveSelfId(
|
|
1461
|
+
const selfId = resolveSelfId(platform, callCtx, args);
|
|
1440
1462
|
const parsed = parseOneBotSession(callCtx.sessionId);
|
|
1441
1463
|
const argGroupId = args.group_id != null && String(args.group_id).trim() ? String(args.group_id).trim() : '';
|
|
1442
1464
|
const argUserId = args.user_id != null && String(args.user_id).trim() ? String(args.user_id).trim() : '';
|
|
@@ -1447,13 +1469,13 @@ function registerInteractionTools(ctx, bundle) {
|
|
|
1447
1469
|
throw new Error('群聊戳一戳必须显式提供 user_id(要戳的对象)。');
|
|
1448
1470
|
}
|
|
1449
1471
|
try {
|
|
1450
|
-
await callAction(
|
|
1472
|
+
await callAction(platform, selfId, 'group_poke', {
|
|
1451
1473
|
group_id: Number(groupId),
|
|
1452
1474
|
user_id: Number(argUserId),
|
|
1453
1475
|
});
|
|
1454
1476
|
}
|
|
1455
1477
|
catch {
|
|
1456
|
-
await callAction(
|
|
1478
|
+
await callAction(platform, selfId, 'send_group_poke', {
|
|
1457
1479
|
group_id: Number(groupId),
|
|
1458
1480
|
user_id: Number(argUserId),
|
|
1459
1481
|
});
|
|
@@ -1467,10 +1489,10 @@ function registerInteractionTools(ctx, bundle) {
|
|
|
1467
1489
|
}
|
|
1468
1490
|
// NapCat: friend_poke { user_id };其他实现可能用 send_poke
|
|
1469
1491
|
try {
|
|
1470
|
-
await callAction(
|
|
1492
|
+
await callAction(platform, selfId, 'friend_poke', { user_id: Number(userId) });
|
|
1471
1493
|
}
|
|
1472
1494
|
catch {
|
|
1473
|
-
await callAction(
|
|
1495
|
+
await callAction(platform, selfId, 'send_poke', { user_id: Number(userId) });
|
|
1474
1496
|
}
|
|
1475
1497
|
return `已戳了 ${userId} 一下`;
|
|
1476
1498
|
},
|
|
@@ -1493,9 +1515,9 @@ function registerInteractionTools(ctx, bundle) {
|
|
|
1493
1515
|
},
|
|
1494
1516
|
},
|
|
1495
1517
|
handler: async (args, callCtx) => {
|
|
1496
|
-
const selfId = resolveSelfId(
|
|
1518
|
+
const selfId = resolveSelfId(platform, callCtx, args);
|
|
1497
1519
|
const times = Math.min(10, Math.max(1, typeof args.times === 'number' ? Math.floor(args.times) : 1));
|
|
1498
|
-
await callAction(
|
|
1520
|
+
await callAction(platform, selfId, 'send_like', {
|
|
1499
1521
|
user_id: Number(args.user_id),
|
|
1500
1522
|
times,
|
|
1501
1523
|
});
|
|
@@ -1519,25 +1541,26 @@ function registerInteractionTools(ctx, bundle) {
|
|
|
1519
1541
|
},
|
|
1520
1542
|
},
|
|
1521
1543
|
handler: async (args, callCtx) => {
|
|
1522
|
-
const { selfId, groupId } = resolveGroupTarget(
|
|
1523
|
-
await callAction(
|
|
1544
|
+
const { selfId, groupId } = resolveGroupTarget(platform, callCtx, args);
|
|
1545
|
+
await callAction(platform, selfId, 'send_group_sign', {
|
|
1524
1546
|
group_id: Number(groupId),
|
|
1525
1547
|
});
|
|
1526
1548
|
return '打卡成功';
|
|
1527
1549
|
},
|
|
1528
1550
|
});
|
|
1529
|
-
|
|
1551
|
+
logger.info('OneBot 特殊交互工具已注册');
|
|
1530
1552
|
}
|
|
1531
1553
|
/**
|
|
1532
1554
|
* 把 OneBot 的细粒度访问规则注册到 session-history 服务。
|
|
1533
1555
|
* 通用工具 session_get_history 和平台专属工具 onebot_get_session_history
|
|
1534
1556
|
* 调用 service 时都会走这条规则链 —— 不存在绕过路径。
|
|
1535
1557
|
*/
|
|
1536
|
-
function registerOneBotHistoryAccessChecker(
|
|
1537
|
-
|
|
1538
|
-
|
|
1558
|
+
function registerOneBotHistoryAccessChecker(caps, cfg) {
|
|
1559
|
+
const { events, logger, lifecycle, sessionHistory } = caps;
|
|
1560
|
+
events.on('app:ready', () => {
|
|
1561
|
+
const historyService = sessionHistory.current;
|
|
1539
1562
|
if (!historyService?.registerAccessChecker) {
|
|
1540
|
-
|
|
1563
|
+
logger.debug('session-history 服务未提供 registerAccessChecker, 跳过 OneBot 访问规则注册');
|
|
1541
1564
|
return;
|
|
1542
1565
|
}
|
|
1543
1566
|
const checker = {
|
|
@@ -1572,13 +1595,14 @@ function registerOneBotHistoryAccessChecker(ctx, cfg) {
|
|
|
1572
1595
|
},
|
|
1573
1596
|
};
|
|
1574
1597
|
const dispose = historyService.registerAccessChecker(checker);
|
|
1575
|
-
//
|
|
1576
|
-
//
|
|
1577
|
-
|
|
1578
|
-
|
|
1598
|
+
// 规则挂在 session-history 提供者身上,不随本插件的登记账本自动撤回:
|
|
1599
|
+
// 必须进清理链,否则插件 bounce / 卸载后规则会留在下层泄漏。
|
|
1600
|
+
lifecycle.onDispose(dispose);
|
|
1601
|
+
logger.info('OneBot 会话历史访问规则已注册到 session-history');
|
|
1579
1602
|
});
|
|
1580
1603
|
}
|
|
1581
|
-
function registerSessionHistoryTools(
|
|
1604
|
+
function registerSessionHistoryTools(caps, bundle, cfg) {
|
|
1605
|
+
const { platform, logger, sessionHistory } = caps;
|
|
1582
1606
|
const { daily } = bundle;
|
|
1583
1607
|
daily.register({
|
|
1584
1608
|
definition: {
|
|
@@ -1612,7 +1636,7 @@ function registerSessionHistoryTools(ctx, bundle, cfg) {
|
|
|
1612
1636
|
if (!targetId)
|
|
1613
1637
|
return JSON.stringify({ error: 'target_id 不能为空' });
|
|
1614
1638
|
const argSelfId = args.self_id ? String(args.self_id).trim() : '';
|
|
1615
|
-
const selfId = argSelfId || current?.selfId || getAnyOneBotSelfId(
|
|
1639
|
+
const selfId = argSelfId || current?.selfId || getAnyOneBotSelfId(platform) || '';
|
|
1616
1640
|
if (!selfId)
|
|
1617
1641
|
return JSON.stringify({ error: '无法确定 self_id,且未找到可用的 OneBot 连接' });
|
|
1618
1642
|
// 跨账号限制:仅在当前也是 OneBot 会话时才作为参考点检查
|
|
@@ -1672,10 +1696,10 @@ function registerSessionHistoryTools(ctx, bundle, cfg) {
|
|
|
1672
1696
|
if (!targetId)
|
|
1673
1697
|
return JSON.stringify({ error: 'target_id 不能为空' });
|
|
1674
1698
|
const argSelfId = args.self_id ? String(args.self_id).trim() : '';
|
|
1675
|
-
const selfId = argSelfId || current?.selfId || getAnyOneBotSelfId(
|
|
1699
|
+
const selfId = argSelfId || current?.selfId || getAnyOneBotSelfId(platform) || '';
|
|
1676
1700
|
if (!selfId)
|
|
1677
1701
|
return JSON.stringify({ error: '无法确定 self_id,且未找到可用的 OneBot 连接' });
|
|
1678
|
-
const history =
|
|
1702
|
+
const history = sessionHistory.current;
|
|
1679
1703
|
if (!history)
|
|
1680
1704
|
return JSON.stringify({
|
|
1681
1705
|
error: 'session-history 服务不可用,请启用 @aalis/plugin-tool-session',
|
|
@@ -1698,19 +1722,20 @@ function registerSessionHistoryTools(ctx, bundle, cfg) {
|
|
|
1698
1722
|
}
|
|
1699
1723
|
catch (err) {
|
|
1700
1724
|
const message = err instanceof Error ? err.message : String(err);
|
|
1701
|
-
|
|
1725
|
+
logger.warn(`onebot_get_session_history 失败 (${sessionId}): ${message}`);
|
|
1702
1726
|
return JSON.stringify({ error: `读取 OneBot 会话历史失败: ${message}` });
|
|
1703
1727
|
}
|
|
1704
1728
|
},
|
|
1705
1729
|
});
|
|
1706
|
-
|
|
1730
|
+
logger.info('OneBot 会话历史工具已注册');
|
|
1707
1731
|
}
|
|
1708
1732
|
// ===== 请求处理工具(好友申请 / 群请求)=====
|
|
1709
|
-
function registerRequestTools(
|
|
1733
|
+
function registerRequestTools(caps, bundle) {
|
|
1734
|
+
const { platform, logger } = caps;
|
|
1710
1735
|
const { group, personal } = bundle;
|
|
1711
1736
|
/** 找到支持 handleFriendRequest 的 OneBot 适配器 */
|
|
1712
|
-
function findRequestAdapter(
|
|
1713
|
-
const adapter = getPlatformAdapters(
|
|
1737
|
+
function findRequestAdapter(platform) {
|
|
1738
|
+
const adapter = getPlatformAdapters(platform).find(a => a.platform === 'onebot' && typeof a.handleFriendRequest === 'function');
|
|
1714
1739
|
return adapter;
|
|
1715
1740
|
}
|
|
1716
1741
|
personal.register({
|
|
@@ -1731,7 +1756,7 @@ function registerRequestTools(ctx, bundle) {
|
|
|
1731
1756
|
},
|
|
1732
1757
|
},
|
|
1733
1758
|
handler: async (args) => {
|
|
1734
|
-
const adapter = findRequestAdapter(
|
|
1759
|
+
const adapter = findRequestAdapter(platform);
|
|
1735
1760
|
if (!adapter)
|
|
1736
1761
|
return '未找到支持请求处理的 OneBot 适配器';
|
|
1737
1762
|
return adapter.handleFriendRequest(String(args.user_id), !!args.approve, args.remark ? String(args.remark) : undefined);
|
|
@@ -1760,7 +1785,7 @@ function registerRequestTools(ctx, bundle) {
|
|
|
1760
1785
|
},
|
|
1761
1786
|
},
|
|
1762
1787
|
handler: async (args) => {
|
|
1763
|
-
const adapter = findRequestAdapter(
|
|
1788
|
+
const adapter = findRequestAdapter(platform);
|
|
1764
1789
|
if (!adapter)
|
|
1765
1790
|
return '未找到支持请求处理的 OneBot 适配器';
|
|
1766
1791
|
return adapter.handleGroupRequest(String(args.user_id), String(args.group_id), !!args.approve, args.reason ? String(args.reason) : undefined);
|
|
@@ -1785,12 +1810,12 @@ function registerRequestTools(ctx, bundle) {
|
|
|
1785
1810
|
},
|
|
1786
1811
|
},
|
|
1787
1812
|
handler: async (args) => {
|
|
1788
|
-
const adapter = findRequestAdapter(
|
|
1813
|
+
const adapter = findRequestAdapter(platform);
|
|
1789
1814
|
if (!adapter)
|
|
1790
1815
|
return '未找到支持请求处理的 OneBot 适配器';
|
|
1791
1816
|
return adapter.handleGroupRequest(String(args.user_id), String(args.group_id), !!args.approve, args.reason ? String(args.reason) : undefined);
|
|
1792
1817
|
},
|
|
1793
1818
|
});
|
|
1794
|
-
|
|
1819
|
+
logger.info('OneBot 请求处理工具已注册');
|
|
1795
1820
|
}
|
|
1796
1821
|
//# sourceMappingURL=index.js.map
|