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
@@ -17,6 +17,17 @@ multi_progress: false
17
17
  # 控制台触发插件日志颜色 十六进制 默认#FFFF00 不支持热更新
18
18
  log_color: "#E1D919"
19
19
 
20
+ # input适配器配置 以下所有配置均不支持热更新
21
+ AdapterInput:
22
+ # 是否启用
23
+ enable: true
24
+ # 是否将语音、图片、视频消息转为文件 转为文件后可通过url访问
25
+ msgToFile: true
26
+ # url访问token 如果为 AdapterInput 每次启动后会重新生成
27
+ token: "AdapterInput"
28
+ # 访问ip
29
+ ip: 127.0.0.1
30
+
20
31
  # ffmpeg配置 用于音视频处理
21
32
  ffmpeg_path:
22
33
  ffprobe_path:
@@ -0,0 +1,63 @@
1
+ import { KarinAdapter } from '../../types/adapter.js';
2
+ import { contact, KarinElement } from '../../types/index.js';
3
+ /**
4
+ * - 标准输入输出适配器
5
+ */
6
+ export declare class AdapterInput implements KarinAdapter {
7
+ #private;
8
+ socket: WebSocket;
9
+ account: KarinAdapter['account'];
10
+ adapter: KarinAdapter['adapter'];
11
+ version: KarinAdapter['version'];
12
+ constructor();
13
+ get self_id(): string;
14
+ stdin(): void;
15
+ logger(level: 'info' | 'error' | 'trace' | 'debug' | 'mark' | 'warn' | 'fatal', ...args: any[]): void;
16
+ GetVersion(): Promise<{
17
+ name: string;
18
+ app_name: string;
19
+ version: string;
20
+ }>;
21
+ SendMessage(_contact: contact, elements: Array<KarinElement>): Promise<{
22
+ message_id: string;
23
+ }>;
24
+ getAvatarUrl(): string;
25
+ getGroupAvatar(): string;
26
+ GetCurrentAccount(): Promise<{
27
+ account_uid: string;
28
+ account_uin: string;
29
+ account_name: string;
30
+ }>;
31
+ GetEssenceMessageList(): Promise<any>;
32
+ DownloadForwardMessage(): Promise<any>;
33
+ SetEssenceMessage(): Promise<any>;
34
+ DeleteEssenceMessage(): Promise<any>;
35
+ SetFriendApplyResult(): Promise<any>;
36
+ SetGroupApplyResultRequest(): Promise<any>;
37
+ SetInvitedJoinGroupResult(): Promise<any>;
38
+ ReactMessageWithEmojiRequest(): Promise<any>;
39
+ UploadPrivateFile(): Promise<any>;
40
+ UploadGroupFile(): Promise<any>;
41
+ UploadForwardMessage(): Promise<any>;
42
+ sendForwardMessage(): Promise<any>;
43
+ SendMessageByResId(): Promise<any>;
44
+ RecallMessage(): Promise<any>;
45
+ GetMessage(): Promise<any>;
46
+ GetHistoryMessage(): Promise<any>;
47
+ VoteUser(): Promise<any>;
48
+ KickMember(): Promise<any>;
49
+ BanMember(): Promise<any>;
50
+ SetGroupWholeBan(): Promise<any>;
51
+ SetGroupAdmin(): Promise<any>;
52
+ ModifyMemberCard(): Promise<any>;
53
+ ModifyGroupName(): Promise<any>;
54
+ LeaveGroup(): Promise<any>;
55
+ SetGroupUniqueTitle(): Promise<any>;
56
+ GetStrangerProfileCard(): Promise<any>;
57
+ GetFriendList(): Promise<any>;
58
+ GetGroupInfo(): Promise<any>;
59
+ GetGroupList(): Promise<any>;
60
+ GetGroupMemberInfo(): Promise<any>;
61
+ GetGroupMemberList(): Promise<any>;
62
+ GetGroupHonor(): Promise<any>;
63
+ }
@@ -0,0 +1,188 @@
1
+ import fs from 'fs';
2
+ import { randomUUID } from 'crypto';
3
+ import { listener } from '../../core/index.js';
4
+ import { KarinMessage } from '../../event/index.js';
5
+ import { config, common, YamlEditor } from '../../utils/index.js';
6
+ const { enable, msgToFile, token: oldToken, ip } = config.Config.AdapterInput;
7
+ let token = oldToken;
8
+ if (oldToken === 'AdapterInput') {
9
+ try {
10
+ token = randomUUID();
11
+ const yaml = new YamlEditor('./config/config/config.yaml');
12
+ const data = yaml.get('AdapterInput');
13
+ if (!data) {
14
+ const yaml1 = new YamlEditor('./config/defSet/config.yaml');
15
+ const data1 = yaml1.get('AdapterInput');
16
+ data1.token = token;
17
+ yaml.set('AdapterInput', data1);
18
+ }
19
+ else {
20
+ data.token = token;
21
+ yaml.set('AdapterInput', data);
22
+ }
23
+ yaml.save();
24
+ }
25
+ catch (e) {
26
+ logger.error('AdapterInput token更换失败,请手动更换token');
27
+ }
28
+ }
29
+ // 清空文件夹
30
+ fs.readdirSync('./temp/input').forEach((file) => {
31
+ fs.unlinkSync(`./temp/input/${file}`);
32
+ });
33
+ /**
34
+ * - 标准输入输出适配器
35
+ */
36
+ export class AdapterInput {
37
+ #stdin;
38
+ socket;
39
+ account;
40
+ adapter;
41
+ version;
42
+ constructor() {
43
+ this.#stdin = false;
44
+ this.account = { uid: 'input', uin: 'input', name: 'input' };
45
+ this.adapter = { id: 'shell', name: 'input', type: 'internal', sub_type: 'internal', start_time: Date.now(), connect: '' };
46
+ this.version = { name: 'input', app_name: 'input', version: '1.0.0' };
47
+ }
48
+ get self_id() {
49
+ return this.account.uid;
50
+ }
51
+ stdin() {
52
+ if (this.#stdin)
53
+ return;
54
+ this.#stdin = true;
55
+ process.stdin.on('data', data => this.#input(data.toString()));
56
+ process.once('stdin.close', () => process.stdin.removeAllListeners('data'));
57
+ }
58
+ logger(level, ...args) {
59
+ logger.bot(level, this.account.uid || this.account.uin, ...args);
60
+ }
61
+ async #input(elements) {
62
+ const message = {
63
+ event: 'message',
64
+ self_id: 'input',
65
+ user_id: 'input',
66
+ time: Date.now(),
67
+ message_id: `input.${Date.now()}`,
68
+ message_seq: '',
69
+ sender: {
70
+ uid: 'input',
71
+ uin: 'input',
72
+ nick: 'input',
73
+ role: 'member',
74
+ },
75
+ elements: [{ type: 'text', text: elements }],
76
+ contact: {
77
+ scene: 'private',
78
+ peer: 'input',
79
+ sub_peer: '',
80
+ },
81
+ group_id: '',
82
+ raw_message: elements,
83
+ };
84
+ const e = new KarinMessage(message);
85
+ e.bot = this;
86
+ /**
87
+ * 快速回复 开发者不应该使用这个方法,应该使用由karin封装过后的reply方法
88
+ */
89
+ e.replyCallback = async (elements) => {
90
+ this.SendMessage(e.contact, elements);
91
+ return { message_id: e.message_id };
92
+ };
93
+ listener.emit('message', e);
94
+ }
95
+ async #MsgToFile(type, file) {
96
+ if (!msgToFile)
97
+ return '';
98
+ // 判断是否为string 如果是则继续判断是否为url、path
99
+ if (typeof file === 'string') {
100
+ if (file.startsWith('http'))
101
+ return file;
102
+ if (common.exists(file))
103
+ return file;
104
+ }
105
+ const buffer = await common.buffer(file);
106
+ // 生成文件名 根据type生成不同的文件后缀
107
+ const name = `${Date.now()}.${type === 'image' ? 'jpg' : type === 'voice' ? 'mp3' : 'file'}`;
108
+ // 写入文件
109
+ fs.writeFileSync(`./temp/input/${name}`, buffer);
110
+ return `[${type === 'image' ? '图片' : '语音'}: http://${ip}:${config.Server.http.port}/api/input?name=${name}&token=${token} ]`;
111
+ }
112
+ async GetVersion() {
113
+ const data = this.version;
114
+ delete data.name;
115
+ return data;
116
+ }
117
+ async SendMessage(_contact, elements) {
118
+ const text = [];
119
+ for (const v of elements) {
120
+ switch (v.type) {
121
+ case 'at':
122
+ text.push(`@${v.uid}`);
123
+ break;
124
+ case 'face':
125
+ text.push(`[表情:${v.id}]`);
126
+ break;
127
+ case 'text':
128
+ text.push(v.text);
129
+ break;
130
+ case 'image':
131
+ case 'voice':
132
+ text.push(await this.#MsgToFile(v.type, v.file));
133
+ break;
134
+ default:
135
+ text.push(`[未知消息类型:${JSON.stringify(v)}]`);
136
+ }
137
+ }
138
+ this.logger('info', text.join(''));
139
+ return { message_id: 'input' };
140
+ }
141
+ getAvatarUrl() {
142
+ return 'https://p.qlogo.cn/gh/967068507/967068507/0';
143
+ }
144
+ getGroupAvatar() {
145
+ return 'https://p.qlogo.cn/gh/967068507/967068507/0';
146
+ }
147
+ async GetCurrentAccount() {
148
+ return { account_uid: 'input', account_uin: 'input', account_name: 'input' };
149
+ }
150
+ async GetEssenceMessageList() { throw new Error('Method not implemented.'); }
151
+ async DownloadForwardMessage() { throw new Error('Method not implemented.'); }
152
+ async SetEssenceMessage() { throw new Error('Method not implemented.'); }
153
+ async DeleteEssenceMessage() { throw new Error('Method not implemented.'); }
154
+ async SetFriendApplyResult() { throw new Error('Method not implemented.'); }
155
+ async SetGroupApplyResultRequest() { throw new Error('Method not implemented.'); }
156
+ async SetInvitedJoinGroupResult() { throw new Error('Method not implemented.'); }
157
+ async ReactMessageWithEmojiRequest() { throw new Error('Method not implemented.'); }
158
+ async UploadPrivateFile() { throw new Error('Method not implemented.'); }
159
+ async UploadGroupFile() { throw new Error('Method not implemented.'); }
160
+ async UploadForwardMessage() { throw new Error('Method not implemented.'); }
161
+ async sendForwardMessage() { throw new Error('Method not implemented.'); }
162
+ async SendMessageByResId() { throw new Error('Method not implemented.'); }
163
+ async RecallMessage() { throw new Error('Method not implemented.'); }
164
+ async GetMessage() { throw new Error('Method not implemented.'); }
165
+ async GetHistoryMessage() { throw new Error('Method not implemented.'); }
166
+ async VoteUser() { throw new Error('Method not implemented.'); }
167
+ async KickMember() { throw new Error('Method not implemented.'); }
168
+ async BanMember() { throw new Error('Method not implemented.'); }
169
+ async SetGroupWholeBan() { throw new Error('Method not implemented.'); }
170
+ async SetGroupAdmin() { throw new Error('Method not implemented.'); }
171
+ async ModifyMemberCard() { throw new Error('Method not implemented.'); }
172
+ async ModifyGroupName() { throw new Error('Method not implemented.'); }
173
+ async LeaveGroup() { throw new Error('Method not implemented.'); }
174
+ async SetGroupUniqueTitle() { throw new Error('Method not implemented.'); }
175
+ async GetStrangerProfileCard() { throw new Error('Method not implemented.'); }
176
+ async GetFriendList() { throw new Error('Method not implemented.'); }
177
+ async GetGroupInfo() { throw new Error('Method not implemented.'); }
178
+ async GetGroupList() { throw new Error('Method not implemented.'); }
179
+ async GetGroupMemberInfo() { throw new Error('Method not implemented.'); }
180
+ async GetGroupMemberList() { throw new Error('Method not implemented.'); }
181
+ async GetGroupHonor() { throw new Error('Method not implemented.'); }
182
+ }
183
+ if (enable) {
184
+ const bot = new AdapterInput();
185
+ bot.stdin();
186
+ /** 注册bot */
187
+ listener.emit('bot', { type: 'internal', bot });
188
+ }
@@ -1,17 +1,13 @@
1
1
  import WebSocket from 'ws';
2
2
  import { IncomingMessage } from 'http';
3
3
  import { KarinAdapter } from '../../types/adapter.js';
4
- import { Scene, contact, OneBot11Api, KarinElement, OneBot11Segment, CustomNodeSegment, OneBot11ApiParamsType } from '../../types/index.js';
4
+ import { contact, OneBot11Api, KarinElement, OneBot11Segment, CustomNodeSegment, OneBot11ApiParamsType, GroupInfo, KarinNodeElement } from '../../types/index.js';
5
5
  /**
6
6
  * @class OneBot11
7
7
  * @extends KarinAdapter
8
8
  */
9
9
  export declare class OneBot11 implements KarinAdapter {
10
10
  #private;
11
- /**
12
- * 机器人QQ号
13
- */
14
- self_id: string;
15
11
  /**
16
12
  * - 重连次数 仅正向ws使用
17
13
  */
@@ -30,6 +26,7 @@ export declare class OneBot11 implements KarinAdapter {
30
26
  * @param connect - WebSocket连接地址
31
27
  */
32
28
  client(connect: string): Promise<void>;
29
+ get self_id(): string;
33
30
  /**
34
31
  * 获取当前登录号信息
35
32
  */
@@ -38,121 +35,14 @@ export declare class OneBot11 implements KarinAdapter {
38
35
  get isInit(): Promise<unknown>;
39
36
  /**
40
37
  * onebot11转karin
41
- * @param {Array<{type: string, data: any}>} data onebot11格式消息
42
38
  * @return karin格式消息
43
39
  * */
44
- AdapterConvertKarin(data: Array<OneBot11Segment>): (import("../../types/index.js").TextElement | import("../../types/index.js").AtElement | import("../../types/index.js").FaceElement | import("../../types/index.js").ReplyElement | import("../../types/index.js").ImageElement | import("../../types/index.js").VoiceElement | import("../../types/index.js").VideoElement | import("../../types/index.js").PokeElement | import("../../types/index.js").LocationElement | import("../../types/index.js").ForwardElement | import("../../types/index.js").ContactElement | import("../../types/index.js").JsonElement | import("../../types/index.js").XmlElement)[];
40
+ AdapterConvertKarin(data: Array<OneBot11Segment>): Array<KarinElement>;
45
41
  /**
46
42
  * karin转onebot11
47
43
  * @param data karin格式消息
48
- * @return {Array<{type: string, data: any}>} onebot11格式消息
49
44
  * */
50
- KarinConvertAdapter(data: Array<KarinElement>): (import("../../types/index.js").BubbleFaceElement | import("../../types/index.js").RecordElement | import("../../types/index.js").BasketballElement | import("../../types/index.js").DiceElement | import("../../types/index.js").RpsElement | import("../../types/index.js").WeatherElement | import("../../types/index.js").LocationElement | import("../../types/index.js").ShareElement | import("../../types/index.js").GiftElement | import("../../types/index.js").MarketFaceElement | import("../../types/index.js").ContactElement | import("../../types/index.js").RowElement | import("../../types/index.js").LongMsgElement | {
51
- type: string;
52
- data: {
53
- text: string;
54
- id?: undefined;
55
- qq?: undefined;
56
- file?: undefined;
57
- data?: undefined;
58
- magic?: undefined;
59
- type?: undefined;
60
- };
61
- } | {
62
- type: string;
63
- data: {
64
- id: number;
65
- text?: undefined;
66
- qq?: undefined;
67
- file?: undefined;
68
- data?: undefined;
69
- magic?: undefined;
70
- type?: undefined;
71
- };
72
- } | {
73
- type: string;
74
- data: {
75
- qq: string;
76
- text?: undefined;
77
- id?: undefined;
78
- file?: undefined;
79
- data?: undefined;
80
- magic?: undefined;
81
- type?: undefined;
82
- };
83
- } | {
84
- type: string;
85
- data: {
86
- id: string;
87
- text?: undefined;
88
- qq?: undefined;
89
- file?: undefined;
90
- data?: undefined;
91
- magic?: undefined;
92
- type?: undefined;
93
- };
94
- } | {
95
- type: "file" | "video" | "image";
96
- data: {
97
- file: string;
98
- text?: undefined;
99
- id?: undefined;
100
- qq?: undefined;
101
- data?: undefined;
102
- magic?: undefined;
103
- type?: undefined;
104
- };
105
- } | {
106
- type: "json" | "xml";
107
- data: {
108
- data: string;
109
- text?: undefined;
110
- id?: undefined;
111
- qq?: undefined;
112
- file?: undefined;
113
- magic?: undefined;
114
- type?: undefined;
115
- };
116
- } | {
117
- type: string;
118
- data: {
119
- file: string;
120
- magic: boolean;
121
- text?: undefined;
122
- id?: undefined;
123
- qq?: undefined;
124
- data?: undefined;
125
- type?: undefined;
126
- };
127
- } | {
128
- type: "markdown";
129
- data: {
130
- content: string;
131
- custom_template_id: string;
132
- params: Array<{
133
- key: string;
134
- values: Array<string>;
135
- }>;
136
- text?: undefined;
137
- id?: undefined;
138
- qq?: undefined;
139
- file?: undefined;
140
- data?: undefined;
141
- magic?: undefined;
142
- type?: undefined;
143
- };
144
- } | {
145
- type: string;
146
- data: {
147
- type: number;
148
- id: number;
149
- text?: undefined;
150
- qq?: undefined;
151
- file?: undefined;
152
- data?: undefined;
153
- magic?: undefined;
154
- };
155
- })[];
45
+ KarinConvertAdapter(data: Array<KarinElement>): Array<OneBot11Segment>;
156
46
  /**
157
47
  * 专属当前Bot的日志打印方法
158
48
  */
@@ -202,36 +92,30 @@ export declare class OneBot11 implements KarinAdapter {
202
92
  * @param elements - nodes
203
93
  * @returns - 资源id
204
94
  * */
205
- UploadForwardMessage(contact: {
206
- scene: Scene;
207
- peer: string;
208
- }, elements: any[]): Promise<any>;
95
+ UploadForwardMessage(contact: contact, elements: KarinNodeElement[]): Promise<any>;
209
96
  /**
210
97
  * 通过资源id发送转发消息
211
98
  * @param contact - 联系人信息
212
99
  * @param id - 资源id
213
100
  * */
214
- SendMessageByResId(contact: {
215
- scene: Scene;
216
- peer: string;
217
- }, id: any): Promise<{
101
+ SendMessageByResId(contact: contact, id: string): Promise<{
218
102
  message_id: any;
219
103
  message_time: number;
220
104
  }>;
221
105
  /**
222
106
  * 撤回消息
223
- * @param {null} [_contact] - ob11无需提供contact参数
107
+ * @param _contact - ob11无需提供contact参数
224
108
  * @param message_id - 消息ID
225
109
  * @returns {Promise<null>}
226
110
  */
227
111
  RecallMessage(_contact: contact, message_id: string): Promise<any>;
228
112
  /**
229
113
  * 获取消息
230
- * @param {null} [_contact] - ob11无需提供contact参数
114
+ * @param _contact - ob11无需提供contact参数
231
115
  * @param message_id - 消息ID
232
116
  * @returns {Promise<object>} - 消息内容
233
117
  */
234
- GetMessage(_contact: any, message_id: any): Promise<any>;
118
+ GetMessage(_contact: contact, message_id: string): Promise<any>;
235
119
  /**
236
120
  * 获取msg_id获取历史消息
237
121
  * @description 此api各平台实现不同,暂时废弃
@@ -242,7 +126,7 @@ export declare class OneBot11 implements KarinAdapter {
242
126
  message_seq: any;
243
127
  contact: contact;
244
128
  sender: any;
245
- elements: (import("../../types/index.js").TextElement | import("../../types/index.js").AtElement | import("../../types/index.js").FaceElement | import("../../types/index.js").ReplyElement | import("../../types/index.js").ImageElement | import("../../types/index.js").VoiceElement | import("../../types/index.js").VideoElement | import("../../types/index.js").PokeElement | import("../../types/index.js").LocationElement | import("../../types/index.js").ForwardElement | import("../../types/index.js").ContactElement | import("../../types/index.js").JsonElement | import("../../types/index.js").XmlElement)[];
129
+ elements: KarinElement[];
246
130
  }[]>;
247
131
  /**
248
132
  * 获取合并转发消息
@@ -340,18 +224,8 @@ export declare class OneBot11 implements KarinAdapter {
340
224
  * 获取群信息
341
225
  * @param group_id - 群号
342
226
  * @param no_cache - 是否不使用缓存
343
- * @returns {Promise<IGroupInfo>} - 群信息
344
- */
345
- GetGroupInfo(group_id: string, no_cache?: boolean): Promise<{
346
- group_id: any;
347
- group_name: any;
348
- group_remark: any;
349
- max_member_count: any;
350
- member_count: any;
351
- group_uin: any;
352
- admins: any;
353
- owner: any;
354
- }>;
227
+ */
228
+ GetGroupInfo(group_id: string, no_cache?: boolean): Promise<GroupInfo>;
355
229
  /**
356
230
  * 获取群列表
357
231
  */