koishi-plugin-chat-patch 1.0.7 → 1.0.8
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/lib/api-handlers.d.ts +17 -0
- package/lib/config.d.ts +13 -0
- package/lib/file-manager.d.ts +18 -0
- package/lib/index.d.ts +11 -0
- package/lib/index.js +95 -51
- package/lib/message-handler.d.ts +16 -0
- package/lib/types.d.ts +53 -0
- package/lib/utils.d.ts +9 -0
- package/package.json +1 -1
- package/src/file-manager.ts +7 -1
- package/src/message-handler.ts +6 -6
- package/src/utils.ts +57 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Context } from 'koishi';
|
|
2
|
+
import { Config } from './config';
|
|
3
|
+
import { FileManager } from './file-manager';
|
|
4
|
+
export declare class ApiHandlers {
|
|
5
|
+
private ctx;
|
|
6
|
+
private config;
|
|
7
|
+
private fileManager;
|
|
8
|
+
private logger;
|
|
9
|
+
constructor(ctx: Context, config: Config, fileManager: FileManager);
|
|
10
|
+
registerApiHandlers(): void;
|
|
11
|
+
private isFileUrl;
|
|
12
|
+
private createFileUrl;
|
|
13
|
+
private handleLocalFileRequest;
|
|
14
|
+
private setupTempFileCleanup;
|
|
15
|
+
private cleanupTempImagesByCount;
|
|
16
|
+
private logInfo;
|
|
17
|
+
}
|
package/lib/config.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Schema } from 'koishi';
|
|
2
|
+
export interface Config {
|
|
3
|
+
loggerinfo: boolean;
|
|
4
|
+
maxMessagesPerChannel: number;
|
|
5
|
+
keepMessagesOnClear: number;
|
|
6
|
+
keepTempImages: number;
|
|
7
|
+
blockedPlatforms: Array<{
|
|
8
|
+
platformName: string;
|
|
9
|
+
exactMatch: boolean;
|
|
10
|
+
}>;
|
|
11
|
+
chatContainerHeight: number;
|
|
12
|
+
}
|
|
13
|
+
export declare const Config: Schema<Config>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Context } from 'koishi';
|
|
2
|
+
import { ChatData, MessageInfo } from './types';
|
|
3
|
+
import { Config } from './config';
|
|
4
|
+
export declare class FileManager {
|
|
5
|
+
private ctx;
|
|
6
|
+
private config;
|
|
7
|
+
private dataFilePath;
|
|
8
|
+
private fileOperationLock;
|
|
9
|
+
private logger;
|
|
10
|
+
private utils;
|
|
11
|
+
constructor(ctx: Context, config: Config);
|
|
12
|
+
private ensureDataDir;
|
|
13
|
+
readChatDataFromFile(): ChatData;
|
|
14
|
+
writeChatDataToFile(data: ChatData): void;
|
|
15
|
+
cleanExcessMessages(data: ChatData): ChatData;
|
|
16
|
+
addMessageToFile(messageInfo: MessageInfo): Promise<void>;
|
|
17
|
+
private logInfo;
|
|
18
|
+
}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Context } from 'koishi';
|
|
2
|
+
import { Config } from './config';
|
|
3
|
+
export declare const name = "chat-patch";
|
|
4
|
+
export declare const reusable = false;
|
|
5
|
+
export declare const filter = false;
|
|
6
|
+
export declare const inject: {
|
|
7
|
+
required: string[];
|
|
8
|
+
};
|
|
9
|
+
export declare const usage = "\n\n---\n\n\u5F00\u542F\u540E\uFF0C\u5373\u53EF\u5728koishi\u63A7\u5236\u53F0\u64CD\u4F5C\u673A\u5668\u4EBA\u6536\u53D1\u6D88\u606F\u5566\n\n\u6682\u65F6\u53EA\u652F\u6301\u63A5\u53D7\u56FE\u6587\u6D88\u606F / \u53D1\u9001\u6587\u5B57\u6D88\u606F\n\n---\n";
|
|
10
|
+
export { Config } from './config';
|
|
11
|
+
export declare function apply(ctx: Context, config: Config): Promise<void>;
|
package/lib/index.js
CHANGED
|
@@ -44,12 +44,98 @@ var import_node_path2 = __toESM(require("node:path"));
|
|
|
44
44
|
// src/file-manager.ts
|
|
45
45
|
var import_node_path = __toESM(require("node:path"));
|
|
46
46
|
var import_node_fs = __toESM(require("node:fs"));
|
|
47
|
+
|
|
48
|
+
// src/utils.ts
|
|
49
|
+
var Utils = class {
|
|
50
|
+
constructor(config) {
|
|
51
|
+
this.config = config;
|
|
52
|
+
}
|
|
53
|
+
static {
|
|
54
|
+
__name(this, "Utils");
|
|
55
|
+
}
|
|
56
|
+
// 检查平台是否被屏蔽
|
|
57
|
+
isPlatformBlocked(platform) {
|
|
58
|
+
if (!this.config.blockedPlatforms || this.config.blockedPlatforms.length === 0) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
for (const blockedPlatform of this.config.blockedPlatforms) {
|
|
62
|
+
if (blockedPlatform.exactMatch) {
|
|
63
|
+
if (platform === blockedPlatform.platformName) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
if (platform.includes(blockedPlatform.platformName)) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
// 递归提取所有文本内容的函数
|
|
75
|
+
extractTextContent(elements) {
|
|
76
|
+
let text = "";
|
|
77
|
+
for (const element of elements) {
|
|
78
|
+
if (element.type === "text") {
|
|
79
|
+
text += element.attrs?.content || "";
|
|
80
|
+
} else if (element.type === "p") {
|
|
81
|
+
if (element.children && element.children.length > 0) {
|
|
82
|
+
text += this.extractTextContent(element.children) + "\n";
|
|
83
|
+
}
|
|
84
|
+
} else if (element.children && element.children.length > 0) {
|
|
85
|
+
text += this.extractTextContent(element.children);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return text;
|
|
89
|
+
}
|
|
90
|
+
// 检查字符串是否为base64格式
|
|
91
|
+
isBase64(str) {
|
|
92
|
+
if (!str || typeof str !== "string") return false;
|
|
93
|
+
if (str.startsWith("data:")) {
|
|
94
|
+
return str.includes("base64,");
|
|
95
|
+
}
|
|
96
|
+
if (str.length > 100) {
|
|
97
|
+
const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
|
|
98
|
+
return base64Regex.test(str);
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
// 清理对象中的base64内容
|
|
103
|
+
cleanBase64Content(obj) {
|
|
104
|
+
if (obj === null || obj === void 0) {
|
|
105
|
+
return obj;
|
|
106
|
+
}
|
|
107
|
+
if (typeof obj === "string") {
|
|
108
|
+
if (this.isBase64(obj)) {
|
|
109
|
+
return "暂不支持记录base64内容";
|
|
110
|
+
}
|
|
111
|
+
return obj;
|
|
112
|
+
}
|
|
113
|
+
if (Array.isArray(obj)) {
|
|
114
|
+
return obj.map((item) => this.cleanBase64Content(item));
|
|
115
|
+
}
|
|
116
|
+
if (typeof obj === "object") {
|
|
117
|
+
const cleaned = {};
|
|
118
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
119
|
+
if (typeof value === "string" && (key === "src" || key === "url" || key === "file" || key === "data" || key === "content") && this.isBase64(value)) {
|
|
120
|
+
cleaned[key] = "暂不支持记录base64内容";
|
|
121
|
+
} else {
|
|
122
|
+
cleaned[key] = this.cleanBase64Content(value);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return cleaned;
|
|
126
|
+
}
|
|
127
|
+
return obj;
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// src/file-manager.ts
|
|
47
132
|
var FileManager = class {
|
|
48
133
|
constructor(ctx, config) {
|
|
49
134
|
this.ctx = ctx;
|
|
50
135
|
this.config = config;
|
|
51
136
|
this.dataFilePath = import_node_path.default.resolve(ctx.baseDir, "data", "chat-patch", "chat-data.json");
|
|
52
137
|
this.logger = ctx.logger("chat-patch");
|
|
138
|
+
this.utils = new Utils(config);
|
|
53
139
|
}
|
|
54
140
|
static {
|
|
55
141
|
__name(this, "FileManager");
|
|
@@ -57,6 +143,7 @@ var FileManager = class {
|
|
|
57
143
|
dataFilePath;
|
|
58
144
|
fileOperationLock = Promise.resolve();
|
|
59
145
|
logger;
|
|
146
|
+
utils;
|
|
60
147
|
// 确保目录存在
|
|
61
148
|
ensureDataDir() {
|
|
62
149
|
const dir = import_node_path.default.dirname(this.dataFilePath);
|
|
@@ -147,8 +234,9 @@ var FileManager = class {
|
|
|
147
234
|
if (!messageInfo.timestamp) {
|
|
148
235
|
messageInfo.timestamp = Date.now();
|
|
149
236
|
}
|
|
237
|
+
const cleanedMessageInfo = this.utils.cleanBase64Content(messageInfo);
|
|
150
238
|
const beforeCount = data.messages[channelKey].length;
|
|
151
|
-
data.messages[channelKey].push(
|
|
239
|
+
data.messages[channelKey].push(cleanedMessageInfo);
|
|
152
240
|
const afterCount = data.messages[channelKey].length;
|
|
153
241
|
if (data.messages[channelKey].length > this.config.maxMessagesPerChannel) {
|
|
154
242
|
data.messages[channelKey].sort((a, b) => a.timestamp - b.timestamp);
|
|
@@ -181,50 +269,6 @@ var FileManager = class {
|
|
|
181
269
|
}
|
|
182
270
|
};
|
|
183
271
|
|
|
184
|
-
// src/utils.ts
|
|
185
|
-
var Utils = class {
|
|
186
|
-
constructor(config) {
|
|
187
|
-
this.config = config;
|
|
188
|
-
}
|
|
189
|
-
static {
|
|
190
|
-
__name(this, "Utils");
|
|
191
|
-
}
|
|
192
|
-
// 检查平台是否被屏蔽
|
|
193
|
-
isPlatformBlocked(platform) {
|
|
194
|
-
if (!this.config.blockedPlatforms || this.config.blockedPlatforms.length === 0) {
|
|
195
|
-
return false;
|
|
196
|
-
}
|
|
197
|
-
for (const blockedPlatform of this.config.blockedPlatforms) {
|
|
198
|
-
if (blockedPlatform.exactMatch) {
|
|
199
|
-
if (platform === blockedPlatform.platformName) {
|
|
200
|
-
return true;
|
|
201
|
-
}
|
|
202
|
-
} else {
|
|
203
|
-
if (platform.includes(blockedPlatform.platformName)) {
|
|
204
|
-
return true;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
return false;
|
|
209
|
-
}
|
|
210
|
-
// 递归提取所有文本内容的函数
|
|
211
|
-
extractTextContent(elements) {
|
|
212
|
-
let text = "";
|
|
213
|
-
for (const element of elements) {
|
|
214
|
-
if (element.type === "text") {
|
|
215
|
-
text += element.attrs?.content || "";
|
|
216
|
-
} else if (element.type === "p") {
|
|
217
|
-
if (element.children && element.children.length > 0) {
|
|
218
|
-
text += this.extractTextContent(element.children) + "\n";
|
|
219
|
-
}
|
|
220
|
-
} else if (element.children && element.children.length > 0) {
|
|
221
|
-
text += this.extractTextContent(element.children);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
return text;
|
|
225
|
-
}
|
|
226
|
-
};
|
|
227
|
-
|
|
228
272
|
// src/message-handler.ts
|
|
229
273
|
var MessageHandler = class {
|
|
230
274
|
constructor(ctx, config, fileManager) {
|
|
@@ -325,12 +369,12 @@ var MessageHandler = class {
|
|
|
325
369
|
timestamp,
|
|
326
370
|
channelId: session.channelId,
|
|
327
371
|
selfId: session.selfId,
|
|
328
|
-
elements,
|
|
372
|
+
elements: this.utils.cleanBase64Content(elements),
|
|
329
373
|
type: "user",
|
|
330
374
|
guildId: session.guildId,
|
|
331
375
|
guildName,
|
|
332
376
|
platform: session.platform || "unknown",
|
|
333
|
-
quote: quoteInfo
|
|
377
|
+
quote: quoteInfo ? this.utils.cleanBase64Content(quoteInfo) : void 0
|
|
334
378
|
};
|
|
335
379
|
await this.fileManager.addMessageToFile(messageInfo);
|
|
336
380
|
const messageEvent = {
|
|
@@ -347,8 +391,8 @@ var MessageHandler = class {
|
|
|
347
391
|
guildId: session.guildId,
|
|
348
392
|
guildName,
|
|
349
393
|
channelType: session.type || 0,
|
|
350
|
-
elements,
|
|
351
|
-
quote: quoteInfo,
|
|
394
|
+
elements: this.utils.cleanBase64Content(elements),
|
|
395
|
+
quote: quoteInfo ? this.utils.cleanBase64Content(quoteInfo) : void 0,
|
|
352
396
|
bot: {
|
|
353
397
|
avatar: session.bot.user?.avatar,
|
|
354
398
|
name: session.bot.user?.name
|
|
@@ -378,7 +422,7 @@ var MessageHandler = class {
|
|
|
378
422
|
timestamp,
|
|
379
423
|
channelId: session.event?.channel?.id || session.channelId,
|
|
380
424
|
selfId: session.selfId,
|
|
381
|
-
elements: session.event?.message?.elements,
|
|
425
|
+
elements: this.utils.cleanBase64Content(session.event?.message?.elements),
|
|
382
426
|
type: "bot",
|
|
383
427
|
guildId: session.event?.guild?.id || session.guildId,
|
|
384
428
|
guildName,
|
|
@@ -399,7 +443,7 @@ var MessageHandler = class {
|
|
|
399
443
|
guildId: session.event?.guild?.id || session.guildId,
|
|
400
444
|
guildName,
|
|
401
445
|
channelType: session.event?.channel?.type || session.type || 0,
|
|
402
|
-
elements: session.event?.message?.elements,
|
|
446
|
+
elements: this.utils.cleanBase64Content(session.event?.message?.elements),
|
|
403
447
|
bot: {
|
|
404
448
|
avatar: session.bot.user?.avatar,
|
|
405
449
|
name: session.bot.user?.name
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Context, Session } from 'koishi';
|
|
2
|
+
import { Config } from './config';
|
|
3
|
+
import { FileManager } from './file-manager';
|
|
4
|
+
export declare class MessageHandler {
|
|
5
|
+
private ctx;
|
|
6
|
+
private config;
|
|
7
|
+
private fileManager;
|
|
8
|
+
private logger;
|
|
9
|
+
private utils;
|
|
10
|
+
constructor(ctx: Context, config: Config, fileManager: FileManager);
|
|
11
|
+
updateBotInfoToFile(session: Session): Promise<void>;
|
|
12
|
+
updateChannelInfoToFile(session: Session): Promise<string>;
|
|
13
|
+
broadcastMessageEvent(session: Session): Promise<void>;
|
|
14
|
+
broadcastBotMessageEvent(session: Session): Promise<void>;
|
|
15
|
+
private logInfo;
|
|
16
|
+
}
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { h } from 'koishi';
|
|
2
|
+
export interface BotInfo {
|
|
3
|
+
selfId: string;
|
|
4
|
+
platform: string;
|
|
5
|
+
username: string;
|
|
6
|
+
avatar?: string;
|
|
7
|
+
status: 'online' | 'offline';
|
|
8
|
+
}
|
|
9
|
+
export interface ChannelInfo {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
type: number | string;
|
|
13
|
+
guildId?: string;
|
|
14
|
+
guildName?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface QuoteInfo {
|
|
17
|
+
messageId: string;
|
|
18
|
+
id: string;
|
|
19
|
+
content: string;
|
|
20
|
+
elements?: h[];
|
|
21
|
+
user: {
|
|
22
|
+
id: string;
|
|
23
|
+
name: string;
|
|
24
|
+
userId: string;
|
|
25
|
+
avatar?: string;
|
|
26
|
+
username: string;
|
|
27
|
+
};
|
|
28
|
+
timestamp: number;
|
|
29
|
+
}
|
|
30
|
+
export interface MessageInfo {
|
|
31
|
+
id: string;
|
|
32
|
+
content: string;
|
|
33
|
+
userId: string;
|
|
34
|
+
username: string;
|
|
35
|
+
avatar?: string;
|
|
36
|
+
timestamp: number;
|
|
37
|
+
channelId: string;
|
|
38
|
+
selfId: string;
|
|
39
|
+
elements?: h[];
|
|
40
|
+
type: 'user' | 'bot';
|
|
41
|
+
guildId?: string;
|
|
42
|
+
guildName?: string;
|
|
43
|
+
platform: string;
|
|
44
|
+
quote?: QuoteInfo;
|
|
45
|
+
}
|
|
46
|
+
export interface ChatData {
|
|
47
|
+
bots: Record<string, BotInfo>;
|
|
48
|
+
channels: Record<string, Record<string, ChannelInfo>>;
|
|
49
|
+
messages: Record<string, MessageInfo[]>;
|
|
50
|
+
pinnedBots: string[];
|
|
51
|
+
pinnedChannels: string[];
|
|
52
|
+
lastSaveTime?: number;
|
|
53
|
+
}
|
package/lib/utils.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Config } from './config';
|
|
2
|
+
export declare class Utils {
|
|
3
|
+
private config;
|
|
4
|
+
constructor(config: Config);
|
|
5
|
+
isPlatformBlocked(platform: string): boolean;
|
|
6
|
+
extractTextContent(elements: any[]): string;
|
|
7
|
+
private isBase64;
|
|
8
|
+
cleanBase64Content(obj: any): any;
|
|
9
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koishi-plugin-chat-patch",
|
|
3
3
|
"description": "[<ruby>chat-patch<rp>(</rp><rt>点我预览效果</rt><rp>)</rp></ruby>](https://i0.hdslb.com/bfs/openplatform/71074dfc9e5256fc3333d8bd8478bec1af874046.png) 视奸小插件((bushi( (低性能警告)。手机端适配。灵感来自 chat 插件。",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.8",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
7
7
|
"files": [
|
package/src/file-manager.ts
CHANGED
|
@@ -3,11 +3,13 @@ import fs from 'node:fs'
|
|
|
3
3
|
import { Context, Logger } from 'koishi'
|
|
4
4
|
import { ChatData, MessageInfo } from './types'
|
|
5
5
|
import { Config } from './config'
|
|
6
|
+
import { Utils } from './utils'
|
|
6
7
|
|
|
7
8
|
export class FileManager {
|
|
8
9
|
private dataFilePath: string
|
|
9
10
|
private fileOperationLock = Promise.resolve()
|
|
10
11
|
private logger: Logger
|
|
12
|
+
private utils: Utils
|
|
11
13
|
|
|
12
14
|
constructor(
|
|
13
15
|
private ctx: Context,
|
|
@@ -15,6 +17,7 @@ export class FileManager {
|
|
|
15
17
|
) {
|
|
16
18
|
this.dataFilePath = path.resolve(ctx.baseDir, 'data', 'chat-patch', 'chat-data.json')
|
|
17
19
|
this.logger = ctx.logger('chat-patch')
|
|
20
|
+
this.utils = new Utils(config)
|
|
18
21
|
}
|
|
19
22
|
|
|
20
23
|
// 确保目录存在
|
|
@@ -119,8 +122,11 @@ export class FileManager {
|
|
|
119
122
|
messageInfo.timestamp = Date.now()
|
|
120
123
|
}
|
|
121
124
|
|
|
125
|
+
// 清理消息中的base64内容
|
|
126
|
+
const cleanedMessageInfo = this.utils.cleanBase64Content(messageInfo) as MessageInfo
|
|
127
|
+
|
|
122
128
|
const beforeCount = data.messages[channelKey].length
|
|
123
|
-
data.messages[channelKey].push(
|
|
129
|
+
data.messages[channelKey].push(cleanedMessageInfo)
|
|
124
130
|
const afterCount = data.messages[channelKey].length
|
|
125
131
|
|
|
126
132
|
// 限制消息数量 - 保留最新的消息
|
package/src/message-handler.ts
CHANGED
|
@@ -127,12 +127,12 @@ export class MessageHandler {
|
|
|
127
127
|
timestamp: timestamp,
|
|
128
128
|
channelId: session.channelId,
|
|
129
129
|
selfId: session.selfId,
|
|
130
|
-
elements: elements,
|
|
130
|
+
elements: this.utils.cleanBase64Content(elements),
|
|
131
131
|
type: 'user',
|
|
132
132
|
guildId: session.guildId,
|
|
133
133
|
guildName: guildName,
|
|
134
134
|
platform: session.platform || 'unknown',
|
|
135
|
-
quote: quoteInfo
|
|
135
|
+
quote: quoteInfo ? this.utils.cleanBase64Content(quoteInfo) : undefined
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
await this.fileManager.addMessageToFile(messageInfo)
|
|
@@ -151,8 +151,8 @@ export class MessageHandler {
|
|
|
151
151
|
guildId: session.guildId,
|
|
152
152
|
guildName: guildName,
|
|
153
153
|
channelType: session.type || 0,
|
|
154
|
-
elements: elements,
|
|
155
|
-
quote: quoteInfo,
|
|
154
|
+
elements: this.utils.cleanBase64Content(elements),
|
|
155
|
+
quote: quoteInfo ? this.utils.cleanBase64Content(quoteInfo) : undefined,
|
|
156
156
|
bot: {
|
|
157
157
|
avatar: session.bot.user?.avatar,
|
|
158
158
|
name: session.bot.user?.name,
|
|
@@ -189,7 +189,7 @@ export class MessageHandler {
|
|
|
189
189
|
timestamp: timestamp,
|
|
190
190
|
channelId: session.event?.channel?.id || session.channelId,
|
|
191
191
|
selfId: session.selfId,
|
|
192
|
-
elements: session.event?.message?.elements,
|
|
192
|
+
elements: this.utils.cleanBase64Content(session.event?.message?.elements),
|
|
193
193
|
type: 'bot',
|
|
194
194
|
guildId: session.event?.guild?.id || session.guildId,
|
|
195
195
|
guildName: guildName,
|
|
@@ -212,7 +212,7 @@ export class MessageHandler {
|
|
|
212
212
|
guildId: session.event?.guild?.id || session.guildId,
|
|
213
213
|
guildName: guildName,
|
|
214
214
|
channelType: session.event?.channel?.type || session.type || 0,
|
|
215
|
-
elements: session.event?.message?.elements,
|
|
215
|
+
elements: this.utils.cleanBase64Content(session.event?.message?.elements),
|
|
216
216
|
bot: {
|
|
217
217
|
avatar: session.bot.user?.avatar,
|
|
218
218
|
name: session.bot.user?.name,
|
package/src/utils.ts
CHANGED
|
@@ -40,4 +40,61 @@ export class Utils {
|
|
|
40
40
|
}
|
|
41
41
|
return text
|
|
42
42
|
}
|
|
43
|
+
|
|
44
|
+
// 检查字符串是否为base64格式
|
|
45
|
+
private isBase64(str: string): boolean {
|
|
46
|
+
if (!str || typeof str !== 'string') return false
|
|
47
|
+
|
|
48
|
+
// 检查是否以data:开头的base64格式
|
|
49
|
+
if (str.startsWith('data:')) {
|
|
50
|
+
return str.includes('base64,')
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 检查纯base64字符串(长度大于100且符合base64格式)
|
|
54
|
+
if (str.length > 100) {
|
|
55
|
+
const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/
|
|
56
|
+
return base64Regex.test(str)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return false
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// 清理对象中的base64内容
|
|
63
|
+
cleanBase64Content(obj: any): any {
|
|
64
|
+
if (obj === null || obj === undefined) {
|
|
65
|
+
return obj
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (typeof obj === 'string') {
|
|
69
|
+
if (this.isBase64(obj)) {
|
|
70
|
+
return '暂不支持记录base64内容'
|
|
71
|
+
}
|
|
72
|
+
return obj
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (Array.isArray(obj)) {
|
|
76
|
+
return obj.map(item => this.cleanBase64Content(item))
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (typeof obj === 'object') {
|
|
80
|
+
const cleaned: any = {}
|
|
81
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
82
|
+
// 特别处理常见的base64字段
|
|
83
|
+
if (typeof value === 'string' && (
|
|
84
|
+
key === 'src' ||
|
|
85
|
+
key === 'url' ||
|
|
86
|
+
key === 'file' ||
|
|
87
|
+
key === 'data' ||
|
|
88
|
+
key === 'content'
|
|
89
|
+
) && this.isBase64(value)) {
|
|
90
|
+
cleaned[key] = '暂不支持记录base64内容'
|
|
91
|
+
} else {
|
|
92
|
+
cleaned[key] = this.cleanBase64Content(value)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return cleaned
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return obj
|
|
99
|
+
}
|
|
43
100
|
}
|