node-karin 0.3.9 → 0.5.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.
Files changed (56) hide show
  1. package/config/defSet/config.yaml +11 -0
  2. package/lib/adapter/input/index.d.ts +63 -0
  3. package/lib/adapter/input/index.js +188 -0
  4. package/lib/adapter/onebot/onebot11.d.ts +12 -138
  5. package/lib/adapter/onebot/onebot11.js +70 -50
  6. package/lib/core/index.d.ts +1 -0
  7. package/lib/core/index.js +1 -0
  8. package/lib/core/karin.d.ts +45 -4
  9. package/lib/core/karin.js +52 -1
  10. package/lib/core/listener.js +6 -2
  11. package/lib/core/plugin.app.d.ts +4 -1
  12. package/lib/core/plugin.app.js +3 -3
  13. package/lib/core/plugin.d.ts +8 -2
  14. package/lib/core/plugin.loader.d.ts +7 -0
  15. package/lib/core/plugin.loader.js +49 -12
  16. package/lib/core/server.js +26 -0
  17. package/lib/db/index.d.ts +2 -4
  18. package/lib/db/index.js +2 -4
  19. package/lib/db/level.d.ts +1 -0
  20. package/lib/db/level.js +1 -0
  21. package/lib/db/redis.d.ts +2 -41
  22. package/lib/db/redis.js +2 -3
  23. package/lib/event/event.d.ts +7 -3
  24. package/lib/event/event.handler.d.ts +7 -6
  25. package/lib/event/event.handler.js +6 -1
  26. package/lib/event/event.js +6 -1
  27. package/lib/event/index.js +2 -2
  28. package/lib/event/message.handler.d.ts +3 -3
  29. package/lib/event/message.handler.js +8 -11
  30. package/lib/event/notice.d.ts +4 -4
  31. package/lib/event/notice.handler.d.ts +17 -0
  32. package/lib/event/notice.handler.js +203 -0
  33. package/lib/event/request.d.ts +4 -4
  34. package/lib/event/request.handler.d.ts +17 -0
  35. package/lib/event/request.handler.js +109 -0
  36. package/lib/event/request.js +1 -0
  37. package/lib/event/review.handler.js +12 -24
  38. package/lib/index.d.ts +2 -1
  39. package/lib/types/adapter.d.ts +3 -2
  40. package/lib/types/api.d.ts +295 -0
  41. package/lib/types/api.js +1 -0
  42. package/lib/types/config.d.ts +21 -0
  43. package/lib/types/event.d.ts +127 -241
  44. package/lib/types/index.d.ts +1 -0
  45. package/lib/types/index.js +1 -0
  46. package/lib/types/plugin.d.ts +4 -4
  47. package/lib/utils/button.d.ts +2 -2
  48. package/lib/utils/common.d.ts +5 -6
  49. package/lib/utils/common.js +3 -4
  50. package/lib/utils/config.d.ts +5 -2
  51. package/lib/utils/config.js +43 -17
  52. package/lib/utils/handler.d.ts +5 -12
  53. package/lib/utils/handler.js +3 -1
  54. package/lib/utils/yamlEditor.d.ts +1 -1
  55. package/package.json +4 -3
  56. package/lib/utils/kritor-proto.d.ts +0 -1
package/lib/db/redis.d.ts CHANGED
@@ -1,41 +1,2 @@
1
- import RedisLevel from './redis_level.js';
2
- import redis from 'redis';
3
- export default class Redis {
4
- id: 'redis';
5
- RunCmd: string;
6
- constructor();
7
- /**
8
- * redis实例化
9
- */
10
- start(): Promise<(redis.RedisClientType | string) | RedisLevel | false>;
11
- /**
12
- * 降级为 LevelDB
13
- */
14
- LevelDB(): Promise<false | RedisLevel>;
15
- /**
16
- * 连接 Redis 单例
17
- * @param {import("redis").RedisClientOptions} options
18
- * @return {Promise<{status: 'ok', data: import("redis").RedisClientType} | {status: 'error', data: Error}>}
19
- */
20
- connect(options: redis.RedisClientOptions): Promise<{
21
- status: 'ok';
22
- data: redis.RedisClientType;
23
- } | {
24
- status: 'error';
25
- data: string;
26
- }>;
27
- /**
28
- * 连接 Redis 集群
29
- */
30
- connectCluster(rootNodes: {
31
- url: string;
32
- }[]): Promise<{
33
- status: string;
34
- data: unknown;
35
- }>;
36
- /**
37
- * 判断是否为 ARM64 并返回参数
38
- */
39
- aarch64(): Promise<string>;
40
- execSync(cmd: string): Promise<string>;
41
- }
1
+ import { RedisClientType } from 'redis';
2
+ export declare const redis: RedisClientType;
package/lib/db/redis.js CHANGED
@@ -2,7 +2,7 @@ import { exec } from 'child_process'
2
2
  import RedisLevel from './redis_level.js'
