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/commands/group.ts +463 -473
- package/commands/notice.ts +3 -3
- package/commands/personal.ts +234 -276
- package/commands/verify.ts +325 -308
- package/config.ts +29 -17
- package/index.ts +5 -7
- package/notify/index.ts +110 -140
- package/notify/welcome.ts +52 -44
- package/package.json +4 -283
- package/skills/group.ts +87 -143
- package/skills/message-image.ts +8 -9
- package/skills/personal.ts +72 -98
- package/verify/chiral.ts +4 -4
- package/verify/index.ts +59 -45
- package/verify/number.ts +4 -4
- package/verify/reaction.ts +62 -14
- package/verify/state.ts +1 -1
- package/verify/types.ts +18 -8
package/commands/personal.ts
CHANGED
|
@@ -1,18 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
MessageEvent,
|
|
4
|
-
RecvAtElement,
|
|
5
|
-
RecvElement,
|
|
6
|
-
RecvFaceElement,
|
|
7
|
-
RecvFileElement,
|
|
8
|
-
RecvForwardElement,
|
|
9
|
-
RecvImageElement,
|
|
10
|
-
RecvJsonElement,
|
|
11
|
-
RecvRecordElement,
|
|
12
|
-
RecvReplyElement,
|
|
13
|
-
RecvTextElement,
|
|
14
|
-
RecvVideoElement,
|
|
15
|
-
} from "napcat-sdk";
|
|
1
|
+
import type { Bot, CommandDefinition, MessageEvent, MessageInput, MessageTarget, MiokuContext, MessageSegment } from "mioku";
|
|
2
|
+
import {createGroupRef} from "mioku";
|
|
16
3
|
import { extractImageUrl } from "../config";
|
|
17
4
|
import { replyAdminErrorNotice } from "./notice";
|
|
18
5
|
|
|
@@ -23,80 +10,70 @@ function parseProfileSex(value: string): 0 | 1 | 2 {
|
|
|
23
10
|
return 0;
|
|
24
11
|
}
|
|
25
12
|
|
|
26
|
-
function toSendSegment(ctx:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if (seg.type === "image" || seg.type === "record" || seg.type === "video") {
|
|
33
|
-
const mediaSeg = seg as
|
|
34
|
-
| RecvImageElement
|
|
35
|
-
| RecvRecordElement
|
|
36
|
-
| RecvVideoElement;
|
|
37
|
-
const source = String(mediaSeg.url || mediaSeg.file || "").trim();
|
|
38
|
-
if (!source) return null;
|
|
39
|
-
if (seg.type === "image") {
|
|
40
|
-
return ctx.segment.image(source);
|
|
13
|
+
function toSendSegment(ctx: MiokuContext, seg: MessageSegment): MessageSegment | null {
|
|
14
|
+
const data = seg.data as Record<string, unknown>;
|
|
15
|
+
switch (seg.type) {
|
|
16
|
+
case "text": {
|
|
17
|
+
const text = String(data.text ?? "").trim();
|
|
18
|
+
return text ? ctx.segment.text(text) : null;
|
|
41
19
|
}
|
|
42
|
-
|
|
43
|
-
|
|
20
|
+
case "image": {
|
|
21
|
+
const source = String(data.url ?? data.file ?? "").trim();
|
|
22
|
+
return source ? ctx.segment.image(source) : null;
|
|
44
23
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const data = (seg as RecvJsonElement).data;
|
|
79
|
-
return ctx.segment.json ? ctx.segment.json(data) : null;
|
|
24
|
+
case "record": {
|
|
25
|
+
const source = String(data.file ?? data.url ?? "").trim();
|
|
26
|
+
return source ? ctx.segment.raw("record", { file: source }) : null;
|
|
27
|
+
}
|
|
28
|
+
case "video": {
|
|
29
|
+
const source = String(data.file ?? data.url ?? "").trim();
|
|
30
|
+
return source ? ctx.segment.raw("video", { file: source }) : null;
|
|
31
|
+
}
|
|
32
|
+
case "file": {
|
|
33
|
+
const source = String(data.file ?? data.url ?? "").trim();
|
|
34
|
+
return source ? ctx.segment.raw("file", { file: source }) : null;
|
|
35
|
+
}
|
|
36
|
+
case "at": {
|
|
37
|
+
const target = String(data.qq ?? data.target ?? "");
|
|
38
|
+
return target && target !== "all" ? ctx.segment.at(target) : null;
|
|
39
|
+
}
|
|
40
|
+
case "face": {
|
|
41
|
+
const id = data.id;
|
|
42
|
+
return id == null ? null : ctx.segment.raw("face", { id: String(id) });
|
|
43
|
+
}
|
|
44
|
+
case "reply": {
|
|
45
|
+
const id = data.message_id ?? data.id;
|
|
46
|
+
return id == null ? null : ctx.segment.reply(String(id));
|
|
47
|
+
}
|
|
48
|
+
case "forward": {
|
|
49
|
+
const id = data.id;
|
|
50
|
+
return id == null ? null : ctx.segment.raw("forward", { id: String(id) });
|
|
51
|
+
}
|
|
52
|
+
case "json": {
|
|
53
|
+
return ctx.segment.raw("json", data);
|
|
54
|
+
}
|
|
55
|
+
default:
|
|
56
|
+
return seg;
|
|
80
57
|
}
|
|
81
|
-
|
|
82
|
-
return null;
|
|
83
58
|
}
|
|
84
59
|
|
|
85
60
|
function normalizeIncomingSegments(
|
|
86
|
-
ctx:
|
|
87
|
-
segments:
|
|
88
|
-
):
|
|
61
|
+
ctx: MiokuContext,
|
|
62
|
+
segments: readonly MessageSegment[],
|
|
63
|
+
): MessageSegment[] {
|
|
89
64
|
if (!Array.isArray(segments)) return [];
|
|
90
|
-
return segments
|
|
65
|
+
return segments
|
|
66
|
+
.map((seg) => toSendSegment(ctx, seg))
|
|
67
|
+
.filter((seg): seg is MessageSegment => seg !== null);
|
|
91
68
|
}
|
|
92
69
|
|
|
93
70
|
function buildForwardPayloadAfterCommand(
|
|
94
|
-
ctx:
|
|
95
|
-
message:
|
|
71
|
+
ctx: MiokuContext,
|
|
72
|
+
message: readonly MessageSegment[],
|
|
96
73
|
commandPattern: RegExp,
|
|
97
74
|
fallbackText?: string,
|
|
98
|
-
):
|
|
99
|
-
const payload:
|
|
75
|
+
): MessageSegment[] {
|
|
76
|
+
const payload: MessageSegment[] = [];
|
|
100
77
|
let stripped = false;
|
|
101
78
|
|
|
102
79
|
for (const seg of message) {
|
|
@@ -107,7 +84,7 @@ function buildForwardPayloadAfterCommand(
|
|
|
107
84
|
}
|
|
108
85
|
continue;
|
|
109
86
|
}
|
|
110
|
-
const original = String((seg as
|
|
87
|
+
const original = String((seg.data as Record<string, unknown>).text ?? "");
|
|
111
88
|
if (!stripped) {
|
|
112
89
|
const nextText = original.replace(commandPattern, "");
|
|
113
90
|
if (nextText !== original) {
|
|
@@ -134,110 +111,72 @@ function buildForwardPayloadAfterCommand(
|
|
|
134
111
|
return payload;
|
|
135
112
|
}
|
|
136
113
|
|
|
137
|
-
function toForwardMessages(bot: any, nodes: any[]): any[] {
|
|
138
|
-
const normalizeElements = (elements: any[]): any[] => {
|
|
139
|
-
if (typeof bot?.normalizeSendable === "function") {
|
|
140
|
-
return bot.normalizeSendable(elements);
|
|
141
|
-
}
|
|
142
|
-
return elements.map((element: any) => {
|
|
143
|
-
if (
|
|
144
|
-
element &&
|
|
145
|
-
typeof element === "object" &&
|
|
146
|
-
"type" in element &&
|
|
147
|
-
"data" in element
|
|
148
|
-
) {
|
|
149
|
-
return element;
|
|
150
|
-
}
|
|
151
|
-
if (element && typeof element === "object" && "type" in element) {
|
|
152
|
-
const { type, ...data } = element;
|
|
153
|
-
return { type, data };
|
|
154
|
-
}
|
|
155
|
-
return element;
|
|
156
|
-
});
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
return nodes.map((node: any) => {
|
|
160
|
-
const rawNode =
|
|
161
|
-
node && typeof node === "object" && "type" in node && "data" in node
|
|
162
|
-
? { type: node.type, ...node.data }
|
|
163
|
-
: node;
|
|
164
|
-
if (!rawNode || rawNode.type !== "node") {
|
|
165
|
-
return normalizeElements([rawNode])[0];
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const content = Array.isArray(rawNode.content) ? rawNode.content : [];
|
|
169
|
-
if ("id" in rawNode && rawNode.id) {
|
|
170
|
-
return {
|
|
171
|
-
type: "node",
|
|
172
|
-
data: {
|
|
173
|
-
user_id: rawNode.user_id,
|
|
174
|
-
nickname: rawNode.nickname,
|
|
175
|
-
id: rawNode.id,
|
|
176
|
-
},
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
return {
|
|
181
|
-
type: "node",
|
|
182
|
-
data: {
|
|
183
|
-
user_id: rawNode.user_id,
|
|
184
|
-
nickname: rawNode.nickname,
|
|
185
|
-
content: normalizeElements(content),
|
|
186
|
-
},
|
|
187
|
-
};
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
|
|
191
114
|
async function sendForwardByEvent(options: {
|
|
192
|
-
bot:
|
|
193
|
-
event:
|
|
194
|
-
messages:
|
|
115
|
+
bot: Bot;
|
|
116
|
+
event: MessageEvent;
|
|
117
|
+
messages: readonly unknown[];
|
|
195
118
|
}): Promise<void> {
|
|
196
119
|
const { bot, event, messages } = options;
|
|
197
120
|
const chunkSize = 50;
|
|
198
121
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
122
|
+
const nodes = (messages as Array<{
|
|
123
|
+
type?: string;
|
|
124
|
+
data?: { user_id?: string; nickname?: string; content?: unknown };
|
|
125
|
+
}>)
|
|
126
|
+
.map((node) => ({
|
|
127
|
+
user_id: String(node?.data?.user_id ?? event.user_id ?? ""),
|
|
128
|
+
nickname:
|
|
129
|
+
String(node?.data?.nickname || "") ||
|
|
130
|
+
String(node?.data?.user_id ?? event.user_id ?? "转发"),
|
|
131
|
+
content: Array.isArray(node?.data?.content)
|
|
132
|
+
? node.data.content
|
|
133
|
+
: [node?.data?.content],
|
|
134
|
+
}))
|
|
135
|
+
.filter((node) => node.content.length > 0)
|
|
136
|
+
.map((node) => ({
|
|
137
|
+
user_id: node.user_id,
|
|
138
|
+
nickname: node.nickname,
|
|
139
|
+
content: node.content as MessageInput,
|
|
140
|
+
}));
|
|
141
|
+
|
|
142
|
+
const target: MessageTarget =
|
|
143
|
+
event.message_type === "group" && event.group_id
|
|
144
|
+
? { type: "group", group_id: event.group_id }
|
|
145
|
+
: { type: "private", user_id: event.user_id ?? "" };
|
|
146
|
+
|
|
147
|
+
for (let i = 0; i < nodes.length; i += chunkSize) {
|
|
148
|
+
await bot.sendForward(target, nodes.slice(i, i + chunkSize));
|
|
213
149
|
}
|
|
214
150
|
}
|
|
215
151
|
|
|
216
|
-
export function registerPersonalCommands(ctx:
|
|
217
|
-
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
const isGroup = event.message_type === "group";
|
|
152
|
+
export function registerPersonalCommands(ctx: MiokuContext) {
|
|
153
|
+
const register = (command: CommandDefinition) => {
|
|
154
|
+
const { handler, ...rest } = command;
|
|
155
|
+
ctx.command({
|
|
156
|
+
...rest,
|
|
157
|
+
prefixes: false,
|
|
158
|
+
handler: async (c) => {
|
|
159
|
+
if (c.event.user_id === c.event.self_id) return;
|
|
160
|
+
await handler(c);
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
};
|
|
229
164
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
165
|
+
register({
|
|
166
|
+
name: "/改头像",
|
|
167
|
+
match: /^\/改头像/,
|
|
168
|
+
permission: "master",
|
|
169
|
+
description: "修改Bot头像",
|
|
170
|
+
handler: async ({ event }) => {
|
|
171
|
+
const bot = event.bot;
|
|
172
|
+
if (!bot) return;
|
|
235
173
|
const imageUrl = extractImageUrl(event.message);
|
|
236
174
|
if (!imageUrl) {
|
|
237
|
-
|
|
175
|
+
await event.reply("图片呢图片呢~", true);
|
|
176
|
+
return;
|
|
238
177
|
}
|
|
239
178
|
try {
|
|
240
|
-
await bot.
|
|
179
|
+
await bot.setAvatar(imageUrl);
|
|
241
180
|
await event.reply("done");
|
|
242
181
|
} catch (err) {
|
|
243
182
|
await replyAdminErrorNotice({
|
|
@@ -247,22 +186,25 @@ export function registerPersonalCommands(ctx: MiokiContext) {
|
|
|
247
186
|
fallbackMessage: `出错了,笨蛋~ ${String(err)}`,
|
|
248
187
|
error: err,
|
|
249
188
|
});
|
|
250
|
-
return;
|
|
251
189
|
}
|
|
252
|
-
|
|
253
|
-
|
|
190
|
+
},
|
|
191
|
+
});
|
|
254
192
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
193
|
+
register({
|
|
194
|
+
name: "/改昵称",
|
|
195
|
+
match: /^\/改昵称/,
|
|
196
|
+
permission: "master",
|
|
197
|
+
description: "修改Bot昵称",
|
|
198
|
+
handler: async ({ event, body }) => {
|
|
199
|
+
const bot = event.bot;
|
|
200
|
+
if (!bot) return;
|
|
201
|
+
const nickname = body.replace(/^\/改昵称\s*/, "").trim();
|
|
261
202
|
if (!nickname) {
|
|
262
|
-
|
|
203
|
+
await event.reply("想改成什么昵称呀~", true);
|
|
204
|
+
return;
|
|
263
205
|
}
|
|
264
206
|
try {
|
|
265
|
-
await bot.
|
|
207
|
+
await bot.setProfile({ nickname });
|
|
266
208
|
await event.reply("done");
|
|
267
209
|
} catch (err) {
|
|
268
210
|
await replyAdminErrorNotice({
|
|
@@ -273,20 +215,24 @@ export function registerPersonalCommands(ctx: MiokiContext) {
|
|
|
273
215
|
error: err,
|
|
274
216
|
});
|
|
275
217
|
}
|
|
276
|
-
|
|
277
|
-
|
|
218
|
+
},
|
|
219
|
+
});
|
|
278
220
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
221
|
+
register({
|
|
222
|
+
name: "/改签名",
|
|
223
|
+
match: /^\/改签名/,
|
|
224
|
+
permission: "master",
|
|
225
|
+
description: "修改Bot个性签名",
|
|
226
|
+
handler: async ({ event, body }) => {
|
|
227
|
+
const bot = event.bot;
|
|
228
|
+
if (!bot) return;
|
|
229
|
+
const personalNote = body.replace(/^\/改签名\s*/, "").trim();
|
|
285
230
|
if (!personalNote) {
|
|
286
|
-
|
|
231
|
+
await event.reply("想改成什么签名呀~", true);
|
|
232
|
+
return;
|
|
287
233
|
}
|
|
288
234
|
try {
|
|
289
|
-
await bot.
|
|
235
|
+
await bot.setProfile({ personal_note: personalNote });
|
|
290
236
|
await event.reply("done");
|
|
291
237
|
} catch (err) {
|
|
292
238
|
await replyAdminErrorNotice({
|
|
@@ -297,18 +243,20 @@ export function registerPersonalCommands(ctx: MiokiContext) {
|
|
|
297
243
|
error: err,
|
|
298
244
|
});
|
|
299
245
|
}
|
|
300
|
-
|
|
301
|
-
|
|
246
|
+
},
|
|
247
|
+
});
|
|
302
248
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
const
|
|
249
|
+
register({
|
|
250
|
+
name: "/改性别",
|
|
251
|
+
match: /^\/改性别/,
|
|
252
|
+
permission: "master",
|
|
253
|
+
description: "修改Bot性别",
|
|
254
|
+
handler: async ({ event, body }) => {
|
|
255
|
+
const bot = event.bot;
|
|
256
|
+
if (!bot) return;
|
|
257
|
+
const sex = parseProfileSex(body.replace(/^\/改性别\s*/, ""));
|
|
310
258
|
try {
|
|
311
|
-
await bot.
|
|
259
|
+
await bot.setProfile({ sex });
|
|
312
260
|
await event.reply("done");
|
|
313
261
|
} catch (err) {
|
|
314
262
|
await replyAdminErrorNotice({
|
|
@@ -319,15 +267,19 @@ export function registerPersonalCommands(ctx: MiokiContext) {
|
|
|
319
267
|
error: err,
|
|
320
268
|
});
|
|
321
269
|
}
|
|
322
|
-
|
|
323
|
-
|
|
270
|
+
},
|
|
271
|
+
});
|
|
324
272
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
273
|
+
register({
|
|
274
|
+
name: "/删好友",
|
|
275
|
+
match: /^\/删好友(?:\s|$)/,
|
|
276
|
+
permission: "master",
|
|
277
|
+
description: "删除好友",
|
|
278
|
+
usage: "/删好友 qq号",
|
|
279
|
+
handler: async ({ event, body }) => {
|
|
280
|
+
const bot = event.bot;
|
|
281
|
+
if (!bot) return;
|
|
282
|
+
const qq = parseInt(body.replace(/^\/删好友\s*/, "").trim(), 10);
|
|
331
283
|
if (!qq) {
|
|
332
284
|
await replyAdminErrorNotice({
|
|
333
285
|
ctx,
|
|
@@ -338,7 +290,7 @@ export function registerPersonalCommands(ctx: MiokiContext) {
|
|
|
338
290
|
return;
|
|
339
291
|
}
|
|
340
292
|
try {
|
|
341
|
-
await bot.
|
|
293
|
+
await bot.deleteFriend(qq);
|
|
342
294
|
await event.reply("done");
|
|
343
295
|
} catch (err) {
|
|
344
296
|
await replyAdminErrorNotice({
|
|
@@ -349,15 +301,19 @@ export function registerPersonalCommands(ctx: MiokiContext) {
|
|
|
349
301
|
error: err,
|
|
350
302
|
});
|
|
351
303
|
}
|
|
352
|
-
|
|
353
|
-
|
|
304
|
+
},
|
|
305
|
+
});
|
|
354
306
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
307
|
+
register({
|
|
308
|
+
name: "/退群",
|
|
309
|
+
match: /^\/退群(?:\s|$)/,
|
|
310
|
+
permission: "master",
|
|
311
|
+
description: "退出群聊",
|
|
312
|
+
usage: "/退群 群号",
|
|
313
|
+
handler: async ({ event, body }) => {
|
|
314
|
+
const bot = event.bot;
|
|
315
|
+
if (!bot) return;
|
|
316
|
+
const targetGroup = parseInt(body.replace(/^\/退群\s*/, "").trim(), 10);
|
|
361
317
|
if (!targetGroup) {
|
|
362
318
|
await replyAdminErrorNotice({
|
|
363
319
|
ctx,
|
|
@@ -368,10 +324,7 @@ export function registerPersonalCommands(ctx: MiokiContext) {
|
|
|
368
324
|
return;
|
|
369
325
|
}
|
|
370
326
|
try {
|
|
371
|
-
await bot.
|
|
372
|
-
group_id: targetGroup,
|
|
373
|
-
is_dismiss: false,
|
|
374
|
-
});
|
|
327
|
+
await createGroupRef(bot, String(targetGroup)).leave(false);
|
|
375
328
|
await event.reply("done");
|
|
376
329
|
} catch (err) {
|
|
377
330
|
await replyAdminErrorNotice({
|
|
@@ -382,15 +335,19 @@ export function registerPersonalCommands(ctx: MiokiContext) {
|
|
|
382
335
|
error: err,
|
|
383
336
|
});
|
|
384
337
|
}
|
|
385
|
-
|
|
386
|
-
|
|
338
|
+
},
|
|
339
|
+
});
|
|
387
340
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
341
|
+
register({
|
|
342
|
+
name: "/发好友",
|
|
343
|
+
match: /^\/发好友(?:\s|$)/,
|
|
344
|
+
permission: "master",
|
|
345
|
+
description: "给好友发送私聊消息",
|
|
346
|
+
usage: "/发好友 qq号 内容",
|
|
347
|
+
handler: async ({ event, body }) => {
|
|
348
|
+
const bot = event.bot;
|
|
349
|
+
if (!bot) return;
|
|
350
|
+
const matched = body.match(/^\/发好友\s*(\d+)\s*([\s\S]*)$/);
|
|
394
351
|
if (!matched) {
|
|
395
352
|
await replyAdminErrorNotice({
|
|
396
353
|
ctx,
|
|
@@ -420,7 +377,7 @@ export function registerPersonalCommands(ctx: MiokiContext) {
|
|
|
420
377
|
return;
|
|
421
378
|
}
|
|
422
379
|
try {
|
|
423
|
-
await bot.
|
|
380
|
+
await bot.sendMessage({ type: "private", user_id: targetUser}, payload);
|
|
424
381
|
await event.reply("done");
|
|
425
382
|
} catch (err) {
|
|
426
383
|
await replyAdminErrorNotice({
|
|
@@ -431,15 +388,19 @@ export function registerPersonalCommands(ctx: MiokiContext) {
|
|
|
431
388
|
error: err,
|
|
432
389
|
});
|
|
433
390
|
}
|
|
434
|
-
|
|
435
|
-
|
|
391
|
+
},
|
|
392
|
+
});
|
|
436
393
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
394
|
+
register({
|
|
395
|
+
name: "/发群聊",
|
|
396
|
+
match: /^\/发群聊(?:\s|$)/,
|
|
397
|
+
permission: "master",
|
|
398
|
+
description: "给群聊发送消息",
|
|
399
|
+
usage: "/发群聊 群号 内容",
|
|
400
|
+
handler: async ({ event, body }) => {
|
|
401
|
+
const bot = event.bot;
|
|
402
|
+
if (!bot) return;
|
|
403
|
+
const matched = body.match(/^\/发群聊\s*(\d+)\s*([\s\S]*)$/);
|
|
443
404
|
if (!matched) {
|
|
444
405
|
await replyAdminErrorNotice({
|
|
445
406
|
ctx,
|
|
@@ -469,7 +430,7 @@ export function registerPersonalCommands(ctx: MiokiContext) {
|
|
|
469
430
|
return;
|
|
470
431
|
}
|
|
471
432
|
try {
|
|
472
|
-
await bot.
|
|
433
|
+
await bot.sendMessage({ type: "group", group_id: targetGroup}, payload);
|
|
473
434
|
await event.reply("done");
|
|
474
435
|
} catch (err) {
|
|
475
436
|
await replyAdminErrorNotice({
|
|
@@ -480,20 +441,23 @@ export function registerPersonalCommands(ctx: MiokiContext) {
|
|
|
480
441
|
error: err,
|
|
481
442
|
});
|
|
482
443
|
}
|
|
483
|
-
|
|
484
|
-
|
|
444
|
+
},
|
|
445
|
+
});
|
|
485
446
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
447
|
+
register({
|
|
448
|
+
name: "/全部好友",
|
|
449
|
+
match: /^\/全部好友$/,
|
|
450
|
+
permission: "master",
|
|
451
|
+
description: "获取全部好友列表",
|
|
452
|
+
handler: async ({ event }) => {
|
|
453
|
+
const bot = event.bot;
|
|
454
|
+
if (!bot) return;
|
|
455
|
+
if (event.message_type === "group") {
|
|
492
456
|
await event.reply("在私聊使用试试看吧~", true);
|
|
493
457
|
return;
|
|
494
458
|
}
|
|
495
459
|
try {
|
|
496
|
-
const friendList
|
|
460
|
+
const friendList = await bot.getFriendList();
|
|
497
461
|
if (!Array.isArray(friendList) || friendList.length === 0) {
|
|
498
462
|
await replyAdminErrorNotice({
|
|
499
463
|
ctx,
|
|
@@ -503,9 +467,9 @@ export function registerPersonalCommands(ctx: MiokiContext) {
|
|
|
503
467
|
});
|
|
504
468
|
return;
|
|
505
469
|
}
|
|
506
|
-
const nodes = friendList.map((friend
|
|
507
|
-
ctx.segment.node
|
|
508
|
-
user_id:
|
|
470
|
+
const nodes = friendList.map((friend) =>
|
|
471
|
+
ctx.segment.raw("node", {
|
|
472
|
+
user_id: friend.user_id,
|
|
509
473
|
nickname:
|
|
510
474
|
friend.nickname || friend.remark || String(friend.user_id),
|
|
511
475
|
content: [
|
|
@@ -518,11 +482,7 @@ export function registerPersonalCommands(ctx: MiokiContext) {
|
|
|
518
482
|
],
|
|
519
483
|
}),
|
|
520
484
|
);
|
|
521
|
-
await sendForwardByEvent({
|
|
522
|
-
bot,
|
|
523
|
-
event,
|
|
524
|
-
messages: toForwardMessages(bot, nodes),
|
|
525
|
-
});
|
|
485
|
+
await sendForwardByEvent({ bot, event, messages: nodes });
|
|
526
486
|
} catch (err) {
|
|
527
487
|
await replyAdminErrorNotice({
|
|
528
488
|
ctx,
|
|
@@ -532,20 +492,23 @@ export function registerPersonalCommands(ctx: MiokiContext) {
|
|
|
532
492
|
error: err,
|
|
533
493
|
});
|
|
534
494
|
}
|
|
535
|
-
|
|
536
|
-
|
|
495
|
+
},
|
|
496
|
+
});
|
|
537
497
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
498
|
+
register({
|
|
499
|
+
name: "/全部群聊",
|
|
500
|
+
match: /^\/全部群聊$/,
|
|
501
|
+
permission: "master",
|
|
502
|
+
description: "获取全部群聊列表",
|
|
503
|
+
handler: async ({ event }) => {
|
|
504
|
+
const bot = event.bot;
|
|
505
|
+
if (!bot) return;
|
|
506
|
+
if (event.message_type === "group") {
|
|
544
507
|
await event.reply("在私聊使用试试看吧~", true);
|
|
545
508
|
return;
|
|
546
509
|
}
|
|
547
510
|
try {
|
|
548
|
-
const groupList
|
|
511
|
+
const groupList = await bot.getGroupList();
|
|
549
512
|
if (!Array.isArray(groupList) || groupList.length === 0) {
|
|
550
513
|
await replyAdminErrorNotice({
|
|
551
514
|
ctx,
|
|
@@ -555,10 +518,10 @@ export function registerPersonalCommands(ctx: MiokiContext) {
|
|
|
555
518
|
});
|
|
556
519
|
return;
|
|
557
520
|
}
|
|
558
|
-
const nodes = groupList.map((group
|
|
559
|
-
ctx.segment.node
|
|
560
|
-
user_id:
|
|
561
|
-
nickname: String(
|
|
521
|
+
const nodes = groupList.map((group) =>
|
|
522
|
+
ctx.segment.raw("node", {
|
|
523
|
+
user_id: event.self_id ?? "",
|
|
524
|
+
nickname: String(event.self_id ?? ""),
|
|
562
525
|
content: [
|
|
563
526
|
ctx.segment.image(
|
|
564
527
|
`https://p.qlogo.cn/gh/${group.group_id}/${group.group_id}/640/`,
|
|
@@ -569,11 +532,7 @@ export function registerPersonalCommands(ctx: MiokiContext) {
|
|
|
569
532
|
],
|
|
570
533
|
}),
|
|
571
534
|
);
|
|
572
|
-
await sendForwardByEvent({
|
|
573
|
-
bot,
|
|
574
|
-
event,
|
|
575
|
-
messages: toForwardMessages(bot, nodes),
|
|
576
|
-
});
|
|
535
|
+
await sendForwardByEvent({ bot, event, messages: nodes });
|
|
577
536
|
} catch (err) {
|
|
578
537
|
await replyAdminErrorNotice({
|
|
579
538
|
ctx,
|
|
@@ -583,7 +542,6 @@ export function registerPersonalCommands(ctx: MiokiContext) {
|
|
|
583
542
|
error: err,
|
|
584
543
|
});
|
|
585
544
|
}
|
|
586
|
-
|
|
587
|
-
}
|
|
545
|
+
},
|
|
588
546
|
});
|
|
589
547
|
}
|