koishi-plugin-chat-patch 2.1.2 → 2.3.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/client/icons/activity.vue +9 -9
- package/client/icons/index.ts +4 -4
- package/client/index.scss +90 -90
- package/client/index.ts +25 -25
- package/client/vue/chat-logic.ts +683 -678
- package/client/vue/composables/useChatActions.ts +1 -1
- package/client/vue/composables/useChatData.ts +1 -1
- package/client/vue/composables/useImageCache.ts +1 -1
- package/client/vue/composables/useVideoCache.ts +130 -0
- package/client/vue/index.vue +658 -612
- package/client/vue/types.ts +1 -1
- package/dist/index.js +2 -2
- package/lib/api-handlers.d.ts +1 -0
- package/lib/file-manager.d.ts +25 -0
- package/lib/index.js +362 -200
- package/lib/message-handler.d.ts +7 -5
- package/lib/utils.d.ts +13 -0
- package/package.json +52 -52
- package/readme.md +25 -25
- package/src/api-handlers.ts +704 -704
- package/src/config.ts +45 -46
- package/src/file-manager.ts +215 -169
- package/src/index.ts +175 -125
- package/src/message-handler.ts +440 -407
- package/src/types.ts +62 -62
- package/src/utils.ts +151 -144
package/src/index.ts
CHANGED
|
@@ -1,125 +1,175 @@
|
|
|
1
|
-
|
|
2
|
-
import { Console } from '@koishijs/console'
|
|
3
|
-
import { Context, h } from 'koishi'
|
|
4
|
-
import path from 'node:path'
|
|
5
|
-
|
|
6
|
-
import { MessageHandler } from './message-handler'
|
|
7
|
-
import { FileManager } from './file-manager'
|
|
8
|
-
import { ApiHandlers } from './api-handlers'
|
|
9
|
-
import { Config } from './config'
|
|
10
|
-
import { Utils } from './utils'
|
|
11
|
-
|
|
12
|
-
export const name = 'chat-patch'
|
|
13
|
-
export const reusable = false
|
|
14
|
-
export const filter = true
|
|
15
|
-
export const inject = {
|
|
16
|
-
required: ['console']
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
declare module 'koishi' {
|
|
20
|
-
interface Context {
|
|
21
|
-
console: Console
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export const usage = `
|
|
26
|
-
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
开启后,即可在koishi控制台操作机器人收发消息啦
|
|
30
|
-
|
|
31
|
-
暂时只支持接受图文消息 / 发送文字消息
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
`
|
|
35
|
-
|
|
36
|
-
export { Config } from './config'
|
|
37
|
-
|
|
38
|
-
export async function apply(ctx: Context, config: Config) {
|
|
39
|
-
const logger = ctx.logger('chat-patch')
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
1
|
+
|
|
2
|
+
import { Console } from '@koishijs/console'
|
|
3
|
+
import { Context, h } from 'koishi'
|
|
4
|
+
import path from 'node:path'
|
|
5
|
+
|
|
6
|
+
import { MessageHandler } from './message-handler'
|
|
7
|
+
import { FileManager } from './file-manager'
|
|
8
|
+
import { ApiHandlers } from './api-handlers'
|
|
9
|
+
import { Config } from './config'
|
|
10
|
+
import { Utils } from './utils'
|
|
11
|
+
|
|
12
|
+
export const name = 'chat-patch'
|
|
13
|
+
export const reusable = false
|
|
14
|
+
export const filter = true
|
|
15
|
+
export const inject = {
|
|
16
|
+
required: ['console']
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
declare module 'koishi' {
|
|
20
|
+
interface Context {
|
|
21
|
+
console: Console
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const usage = `
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
开启后,即可在koishi控制台操作机器人收发消息啦
|
|
30
|
+
|
|
31
|
+
暂时只支持接受图文消息 / 发送文字消息
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
`
|
|
35
|
+
|
|
36
|
+
export { Config } from './config'
|
|
37
|
+
|
|
38
|
+
export async function apply(ctx: Context, config: Config) {
|
|
39
|
+
const logger = ctx.logger('chat-patch')
|
|
40
|
+
|
|
41
|
+
const mediaDir = path.join(ctx.baseDir, 'data', 'chat-patch', 'persist-media', 'media')
|
|
42
|
+
if (require('node:fs').existsSync(mediaDir)) {
|
|
43
|
+
try {
|
|
44
|
+
const files = require('node:fs').readdirSync(mediaDir)
|
|
45
|
+
let deletedCount = 0
|
|
46
|
+
for (const file of files) {
|
|
47
|
+
const filePath = path.join(mediaDir, file)
|
|
48
|
+
try {
|
|
49
|
+
require('node:fs').unlinkSync(filePath)
|
|
50
|
+
deletedCount++
|
|
51
|
+
} catch (e) {
|
|
52
|
+
logger.warn('删除媒体文件失败:', filePath, e)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (deletedCount > 0) {
|
|
56
|
+
logger.info(`启动时清理了 ${deletedCount} 个旧版本的媒体缓存文件`)
|
|
57
|
+
}
|
|
58
|
+
} catch (e) {
|
|
59
|
+
logger.warn('清理媒体文件夹失败:', e)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const fileManager = new FileManager(ctx, config)
|
|
64
|
+
const messageHandler = new MessageHandler(ctx, config, fileManager)
|
|
65
|
+
const apiHandlers = new ApiHandlers(ctx, config, fileManager, messageHandler)
|
|
66
|
+
const utils = new Utils(config, ctx)
|
|
67
|
+
|
|
68
|
+
const initialData = fileManager.readChatDataFromFile()
|
|
69
|
+
const cleanedData = fileManager.cleanExcessMessages(initialData)
|
|
70
|
+
|
|
71
|
+
const originalCount = Object.values(initialData.messages).reduce((total, msgs) => total + msgs.length, 0)
|
|
72
|
+
const cleanedCount = Object.values(cleanedData.messages).reduce((total, msgs) => total + msgs.length, 0)
|
|
73
|
+
|
|
74
|
+
if (originalCount !== cleanedCount) {
|
|
75
|
+
fileManager.writeChatDataToFile(cleanedData)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function logInfo(...args: any[]) {
|
|
79
|
+
if (config.loggerinfo) {
|
|
80
|
+
(logger.info as (...args: any[]) => void)(...args)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
logInfo('插件加载完成,数据统计:', {
|
|
85
|
+
机器人数量: Object.keys(cleanedData.bots).length,
|
|
86
|
+
频道数量: Object.keys(cleanedData.channels).reduce((total, botId) =>
|
|
87
|
+
total + Object.keys(cleanedData.channels[botId] || {}).length, 0),
|
|
88
|
+
消息频道数: Object.keys(cleanedData.messages).length,
|
|
89
|
+
总消息数: Object.values(cleanedData.messages).reduce((total, msgs) => total + msgs.length, 0)
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
ctx.on('message', (session) => {
|
|
93
|
+
if (utils.isPlatformBlocked(session.platform || 'unknown')) return
|
|
94
|
+
|
|
95
|
+
const timestamp = Date.now()
|
|
96
|
+
|
|
97
|
+
ctx.console.broadcast('chat-message-event', {
|
|
98
|
+
type: 'message',
|
|
99
|
+
selfId: session.selfId,
|
|
100
|
+
platform: session.platform || 'unknown',
|
|
101
|
+
channelId: session.channelId,
|
|
102
|
+
messageId: session.event?.message?.id || `msg-${timestamp}`,
|
|
103
|
+
content: session.content || '',
|
|
104
|
+
userId: session.userId || 'unknown',
|
|
105
|
+
username: session.username || session.userId || 'unknown',
|
|
106
|
+
avatar: session.event?.user?.avatar,
|
|
107
|
+
timestamp: timestamp,
|
|
108
|
+
isDirect: session.isDirect,
|
|
109
|
+
elements: utils.cleanBase64Content(session.elements, false),
|
|
110
|
+
bot: {
|
|
111
|
+
avatar: session.bot.user?.avatar,
|
|
112
|
+
name: session.bot.user?.name,
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
messageHandler.recordUserMessage(session, timestamp)
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
ctx.on('before-send', (session) => {
|
|
120
|
+
if (utils.isPlatformBlocked(session.platform || 'unknown')) return
|
|
121
|
+
|
|
122
|
+
const timestamp = Date.now()
|
|
123
|
+
|
|
124
|
+
ctx.console.broadcast('chat-bot-message-event', {
|
|
125
|
+
type: 'bot-message',
|
|
126
|
+
selfId: session.selfId,
|
|
127
|
+
platform: session.platform || 'unknown',
|
|
128
|
+
channelId: session.channelId,
|
|
129
|
+
messageId: `bot-msg-${timestamp}`,
|
|
130
|
+
content: session.content || '',
|
|
131
|
+
userId: session.selfId,
|
|
132
|
+
username: session.bot.user?.name || `Bot-${session.selfId}`,
|
|
133
|
+
avatar: session.bot.user?.avatar,
|
|
134
|
+
timestamp: timestamp,
|
|
135
|
+
sending: true,
|
|
136
|
+
elements: utils.cleanBase64Content(session.event?.message?.elements, true),
|
|
137
|
+
bot: {
|
|
138
|
+
avatar: session.bot.user?.avatar,
|
|
139
|
+
name: session.bot.user?.name,
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
messageHandler.recordBotMessage(session, timestamp)
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
ctx.on('ready', async () => {
|
|
147
|
+
logInfo('插件启动完成,开始监听消息')
|
|
148
|
+
|
|
149
|
+
ctx.setInterval(() => {
|
|
150
|
+
const data = fileManager.readChatDataFromFile()
|
|
151
|
+
const cleanedData = fileManager.cleanExcessMessages(data)
|
|
152
|
+
|
|
153
|
+
const originalCount = Object.values(data.messages).reduce((total, msgs) => total + msgs.length, 0)
|
|
154
|
+
const cleanedCount = Object.values(cleanedData.messages).reduce((total, msgs) => total + msgs.length, 0)
|
|
155
|
+
|
|
156
|
+
if (originalCount !== cleanedCount) {
|
|
157
|
+
fileManager.writeChatDataToFile(cleanedData)
|
|
158
|
+
logInfo('定期清理完成,清理了', originalCount - cleanedCount, '条超量消息')
|
|
159
|
+
}
|
|
160
|
+
}, 300000)
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
apiHandlers.registerApiHandlers()
|
|
164
|
+
|
|
165
|
+
ctx.console.addEntry({
|
|
166
|
+
dev: path.resolve(__dirname, '../client/index.ts'),
|
|
167
|
+
prod: path.resolve(__dirname, '../dist'),
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
ctx.on('dispose', () => {
|
|
171
|
+
|
|
172
|
+
fileManager.dispose()
|
|
173
|
+
logInfo('插件已卸载,所有待处理的消息已写入')
|
|
174
|
+
})
|
|
175
|
+
}
|