node-karin 0.0.3

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.
Files changed (107) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +57 -0
  3. package/config/defSet/App.yaml +37 -0
  4. package/config/defSet/config.yaml +43 -0
  5. package/config/defSet/group.yaml +18 -0
  6. package/config/defSet/pm2.yaml +21 -0
  7. package/config/defSet/redis.yaml +18 -0
  8. package/config/defSet/server.yaml +42 -0
  9. package/config/view/App.yaml +74 -0
  10. package/config/view/config.yaml +100 -0
  11. package/config/view/group.yaml +62 -0
  12. package/config/view/pm2.yaml +41 -0
  13. package/config/view/redis.yaml +25 -0
  14. package/config/view/server.yaml +93 -0
  15. package/lib/adapter/onebot/onebot11.d.ts +430 -0
  16. package/lib/adapter/onebot/onebot11.js +1302 -0
  17. package/lib/core/init.d.ts +0 -0
  18. package/lib/core/init.js +4 -0
  19. package/lib/core/karin.d.ts +72 -0
  20. package/lib/core/karin.js +51 -0
  21. package/lib/core/listener.d.ts +121 -0
  22. package/lib/core/listener.js +188 -0
  23. package/lib/core/plugin.app.d.ts +15 -0
  24. package/lib/core/plugin.app.js +18 -0
  25. package/lib/core/plugin.d.ts +182 -0
  26. package/lib/core/plugin.js +138 -0
  27. package/lib/core/plugin.loader.d.ts +149 -0
  28. package/lib/core/plugin.loader.js +462 -0
  29. package/lib/core/server.d.ts +26 -0
  30. package/lib/core/server.js +213 -0
  31. package/lib/db/level.d.ts +20 -0
  32. package/lib/db/level.js +38 -0
  33. package/lib/db/redis.d.ts +41 -0
  34. package/lib/db/redis.js +137 -0
  35. package/lib/db/redis_level.d.ts +113 -0
  36. package/lib/db/redis_level.js +290 -0
  37. package/lib/event/event.d.ts +138 -0
  38. package/lib/event/event.handler.d.ts +29 -0
  39. package/lib/event/event.handler.js +142 -0
  40. package/lib/event/event.js +120 -0
  41. package/lib/event/message.d.ts +102 -0
  42. package/lib/event/message.handler.d.ts +25 -0
  43. package/lib/event/message.handler.js +240 -0
  44. package/lib/event/message.js +70 -0
  45. package/lib/event/notice.d.ts +49 -0
  46. package/lib/event/notice.js +15 -0
  47. package/lib/event/request.d.ts +49 -0
  48. package/lib/event/request.js +15 -0
  49. package/lib/event/review.handler.d.ts +54 -0
  50. package/lib/event/review.handler.js +382 -0
  51. package/lib/index.d.ts +23 -0
  52. package/lib/index.js +40 -0
  53. package/lib/renderer/app.d.ts +53 -0
  54. package/lib/renderer/app.js +93 -0
  55. package/lib/renderer/base.d.ts +30 -0
  56. package/lib/renderer/base.js +71 -0
  57. package/lib/renderer/client.d.ts +30 -0
  58. package/lib/renderer/client.js +159 -0
  59. package/lib/renderer/http.d.ts +19 -0
  60. package/lib/renderer/http.js +51 -0
  61. package/lib/renderer/server.d.ts +42 -0
  62. package/lib/renderer/server.js +112 -0
  63. package/lib/renderer/wormhole.d.ts +1 -0
  64. package/lib/renderer/wormhole.js +154 -0
  65. package/lib/types/adapter.d.ts +575 -0
  66. package/lib/types/adapter.js +1 -0
  67. package/lib/types/config.d.ts +327 -0
  68. package/lib/types/config.js +1 -0
  69. package/lib/types/element.d.ts +576 -0
  70. package/lib/types/element.js +1 -0
  71. package/lib/types/index.d.ts +8 -0
  72. package/lib/types/index.js +8 -0
  73. package/lib/types/logger.d.ts +109 -0
  74. package/lib/types/logger.js +1 -0
  75. package/lib/types/onebots11.d.ts +1371 -0
  76. package/lib/types/onebots11.js +1 -0
  77. package/lib/types/plugin.d.ts +282 -0
  78. package/lib/types/plugin.js +1 -0
  79. package/lib/types/render.d.ts +111 -0
  80. package/lib/types/render.js +1 -0
  81. package/lib/types/reply.d.ts +40 -0
  82. package/lib/types/reply.js +1 -0
  83. package/lib/types/types.d.ts +898 -0
  84. package/lib/types/types.js +1 -0
  85. package/lib/utils/YamlEditor.d.ts +62 -0
  86. package/lib/utils/YamlEditor.js +208 -0
  87. package/lib/utils/button.d.ts +49 -0
  88. package/lib/utils/button.js +79 -0
  89. package/lib/utils/common.d.ts +123 -0
  90. package/lib/utils/common.js +413 -0
  91. package/lib/utils/config.d.ts +72 -0
  92. package/lib/utils/config.js +254 -0
  93. package/lib/utils/exec.d.ts +22 -0
  94. package/lib/utils/exec.js +36 -0
  95. package/lib/utils/ffmpeg.d.ts +12 -0
  96. package/lib/utils/ffmpeg.js +25 -0
  97. package/lib/utils/handler.d.ts +76 -0
  98. package/lib/utils/handler.js +102 -0
  99. package/lib/utils/logger.d.ts +3 -0
  100. package/lib/utils/logger.js +104 -0
  101. package/lib/utils/segment.d.ts +276 -0
  102. package/lib/utils/segment.js +448 -0
  103. package/lib/utils/update.d.ts +69 -0
  104. package/lib/utils/update.js +151 -0
  105. package/lib/utils/updateVersion.d.ts +33 -0
  106. package/lib/utils/updateVersion.js +145 -0
  107. package/package.json +92 -0