3
3
  import { logger, config } from '../utils/index.js'
4
4
  import { createClient, createCluster } from 'redis'
5
- export default class Redis {
5
+ class Redis {
6
6
  id
7
7
  RunCmd
8
8
  constructor () {
@@ -76,8 +76,6 @@ export default class Redis {
76
76
 
77
77
  /**
78
78
  * 连接 Redis 单例
79
- * @param {import("redis").RedisClientOptions} options
80
- * @return {Promise<{status: 'ok', data: import("redis").RedisClientType} | {status: 'error', data: Error}>}
81
79
  */
82
80
  async connect (options) {
83
81
  const client = createClient(options)
@@ -134,3 +132,4 @@ export default class Redis {
134
132
  })
135
133
  }
136
134
  }
135
+ export const redis = await new Redis().start()
@@ -1,4 +1,4 @@
1
- import { KarinAdapter, Reply, replyCallback, Event, contact, Sender, SubEventForEvent } from '../types/index.js';
1
+ import { KarinAdapter, Reply, replyCallback, Event, contact, Sender, EventToSubEvent } from '../types/index.js';
2
2
  /**
3
3
  * - 事件基类 所有事件都继承自此类并且需要实现此类的所有属性
4
4
  * @class KarinEvent
@@ -24,7 +24,7 @@ export declare class KarinEvent {
24
24
  /**
25
25
  * - 事件子类型
26
26
  */
27
- sub_event: SubEventForEvent<Event>;
27
+ sub_event: EventToSubEvent[Event];
28
28
  /**
29
29
  * - 事件ID
30
30
  */
@@ -83,6 +83,10 @@ export declare class KarinEvent {
83
83
  * - 存储器 由开发者自行调用
84
84
  */
85
85
  store: Map<string, any>;
86
+ /**
87
+ * - 原始消息
88
+ */
89
+ raw_message: string;
86
90
  /**
87
91
  * - 回复函数
88
92
  */
@@ -127,7 +131,7 @@ export declare class KarinEvent {
127
131
  /**
128
132
  * - 事件子类型
129
133
  */
130
- sub_event: SubEventForEvent<Event>;
134
+ sub_event: EventToSubEvent[Event];
131
135
  /**
132
136
  * - 事件ID
133
137
  */
@@ -1,14 +1,15 @@
1
- import { KarinMessage } from './message.js';
2
- import { KarinNotice } from './notice.js';
3
- import { KarinRequest } from './request.js';
4
- import { Event, Permission, SubEvent, GroupCfg } from '../types/index.js';
1
+ import { Event, Permission, SubEvent, GroupCfg, KarinMessageEvent, KarinNoticeEvent, KarinRequestEvent } from '../types/index.js';
5
2
  export default class EventHandler {
6
- e: KarinMessage | KarinNotice | KarinRequest;
3
+ e: KarinMessageEvent | KarinNoticeEvent | KarinRequestEvent;
7
4
  config: GroupCfg | {};
5
+ /**
6
+ * - 是否打印群消息日志
7
+ */
8
+ GroupMsgPrint: boolean;
8
9
  /**
9
10
  * 处理事件,加入自定义字段
10
11
  */
11
- constructor(e: KarinMessage | KarinNotice | KarinRequest);
12
+ constructor(e: KarinMessageEvent | KarinNoticeEvent | KarinRequestEvent);
12
13
  /**
13
14
  * 事件处理
14
15
  */
@@ -4,12 +4,17 @@ import { segment, common, logger, config } from '../utils/index.js'
4
4
  export default class EventHandler {
5
5
  e
6
6
  config
7
+ /**
8
+ * - 是否打印群消息日志
9
+ */
10
+ GroupMsgPrint
7
11
  /**
8
12
  * 处理事件,加入自定义字段
9
13
  */
10
14
  constructor (e) {
11
15
  this.e = e
12
16
  this.config = {}
17
+ this.GroupMsgPrint = false
13
18
  /** 加入e.bot */
14
19
  Object.defineProperty(this.e, 'bot', { value: listener.getBot(this.e.self_id) })
15
20
  if (this.e.group_id) { this.config = config.group(this.e.group_id) }
@@ -115,7 +120,7 @@ export default class EventHandler {
115
120
  if (this.e.isGroup) {
116
121
  review.GroupMsgPrint(this.e) && logger.bot('info', this.e.self_id, `${logger.green(`Send Group ${this.e.group_id}: `)}${ReplyLog}`)
117
122
  } else {
118
- logger.bot('info', this.e.self_id, `${logger.green(`Send private ${this.e.user_id}: `)}${ReplyLog}`)
123
+ this.e.self_id === 'input' && logger.bot('info', this.e.self_id, `${logger.green(`Send private ${this.e.user_id}: `)}${ReplyLog}`)
119
124
  }
120
125
  let message_id = ''
121
126
  try {
@@ -82,6 +82,10 @@ export class KarinEvent {
82
82
  * - 存储器 由开发者自行调用
83
83
  */
84
84
  store
85
+ /**
86
+ * - 原始消息
87
+ */
88
+ raw_message
85
89
  /**
86
90
  * - 回复函数
87
91
  */
@@ -97,7 +101,7 @@ export class KarinEvent {
97
101
  constructor ({ event, self_id, user_id, group_id = '', time, contact, sender, sub_event, event_id }) {
98
102
  this.self_id = self_id
99
103
  this.user_id = user_id
100
- this.group_id = group_id
104
+ this.group_id = contact.scene === 'group' ? (contact.peer || group_id) : group_id
101
105
  this.time = time
102
106
  this.event = event
103
107
  this.event_id = event_id
@@ -113,6 +117,7 @@ export class KarinEvent {
113
117
  this.logFnc = ''
114
118
  this.logText = ''
115
119
  this.store = new Map()
120
+ this.raw_message = ''
116
121
  this.reply = (elements, options) => Promise.resolve({ message_id: '' })
117
122
  this.replyCallback = (elements, options) => Promise.resolve({ message_id: '' })
118
123
  this.bot = {}
@@ -3,7 +3,7 @@ export * from './event.handler.js'
3
3
  export * from './message.js'
4
4
  export * from './message.handler.js'
5
5
  export * from './notice.js'
6
- // export * from './notice.handler'
6
+ // export * from './notice.handler.js'
7
7
  export * from './request.js'
8
- // export * from './request.handler'
8
+ // export * from './request.handler.js'
9
9
  export * from './review.handler.js'
@@ -1,15 +1,15 @@
1
- import { KarinMessage } from './message.js';
2
1
  import EventHandler from './event.handler.js';
2
+ import { KarinMessageEvent } from '../types/index.js';
3
3
  /**
4
4
  * 消息事件
5
5
  */
6
6
  export declare class MessageHandler extends EventHandler {
7
- e: KarinMessage;
7
+ e: KarinMessageEvent;
8
8
  /**
9
9
  * - 是否打印群消息日志
10
10
  */
11
11
  GroupMsgPrint: boolean;
12
- constructor(e: KarinMessage);
12
+ constructor(e: KarinMessageEvent);
13
13
  /**
14
14
  * 处理消息
15
15
  */
@@ -56,19 +56,18 @@ export class MessageHandler extends EventHandler {
56
56
  this.GroupMsgPrint && typeof v.log === 'function' && v.log(this.e.self_id, `${logFnc}${this.e.logText} ${lodash.truncate(this.e.msg, { length: 80 })}`)
57
57
  /** 判断权限 */
58
58
  if (!this.filterPermission(v.permission)) { break a }
59
+ /** 计算插件处理时间 */
60
+ const start = Date.now()
61
+ listener.emit('karin:count:fnc', this.e.logFnc)
59
62
  try {
60
63
  let res
61
64
  if (app.file.type === 'function' && typeof v.fnc === 'function') {
62
- res = v.fnc(this.e)
65
+ res = await v.fnc(this.e)
63
66
  } else {
64
67
  const cla = new app.file.Fnc()
65
68
  cla.e = this.e
66
- res = cla[v.fnc](this.e)
69
+ res = await cla[v.fnc](this.e)
67
70
  }
68
- /** 计算插件处理时间 */
69
- const start = Date.now()
70
- listener.emit('karin:count:fnc', this.e.logFnc)
71
- res = await res
72
71
  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')}`)
73
72
  if (res !== false) { break a }
74
73
  } catch (error) {
@@ -191,16 +190,14 @@ export class MessageHandler extends EventHandler {
191
190
  this.e.raw_message = logs.join('')
192
191
  /** 前缀处理 */
193
192
  this.e.group_id && 'GroupCD' in this.config && review.alias(this.e, this.config)
194
- /** 主人 这里强制是因为yaml在自动保存QQ号的时候会强制化为数字 */
195
- const masterId = (Number(this.e.user_id) || String(this.e.user_id))
196
- if (config.master.includes(masterId)) {
193
+ /** 主人 */
194
+ if (config.master.includes(String(this.e.user_id))) {
197
195
  this.e.isMaster = true
198
196
  this.e.isAdmin = true
199
- } else if (config.admin.includes(masterId)) {
197
+ } else if (config.admin.includes(String(this.e.user_id))) {
200
198
  /** 管理员 */
201
199
  this.e.isAdmin = true
202
200
  }
203
- this.GroupMsgPrint = false
204
201
  if (this.e.contact.scene === 'private') {
205
202
  this.e.isPrivate = true
206
203
  this.e.logText = `[Private:${this.e.sender.nick || ''}(${this.e.user_id})]`
@@ -1,5 +1,5 @@
1
1
  import { KarinEvent } from './event.js';
2
- import { contact, Sender, SubEventForEvent, NoticeEvent } from '../types/index.js';
2
+ import { contact, Sender, NoticeType, EventToSubEvent } from '../types/index.js';
3
3
  /**
4
4
  * - 通知事件基类
5
5
  */
@@ -32,11 +32,11 @@ export declare class KarinNotice extends KarinEvent {
32
32
  /**
33
33
  * 事件子类型
34
34
  */
35
- sub_event: SubEventForEvent<'notice'>;
35
+ sub_event: EventToSubEvent['notice'];
36
36
  /**
37
37
  * 事件对应的内容参数
38
38
  */
39
- content: NoticeEvent<SubEventForEvent<'notice'>>;
39
+ content: NoticeType[EventToSubEvent['notice']];
40
40
  /**
41
41
  * 群ID
42
42
  */
@@ -45,5 +45,5 @@ export declare class KarinNotice extends KarinEvent {
45
45
  /**
46
46
  * - 事件对应的内容参数
47
47
  */
48
- content: NoticeEvent<SubEventForEvent<'notice'>>;
48
+ content: NoticeType[EventToSubEvent['notice']];
49
49
  }
@@ -0,0 +1,17 @@
1
+ import EventHandler from './event.handler.js';
2
+ import { KarinNoticeEvent } from '../types/index.js';
3
+ /**
4
+ * 通知事件
5
+ */
6
+ export default class NoticeHandler extends EventHandler {
7
+ e: KarinNoticeEvent;
8
+ constructor(e: KarinNoticeEvent);
9
+ /**
10
+ * 处理事件
11
+ */
12
+ deal(): Promise<void>;
13
+ /**
14
+ * 构建原始消息
15
+ */
16
+ raw_message(): void;
17
+ }
@@ -0,0 +1,203 @@
1
+ import { review } from './review.handler.js'
2
+ import EventHandler from './event.handler.js'
3
+ import { logger, config } from '../utils/index.js'
4
+ import { pluginLoader } from '../core/index.js'
5
+ /**
6
+ * 通知事件
7
+ */
8
+ export default class NoticeHandler extends EventHandler {
9
+ e
10
+ constructor (e) {
11
+ super(e)
12
+ this.e = e
13
+ /** 事件处理 */
14
+ if (this.review()) { return }
15
+ /** 处理回复 */
16
+ this.reply()
17
+ /** raw */
18
+ this.raw_message()
19
+ /** 处理消息 */
20
+ this.deal()
21
+ }
22
+
23
+ /**
24
+ * 处理事件
25
+ */
26
+ async deal () {
27
+ /** 主人 */
28
+ if (config.master.includes(String(this.e.user_id))) {
29
+ this.e.isMaster = true
30
+ this.e.isAdmin = true
31
+ } else if (config.admin.includes(String(this.e.user_id))) {
32
+ /** 管理员 */
33
+ this.e.isAdmin = true
34
+ }
35
+ if (this.e.contact.scene === 'private') {
36
+ this.e.isPrivate = true
37
+ this.e.logText = `[Private:${this.e.sender.nick || ''}(${this.e.user_id})]`
38
+ logger.bot('info', this.e.self_id, `${logger.green('私聊通知: ')}[${this.e.user_id}(${this.e.sender.nick || ''})] ${this.e.raw_message}`)
39
+ } else if (this.e.contact.scene === 'group') {
40
+ this.e.isGroup = true
41
+ this.e.logText = `[Group:${this.e.group_id}-${this.e.user_id}(${this.e.sender.nick || ''})]`
42
+ this.GroupMsgPrint = review.GroupMsgPrint(this.e)
43
+ this.GroupMsgPrint && logger.bot('info', this.e.self_id, `${logger.green('群通知: ')}[${this.e.group_id}-${this.e.user_id}(${this.e.sender.nick || ''})] ${this.e.raw_message}`)
44
+ } else {
45
+ logger.bot('info', this.e.self_id, `未知来源通知事件:${JSON.stringify(this.e)}`)
46
+ }
47
+ /* eslint-disable no-labels */
48
+ a: for (const index of pluginLoader.acceptIds) {
49
+ const app = pluginLoader.PluginList[index]
50
+ /** 判断事件 */
51
+ if (!this.filtEvent(app.event)) { continue }
52
+ /** 检查黑白名单插件 */
53
+ if ('GroupCD' in this.config && !review.PluginEnable(app, this.config)) { continue }
54
+ /** 日志方法字符串 */
55
+ this.e.logFnc = `[${app.file.dir}][${app.name}][accept]`
56
+ const logFnc = logger.fnc(`[${app.name}][accept]`)
57
+ /** 计算插件处理时间 */
58
+ const start = Date.now()
59
+ let res
60
+ try {
61
+ if (typeof app.accept === 'function') {
62
+ res = await app.accept(this.e)
63
+ } else {
64
+ const cla = new app.file.Fnc()
65
+ if (!cla.accept || typeof cla.accept !== 'function') { continue }
66
+ (cla.e) = this.e
67
+ res = await cla.accept(this.e)
68
+ }
69
+ if (res !== false) {
70
+ this.GroupMsgPrint && logger.bot('info', this.e.self_id, `${logFnc} 处理完成 ${logger.green(Date.now() - start + 'ms')}`)
71
+ break a
72
+ }
73
+ } catch (error) {
74
+ logger.error(`${logFnc}`)
75
+ logger.error(error.stack || error.message || JSON.stringify(error))
76
+ break a
77
+ }
78
+ }
79
+ }
80
+
81
+ /**
82
+ * 构建原始消息
83
+ */
84
+ raw_message () {
85
+ switch (this.e.sub_event) {
86
+ /** 好友头像戳一戳 */
87
+ case 'friend_poke': {
88
+ this.e.raw_message = '[好友戳一戳]: 戳了你一下'
89
+ break
90
+ }
91
+ /** 好友消息撤回 */
92
+ case 'friend_recall': {
93
+ this.e.raw_message = `[好友消息撤回]: ${this.e.content.message_id}`
94
+ break
95
+ }
96
+ /** 私聊文件上传 */
97
+ case 'friend_file_uploaded': {
98
+ const content = this.e.content
99
+ const { url } = content
100
+ this.e.raw_message = `[私聊文件上传]: ${url}`
101
+ break
102
+ }
103
+ /** 群头像戳一戳 */
104
+ case 'group_poke': {
105
+ const { operator_uid, operator_uin, target_uid, target_uin } = this.e.content
106
+ this.e.raw_message = `[群戳一戳]: ${operator_uid || operator_uin} 戳了戳 ${target_uid || target_uin}`
107
+ break
108
+ }
109
+ /** 群消息撤回 */
110
+ case 'group_recall': {
111
+ const { operator_uid, operator_uin, message_id } = this.e.content
112
+ this.e.raw_message = `[群消息撤回]: ${operator_uid || operator_uin} 撤回了一条消息 ${message_id}`
113
+ break
114
+ }
115
+ /** 群文件上传 */
116
+ case 'group_file_uploaded': {
117
+ const { url, operator_uid, operator_uin } = this.e.content
118
+ this.e.raw_message = `[群文件上传]: ${operator_uid || operator_uin} 上传了 ${url}`
119
+ break
120
+ }
121
+ /** 群成员增加 */
122
+ case 'group_member_increase': {
123
+ const { operator_uid, operator_uin, target_uid, target_uin, type } = this.e.content
124
+ this.e.raw_message = `[群成员新增]: ${operator_uid || operator_uin} ${type === 'invite' ? '邀请' : '同意'} ${target_uid || target_uin} 加入群聊`
125
+ break
126
+ }
127
+ /** 群成员减少 */
128
+ case 'group_member_decrease': {
129
+ switch (this.e.content.type) {
130
+ case 'leave': {
131
+ const { target_uid, target_uin } = this.e.content
132
+ this.e.raw_message = `[群成员减少]: ${target_uid || target_uin} 主动退出群聊`
133
+ break
134
+ }
135
+ // 群成员被踢
136
+ case 'kick': {
137
+ const { operator_uid, operator_uin, target_uid, target_uin } = this.e.content
138
+ this.e.raw_message = `[群成员减少]: ${operator_uid || operator_uin} 将 ${target_uid || target_uin} 踢出群聊`
139
+ break
140
+ }
141
+ // bot被踢
142
+ case 'kick_me': {
143
+ const { operator_uid, operator_uin } = this.e.content
144
+ this.e.raw_message = `[群成员减少]: 机器人被移除群聊,操作人:${operator_uid || operator_uin}`
145
+ break
146
+ }
147
+ }
148
+ break
149
+ }
150
+ /** 群管理员变动 */
151
+ case 'group_admin_changed': {
152
+ const { target_uid, target_uin, is_admin } = this.e.content
153
+ this.e.raw_message = `[群管理员变动]: ${target_uid || target_uin} 被${is_admin ? '设置' : '取消'}群管理员`
154
+ break
155
+ }
156
+ /** 群成员被禁言 */
157
+ case 'group_member_ban': {
158
+ const { operator_uid, operator_uin, target_uid, target_uin, type } = this.e.content
159
+ this.e.raw_message = `[群成员禁言]: ${operator_uid || operator_uin} ${type === 'ban' ? '禁言' : '解禁'}了 ${target_uid || target_uin}`
160
+ break
161
+ }
162
+ /** 群签到 */
163
+ case 'group_sign': {
164
+ const { target_uid, target_uin } = this.e.content
165
+ this.e.raw_message = `[群签到]: ${target_uid || target_uin}`
166
+ break
167
+ }
168
+ /** 群全员禁言 */
169
+ case 'group_whole_ban': {
170
+ const { operator_uid, operator_uin, is_ban } = this.e.content
171
+ this.e.raw_message = `[群全员禁言]: ${operator_uid || operator_uin} ${is_ban ? '开启全员禁言' : '解除全员禁言'}`
172
+ break
173
+ }
174
+ /** 群名片改变 */
175
+ case 'group_card_changed': {
176
+ const { operator_uid, operator_uin, target_uid, target_uin, new_card } = this.e.content
177
+ this.e.raw_message = `[群名片改变]: ${operator_uid || operator_uin} 修改了 ${target_uid || target_uin} 的名片为 ${new_card}`
178
+ break
179
+ }
180
+ /** 群成员专属头衔改变 */
181
+ case 'group_member_unique_title_changed': {
182
+ const { target_uid, target_uin, title } = this.e.content
183
+ this.e.raw_message = `[群头衔更改]: ${target_uid || target_uin} 的专属头衔改变为 ${title}`
184
+ break
185
+ }
186
+ /** 群精华消息改变 */
187
+ case 'group_essence_changed': {
188
+ const { operator_uid, operator_uin, target_uid, target_uin, message_id, is_set } = this.e.content
189
+ this.e.raw_message = `[群精华消息]: ${operator_uid || operator_uin} ${is_set ? `将${target_uid || target_uin}的消息${message_id}设置为精华消息` : `取消了${target_uid || target_uin}精华消息 ${message_id}`}`
190
+ break
191
+ }
192
+ /** 群表情回应 */
193
+ case 'group_message_reaction': {
194
+ const { message_id, face_id } = this.e.content
195
+ this.e.raw_message = `[群表情回应]: ${this.e.user_id} 给消息 ${message_id} 回应了一个${face_id}的表情`
196
+ break
197
+ }
198
+ default: {
199
+ this.e.raw_message = `[未知事件]: ${JSON.stringify(this.e)}`
200
+ }
201
+ }
202
+ }
203
+ }
@@ -1,5 +1,5 @@
1
1
  import { KarinEvent } from './event.js';
2
- import { contact, Sender, SubEventForEvent, RequestEvent } from '../types/index.js';
2
+ import { contact, Sender, EventToSubEvent, RequestType, KarinRequestEvent } from '../types/index.js';
3
3
  /**
4
4
  * - 请求事件基类
5
5
  */
@@ -32,11 +32,11 @@ export declare class KarinRequest extends KarinEvent {
32
32
  /**
33
33
  * 事件子类型
34
34
  */
35
- sub_event: SubEventForEvent<'request'>;
35
+ sub_event: EventToSubEvent['request'];
36
36
  /**
37
37
  * 事件对应的内容参数
38
38
  */
39
- content: RequestEvent<SubEventForEvent<'request'>>;
39
+ content: RequestType[EventToSubEvent['request']];
40
40
  /**
41
41
  * 群ID
42
42
  */
@@ -45,5 +45,5 @@ export declare class KarinRequest extends KarinEvent {
45
45
  /**
46
46
  * - 事件对应的内容参数
47
47
  */
48
- content: RequestEvent<SubEventForEvent<'request'>>;
48
+ content: KarinRequestEvent;
49
49
  }
@@ -0,0 +1,17 @@
1
+ import EventHandler from './event.handler.js';
2
+ import { KarinRequestEvent } from '../types/index.js';
3
+ /**
4
+ * 请求事件
5
+ */
6
+ export default class RequestHandler extends EventHandler {
7
+ e: KarinRequestEvent;
8
+ constructor(e: KarinRequestEvent);
9
+ /**
10
+ * 处理事件
11
+ */
12
+ deal(): Promise<void>;
13
+ /**
14
+ * 构建原始消息
15
+ */
16
+ raw_message(): void;
17
+ }
@@ -0,0 +1,109 @@
1
+ import { review } from './review.handler.js'
2
+ import EventHandler from './event.handler.js'
3
+ import { logger, config } from '../utils/index.js'
4
+ import { pluginLoader } from '../core/index.js'
5
+ /**
6
+ * 请求事件
7
+ */
8
+ export default class RequestHandler extends EventHandler {
9
+ e
10
+ constructor (e) {
11
+ super(e)
12
+ this.e = e
13
+ /** 事件处理 */
14
+ if (this.review()) { return }
15
+ /** 处理回复 */
16
+ this.reply()
17
+ /** raw */
18
+ this.raw_message()
19
+ /** 处理消息 */
20
+ this.deal()
21
+ }
22
+
23
+ /**
24
+ * 处理事件
25
+ */
26
+ async deal () {
27
+ /** 主人 */
28
+ if (config.master.includes(String(this.e.user_id))) {
29
+ this.e.isMaster = true
30
+ this.e.isAdmin = true
31
+ } else if (config.admin.includes(String(this.e.user_id))) {
32
+ /** 管理员 */
33
+ this.e.isAdmin = true
34
+ }
35
+ if (this.e.contact.scene === 'private') {
36
+ this.e.isPrivate = true
37
+ this.e.logText = `[Private:${this.e.sender.nick || ''}(${this.e.user_id})]`
38
+ logger.bot('info', this.e.self_id, `${logger.green('私聊请求: ')}[${this.e.user_id}(${this.e.sender.nick || ''})] ${this.e.raw_message}`)
39
+ } else if (this.e.contact.scene === 'group') {
40
+ this.e.isGroup = true
41
+ this.e.logText = `[Group:${this.e.group_id}-${this.e.user_id}(${this.e.sender.nick || ''})]`
42
+ this.GroupMsgPrint = review.GroupMsgPrint(this.e)
43
+ this.GroupMsgPrint && logger.bot('info', this.e.self_id, `${logger.green('群请求: ')}[${this.e.group_id}-${this.e.user_id}(${this.e.sender.nick || ''})] ${this.e.raw_message}`)
44
+ } else {
45
+ logger.bot('info', this.e.self_id, `未知来源请求事件:${JSON.stringify(this.e)}`)
46
+ }
47
+ /* eslint-disable no-labels */
48
+ a: for (const index of pluginLoader.acceptIds) {
49
+ const app = pluginLoader.PluginList[index]
50
+ /** 判断事件 */
51
+ if (!this.filtEvent(app.event)) { continue }
52
+ /** 检查黑白名单插件 */
53
+ if ('GroupCD' in this.config && !review.PluginEnable(app, this.config)) { continue }
54
+ /** 日志方法字符串 */
55
+ this.e.logFnc = `[${app.file.dir}][${app.name}][accept]`
56
+ const logFnc = logger.fnc(`[${app.name}][accept]`)
57
+ /** 计算插件处理时间 */
58
+ const start = Date.now()
59
+ let res
60
+ try {
61
+ if (typeof app.accept === 'function') {
62
+ res = await app.accept(this.e)
63
+ } else {
64
+ const cla = new app.file.Fnc()
65
+ if (!cla.accept || typeof cla.accept !== 'function') { continue }
66
+ (cla.e) = this.e
67
+ res = await cla.accept(this.e)
68
+ }
69
+ if (res !== false) {
70
+ this.GroupMsgPrint && logger.bot('info', this.e.self_id, `${logFnc} 处理完成 ${logger.green(Date.now() - start + 'ms')}`)
71
+ break a
72
+ }
73
+ } catch (error) {
74
+ logger.error(`${logFnc}`)
75
+ logger.error(error.stack || error.message || JSON.stringify(error))
76
+ break a
77
+ }
78
+ }
79
+ }
80
+
81
+ /**
82
+ * 构建原始消息
83
+ */
84
+ raw_message () {
85
+ switch (this.e.sub_event) {
86
+ /** 好友申请 */
87
+ case 'friend_apply': {
88
+ const { applier_uid, applier_uin, message } = this.e.content
89
+ this.e.raw_message = `[好友申请]: ${applier_uid || applier_uin} 申请理由: ${message}`
90
+ break
91
+ }
92
+ /** 群申请 */
93
+ case 'group_apply': {
94
+ const { group_id, applier_uid, applier_uin, inviter_uid, inviter_uin, reason } = this.e.content
95
+ this.e.raw_message = `[群申请]: ${group_id} 申请人: ${applier_uid || applier_uin} 邀请人: ${inviter_uid || inviter_uin} 理由: ${reason}`
96
+ break
97
+ }
98
+ /** 邀请入群 */
99
+ case 'invited_group': {
100
+ const { group_id, inviter_uid, inviter_uin } = this.e.content
101
+ this.e.raw_message = `[邀请入群]: ${group_id} 邀请人: ${inviter_uid || inviter_uin}`
102
+ break
103
+ }
104
+ default: {
105
+ this.e.raw_message = `[未知事件]: ${JSON.stringify(this.e)}`
106
+ }
107
+ }
108
+ }
109
+ }
@@ -5,6 +5,7 @@ import { KarinEvent } from './event.js'
5
5
  export class KarinRequest extends KarinEvent {
6
6
  constructor ({ self_id, event_id, user_id, time, contact, sender, sub_event, content, group_id = '' }) {
7
7
  super({ event: 'request', event_id, self_id, user_id, group_id, time, contact, sender, sub_event })
8
+ // ...
8
9
  this.content = content
9
10
  }
10
11