mioku-plugin-admin 2.3.5 → 3.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.
package/skills/group.ts CHANGED
@@ -1,25 +1,42 @@
1
- import type { AISkill } from "mioku";
1
+ import type { AISkill, Bot, MessageEvent } from "mioku";
2
+
2
3
  import { getMemberRole } from "../config";
3
4
  import { getImageUrlByMessageId } from "./message-image";
4
5
 
5
- async function resolveGroupRuntime(runtimeCtx: any) {
6
+ interface GroupRuntime {
7
+ ctx: { logger?: { error?: (...args: unknown[]) => void } };
8
+ event: MessageEvent;
9
+ bot: Bot;
10
+ groupId: number;
11
+ selfId: number;
12
+ }
13
+
14
+ interface SkillRuntimeContext {
15
+ ctx?: GroupRuntime["ctx"];
16
+ event?: MessageEvent;
17
+ rawEvent?: MessageEvent;
18
+ }
19
+
20
+ function resolveGroupRuntime(runtimeCtx: SkillRuntimeContext | undefined):
21
+ | GroupRuntime
22
+ | { error: string } {
6
23
  const ctx = runtimeCtx?.ctx;
7
24
  if (!ctx) return { error: "无法获取上下文" };
8
25
 
9
- const event = runtimeCtx?.event || runtimeCtx?.rawEvent;
10
- const groupId = Number(event?.group_id || 0);
26
+ const event = runtimeCtx?.event ?? runtimeCtx?.rawEvent;
27
+ const groupId = Number(event?.group_id ?? 0);
11
28
  if (!groupId) return { error: "这个工具只能在群聊中使用" };
12
29
 
13
- const selfId = runtimeCtx?.event?.self_id || runtimeCtx?.rawEvent?.self_id;
30
+ const selfId = Number(event?.self_id ?? 0);
14
31
  if (!selfId) return { error: "无法获取Bot ID" };
15
32
 
16
- const bot = ctx.pickBot(selfId);
33
+ const bot = event?.bot;
17
34
  if (!bot) return { error: "Bot不可用" };
18
35
 
19
- return { ctx, selfId, bot, groupId, event };
36
+ return { ctx, event: event!, bot, groupId, selfId };
20
37
  }
21
38
 
22
- function logAdminSkillError(runtimeCtx: any, toolName: string, err: unknown) {
39
+ function logAdminSkillError(runtimeCtx: SkillRuntimeContext | undefined, toolName: string, err: unknown) {
23
40
  runtimeCtx?.ctx?.logger?.error?.(
24
41
  `[admin skills] ${toolName} failed: ${String(err)}`,
25
42
  );
@@ -32,22 +49,16 @@ function formatGroupRole(role: string): string {
32
49
  }
33
50
 
34
51
  async function checkDangerousTargetPermission(
35
- runtime: any,
52
+ runtime: GroupRuntime,
36
53
  targetUserId: number,
37
54
  ): Promise<string | null> {
38
- const operatorUserId = Number(runtime.event?.user_id || 0);
55
+ const operatorUserId = Number(runtime.event.user_id ?? 0);
39
56
  if (!operatorUserId) return "无法获取当前操作人ID";
40
57
 
41
- const operatorRole = await getMemberRole(
42
- runtime.bot,
43
- runtime.groupId,
44
- operatorUserId,
45
- );
46
- const targetRole = await getMemberRole(
47
- runtime.bot,
48
- runtime.groupId,
49
- targetUserId,
50
- );
58
+ const [operatorRole, targetRole] = await Promise.all([
59
+ getMemberRole(runtime.bot, runtime.groupId, operatorUserId),
60
+ getMemberRole(runtime.bot, runtime.groupId, targetUserId),
61
+ ]);
51
62
  if (operatorRole !== targetRole) return null;
52
63
 
53
64
  return `无权操作同级成员:操作人与被操作人均为${formatGroupRole(operatorRole)}`;
@@ -94,108 +105,74 @@ const groupAdminSkill: AISkill = {
94
105
  },
95
106
  required: ["action"],
96
107
  },
97
- handler: async (args: any, runtimeCtx?: any) => {
98
- const runtime = await resolveGroupRuntime(runtimeCtx);
108
+ handler: async (args: unknown, runtimeCtx?: SkillRuntimeContext) => {
109
+ const runtime = resolveGroupRuntime(runtimeCtx);
99
110
  if ("error" in runtime) return { error: runtime.error };
100
- const { bot, selfId, groupId, event } = runtime;
101
- const action = String(args?.action || "");
111
+ const { bot, groupId, event } = runtime;
112
+ const action = String((args as { action?: unknown })?.action ?? "");
102
113
 
103
114
  try {
104
115
  switch (action) {
105
116
  case "kick": {
106
- const userId = Number(args?.user_id);
117
+ const userId = Number((args as { user_id?: unknown })?.user_id);
107
118
  if (!userId) return { error: "kick 需要提供 user_id" };
108
- const permErr = await checkDangerousTargetPermission(
109
- runtime,
110
- userId,
111
- );
119
+ const permErr = await checkDangerousTargetPermission(runtime, userId);
112
120
  if (permErr) return { error: permErr };
113
- await bot.api("set_group_kick", {
114
- group_id: groupId,
115
- user_id: userId,
116
- });
121
+ await bot.kickMember(groupId, userId);
117
122
  return { success: true, message: `已将 ${userId} 移出当前群` };
118
123
  }
119
124
  case "mute": {
120
- const userId = Number(args?.user_id);
125
+ const userId = Number((args as { user_id?: unknown })?.user_id);
121
126
  if (!userId) return { error: "mute 需要提供 user_id" };
122
- const permErr = await checkDangerousTargetPermission(
123
- runtime,
124
- userId,
125
- );
127
+ const permErr = await checkDangerousTargetPermission(runtime, userId);
126
128
  if (permErr) return { error: permErr };
127
129
  const duration =
128
- Number(args?.duration) > 0 ? Number(args.duration) : 10 * 60;
129
- await bot.setGroupBan(groupId, userId, duration);
130
- return {
131
- success: true,
132
- message: `已禁言 ${userId} ${duration}秒`,
133
- };
130
+ Number((args as { duration?: unknown })?.duration) > 0
131
+ ? Number((args as { duration?: unknown }).duration)
132
+ : 10 * 60;
133
+ await bot.banMember(groupId, userId, duration);
134
+ return { success: true, message: `已禁言 ${userId} ${duration}秒` };
134
135
  }
135
136
  case "unmute": {
136
- const userId = Number(args?.user_id);
137
+ const userId = Number((args as { user_id?: unknown })?.user_id);
137
138
  if (!userId) return { error: "unmute 需要提供 user_id" };
138
- await bot.setGroupBan(groupId, userId, 0);
139
+ await bot.banMember(groupId, userId, 0);
139
140
  return { success: true, message: `已解除 ${userId} 的禁言` };
140
141
  }
141
142
  case "set_admin": {
142
- const userId = Number(args?.user_id);
143
+ const userId = Number((args as { user_id?: unknown })?.user_id);
143
144
  if (!userId) return { error: "set_admin 需要提供 user_id" };
144
- await bot.api("set_group_admin", {
145
- group_id: groupId,
146
- user_id: userId,
147
- enable: true,
148
- });
149
- return {
150
- success: true,
151
- message: `已将 ${userId} 设为当前群的管理员`,
152
- };
145
+ await bot.setMemberAdmin(groupId, userId, true);
146
+ return { success: true, message: `已将 ${userId} 设为当前群的管理员` };
153
147
  }
154
148
  case "unset_admin": {
155
- const userId = Number(args?.user_id);
149
+ const userId = Number((args as { user_id?: unknown })?.user_id);
156
150
  if (!userId) return { error: "unset_admin 需要提供 user_id" };
157
- await bot.api("set_group_admin", {
158
- group_id: groupId,
159
- user_id: userId,
160
- enable: false,
161
- });
162
- return {
163
- success: true,
164
- message: `已取消 ${userId} 在当前群的管理员`,
165
- };
151
+ await bot.setMemberAdmin(groupId, userId, false);
152
+ return { success: true, message: `已取消 ${userId} 在当前群的管理员` };
166
153
  }
167
154
  case "set_title": {
168
- const userId = Number(args?.user_id);
169
- const title = String(args?.title || "").trim();
155
+ const userId = Number((args as { user_id?: unknown })?.user_id);
156
+ const title = String((args as { title?: unknown })?.title ?? "").trim();
170
157
  if (!userId || !title) {
171
158
  return { error: "set_title 需要提供 user_id 和 title" };
172
159
  }
173
- await (bot as any).setGroupSpecialTitle(groupId, userId, title);
174
- return {
175
- success: true,
176
- message: `已将 ${userId} 的头衔设为 "${title}"`,
177
- };
160
+ await bot.setMemberTitle(groupId, userId, title);
161
+ return { success: true, message: `已将 ${userId} 的头衔设为 "${title}"` };
178
162
  }
179
163
  case "set_self_title": {
180
- const userId = Number(event?.user_id);
164
+ const userId = Number(event.user_id);
181
165
  if (!userId) return { error: "无法获取当前用户ID" };
182
- const title = String(args?.title || "").trim();
166
+ const title = String((args as { title?: unknown })?.title ?? "").trim();
183
167
  if (!title) return { error: "set_self_title 需要提供 title" };
184
- await (bot as any).setGroupSpecialTitle(groupId, userId, title);
185
- return {
186
- success: true,
187
- message: `已将你的头衔设为 "${title}"`,
188
- };
168
+ await bot.setMemberTitle(groupId, userId, title);
169
+ return { success: true, message: `已将你的头衔设为 "${title}"` };
189
170
  }
190
171
  default:
191
172
  return { error: `未知的 action: ${action}` };
192
173
  }
193
174
  } catch (err) {
194
- logAdminSkillError(
195
- runtimeCtx,
196
- `admin_group.manage_member.${action}`,
197
- err,
198
- );
175
+ logAdminSkillError(runtimeCtx, `admin_group.manage_member.${action}`, err);
199
176
  return { error: `执行 ${action} 失败: ${err}` };
200
177
  }
201
178
  },
@@ -240,87 +217,58 @@ const groupAdminSkill: AISkill = {
240
217
  },
241
218
  required: ["action"],
242
219
  },
243
- handler: async (args: any, runtimeCtx?: any) => {
244
- const runtime = await resolveGroupRuntime(runtimeCtx);
220
+ handler: async (args: unknown, runtimeCtx?: SkillRuntimeContext) => {
221
+ const runtime = resolveGroupRuntime(runtimeCtx);
245
222
  if ("error" in runtime) return { error: runtime.error };
246
- const { bot, selfId, groupId } = runtime;
247
- const action = String(args?.action || "");
223
+ const { bot, groupId, selfId } = runtime;
224
+ const action = String((args as { action?: unknown })?.action ?? "");
248
225
 
249
226
  try {
250
227
  switch (action) {
251
228
  case "set_whole_ban":
252
- await bot.api("set_group_whole_ban", {
253
- group_id: groupId,
254
- enable: true,
255
- });
229
+ await bot.setGroupWholeBan(groupId, true);
256
230
  return { success: true, message: "当前群已开启全体禁言" };
257
231
  case "unset_whole_ban":
258
- await bot.api("set_group_whole_ban", {
259
- group_id: groupId,
260
- enable: false,
261
- });
232
+ await bot.setGroupWholeBan(groupId, false);
262
233
  return { success: true, message: "当前群已关闭全体禁言" };
263
234
  case "set_group_name": {
264
- const groupName = String(args?.group_name || "").trim();
265
- if (!groupName)
266
- return { error: "set_group_name 需要提供 group_name" };
267
- await bot.api("set_group_name", {
268
- group_id: groupId,
269
- group_name: groupName,
270
- });
271
- return {
272
- success: true,
273
- message: `当前群名称已修改为 ${groupName}`,
274
- };
235
+ const groupName = String((args as { group_name?: unknown })?.group_name ?? "").trim();
236
+ if (!groupName) return { error: "set_group_name 需要提供 group_name" };
237
+ await bot.setGroupName(groupId, groupName);
238
+ return { success: true, message: `当前群名称已修改为 ${groupName}` };
275
239
  }
276
240
  case "set_self_card": {
277
- const card = String(args?.card || "").trim();
241
+ const card = String((args as { card?: unknown })?.card ?? "").trim();
278
242
  if (!card) return { error: "set_self_card 需要提供 card" };
279
- await bot.setGroupCard(groupId, selfId, card);
280
- return {
281
- success: true,
282
- message: `Bot在当前群的群名片已修改为 ${card}`,
283
- };
243
+ await bot.setMemberCard(groupId, selfId, card);
244
+ return { success: true, message: `Bot在当前群的群名片已修改为 ${card}` };
284
245
  }
285
246
  case "set_group_avatar": {
286
- const messageId = Number(args?.message_id);
247
+ const messageId = Number((args as { message_id?: unknown })?.message_id);
287
248
  if (!Number.isFinite(messageId) || messageId <= 0) {
288
249
  return { error: "set_group_avatar 需要提供有效的 message_id" };
289
250
  }
290
251
  const imageUrl = await getImageUrlByMessageId(bot, messageId);
291
- if (!imageUrl) {
292
- return { error: "指定 message_id 中未找到图片" };
293
- }
294
- await bot.api("set_group_portrait", {
295
- group_id: groupId,
296
- file: imageUrl,
297
- });
252
+ if (!imageUrl) return { error: "指定 message_id 中未找到图片" };
253
+ await bot.setGroupPortrait(groupId, imageUrl);
298
254
  return { success: true, message: "当前群头像已修改" };
299
255
  }
300
256
  case "recall_messages": {
301
- const ids = Array.isArray(args?.message_ids)
302
- ? args.message_ids
303
- .map((v: any) => Number(v))
304
- .filter((n: number) => Number.isFinite(n) && n !== 0)
257
+ const ids = Array.isArray((args as { message_ids?: unknown })?.message_ids)
258
+ ? ((args as { message_ids: unknown[] }).message_ids)
259
+ .map((v) => Number(v))
260
+ .filter((n) => Number.isFinite(n) && n !== 0)
305
261
  : [];
306
262
  if (ids.length === 0) {
307
263
  return { error: "recall_messages 需要提供至少一个 message_id" };
308
264
  }
309
- const results: Array<{
310
- message_id: number;
311
- success: boolean;
312
- error?: string;
313
- }> = [];
265
+ const results: Array<{ message_id: number; success: boolean; error?: string }> = [];
314
266
  for (const id of ids) {
315
267
  try {
316
- await bot.api("delete_msg", { message_id: id });
268
+ await bot.recallMessage(id);
317
269
  results.push({ message_id: id, success: true });
318
270
  } catch (err) {
319
- results.push({
320
- message_id: id,
321
- success: false,
322
- error: String(err),
323
- });
271
+ results.push({ message_id: id, success: false, error: String(err) });
324
272
  }
325
273
  }
326
274
  const ok = results.filter((r) => r.success).length;
@@ -334,11 +282,7 @@ const groupAdminSkill: AISkill = {
334
282
  return { error: `未知的 action: ${action}` };
335
283
  }
336
284
  } catch (err) {
337
- logAdminSkillError(
338
- runtimeCtx,
339
- `admin_group.manage_group.${action}`,
340
- err,
341
- );
285
+ logAdminSkillError(runtimeCtx, `admin_group.manage_group.${action}`, err);
342
286
  return { error: `执行 ${action} 失败: ${err}` };
343
287
  }
344
288
  },
@@ -346,4 +290,4 @@ const groupAdminSkill: AISkill = {
346
290
  ],
347
291
  };
348
292
 
349
- export default groupAdminSkill;
293
+ export default groupAdminSkill;
@@ -1,17 +1,16 @@
1
+ import type { Bot } from "mioku";
2
+
1
3
  export async function getImageUrlByMessageId(
2
- bot: any,
4
+ bot: Bot,
3
5
  messageId: number,
4
6
  ): Promise<string | null> {
5
7
  try {
6
- const msg =
7
- typeof bot?.getMsg === "function"
8
- ? await bot.getMsg(messageId)
9
- : await bot.api("get_msg", { message_id: messageId });
8
+ const msg = await bot.sendApi<{
9
+ message?: Array<{ type?: string; url?: string; file?: string }>;
10
+ }>("get_msg", { message_id: messageId });
10
11
  const segments = Array.isArray(msg?.message) ? msg.message : [];
11
- const imageSeg = segments.find((seg: any) => seg?.type === "image");
12
- if (!imageSeg) {
13
- return null;
14
- }
12
+ const imageSeg = segments.find((seg) => seg?.type === "image");
13
+ if (!imageSeg) return null;
15
14
 
16
15
  return imageSeg.url || imageSeg.file || null;
17
16
  } catch {
@@ -1,18 +1,30 @@
1
- import type { AISkill } from "mioku";
1
+ import type { AISkill, Bot, MessageEvent } from "mioku";
2
+
2
3
  import { getImageUrlByMessageId } from "./message-image";
3
4
 
5
+ import type { MessageSegment } from "mioku";
6
+
7
+ interface SkillRuntimeContext {
8
+ ctx?: {
9
+ segment: { text(text: string): MessageSegment };
10
+ logger?: { error?: (...args: unknown[]) => void };
11
+ };
12
+ event?: MessageEvent;
13
+ rawEvent?: MessageEvent;
14
+ }
15
+
4
16
  function parseProfileSex(value: string): 0 | 1 | 2 {
5
- const normalized = String(value || "")
6
- .trim()
7
- .toLowerCase();
8
- if (normalized === "男" || normalized === "male" || normalized === "1")
9
- return 1;
10
- if (normalized === "女" || normalized === "female" || normalized === "2")
11
- return 2;
17
+ const normalized = String(value || "").trim().toLowerCase();
18
+ if (normalized === "男" || normalized === "male" || normalized === "1") return 1;
19
+ if (normalized === "女" || normalized === "female" || normalized === "2") return 2;
12
20
  return 0;
13
21
  }
14
22
 
15
- function logAdminSkillError(runtimeCtx: any, toolName: string, err: unknown) {
23
+ function logAdminSkillError(
24
+ runtimeCtx: SkillRuntimeContext | undefined,
25
+ toolName: string,
26
+ err: unknown,
27
+ ) {
16
28
  runtimeCtx?.ctx?.logger?.error?.(
17
29
  `[admin skills] ${toolName} failed: ${String(err)}`,
18
30
  );
@@ -51,10 +63,7 @@ const personalSkill: AISkill = {
51
63
  type: "number",
52
64
  description: "包含图片的消息 message_id,仅 set_avatar 需要",
53
65
  },
54
- nickname: {
55
- type: "string",
56
- description: "新昵称,仅 set_nickname 需要",
57
- },
66
+ nickname: { type: "string", description: "新昵称,仅 set_nickname 需要" },
58
67
  personal_note: {
59
68
  type: "string",
60
69
  description: "新个性签名,仅 set_signature 需要",
@@ -79,94 +88,72 @@ const personalSkill: AISkill = {
79
88
  },
80
89
  required: ["action"],
81
90
  },
82
- handler: async (args: any, runtimeCtx?: any) => {
91
+ handler: async (args: unknown, runtimeCtx?: SkillRuntimeContext) => {
83
92
  const ctx = runtimeCtx?.ctx;
84
93
  if (!ctx) return { error: "无法获取上下文" };
85
- const event = runtimeCtx?.event || runtimeCtx?.rawEvent;
86
- const selfId = event?.self_id;
87
- if (!selfId) return { error: "无法获取Bot ID" };
88
- const bot = ctx.pickBot(selfId);
94
+ const event = runtimeCtx?.event ?? runtimeCtx?.rawEvent;
95
+ if (!event) return { error: "无法获取事件" };
96
+ const bot = event.bot;
89
97
  if (!bot) return { error: "Bot不可用" };
90
- const action = String(args?.action || "");
98
+ const a = args as Record<string, unknown>;
99
+ const action = String(a?.action ?? "");
91
100
 
92
101
  try {
93
102
  switch (action) {
94
103
  case "set_avatar": {
95
- const messageId = Number(args?.message_id);
104
+ const messageId = Number(a?.message_id);
96
105
  if (!Number.isFinite(messageId) || messageId <= 0) {
97
106
  return { error: "set_avatar 需要提供有效的 message_id" };
98
107
  }
99
108
  const imageUrl = await getImageUrlByMessageId(bot, messageId);
100
- if (!imageUrl) {
101
- return { error: "指定 message_id 中未找到图片" };
102
- }
103
- await bot.api("set_qq_avatar", { file: imageUrl });
109
+ if (!imageUrl) return { error: "指定 message_id 中未找到图片" };
110
+ await bot.setAvatar(imageUrl);
104
111
  return { success: true, message: "Bot头像已修改" };
105
112
  }
106
113
  case "set_nickname": {
107
- const nickname = String(args?.nickname || "").trim();
108
- if (!nickname) {
109
- return { error: "set_nickname 需要提供 nickname" };
110
- }
111
- await bot.api("set_qq_profile", { nickname });
112
- return {
113
- success: true,
114
- message: `Bot昵称已修改为: ${nickname}`,
115
- };
114
+ const nickname = String(a?.nickname ?? "").trim();
115
+ if (!nickname) return { error: "set_nickname 需要提供 nickname" };
116
+ await bot.setProfile({ nickname });
117
+ return { success: true, message: `Bot昵称已修改为: ${nickname}` };
116
118
  }
117
119
  case "set_signature": {
118
- const personalNote = String(args?.personal_note || "").trim();
119
- if (!personalNote) {
120
- return { error: "set_signature 需要提供 personal_note" };
121
- }
122
- await bot.api("set_qq_profile", { personal_note: personalNote });
120
+ const personalNote = String(a?.personal_note ?? "").trim();
121
+ if (!personalNote) return { error: "set_signature 需要提供 personal_note" };
122
+ await bot.setProfile({ personal_note: personalNote });
123
123
  return { success: true, message: "Bot个性签名已修改" };
124
124
  }
125
125
  case "set_gender": {
126
- const sex = parseProfileSex(args?.gender);
127
- await bot.api("set_qq_profile", { sex });
128
- const genderMap: Record<number, string> = {
129
- 0: "无",
130
- 1: "男",
131
- 2: "女",
132
- };
133
- return {
134
- success: true,
135
- message: `Bot性别已修改为: ${genderMap[sex]}`,
136
- };
126
+ const sex = parseProfileSex(String(a?.gender ?? ""));
127
+ await bot.setProfile({ sex });
128
+ const genderMap: Record<number, string> = { 0: "无", 1: "男", 2: "女" };
129
+ return { success: true, message: `Bot性别已修改为: ${genderMap[sex]}` };
137
130
  }
138
131
  case "send_private": {
139
- const userId = Number(args?.user_id);
140
- const content = String(args?.content || "");
141
- if (!userId || !content) {
142
- return { error: "send_private 需要提供 user_id 和 content" };
143
- }
144
- await bot.sendPrivateMsg(userId, [ctx.segment.text(content)]);
145
- return {
146
- success: true,
147
- message: `已发送私聊消息给 ${userId}`,
148
- };
132
+ const userId = Number(a?.user_id);
133
+ const content = String(a?.content ?? "");
134
+ if (!userId || !content) return { error: "send_private 需要提供 user_id 和 content" };
135
+ await bot.sendMessage(
136
+ { type: "private", user_id: userId},
137
+ [ctx.segment.text(content)],
138
+ );
139
+ return { success: true, message: `已发送私聊消息给 ${userId}` };
149
140
  }
150
141
  case "send_group": {
151
- const groupId = Number(args?.group_id);
152
- const content = String(args?.content || "");
153
- if (!groupId || !content) {
154
- return { error: "send_group 需要提供 group_id 和 content" };
155
- }
156
- await bot.sendGroupMsg(groupId, [ctx.segment.text(content)]);
157
- return {
158
- success: true,
159
- message: `已发送群消息到 ${groupId}`,
160
- };
142
+ const groupId = Number(a?.group_id);
143
+ const content = String(a?.content ?? "");
144
+ if (!groupId || !content) return { error: "send_group 需要提供 group_id 和 content" };
145
+ await bot.sendMessage(
146
+ { type: "group", group_id: groupId},
147
+ [ctx.segment.text(content)],
148
+ );
149
+ return { success: true, message: `已发送群消息到 ${groupId}` };
161
150
  }
162
151
  case "list_friends": {
163
- if (event?.message_type === "group") {
164
- return { error: "在私聊使用试试看吧~" };
165
- }
166
- const friendList: any[] = await bot.api("get_friend_list");
152
+ if (event?.message_type === "group") return { error: "在私聊使用试试看吧~" };
153
+ const friendList = await bot.getFriendList();
167
154
  if (!Array.isArray(friendList)) return { friends: [] };
168
155
  return {
169
- friends: friendList.map((f) => ({
156
+ friends: friendList.map((f: { user_id?: unknown; nickname?: unknown; remark?: unknown }) => ({
170
157
  user_id: f.user_id,
171
158
  nickname: f.nickname,
172
159
  remark: f.remark,
@@ -174,13 +161,11 @@ const personalSkill: AISkill = {
174
161
  };
175
162
  }
176
163
  case "list_groups": {
177
- if (event?.message_type === "group") {
178
- return { error: "在私聊使用试试看吧~" };
179
- }
180
- const groupList: any[] = await bot.api("get_group_list");
164
+ if (event?.message_type === "group") return { error: "在私聊使用试试看吧~" };
165
+ const groupList = await bot.getGroupList();
181
166
  if (!Array.isArray(groupList)) return { groups: [] };
182
167
  return {
183
- groups: groupList.map((g) => ({
168
+ groups: groupList.map((g: { group_id?: unknown; group_name?: unknown; member_count?: unknown }) => ({
184
169
  group_id: g.group_id,
185
170
  group_name: g.group_name,
186
171
  member_count: g.member_count,
@@ -188,33 +173,22 @@ const personalSkill: AISkill = {
188
173
  };
189
174
  }
190
175
  case "delete_friend": {
191
- const userId = Number(args?.user_id);
192
- if (!userId) {
193
- return { error: "delete_friend 需要提供 user_id" };
194
- }
195
- await bot.api("delete_friend", { user_id: userId });
176
+ const userId = Number(a?.user_id);
177
+ if (!userId) return { error: "delete_friend 需要提供 user_id" };
178
+ await bot.deleteFriend(userId);
196
179
  return { success: true, message: `已删除好友 ${userId}` };
197
180
  }
198
181
  case "leave_group": {
199
- const groupId = Number(args?.group_id);
200
- if (!groupId) {
201
- return { error: "leave_group 需要提供 group_id" };
202
- }
203
- await bot.api("set_group_leave", {
204
- group_id: groupId,
205
- is_dismiss: false,
206
- });
182
+ const groupId = Number(a?.group_id);
183
+ if (!groupId) return { error: "leave_group 需要提供 group_id" };
184
+ await bot.leaveGroup(groupId, false);
207
185
  return { success: true, message: `已退出群 ${groupId}` };
208
186
  }
209
187
  default:
210
188
  return { error: `未知的 action: ${action}` };
211
189
  }
212
190
  } catch (err) {
213
- logAdminSkillError(
214
- runtimeCtx,
215
- `admin_personal.manage_personal.${action}`,
216
- err,
217
- );
191
+ logAdminSkillError(runtimeCtx, `admin_personal.manage_personal.${action}`, err);
218
192
  return { error: `执行 ${action} 失败: ${err}` };
219
193
  }
220
194
  },
@@ -222,4 +196,4 @@ const personalSkill: AISkill = {
222
196
  ],
223
197
  };
224
198
 
225
- export default personalSkill;
199
+ export default personalSkill;
package/verify/chiral.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { MiokiContext } from "mioki";
1
+ import type { MiokuContext } from "mioku";
2
2
  import type { VerifyConfig } from "./config";
3
3
  import type { PendingVerify } from "./types";
4
4
 
@@ -41,11 +41,11 @@ async function fetchChiralCaptcha(
41
41
  }
42
42
 
43
43
  export async function prepareChiral(
44
- ctx: MiokiContext,
44
+ ctx: MiokuContext,
45
45
  cfg: VerifyConfig,
46
46
  p: PendingVerify,
47
47
  ): Promise<boolean> {
48
- const bot = ctx.pickBot(p.selfId);
48
+ const bot = p.bot;
49
49
  if (!bot) return false;
50
50
  try {
51
51
  const captcha = await fetchChiralCaptcha(cfg.chiralApiUrl, cfg.chiralDifficulty);
@@ -55,7 +55,7 @@ export async function prepareChiral(
55
55
  "{count}",
56
56
  String(captcha.regions.length),
57
57
  );
58
- await bot.sendGroupMsg(p.groupId, [
58
+ await bot.sendMessage({ type: "group", group_id: p.groupId}, [
59
59
  ctx.segment.at(String(p.userId)),
60
60
  ctx.segment.text(` ${prompt}`),
61
61
  ctx.segment.image(captcha.imageDataUrl),