@@ -0,0 +1,240 @@
1
+ import lodash from 'lodash'
2
+ import Config from '../utils/config.js'
3
+ import logger from '../utils/logger.js'
4
+ import Review from './review.handler.js'
5
+ import Listener from '../core/listener.js'
6
+ import { stateArr } from '../core/plugin.js'
7
+ import EventHandler from './event.handler.js'
8
+ import PluginLoader from '../core/plugin.loader.js'
9
+ /**
10
+ * 消息事件
11
+ */
12
+ export default class Message extends EventHandler {
13
+ e
14
+ /**
15
+ * - 是否打印群消息日志
16
+ */
17
+ GroupMsgPrint = false
18
+ constructor (e) {
19
+ super(e)
20
+ this.e = e
21
+ Listener.emit('karin:count:recv', 1)
22
+ /** 处理消息 保证日志的打印 */
23
+ this.dealMsg()
24
+ /** 事件处理 */
25
+ if (this.review()) { return }
26
+ /** 响应模式 */
27
+ if (this.e.group_id && 'mode' in this.config && this.config.mode && !Review.mode(this.e, this.config)) {
28
+ logger.debug('[消息拦截] 响应模式不匹配')
29
+ return
30
+ }
31
+ this.GroupMsgPrint = false
32
+ /** 处理回复 */
33
+ this.reply()
34
+ /** 处理消息 */
35
+ this.deal()
36
+ }
37
+
38
+ /**
39
+ * 处理消息
40
+ */
41
+ async deal () {
42
+ /** 上下文 */
43
+ if (await this.context()) { return }
44
+ /* eslint-disable no-labels */
45
+ a: for (const index of PluginLoader.rule) {
46
+ const app = PluginLoader.PluginList[index]
47
+ /** 判断事件 */
48
+ if (app.event && !this.filtEvent(app.event)) { continue }
49
+ /** 正则匹配 */
50
+ for (const v of app.rule) {
51
+ /** 这里的lastIndex是为了防止正则无法从头开始匹配 */
52
+ v.reg.lastIndex = 0
53
+ if (v.reg.test(this.e.msg)) {
54
+ /** 检查黑白名单插件 */
55
+ if ('GroupCD' in this.config && !Review.PluginEnable(app, this.config)) { continue }
56
+ /** 判断子事件 */
57
+ if (v.event && !this.filtEvent(v.event)) { continue }
58
+ this.e.logFnc = `[${app.file.dir}][${app.name}][${v.fnc}]`
59
+ const logFnc = logger.fnc(`[${app.name}][${v.fnc}]`)
60
+ this.GroupMsgPrint && typeof v.log === 'function' && v.log(this.e.self_id, `${logFnc}${this.e.logText} ${lodash.truncate(this.e.msg, { length: 80 })}`)
61
+ /** 判断权限 */
62
+ if (!this.filterPermission(v.permission)) { break a }
63
+ try {
64
+ let res
65
+ if (app.file.type === 'function' && typeof v.fnc === 'function') {
66
+ res = v.fnc(this.e)
67
+ } else {
68
+ const cla = new app.file.Fnc()
69
+ cla.e = this.e
70
+ res = cla[v.fnc](this.e)
71
+ }
72
+ /** 计算插件处理时间 */
73
+ const start = Date.now()
74
+ Listener.emit('karin:count:fnc', this.e.logFnc)
75
+ res = await res
76
+ this.GroupMsgPrint && typeof v.log === 'function' && v.log(this.e.self_id, `${logFnc} ${lodash.truncate(this.e.msg, { length: 80 })} 处理完成 ${logger.green(Date.now() - start + 'ms')}`)
77
+ if (res !== false) { break a }
78
+ } catch (error) {
79
+ logger.error(`${this.e.logFnc}`)
80
+ logger.error(error.stack || error.message || JSON.stringify(error))
81
+ break a
82
+ }
83
+ }
84
+ }
85
+ }
86
+ }
87
+
88
+ /**
89
+ * 处理消息体
90
+ */
91
+ dealMsg () {
92
+ const logs = []
93
+ for (const val of this.e.elements) {
94
+ switch (val.type) {
95
+ case 'text': {
96
+ const msg = (val.text || '')
97
+ .replace(/^\s*[#井#]+\s*/, '#')
98
+ .replace(/^\s*[\\*※*]+\s*/, '*')
99
+ .trim()
100
+ this.e.msg += msg
101
+ /** 美观一点... */
102
+ logs.push(msg)
103
+ break
104
+ }
105
+ case 'face':
106
+ logs.push(`[face:${val.id}]`)
107
+ break
108
+ case 'video':
109
+ case 'record':
110
+ logs.push(`[${val.type}:${val.file}]`)
111
+ break
112
+ case 'image':
113
+ this.e.image.push(val.file)
114
+ logs.push(`[image:${val.file}]`)
115
+ break
116
+ case 'file':
117
+ this.e.file = val
118
+ logs.push(`[file:${val.file}]`)
119
+ break
120
+ case 'at':
121
+ /** atBot不计入e.at */
122
+ // eslint-disable-next-line eqeqeq
123
+ if (val.uid && val.uid == this.e.bot.account.uid) {
124
+ this.e.atBot = true
125
+ // eslint-disable-next-line eqeqeq
126
+ } else if (val.uin == this.e.bot.account.uin) {
127
+ this.e.atBot = true
128
+ } else if (val.uid && val.uid === 'all') {
129
+ this.e.atAll = true
130
+ } else {
131
+ const id = (val.uid || val.uin)
132
+ this.e.at.push(id)
133
+ }
134
+ logs.push(`[at:${val.uid || val.uin}]`)
135
+ break
136
+ case 'rps':
137
+ logs.push(`[rps:${val.id}]`)
138
+ break
139
+ case 'dice':
140
+ logs.push(`[dice:${val.id}]`)
141
+ break
142
+ case 'poke':
143
+ logs.push(`[poke:${val.id}]`)
144
+ break
145
+ case 'share':
146
+ logs.push(`[share:${val.url}]`)
147
+ break
148
+ case 'contact':
149
+ logs.push(`[contact:${val.peer}]`)
150
+ break
151
+ case 'location':
152
+ logs.push(`[location:${val.lat}-${val.lon}]`)
153
+ break
154
+ case 'music':
155
+ logs.push(`[music:${JSON.stringify(val)}]`)
156
+ break
157
+ case 'reply':
158
+ this.e.reply_id = val.message_id
159
+ logs.push(`[reply:${val.message_id}]`)
160
+ break
161
+ case 'forward':
162
+ logs.push(`[forward:${val.res_id}]`)
163
+ break
164
+ case 'xml':
165
+ this.e.msg += val.data
166
+ logs.push(`[xml:${val.data}]`)
167
+ break
168
+ case 'json':
169
+ this.e.msg += val.data
170
+ logs.push(`[json:${JSON.stringify(val.data)}]`)
171
+ break
172
+ case 'markdown': {
173
+ if (val.content) {
174
+ logs.push(`[markdown:${val.content}]`)
175
+ } else {
176
+ const content = { id: val.custom_template_id }
177
+ for (const v of val.params) { content[v.key] = v.values[0] }
178
+ logs.push(`[markdown:${JSON.stringify(content)}]`)
179
+ }
180
+ break
181
+ }
182
+ case 'rows': {
183
+ const rows = []
184
+ for (const v of val.rows) { rows.push(JSON.stringify(v.data)) }
185
+ logs.push(`[rows:${JSON.stringify(rows)}]`)
186
+ break
187
+ }
188
+ case 'button':
189
+ logs.push(`[button:${JSON.stringify(val.data)}]`)
190
+ break
191
+ default:
192
+ logs.push(`[未知:${JSON.stringify(val)}]`)
193
+ }
194
+ }
195
+ this.e.raw_message = logs.join('')
196
+ /** 前缀处理 */
197
+ this.e.group_id && 'GroupCD' in this.config && Review.alias(this.e, this.config)
198
+ /** 主人 这里强制是因为yaml在自动保存QQ号的时候会强制化为数字 */
199
+ const masterId = (Number(this.e.user_id) || String(this.e.user_id))
200
+ if (Config.master.includes(masterId)) {
201
+ this.e.isMaster = true
202
+ this.e.isAdmin = true
203
+ } else if (Config.admin.includes(masterId)) {
204
+ /** 管理员 */
205
+ this.e.isAdmin = true
206
+ }
207
+ this.GroupMsgPrint = false
208
+ if (this.e.contact.scene === 'private') {
209
+ this.e.isPrivate = true
210
+ this.e.logText = `[Private:${this.e.sender.nick || ''}(${this.e.user_id})]`
211
+ logger.bot('info', this.e.self_id, `私聊:[${this.e.user_id}(${this.e.sender.nick || ''})] ${this.e.raw_message}`)
212
+ } else if (this.e.contact.scene === 'group') {
213
+ this.e.isGroup = true
214
+ this.e.logText = `[Group:${this.e.group_id}-${this.e.user_id}(${this.e.sender.nick || ''})]`
215
+ this.GroupMsgPrint = Review.GroupMsgPrint(this.e)
216
+ this.GroupMsgPrint && logger.bot('info', this.e.self_id, `群消息:[${this.e.group_id}-${this.e.user_id}(${this.e.sender.nick || ''})] ${this.e.raw_message}`)
217
+ } else {
218
+ logger.bot('info', this.e.self_id, `未知消息:${JSON.stringify(this.e)}`)
219
+ }
220
+ }
221
+
222
+ /**
223
+ * 处理上下文
224
+ */
225
+ async context () {
226
+ const key = this.e.isGroup ? `${this.e.group_id}.${this.e.user_id}` : this.e.user_id
227
+ const App = stateArr[key]
228
+ if (App) {
229
+ const { plugin, fnc } = App
230
+ this.e.logFnc = `[${plugin.name}][${fnc}]`
231
+ /** 计算插件处理时间 */
232
+ const start = Date.now()
233
+ plugin.e = this.e
234
+ await plugin[fnc]()
235
+ logger.bot('mark', this.e.self_id, `${this.e.logFnc} 上下文处理完成 ${Date.now() - start}ms`)
236
+ return true
237
+ }
238
+ return false
239
+ }
240
+ }
@@ -0,0 +1,70 @@
1
+ import { KarinEvent } from './event.js'
2
+ /**
3
+ * - 消息事件基类
4
+ */
5
+ export class KarinMessage extends KarinEvent {
6
+ constructor ({ event = 'message', self_id, user_id, time, message_id, message_seq = '', raw_message = '', contact, sender, elements, group_id = '' }) {
7
+ super({ event, event_id: message_id, self_id, user_id, group_id, time, contact, sender, sub_event: contact.scene === 'group' ? 'group_message' : 'friend_message' })
8
+ this.message_id = message_id
9
+ this.message_seq = message_seq
10
+ this.raw_message = raw_message
11
+ this.elements = elements
12
+ this.msg = ''
13
+ this.at = []
14
+ this.image = []
15
+ this.file = {}
16
+ this.reply_id = ''
17
+ this.atBot = false
18
+ this.atAll = false
19
+ this.alias = ''
20
+ }
21
+
22
+ /**
23
+ * - 消息ID
24
+ */
25
+ message_id
26
+ /**
27
+ * - 消息序列号
28
+ */
29
+ message_seq
30
+ /**
31
+ * - 原始消息文本
32
+ */
33
+ raw_message
34
+ /**
35
+ * - 消息体元素
36
+ */
37
+ elements
38
+ /**
39
+ * - 框架处理后的文本
40
+ */
41
+ msg
42
+ /**
43
+ * - 图片数组
44
+ */
45
+ image
46
+ /**
47
+ * - AT数组
48
+ */
49
+ at
50
+ /**
51
+ * - 是否AT机器人
52
+ */
53
+ atBot
54
+ /**
55
+ * - 是否AT全体
56
+ */
57
+ atAll
58
+ /**
59
+ * - 文件元素
60
+ */
61
+ file
62
+ /**
63
+ * - 引用消息ID
64
+ */
65
+ reply_id
66
+ /**
67
+ * - 消息别名
68
+ */
69
+ alias
70
+ }
@@ -0,0 +1,49 @@
1
+ import { KarinEvent } from './event.js';
2
+ import { contact, Sender, SubEventForEvent, NoticeEvent } from '../types/types.js';
3
+ /**
4
+ * - 通知事件基类
5
+ */
6
+ export declare class KarinNotice extends KarinEvent {
7
+ constructor({ self_id, event_id, user_id, time, contact, sender, sub_event, content, group_id, }: {
8
+ /**
9
+ * - 机器人ID 请尽量使用UID
10
+ */
11
+ self_id: string;
12
+ /**
13
+ * - 事件ID
14
+ */
15
+ event_id: string;
16
+ /**
17
+ * - 用户ID
18
+ */
19
+ user_id: string;
20
+ /**
21
+ * - 事件触发时间戳
22
+ */
23
+ time: number;
24
+ /**
25
+ * 事件联系人信息
26
+ */
27
+ contact: contact;
28
+ /**
29
+ * 事件发送者信息
30
+ */
31
+ sender: Sender;
32
+ /**
33
+ * 事件子类型
34
+ */
35
+ sub_event: SubEventForEvent<'notice'>;
36
+ /**
37
+ * 事件对应的内容参数
38
+ */
39
+ content: NoticeEvent<SubEventForEvent<'notice'>>;
40
+ /**
41
+ * 群ID
42
+ */
43
+ group_id?: string;
44
+ });
45
+ /**
46
+ * - 事件对应的内容参数
47
+ */
48
+ content: NoticeEvent<SubEventForEvent<'notice'>>;
49
+ }
@@ -0,0 +1,15 @@
1
+ import { KarinEvent } from './event.js'
2
+ /**
3
+ * - 通知事件基类
4
+ */
5
+ export class KarinNotice extends KarinEvent {
6
+ constructor ({ self_id, event_id, user_id, time, contact, sender, sub_event, content, group_id = '' }) {
7
+ super({ event: 'notice', event_id, self_id, user_id, group_id, time, contact, sender, sub_event })
8
+ this.content = content
9
+ }
10
+
11
+ /**
12
+ * - 事件对应的内容参数
13
+ */
14
+ content
15
+ }
@@ -0,0 +1,49 @@
1
+ import { KarinEvent } from './event.js';
2
+ import { contact, Sender, SubEventForEvent, RequestEvent } from '../types/types.js';
3
+ /**
4
+ * - 请求事件基类
5
+ */
6
+ export declare class KarinRequest extends KarinEvent {
7
+ constructor({ self_id, event_id, user_id, time, contact, sender, sub_event, content, group_id, }: {
8
+ /**
9
+ * - 机器人ID 请尽量使用UID
10
+ */
11
+ self_id: string;
12
+ /**
13
+ * - 事件ID
14
+ */
15
+ event_id: string;
16
+ /**
17
+ * - 用户ID
18
+ */
19
+ user_id: string;
20
+ /**
21
+ * - 事件触发时间戳
22
+ */
23
+ time: number;
24
+ /**
25
+ * 事件联系人信息
26
+ */
27
+ contact: contact;
28
+ /**
29
+ * 事件发送者信息
30
+ */
31
+ sender: Sender;
32
+ /**
33
+ * 事件子类型
34
+ */
35
+ sub_event: SubEventForEvent<'request'>;
36
+ /**
37
+ * 事件对应的内容参数
38
+ */
39
+ content: RequestEvent<SubEventForEvent<'request'>>;
40
+ /**
41
+ * 群ID
42
+ */
43
+ group_id?: string;
44
+ });
45
+ /**
46
+ * - 事件对应的内容参数
47
+ */
48
+ content: RequestEvent<SubEventForEvent<'request'>>;
49
+ }
@@ -0,0 +1,15 @@
1
+ import { KarinEvent } from './event.js'
2
+ /**
3
+ * - 请求事件基类
4
+ */
5
+ export class KarinRequest extends KarinEvent {
6
+ constructor ({ self_id, event_id, user_id, time, contact, sender, sub_event, content, group_id = '' }) {
7
+ super({ event: 'request', event_id, self_id, user_id, group_id, time, contact, sender, sub_event })
8
+ this.content = content
9
+ }
10
+
11
+ /**
12
+ * - 事件对应的内容参数
13
+ */
14
+ content
15
+ }
@@ -0,0 +1,54 @@
1
+ import { E } from '../types/types.js';
2
+ import { PluginApps } from '../types/plugin.js';
3
+ import { GroupCfg } from '../types/config.js';
4
+ import { KarinMessage } from '../event/message.js';
5
+ /**
6
+ * 事件拦截器
7
+ * 利用可执行函数的特性,热更新所有拦截器
8
+ * 所有拦截器返回的都是布尔值 为true说明通过 为false则未通过
9
+ */
10
+ declare const _default: {
11
+ GroupCD: {
12
+ [key: string]: boolean;
13
+ };
14
+ GroupUserCD: {
15
+ [key: string]: boolean;
16
+ };
17
+ App: import("../types/config.js").App;
18
+ Config: import("../types/config.js").Config;
19
+ CD: (e: E, config: GroupCfg) => boolean;
20
+ mode: (e: KarinMessage, config: GroupCfg) => boolean;
21
+ alias: (e: KarinMessage, config: GroupCfg) => boolean;
22
+ GroupEnable: (e: E) => boolean;
23
+ UserEnable: (e: E) => boolean;
24
+ GroupMsgPrint: (e: E) => boolean;
25
+ PluginEnable: (app: PluginApps, config: GroupCfg) => boolean;
26
+ main(): void;
27
+ /**
28
+ * 群聊黑白名单 允许哪个群触发事件
29
+ */
30
+ "__#2@#GroupEnable"(): true | undefined;
31
+ /**
32
+ * 用户黑白名单 允许那个用户触发事件
33
+ */
34
+ "__#2@#UserEnable"(): true | undefined;
35
+ /**
36
+ * 群聊事件日志 是否打印
37
+ */
38
+ "__#2@#GroupMsgPrint"(): true | undefined;
39
+ /**
40
+ * 黑白名单插件 哪个插件可以被触发
41
+ */
42
+ "__#2@#PluginEnable"(): boolean;
43
+ /** 群聊cd */
44
+ "__#2@#CD"(): true | undefined;
45
+ /**
46
+ * 响应模式
47
+ */
48
+ "__#2@#mode"(): true | undefined;
49
+ /**
50
+ * 前缀、别名
51
+ */
52
+ "__#2@#alias"(): true | undefined;
53
+ };
54
+ export default _default;