node-karin 0.6.11 → 0.6.13
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/adapter/input/index.js +1 -1
- package/lib/adapter/onebot/onebot11.d.ts +3 -11
- package/lib/adapter/onebot/onebot11.js +36 -28
- package/lib/core/karin.d.ts +22 -0
- package/lib/core/karin.js +25 -0
- package/lib/core/listener.js +1 -1
- package/lib/core/plugin.d.ts +4 -18
- package/lib/core/plugin.js +5 -1
- package/lib/core/plugin.loader.js +17 -5
- package/lib/event/event.handler.js +1 -1
- package/lib/event/message.handler.js +39 -18
- package/lib/event/request.d.ts +2 -2
- package/lib/event/request.js +0 -1
- package/lib/render/client.js +2 -2
- package/lib/types/adapter.d.ts +9 -7
- package/lib/types/element.d.ts +9 -27
- package/lib/types/plugin.d.ts +17 -19
- package/lib/utils/common.d.ts +26 -3
- package/lib/utils/common.js +72 -18
- package/lib/utils/segment.d.ts +15 -13
- package/lib/utils/segment.js +34 -16
- package/package.json +1 -2
|
@@ -2,7 +2,7 @@ import fs from 'fs';
|
|
|
2
2
|
import { randomUUID } from 'crypto';
|
|
3
3
|
import { listener } from '../../core/index.js';
|
|
4
4
|
import { KarinMessage } from '../../event/index.js';
|
|
5
|
-
import { config, common, YamlEditor } from '../../utils/index.js';
|
|
5
|
+
import { config, common, YamlEditor, logger } from '../../utils/index.js';
|
|
6
6
|
const { enable, msgToFile, token: oldToken, ip } = config.Config.AdapterInput;
|
|
7
7
|
/**
|
|
8
8
|
* - 标准输入输出适配器
|
|
@@ -153,17 +153,9 @@ export declare class AdapterOneBot11 implements KarinAdapter {
|
|
|
153
153
|
SetGroupWholeBan(group_id: string, is_ban?: boolean): Promise<void>;
|
|
154
154
|
/**
|
|
155
155
|
* 设置群管理员
|
|
156
|
-
* @param
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
* target_uin?:string,
|
|
160
|
-
* is_admin:boolean
|
|
161
|
-
* }} options - 设置管理员选项
|
|
162
|
-
* @param options.group_id - 群组ID
|
|
163
|
-
* @param options.target_uid - 要设置为管理员的用户uid
|
|
164
|
-
* @param options.target_uin - 要设置为管理员的用户uin
|
|
165
|
-
* @param options.is_admin - 是否设置为管理员
|
|
166
|
-
* @returns {Promise<SetGroupAdminResponse>} - 设置群管理员操作的响应
|
|
156
|
+
* @param group_id - 群号
|
|
157
|
+
* @param target_uid_or_uin - 目标用户ID
|
|
158
|
+
* @param is_admin - 是否设置为管理员
|
|
167
159
|
*/
|
|
168
160
|
SetGroupAdmin(group_id: string, target_uid_or_uin: string, is_admin: boolean): Promise<void>;
|
|
169
161
|
/**
|
|
@@ -213,7 +213,7 @@ export class AdapterOneBot11 {
|
|
|
213
213
|
uid: data.user_id + '',
|
|
214
214
|
uin: data.user_id + '',
|
|
215
215
|
nick: '',
|
|
216
|
-
role: '',
|
|
216
|
+
role: 'unknown',
|
|
217
217
|
};
|
|
218
218
|
const contact = {
|
|
219
219
|
scene: ('group_id' in data ? 'group' : 'friend'),
|
|
@@ -223,8 +223,9 @@ export class AdapterOneBot11 {
|
|
|
223
223
|
switch (data.notice_type) {
|
|
224
224
|
// 群文件上传
|
|
225
225
|
case 'group_upload': {
|
|
226
|
+
const group_id = data.group_id + '';
|
|
226
227
|
const content = {
|
|
227
|
-
group_id
|
|
228
|
+
group_id,
|
|
228
229
|
operator_uid: data.user_id + '',
|
|
229
230
|
operator_uin: data.user_id + '',
|
|
230
231
|
file_id: data.file.id,
|
|
@@ -242,6 +243,7 @@ export class AdapterOneBot11 {
|
|
|
242
243
|
content,
|
|
243
244
|
sender,
|
|
244
245
|
contact,
|
|
246
|
+
group_id,
|
|
245
247
|
sub_event: 'group_file_uploaded',
|
|
246
248
|
};
|
|
247
249
|
notice = new KarinNotice(options);
|
|
@@ -249,8 +251,9 @@ export class AdapterOneBot11 {
|
|
|
249
251
|
}
|
|
250
252
|
// 群管理员变动
|
|
251
253
|
case 'group_admin': {
|
|
254
|
+
const group_id = data.group_id + '';
|
|
252
255
|
const content = {
|
|
253
|
-
group_id
|
|
256
|
+
group_id,
|
|
254
257
|
target_uid: data.user_id + '',
|
|
255
258
|
target_uin: data.user_id + '',
|
|
256
259
|
is_admin: data.sub_type === 'set',
|
|
@@ -263,6 +266,7 @@ export class AdapterOneBot11 {
|
|
|
263
266
|
sender,
|
|
264
267
|
contact,
|
|
265
268
|
content,
|
|
269
|
+
group_id,
|
|
266
270
|
sub_event: 'group_admin_changed',
|
|
267
271
|
};
|
|
268
272
|
notice = new KarinNotice(options);
|
|
@@ -270,10 +274,11 @@ export class AdapterOneBot11 {
|
|
|
270
274
|
}
|
|
271
275
|
// 群成员减少
|
|
272
276
|
case 'group_decrease': {
|
|
277
|
+
const group_id = data.group_id + '';
|
|
273
278
|
const content = {
|
|
274
|
-
group_id
|
|
275
|
-
operator_uid: data.operator_id || '',
|
|
276
|
-
operator_uin: data.operator_id || '',
|
|
279
|
+
group_id,
|
|
280
|
+
operator_uid: (data.operator_id + '') || '',
|
|
281
|
+
operator_uin: (data.operator_id + '') || '',
|
|
277
282
|
target_uid: data.user_id || '',
|
|
278
283
|
target_uin: data.user_id || '',
|
|
279
284
|
type: data.sub_type,
|
|
@@ -286,6 +291,7 @@ export class AdapterOneBot11 {
|
|
|
286
291
|
sender,
|
|
287
292
|
contact,
|
|
288
293
|
content,
|
|
294
|
+
group_id,
|
|
289
295
|
sub_event: 'group_member_decrease',
|
|
290
296
|
};
|
|
291
297
|
notice = new KarinNotice(options);
|
|
@@ -293,8 +299,9 @@ export class AdapterOneBot11 {
|
|
|
293
299
|
}
|
|
294
300
|
// 群成员增加
|
|
295
301
|
case 'group_increase': {
|
|
302
|
+
const group_id = data.group_id + '';
|
|
296
303
|
const content = {
|
|
297
|
-
group_id
|
|
304
|
+
group_id,
|
|
298
305
|
operator_uid: (data.operator_id || '') + '',
|
|
299
306
|
operator_uin: (data.operator_id || '') + '',
|
|
300
307
|
target_uid: (data.user_id || '') + '',
|
|
@@ -309,6 +316,7 @@ export class AdapterOneBot11 {
|
|
|
309
316
|
sender,
|
|
310
317
|
contact,
|
|
311
318
|
content,
|
|
319
|
+
group_id,
|
|
312
320
|
sub_event: 'group_member_increase',
|
|
313
321
|
};
|
|
314
322
|
notice = new KarinNotice(options);
|
|
@@ -316,10 +324,11 @@ export class AdapterOneBot11 {
|
|
|
316
324
|
}
|
|
317
325
|
// 群禁言事件
|
|
318
326
|
case 'group_ban': {
|
|
327
|
+
const group_id = data.group_id + '';
|
|
319
328
|
const content = {
|
|
320
|
-
group_id
|
|
321
|
-
operator_uid: data.operator_id || '',
|
|
322
|
-
operator_uin: data.operator_id || '',
|
|
329
|
+
group_id,
|
|
330
|
+
operator_uid: (data.operator_id + '') || '',
|
|
331
|
+
operator_uin: (data.operator_id + '') || '',
|
|
323
332
|
target_uid: data.user_id || '',
|
|
324
333
|
target_uin: data.user_id || '',
|
|
325
334
|
duration: data.duration,
|
|
@@ -333,6 +342,7 @@ export class AdapterOneBot11 {
|
|
|
333
342
|
sender,
|
|
334
343
|
contact,
|
|
335
344
|
content,
|
|
345
|
+
group_id,
|
|
336
346
|
sub_event: 'group_member_ban',
|
|
337
347
|
};
|
|
338
348
|
notice = new KarinNotice(options);
|
|
@@ -343,10 +353,11 @@ export class AdapterOneBot11 {
|
|
|
343
353
|
this.logger('info', `[好友添加]:${JSON.stringify(data)}`);
|
|
344
354
|
break;
|
|
345
355
|
case 'group_recall': {
|
|
356
|
+
const group_id = data.group_id + '';
|
|
346
357
|
const content = {
|
|
347
|
-
group_id
|
|
348
|
-
operator_uid: data.operator_id || '',
|
|
349
|
-
operator_uin: data.operator_id || '',
|
|
358
|
+
group_id,
|
|
359
|
+
operator_uid: (data.operator_id + '') || '',
|
|
360
|
+
operator_uin: (data.operator_id + '') || '',
|
|
350
361
|
target_uid: data.user_id || '',
|
|
351
362
|
target_uin: data.user_id || '',
|
|
352
363
|
message_id: data.message_id,
|
|
@@ -360,6 +371,7 @@ export class AdapterOneBot11 {
|
|
|
360
371
|
sender,
|
|
361
372
|
contact,
|
|
362
373
|
content,
|
|
374
|
+
group_id,
|
|
363
375
|
sub_event: 'group_recall',
|
|
364
376
|
};
|
|
365
377
|
notice = new KarinNotice(options);
|
|
@@ -388,8 +400,9 @@ export class AdapterOneBot11 {
|
|
|
388
400
|
case 'notify':
|
|
389
401
|
switch (data.sub_type) {
|
|
390
402
|
case 'poke': {
|
|
403
|
+
const group_id = 'group_id' in data ? data.group_id + '' : '';
|
|
391
404
|
const content = {
|
|
392
|
-
group_id
|
|
405
|
+
group_id,
|
|
393
406
|
operator_uid: data.user_id + '',
|
|
394
407
|
operator_uin: data.user_id + '',
|
|
395
408
|
target_uid: data.target_id + '',
|
|
@@ -406,6 +419,7 @@ export class AdapterOneBot11 {
|
|
|
406
419
|
sender,
|
|
407
420
|
contact,
|
|
408
421
|
content,
|
|
422
|
+
group_id,
|
|
409
423
|
sub_event: data.group_id ? 'group_poke' : 'private_poke',
|
|
410
424
|
};
|
|
411
425
|
notice = new KarinNotice(options);
|
|
@@ -422,8 +436,9 @@ export class AdapterOneBot11 {
|
|
|
422
436
|
}
|
|
423
437
|
break;
|
|
424
438
|
case 'group_msg_emoji_like': {
|
|
439
|
+
const group_id = data.group_id + '';
|
|
425
440
|
const content = {
|
|
426
|
-
group_id
|
|
441
|
+
group_id,
|
|
427
442
|
message_id: data.message_id,
|
|
428
443
|
face_id: data.likes[0].emoji_id,
|
|
429
444
|
is_set: true,
|
|
@@ -436,6 +451,7 @@ export class AdapterOneBot11 {
|
|
|
436
451
|
sender,
|
|
437
452
|
contact,
|
|
438
453
|
content,
|
|
454
|
+
group_id,
|
|
439
455
|
sub_event: 'group_message_reaction',
|
|
440
456
|
};
|
|
441
457
|
notice = new KarinNotice(options);
|
|
@@ -465,7 +481,7 @@ export class AdapterOneBot11 {
|
|
|
465
481
|
uid: data.user_id + '',
|
|
466
482
|
uin: data.user_id + '',
|
|
467
483
|
nick: '',
|
|
468
|
-
role: '',
|
|
484
|
+
role: 'unknown',
|
|
469
485
|
},
|
|
470
486
|
sub_event: 'private_apply',
|
|
471
487
|
content: {
|
|
@@ -492,7 +508,7 @@ export class AdapterOneBot11 {
|
|
|
492
508
|
uid: data.user_id + '',
|
|
493
509
|
uin: data.user_id + '',
|
|
494
510
|
nick: '',
|
|
495
|
-
role: '',
|
|
511
|
+
role: 'unknown',
|
|
496
512
|
},
|
|
497
513
|
sub_event: data.sub_type === 'add' ? 'group_apply' : 'invited_group',
|
|
498
514
|
content: {
|
|
@@ -871,17 +887,9 @@ export class AdapterOneBot11 {
|
|
|
871
887
|
}
|
|
872
888
|
/**
|
|
873
889
|
* 设置群管理员
|
|
874
|
-
* @param
|
|
875
|
-
*
|
|
876
|
-
*
|
|
877
|
-
* target_uin?:string,
|
|
878
|
-
* is_admin:boolean
|
|
879
|
-
* }} options - 设置管理员选项
|
|
880
|
-
* @param options.group_id - 群组ID
|
|
881
|
-
* @param options.target_uid - 要设置为管理员的用户uid
|
|
882
|
-
* @param options.target_uin - 要设置为管理员的用户uin
|
|
883
|
-
* @param options.is_admin - 是否设置为管理员
|
|
884
|
-
* @returns {Promise<SetGroupAdminResponse>} - 设置群管理员操作的响应
|
|
890
|
+
* @param group_id - 群号
|
|
891
|
+
* @param target_uid_or_uin - 目标用户ID
|
|
892
|
+
* @param is_admin - 是否设置为管理员
|
|
885
893
|
*/
|
|
886
894
|
async SetGroupAdmin(group_id, target_uid_or_uin, is_admin) {
|
|
887
895
|
const user_id = Number(target_uid_or_uin);
|
package/lib/core/karin.d.ts
CHANGED
|
@@ -119,5 +119,27 @@ export declare class Karin {
|
|
|
119
119
|
* @param options - 渲染参数
|
|
120
120
|
*/
|
|
121
121
|
render(options: KarinRenderType): Promise<string | string[]>;
|
|
122
|
+
/**
|
|
123
|
+
* - 上下文
|
|
124
|
+
* @param e - 消息事件
|
|
125
|
+
*/
|
|
126
|
+
ctx(e: KarinMessage, options?: {
|
|
127
|
+
/**
|
|
128
|
+
* - 指定用户id触发下文 不指定则使用默认e.user_id
|
|
129
|
+
*/
|
|
130
|
+
userId?: string;
|
|
131
|
+
/**
|
|
132
|
+
* - 超时时间 默认120秒
|
|
133
|
+
*/
|
|
134
|
+
time?: number;
|
|
135
|
+
/**
|
|
136
|
+
* - 超时后是否回复
|
|
137
|
+
*/
|
|
138
|
+
reply?: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* - 超时回复文本 默认为'操作超时已取消'
|
|
141
|
+
*/
|
|
142
|
+
replyMsg?: string;
|
|
143
|
+
}): Promise<KarinMessage>;
|
|
122
144
|
}
|
|
123
145
|
export {};
|
package/lib/core/karin.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import PluginApp from './plugin.app.js'
|
|
2
2
|
import { common } from '../utils/index.js'
|
|
3
3
|
import { render } from '../render/index.js'
|
|
4
|
+
import { stateArr } from './plugin.js'
|
|
5
|
+
import { listener } from './listener.js'
|
|
4
6
|
export class Karin {
|
|
5
7
|
/**
|
|
6
8
|
* - 快速构建命令
|
|
@@ -117,4 +119,27 @@ export class Karin {
|
|
|
117
119
|
render (options) {
|
|
118
120
|
return render.render(options)
|
|
119
121
|
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* - 上下文
|
|
125
|
+
* @param e - 消息事件
|
|
126
|
+
*/
|
|
127
|
+
async ctx (e, options) {
|
|
128
|
+
const time = options?.time || 120
|
|
129
|
+
const userId = options?.userId || e.user_id
|
|
130
|
+
const key = e.group_id ? `${e.group_id}.${userId}` : userId
|
|
131
|
+
stateArr[key] = { type: 'ctx' }
|
|
132
|
+
// 返回promise 设置超时时间
|
|
133
|
+
return new Promise((resolve, reject) => {
|
|
134
|
+
setTimeout(() => {
|
|
135
|
+
if (stateArr[key]) {
|
|
136
|
+
delete stateArr[key]
|
|
137
|
+
if (options?.reply) { e.reply(options.replyMsg || '操作超时已取消') }
|
|
138
|
+
reject(new Error('操作超时已取消'))
|
|
139
|
+
return true
|
|
140
|
+
}
|
|
141
|
+
}, time * 1000)
|
|
142
|
+
listener.once(`ctx:${key}`, (e) => resolve(e))
|
|
143
|
+
})
|
|
144
|
+
}
|
|
120
145
|
}
|
package/lib/core/listener.js
CHANGED
|
@@ -163,7 +163,7 @@ class Listeners extends EventEmitter {
|
|
|
163
163
|
/** 标准化 */
|
|
164
164
|
const NewElements = common.makeMessage(elements)
|
|
165
165
|
/** 结果 */
|
|
166
|
-
let result = {
|
|
166
|
+
let result = {}
|
|
167
167
|
const reply_log = common.makeMessageLog(NewElements)
|
|
168
168
|
const self_id = bot.account.uid || bot.account.uin
|
|
169
169
|
if (contact.scene === 'group') {
|
package/lib/core/plugin.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PluginType, KarinElement, KarinNodeElement, EventType, KarinNoticeEvent, KarinRequestEvent } from '../types/index.js';
|
|
1
|
+
import { PluginType, KarinElement, KarinNodeElement, EventType, KarinNoticeEvent, KarinRequestEvent, stateArrType } from '../types/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* 插件基类
|
|
4
4
|
*/
|
|
@@ -142,7 +142,7 @@ export declare class Plugin implements PluginType {
|
|
|
142
142
|
/**
|
|
143
143
|
* @param fnc - 执行方法
|
|
144
144
|
*/
|
|
145
|
-
fnc: string,
|
|
145
|
+
fnc: string | Function,
|
|
146
146
|
/**
|
|
147
147
|
* @param reply - 超时后是否回复
|
|
148
148
|
*/
|
|
@@ -154,10 +154,7 @@ export declare class Plugin implements PluginType {
|
|
|
154
154
|
/**
|
|
155
155
|
* 获取上下文状态
|
|
156
156
|
*/
|
|
157
|
-
getContext():
|
|
158
|
-
plugin: Plugin;
|
|
159
|
-
fnc: string;
|
|
160
|
-
};
|
|
157
|
+
getContext(): stateArrType[string];
|
|
161
158
|
/**
|
|
162
159
|
* 清除上下文状态
|
|
163
160
|
*/
|
|
@@ -166,18 +163,7 @@ export declare class Plugin implements PluginType {
|
|
|
166
163
|
/**
|
|
167
164
|
* 上下文状态
|
|
168
165
|
*/
|
|
169
|
-
export declare const stateArr:
|
|
170
|
-
[key: string]: {
|
|
171
|
-
/**
|
|
172
|
-
* @param plugin - 插件实例
|
|
173
|
-
*/
|
|
174
|
-
plugin: Plugin;
|
|
175
|
-
/**
|
|
176
|
-
* @param fnc - 执行方法名称
|
|
177
|
-
*/
|
|
178
|
-
fnc: string;
|
|
179
|
-
};
|
|
180
|
-
};
|
|
166
|
+
export declare const stateArr: stateArrType;
|
|
181
167
|
/**
|
|
182
168
|
* 通知事件 插件类型
|
|
183
169
|
*/
|
package/lib/core/plugin.js
CHANGED
|
@@ -103,7 +103,11 @@ export class Plugin {
|
|
|
103
103
|
*/
|
|
104
104
|
time = 120) {
|
|
105
105
|
const key = this.conKey()
|
|
106
|
-
|
|
106
|
+
if (typeof fnc === 'string') {
|
|
107
|
+
stateArr[key] = { type: 'class', fnc: this, name: fnc }
|
|
108
|
+
} else {
|
|
109
|
+
stateArr[key] = { type: 'fnc', fnc }
|
|
110
|
+
}
|
|
107
111
|
/** 操作时间 */
|
|
108
112
|
this.timeout = setTimeout(() => {
|
|
109
113
|
if (stateArr[key]) {
|
|
@@ -123,14 +123,23 @@ class PluginLoader {
|
|
|
123
123
|
this.getApps(dir, this.isTs, true)
|
|
124
124
|
continue
|
|
125
125
|
}
|
|
126
|
-
/**
|
|
126
|
+
/** package */
|
|
127
|
+
const pack = common.readJson(`${PluginPath}/package.json`)
|
|
128
|
+
/** 旧版本入口文件 */
|
|
127
129
|
const index = this.getIndex(PluginPath, process.env.karin_app_lang)
|
|
128
130
|
if (index) {
|
|
129
131
|
this.FileList.push({ dir, name: index })
|
|
130
132
|
this.isDev && this.watchList.push({ dir, name: index })
|
|
131
133
|
}
|
|
134
|
+
/** 新版本入口 */
|
|
135
|
+
if (pack.main) {
|
|
136
|
+
const { dir: dirName, pop } = common.splitPath(pack.main)
|
|
137
|
+
const dirPath = `${dir}/${dirName}`
|
|
138
|
+
this.FileList.push({ dir: dirPath, name: pop })
|
|
139
|
+
this.isDev && this.watchList.push({ dir: dirPath, name: pop })
|
|
140
|
+
}
|
|
132
141
|
/** 检查是否存在karin.apps */
|
|
133
|
-
const
|
|
142
|
+
const outDir = (pack?.karin?.outDir || 'dist')
|
|
134
143
|
if (pack && pack?.karin?.apps) {
|
|
135
144
|
const cfg = pack.karin.apps
|
|
136
145
|
if (Array.isArray(cfg)) {
|
|
@@ -144,8 +153,8 @@ class PluginLoader {
|
|
|
144
153
|
/** ts环境 全部加载 如果存在编译产物 则不加载ts */
|
|
145
154
|
if (this.isTs) {
|
|
146
155
|
/** 编译产物 存在不加载ts */
|
|
147
|
-
if (common.exists(`${PluginPath}/
|
|
148
|
-
this.getApps((`${dir}/
|
|
156
|
+
if (common.exists(`${PluginPath}/${outDir}/apps`)) {
|
|
157
|
+
this.getApps((`${dir}/${outDir}/apps`), false)
|
|
149
158
|
continue
|
|
150
159
|
}
|
|
151
160
|
/** ts */
|
|
@@ -157,7 +166,7 @@ class PluginLoader {
|
|
|
157
166
|
/** js环境 */
|
|
158
167
|
if (common.isDir(`${PluginPath}/apps`)) { this.getApps(`${dir}/apps`, false) }
|
|
159
168
|
/** 这里需要判断下 不然ts环境下会重复加载 */
|
|
160
|
-
if (!this.isTs && common.isDir(`${PluginPath}/
|
|
169
|
+
if (!this.isTs && common.isDir(`${PluginPath}/${outDir}/apps`)) { this.getApps(`${dir}/${outDir}/apps`, false) }
|
|
161
170
|
}
|
|
162
171
|
}
|
|
163
172
|
|
|
@@ -247,6 +256,9 @@ class PluginLoader {
|
|
|
247
256
|
if (!App?.name) { return logger.error(`[${dir}][${name}] 插件名称错误`) }
|
|
248
257
|
App.file.dir = dir
|
|
249
258
|
App.file.name = name
|
|
259
|
+
App.rule.forEach((v, index) => {
|
|
260
|
+
App.rule[index].log = v.log === false ? (id, log) => logger.bot('debug', id, log) : (id, log) => logger.bot('mark', id, log)
|
|
261
|
+
})
|
|
250
262
|
/** handler */
|
|
251
263
|
App.task = this.addTaskFnc(dir, App)
|
|
252
264
|
this.PluginList[index] = App
|
|
@@ -16,7 +16,7 @@ export default class EventHandler {
|
|
|
16
16
|
this.config = {}
|
|
17
17
|
this.GroupMsgPrint = false
|
|
18
18
|
/** 加入e.bot */
|
|
19
|
-
Object.defineProperty(this.e, 'bot', { value: listener.getBot(this.e.self_id) })
|
|
19
|
+
!this.e.bot && Object.defineProperty(this.e, 'bot', { value: listener.getBot(this.e.self_id) })
|
|
20
20
|
if (this.e.group_id) { this.config = config.group(this.e.group_id) }
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -25,7 +25,6 @@ export class MessageHandler extends EventHandler {
|
|
|
25
25
|
logger.debug('[消息拦截] 响应模式不匹配')
|
|
26
26
|
return
|
|
27
27
|
}
|
|
28
|
-
this.GroupMsgPrint = false
|
|
29
28
|
/** 处理回复 */
|
|
30
29
|
this.reply()
|
|
31
30
|
/** 处理消息 */
|
|
@@ -51,8 +50,9 @@ export class MessageHandler extends EventHandler {
|
|
|
51
50
|
if ('GroupCD' in this.config && !review.PluginEnable(app, this.config)) { continue }
|
|
52
51
|
/** 判断子事件 */
|
|
53
52
|
if (v.event && !this.filtEvent(v.event)) { continue }
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
const fncName = app.file.type === 'function' ? 'default' : v.fnc
|
|
54
|
+
this.e.logFnc = `[${app.file.dir}][${app.name}][${fncName}]`
|
|
55
|
+
const logFnc = logger.fnc(`[${app.name}][${fncName}]`)
|
|
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 }
|
|
@@ -165,13 +165,15 @@ export class MessageHandler extends EventHandler {
|
|
|
165
165
|
logs.push(`[json:${JSON.stringify(val.data)}]`)
|
|
166
166
|
break
|
|
167
167
|
case 'markdown': {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
168
|
+
logs.push(`[markdown:${val.content}]`)
|
|
169
|
+
break
|
|
170
|
+
}
|
|
171
|
+
case 'markdown_tpl': {
|
|
172
|
+
const params = val.params
|
|
173
|
+
if (!params) { break }
|
|
174
|
+
const content = { id: val.custom_template_id }
|
|
175
|
+
for (const v of params) { content[v.key] = v.values[0] }
|
|
176
|
+
logs.push(`[markdown_tpl:${JSON.stringify(content)}]`)
|
|
175
177
|
break
|
|
176
178
|
}
|
|
177
179
|
case 'rows': {
|
|
@@ -219,14 +221,33 @@ export class MessageHandler extends EventHandler {
|
|
|
219
221
|
const key = this.e.isGroup ? `${this.e.group_id}.${this.e.user_id}` : this.e.user_id
|
|
220
222
|
const App = stateArr[key]
|
|
221
223
|
if (App) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
224
|
+
switch (App.type) {
|
|
225
|
+
case 'ctx': {
|
|
226
|
+
listener.emit(`ctx:${key}`, this.e)
|
|
227
|
+
delete stateArr[key]
|
|
228
|
+
return true
|
|
229
|
+
}
|
|
230
|
+
case 'class': {
|
|
231
|
+
const { fnc, name } = App
|
|
232
|
+
this.e.logFnc = `[${fnc.name}][${name}]`
|
|
233
|
+
/** 计算插件处理时间 */
|
|
234
|
+
const start = Date.now()
|
|
235
|
+
fnc.e = this.e
|
|
236
|
+
await fnc[name]()
|
|
237
|
+
logger.bot('mark', this.e.self_id, `${this.e.logFnc} 上下文处理完成 ${Date.now() - start}ms`)
|
|
238
|
+
return true
|
|
239
|
+
}
|
|
240
|
+
case 'fnc': {
|
|
241
|
+
const { fnc } = App
|
|
242
|
+
this.e.logFnc = `[${fnc.name}]`
|
|
243
|
+
/** 计算插件处理时间 */
|
|
244
|
+
const start = Date.now()
|
|
245
|
+
await fnc(this.e)
|
|
246
|
+
logger.bot('mark', this.e.self_id, `${this.e.logFnc} 上下文处理完成 ${Date.now() - start}ms`)
|
|
247
|
+
delete stateArr[key]
|
|
248
|
+
return true
|
|
249
|
+
}
|
|
250
|
+
}
|
|
230
251
|
}
|
|
231
252
|
return false
|
|
232
253
|
}
|
package/lib/event/request.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { KarinEvent } from './event.js';
|
|
2
|
-
import { contact, Sender, EventToSubEvent, RequestType
|
|
2
|
+
import { contact, Sender, EventToSubEvent, RequestType } from '../types/index.js';
|
|
3
3
|
/**
|
|
4
4
|
* - 请求事件基类
|
|
5
5
|
*/
|
|
@@ -45,5 +45,5 @@ export declare class KarinRequest extends KarinEvent {
|
|
|
45
45
|
/**
|
|
46
46
|
* - 事件对应的内容参数
|
|
47
47
|
*/
|
|
48
|
-
content:
|
|
48
|
+
content: RequestType[EventToSubEvent['request']];
|
|
49
49
|
}
|
package/lib/event/request.js
CHANGED
|
@@ -5,7 +5,6 @@ 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
|
-
// ...
|
|
9
8
|
this.content = content
|
|
10
9
|
}
|
|
11
10
|
|
package/lib/render/client.js
CHANGED
|
@@ -21,14 +21,14 @@ export class RenderClient extends RenderBase {
|
|
|
21
21
|
this.index = 0
|
|
22
22
|
this.retry = 0
|
|
23
23
|
this.reg = new RegExp(`(${process.cwd().replace(/\\/g, '\\\\')}|${process.cwd().replace(/\\/g, '/')})`, 'g')
|
|
24
|
-
/** 连接ws */
|
|
25
|
-
this.ws = new WebSocket(this.url)
|
|
26
24
|
}
|
|
27
25
|
|
|
28
26
|
/**
|
|
29
27
|
* 初始化
|
|
30
28
|
*/
|
|
31
29
|
async start () {
|
|
30
|
+
/** 连接ws */
|
|
31
|
+
this.ws = new WebSocket(this.url)
|
|
32
32
|
/** 建立连接 */
|
|
33
33
|
this.ws.on('open', () => {
|
|
34
34
|
logger.mark(`[渲染器:${this.id}][WebSocket] 建立连接:${logger.green(this.url)}`)
|
package/lib/types/adapter.d.ts
CHANGED
|
@@ -105,9 +105,10 @@ export interface KarinAdapter {
|
|
|
105
105
|
/**
|
|
106
106
|
* - 头像大小,默认需要为`0`,请开发者注意
|
|
107
107
|
*/
|
|
108
|
-
size?:
|
|
108
|
+
size?: 0 | 40 | 100 | 140): string;
|
|
109
109
|
/**
|
|
110
|
-
*
|
|
110
|
+
* 获取群头像url
|
|
111
|
+
* @returns 头像的url地址
|
|
111
112
|
*/
|
|
112
113
|
getGroupAvatar(
|
|
113
114
|
/**
|
|
@@ -117,7 +118,7 @@ export interface KarinAdapter {
|
|
|
117
118
|
/**
|
|
118
119
|
* - 头像大小,默认`0`
|
|
119
120
|
*/
|
|
120
|
-
size?:
|
|
121
|
+
size?: 0 | 40 | 100 | 140,
|
|
121
122
|
/**
|
|
122
123
|
* - 历史头像记录,默认`0`,若要获取历史群头像则填写1,2,3...
|
|
123
124
|
*/
|
|
@@ -141,7 +142,8 @@ export interface KarinAdapter {
|
|
|
141
142
|
/**
|
|
142
143
|
* - 消息ID
|
|
143
144
|
*/
|
|
144
|
-
message_id
|
|
145
|
+
message_id?: string;
|
|
146
|
+
[key: string]: any;
|
|
145
147
|
}>;
|
|
146
148
|
/**
|
|
147
149
|
* - 上传合并转发消息返回一个资源ID
|
|
@@ -193,7 +195,7 @@ export interface KarinAdapter {
|
|
|
193
195
|
/**
|
|
194
196
|
* - 消息ID
|
|
195
197
|
*/
|
|
196
|
-
message_id: string): Promise<void>;
|
|
198
|
+
message_id: string): Promise<void | boolean>;
|
|
197
199
|
/**
|
|
198
200
|
* - 获取消息
|
|
199
201
|
*/
|
|
@@ -281,7 +283,7 @@ export interface KarinAdapter {
|
|
|
281
283
|
/**
|
|
282
284
|
* - 赞的次数,默认为10
|
|
283
285
|
*/
|
|
284
|
-
vote_count: number): Promise<void>;
|
|
286
|
+
vote_count: number): Promise<void | boolean>;
|
|
285
287
|
/**
|
|
286
288
|
* - 群踢人
|
|
287
289
|
*/
|
|
@@ -554,7 +556,7 @@ export interface KarinAdapter {
|
|
|
554
556
|
message_id?: string;
|
|
555
557
|
}>;
|
|
556
558
|
/**
|
|
557
|
-
* 对消息进行表情回应
|
|
559
|
+
* 对消息进行表情回应 icqq需要传递seq
|
|
558
560
|
* @param Contact - 联系人信息
|
|
559
561
|
* @param message_id - 消息ID
|
|
560
562
|
* @param face_id - 表情ID
|
package/lib/types/element.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type ElementType = 'text' | 'at' | 'face' | 'bubble_face' | 'reply' | 'image' | 'voice' | 'video' | 'basketball' | 'dice' | 'rps' | 'poke' | 'music' | 'weather' | 'location' | 'share' | 'gift' | 'market_face' | 'forward' | 'contact' | 'json' | 'xml' | 'file' | 'markdown' | 'keyboard' | 'node' | 'rows' | 'record' | 'long_msg';
|
|
1
|
+
export type ElementType = 'text' | 'at' | 'face' | 'bubble_face' | 'reply' | 'image' | 'voice' | 'video' | 'basketball' | 'dice' | 'rps' | 'poke' | 'music' | 'weather' | 'location' | 'share' | 'gift' | 'market_face' | 'forward' | 'contact' | 'json' | 'xml' | 'file' | 'markdown' | 'markdown_tpl' | 'keyboard' | 'node' | 'rows' | 'record' | 'long_msg';
|
|
2
2
|
export interface Element {
|
|
3
3
|
/**
|
|
4
4
|
* - 元素类型
|
|
@@ -444,36 +444,18 @@ export interface ContentElement extends Element {
|
|
|
444
444
|
* - 原生markdown内容
|
|
445
445
|
*/
|
|
446
446
|
content: string;
|
|
447
|
+
config?: {
|
|
448
|
+
/** 未知的参数 */
|
|
449
|
+
unknown?: number;
|
|
450
|
+
time: number;
|
|
451
|
+
token: string;
|
|
452
|
+
};
|
|
447
453
|
}
|
|
448
454
|
/**
|
|
449
455
|
* - 模板 Markdown 元素
|
|
450
456
|
*/
|
|
451
457
|
export interface TemplateElement extends Element {
|
|
452
|
-
type: '
|
|
453
|
-
/**
|
|
454
|
-
* - 模板ID
|
|
455
|
-
*/
|
|
456
|
-
custom_template_id: string;
|
|
457
|
-
/**
|
|
458
|
-
* - 模板参数
|
|
459
|
-
*/
|
|
460
|
-
params: Array<{
|
|
461
|
-
/**
|
|
462
|
-
* - 模板参数键名称
|
|
463
|
-
*/
|
|
464
|
-
key: string;
|
|
465
|
-
/**
|
|
466
|
-
* - 模板参数值
|
|
467
|
-
*/
|
|
468
|
-
values: Array<string>;
|
|
469
|
-
}>;
|
|
470
|
-
}
|
|
471
|
-
/**
|
|
472
|
-
* - Markdown元素
|
|
473
|
-
*/
|
|
474
|
-
export interface MarkdownElement extends Element {
|
|
475
|
-
type: 'markdown';
|
|
476
|
-
content: string;
|
|
458
|
+
type: 'markdown_tpl';
|
|
477
459
|
/**
|
|
478
460
|
* - 模板ID
|
|
479
461
|
*/
|
|
@@ -566,7 +548,7 @@ export interface LongMsgElement extends Element {
|
|
|
566
548
|
*/
|
|
567
549
|
id: string;
|
|
568
550
|
}
|
|
569
|
-
export type KarinElement = TextElement | AtElement | FaceElement | BubbleFaceElement | ReplyElement | ImageElement | VoiceElement | VideoElement | BasketballElement | DiceElement | RpsElement | PokeElement | MusicElement | WeatherElement | LocationElement | ShareElement | GiftElement | MarketFaceElement | ForwardElement | ContactElement | JsonElement | XmlElement | FileElement |
|
|
551
|
+
export type KarinElement = TextElement | AtElement | FaceElement | BubbleFaceElement | ReplyElement | ImageElement | VoiceElement | VideoElement | BasketballElement | DiceElement | RpsElement | PokeElement | MusicElement | WeatherElement | LocationElement | ShareElement | GiftElement | MarketFaceElement | ForwardElement | ContactElement | JsonElement | XmlElement | FileElement | ButtonElement | RowElement | RecordElement | LongMsgElement | TemplateElement | ContentElement;
|
|
570
552
|
/**
|
|
571
553
|
* - 构建自定义转发节点 此元素仅可通过专用接口发送 不支持混合发送
|
|
572
554
|
*/
|
package/lib/types/plugin.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import schedule from 'node-schedule';
|
|
2
2
|
import { Reply, replyCallback, replyForward } from './reply.js';
|
|
3
3
|
import { EventType, Event, Permission, SubEvent, KarinMessageEvent, KarinNoticeEvent, KarinRequestEvent } from './event.js';
|
|
4
|
+
import { Plugin } from '../core/index.js';
|
|
4
5
|
/**
|
|
5
6
|
* - 插件根目录名称
|
|
6
7
|
* - 例如: karin-plugin-example
|
|
@@ -12,6 +13,21 @@ export type dirName = `karin-plugin-${string}`;
|
|
|
12
13
|
* - 例如: index.js index.ts
|
|
13
14
|
*/
|
|
14
15
|
export type fileName = `${string}.js` | `${string}.ts`;
|
|
16
|
+
/**
|
|
17
|
+
* 上下文状态
|
|
18
|
+
*/
|
|
19
|
+
export interface stateArrType {
|
|
20
|
+
[key: string]: {
|
|
21
|
+
type: 'fnc';
|
|
22
|
+
fnc: Function;
|
|
23
|
+
} | {
|
|
24
|
+
type: 'class';
|
|
25
|
+
fnc: Plugin;
|
|
26
|
+
name: string;
|
|
27
|
+
} | {
|
|
28
|
+
type: 'ctx';
|
|
29
|
+
};
|
|
30
|
+
}
|
|
15
31
|
/**
|
|
16
32
|
* - 插件规则
|
|
17
33
|
*/
|
|
@@ -198,30 +214,12 @@ export interface PluginType {
|
|
|
198
214
|
/**
|
|
199
215
|
* - 获取上下文状态
|
|
200
216
|
*/
|
|
201
|
-
getContext: () =>
|
|
202
|
-
/**
|
|
203
|
-
* - 插件实例
|
|
204
|
-
*/
|
|
205
|
-
plugin: PluginType;
|
|
206
|
-
/**
|
|
207
|
-
* - 执行方法名称
|
|
208
|
-
*/
|
|
209
|
-
fnc: string;
|
|
210
|
-
};
|
|
217
|
+
getContext: () => stateArrType[string];
|
|
211
218
|
/**
|
|
212
219
|
* - accept标准方法 给通知、请求事件使用
|
|
213
220
|
*/
|
|
214
221
|
accept?(e: EventType<this>): Promise<void>;
|
|
215
222
|
}
|
|
216
|
-
/**
|
|
217
|
-
* 上下文状态
|
|
218
|
-
*/
|
|
219
|
-
export interface stateArrType {
|
|
220
|
-
[key: string]: {
|
|
221
|
-
plugin: PluginType;
|
|
222
|
-
fnc: string;
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
223
|
/**
|
|
226
224
|
* - Apps
|
|
227
225
|
*/
|
package/lib/utils/common.d.ts
CHANGED
|
@@ -61,6 +61,18 @@ export declare const common: {
|
|
|
61
61
|
* - 解析json文件
|
|
62
62
|
*/
|
|
63
63
|
readJson(file: string): any;
|
|
64
|
+
/**
|
|
65
|
+
* - 写入json文件
|
|
66
|
+
*/
|
|
67
|
+
writeJson(file: string, data: any): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* - 解析yaml文件
|
|
70
|
+
*/
|
|
71
|
+
readYaml(file: string): any;
|
|
72
|
+
/**
|
|
73
|
+
* - 写入yaml文件
|
|
74
|
+
*/
|
|
75
|
+
writeYaml(file: string, data: any): boolean;
|
|
64
76
|
/**
|
|
65
77
|
* 根据文件后缀名从指定路径下读取符合要求的文件
|
|
66
78
|
* @param path - 路径
|
|
@@ -70,10 +82,22 @@ export declare const common: {
|
|
|
70
82
|
*/
|
|
71
83
|
readDir(_path: string, ext: string | string[]): string[] | null;
|
|
72
84
|
/**
|
|
73
|
-
*
|
|
85
|
+
* 根据传入的 import.meta.url 计算相对于项目根目录的路径,返回需要的 '../' 层级。
|
|
74
86
|
* @param url - import.meta.url
|
|
87
|
+
* @returns 相对路径的层级数量,用 '../' 表示
|
|
88
|
+
* @example
|
|
89
|
+
* // 在 plugins/karin-plugin-example/index.ts 中使用
|
|
90
|
+
* common.urlToPath(import.meta.url) // 返回 '../../'
|
|
75
91
|
*/
|
|
76
92
|
urlToPath(url: string): string;
|
|
93
|
+
/**
|
|
94
|
+
* 传入相对路径 分割为两部分 1为文件夹路径 2为文件名 文件夹路径无前缀开头
|
|
95
|
+
* @param _path - 路径
|
|
96
|
+
*/
|
|
97
|
+
splitPath(_path: string): {
|
|
98
|
+
dir: string;
|
|
99
|
+
pop: string;
|
|
100
|
+
};
|
|
77
101
|
/**
|
|
78
102
|
* 将文件转换为不带前缀的base64字符串
|
|
79
103
|
* @param file - 文件路径或Buffer对象、可读流对象、http地址、base64://字符串
|
|
@@ -106,10 +130,9 @@ export declare const common: {
|
|
|
106
130
|
makeMessage(elements: string | KarinElement | (string | KarinElement)[]): Array<KarinElement>;
|
|
107
131
|
/**
|
|
108
132
|
* 制作简单转发,返回segment.node[]。仅简单包装node,也可以自己组装
|
|
109
|
-
* @param
|
|
133
|
+
* @param elements
|
|
110
134
|
* @param fakeUin 用户id
|
|
111
135
|
* @param fakeNick 用户昵称
|
|
112
|
-
* @return {Array<KarinNodeElement>}
|
|
113
136
|
*/
|
|
114
137
|
makeForward(elements: KarinElement | KarinElement[], fakeUin: string, fakeNick: string): Array<KarinNodeElement>;
|
|
115
138
|
/**
|
package/lib/utils/common.js
CHANGED
|
@@ -2,7 +2,7 @@ import { promisify } from 'util'
|
|
|
2
2
|
import { fileURLToPath } from 'url'
|
|
3
3
|
import { pipeline, Readable } from 'stream'
|
|
4
4
|
import { logger, segment } from '../utils/index.js'
|
|
5
|
-
import { fs, path, axios, lodash } from '../modules.js'
|
|
5
|
+
import { fs, path, axios, lodash, yaml as Yaml } from '../modules.js'
|
|
6
6
|
/**
|
|
7
7
|
* 常用方法
|
|
8
8
|
*/
|
|
@@ -136,11 +136,49 @@ export const common = new (class Common {
|
|
|
136
136
|
try {
|
|
137
137
|
return JSON.parse(fs.readFileSync(file, 'utf8'))
|
|
138
138
|
} catch (error) {
|
|
139
|
-
logger.error('读取json文件错误:' + error)
|
|
139
|
+
logger.error('[common] 读取json文件错误:' + error)
|
|
140
140
|
return null
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
+
/**
|
|
145
|
+
* - 写入json文件
|
|
146
|
+
*/
|
|
147
|
+
writeJson (file, data) {
|
|
148
|
+
try {
|
|
149
|
+
fs.writeFileSync(file, JSON.stringify(data, null, 2))
|
|
150
|
+
return true
|
|
151
|
+
} catch (error) {
|
|
152
|
+
logger.error('[common] 写入json文件错误:' + error)
|
|
153
|
+
return false
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* - 解析yaml文件
|
|
159
|
+
*/
|
|
160
|
+
readYaml (file) {
|
|
161
|
+
try {
|
|
162
|
+
return Yaml.parse(fs.readFileSync(file, 'utf8'))
|
|
163
|
+
} catch (error) {
|
|
164
|
+
logger.error('[common] 读取yaml文件错误:' + error)
|
|
165
|
+
return null
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* - 写入yaml文件
|
|
171
|
+
*/
|
|
172
|
+
writeYaml (file, data) {
|
|
173
|
+
try {
|
|
174
|
+
fs.writeFileSync(file, Yaml.stringify(data))
|
|
175
|
+
return true
|
|
176
|
+
} catch (error) {
|
|
177
|
+
logger.error('[common] 写入yaml文件错误:' + error)
|
|
178
|
+
return false
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
144
182
|
/**
|
|
145
183
|
* 根据文件后缀名从指定路径下读取符合要求的文件
|
|
146
184
|
* @param path - 路径
|
|
@@ -162,25 +200,40 @@ export const common = new (class Common {
|
|
|
162
200
|
}
|
|
163
201
|
|
|
164
202
|
/**
|
|
165
|
-
*
|
|
203
|
+
* 根据传入的 import.meta.url 计算相对于项目根目录的路径,返回需要的 '../' 层级。
|
|
166
204
|
* @param url - import.meta.url
|
|
205
|
+
* @returns 相对路径的层级数量,用 '../' 表示
|
|
206
|
+
* @example
|
|
207
|
+
* // 在 plugins/karin-plugin-example/index.ts 中使用
|
|
208
|
+
* common.urlToPath(import.meta.url) // 返回 '../../'
|
|
167
209
|
*/
|
|
168
210
|
urlToPath (url) {
|
|
169
|
-
|
|
211
|
+
/** 当前文件的绝对路径 */
|
|
170
212
|
const filePath = fileURLToPath(url)
|
|
171
|
-
|
|
213
|
+
/** 当前文件所在目录的绝对路径 */
|
|
172
214
|
const dirPath = path.dirname(filePath)
|
|
173
|
-
|
|
215
|
+
/** 项目根目录 */
|
|
174
216
|
const rootPath = process.cwd()
|
|
175
|
-
|
|
217
|
+
/** 当前文件到项目根目录的相对路径 */
|
|
176
218
|
const relativePath = path.relative(dirPath, rootPath)
|
|
177
|
-
|
|
219
|
+
/** 相对路径的层级数量 */
|
|
178
220
|
const upLevelsCount = relativePath.split(path.sep).length
|
|
179
|
-
|
|
221
|
+
/** 返回构建的路径 */
|
|
180
222
|
const upPath = lodash.repeat('../', upLevelsCount)
|
|
181
223
|
return upPath
|
|
182
224
|
}
|
|
183
225
|
|
|
226
|
+
/**
|
|
227
|
+
* 传入相对路径 分割为两部分 1为文件夹路径 2为文件名 文件夹路径无前缀开头
|
|
228
|
+
* @param _path - 路径
|
|
229
|
+
*/
|
|
230
|
+
splitPath (_path) {
|
|
231
|
+
const list = _path.replace(/\\/g, '/').split('/')
|
|
232
|
+
const pop = list.pop() || ''
|
|
233
|
+
const dir = path.join(...list)
|
|
234
|
+
return { dir, pop }
|
|
235
|
+
}
|
|
236
|
+
|
|
184
237
|
/**
|
|
185
238
|
* 将文件转换为不带前缀的base64字符串
|
|
186
239
|
* @param file - 文件路径或Buffer对象、可读流对象、http地址、base64://字符串
|
|
@@ -297,10 +350,9 @@ export const common = new (class Common {
|
|
|
297
350
|
|
|
298
351
|
/**
|
|
299
352
|
* 制作简单转发,返回segment.node[]。仅简单包装node,也可以自己组装
|
|
300
|
-
* @param
|
|
353
|
+
* @param elements
|
|
301
354
|
* @param fakeUin 用户id
|
|
302
355
|
* @param fakeNick 用户昵称
|
|
303
|
-
* @return {Array<KarinNodeElement>}
|
|
304
356
|
*/
|
|
305
357
|
makeForward (elements, fakeUin, fakeNick) {
|
|
306
358
|
if (!Array.isArray(elements)) { elements = [elements] }
|
|
@@ -406,13 +458,15 @@ export const common = new (class Common {
|
|
|
406
458
|
logs.push(`[json:${val.data}]`)
|
|
407
459
|
break
|
|
408
460
|
case 'markdown': {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
}
|
|
461
|
+
logs.push(`[markdown:${val.content}]`)
|
|
462
|
+
break
|
|
463
|
+
}
|
|
464
|
+
case 'markdown_tpl': {
|
|
465
|
+
const params = val.params
|
|
466
|
+
if (!params) { break }
|
|
467
|
+
const content = { id: val.custom_template_id }
|
|
468
|
+
for (const v of params) { content[v.key] = v.values[0] }
|
|
469
|
+
logs.push(`[markdown_tpl:${JSON.stringify(content)}]`)
|
|
416
470
|
break
|
|
417
471
|
}
|
|
418
472
|
case 'rows': {
|
package/lib/utils/segment.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TextElement, AtElement, ImageElement, FaceElement, BubbleFaceElement, ReplyElement, VoiceElement, VideoElement, BasketballElement, DiceElement, RpsElement, PokeElement, MusicElement, WeatherElement, LocationElement, ShareElement, GiftElement, MarketFaceElement, ForwardElement, ContactElement, JsonElement, XmlElement, FileElement, ButtonElement, CustomMusicElemen, TemplateElement, ContentElement, KarinNodeElement, KarinElement } from '../types/index.js';
|
|
1
|
+
import { TextElement, AtElement, ImageElement, FaceElement, BubbleFaceElement, ReplyElement, VoiceElement, VideoElement, BasketballElement, DiceElement, RpsElement, PokeElement, MusicElement, WeatherElement, LocationElement, ShareElement, GiftElement, MarketFaceElement, ForwardElement, ContactElement, JsonElement, XmlElement, FileElement, ButtonElement, CustomMusicElemen, TemplateElement, ContentElement, KarinNodeElement, KarinElement, LongMsgElement } from '../types/index.js';
|
|
2
2
|
export declare const segment: {
|
|
3
3
|
/**
|
|
4
4
|
* 纯文本
|
|
@@ -78,7 +78,7 @@ export declare const segment: {
|
|
|
78
78
|
*/
|
|
79
79
|
record(file: string, magic?: boolean, md5?: string, name?: string): VoiceElement;
|
|
80
80
|
/**
|
|
81
|
-
* 语音
|
|
81
|
+
* 语音 即将废弃 请使用segment.record
|
|
82
82
|
* @param file - 语音URL或路径、Base64
|
|
83
83
|
* @param magic - 是否魔法语音,默认为 false
|
|
84
84
|
* @param md5 - 语音md5
|
|
@@ -241,21 +241,23 @@ export declare const segment: {
|
|
|
241
241
|
*/
|
|
242
242
|
md5?: string;
|
|
243
243
|
}): FileElement;
|
|
244
|
+
/**
|
|
245
|
+
* 长消息
|
|
246
|
+
* @param id - ID
|
|
247
|
+
*/
|
|
248
|
+
long_msg(id: string): LongMsgElement;
|
|
244
249
|
/**
|
|
245
250
|
* Markdown
|
|
246
251
|
* @param content - 原生markdown内容
|
|
247
|
-
* @
|
|
252
|
+
* @param config - 未知的参数
|
|
248
253
|
*/
|
|
249
|
-
markdown(content:
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
*/
|
|
257
|
-
values: Array<string>;
|
|
258
|
-
}>): ContentElement | TemplateElement;
|
|
254
|
+
markdown(content: ContentElement["content"], config?: ContentElement["config"]): ContentElement;
|
|
255
|
+
/**
|
|
256
|
+
* 构建模板Markdown
|
|
257
|
+
* @param custom_template_id - 模板ID
|
|
258
|
+
* @param params - 模板markdown参数
|
|
259
|
+
*/
|
|
260
|
+
markdown_tpl(custom_template_id: TemplateElement["custom_template_id"], params: TemplateElement["params"]): TemplateElement;
|
|
259
261
|
/**
|
|
260
262
|
* 按钮
|
|
261
263
|
* @param data - 按钮数据
|
package/lib/utils/segment.js
CHANGED
|
@@ -112,7 +112,7 @@ export const segment = new (class Segment {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
/**
|
|
115
|
-
* 语音
|
|
115
|
+
* 语音 即将废弃 请使用segment.record
|
|
116
116
|
* @param file - 语音URL或路径、Base64
|
|
117
117
|
* @param magic - 是否魔法语音,默认为 false
|
|
118
118
|
* @param md5 - 语音md5
|
|
@@ -384,29 +384,47 @@ export const segment = new (class Segment {
|
|
|
384
384
|
}
|
|
385
385
|
}
|
|
386
386
|
|
|
387
|
+
/**
|
|
388
|
+
* 长消息
|
|
389
|
+
* @param id - ID
|
|
390
|
+
*/
|
|
391
|
+
long_msg (id) {
|
|
392
|
+
return {
|
|
393
|
+
type: 'long_msg',
|
|
394
|
+
id,
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
387
398
|
/**
|
|
388
399
|
* Markdown
|
|
389
400
|
* @param content - 原生markdown内容
|
|
390
|
-
* @
|
|
401
|
+
* @param config - 未知的参数
|
|
391
402
|
*/
|
|
392
|
-
markdown (
|
|
403
|
+
markdown (content, config) {
|
|
404
|
+
return {
|
|
405
|
+
type: 'markdown',
|
|
406
|
+
content,
|
|
407
|
+
config,
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* 构建模板Markdown
|
|
413
|
+
* @param custom_template_id - 模板ID
|
|
414
|
+
* @param params - 模板markdown参数
|
|
415
|
+
*/
|
|
416
|
+
markdown_tpl (
|
|
393
417
|
/**
|
|
394
|
-
* -
|
|
418
|
+
* - 模板ID
|
|
395
419
|
*/
|
|
396
|
-
|
|
420
|
+
custom_template_id,
|
|
397
421
|
/**
|
|
398
|
-
* - 模板markdown参数
|
|
399
|
-
*/
|
|
400
|
-
params
|
|
401
|
-
if (typeof content === 'string') {
|
|
402
|
-
return {
|
|
403
|
-
type: 'markdown',
|
|
404
|
-
content,
|
|
405
|
-
}
|
|
406
|
-
}
|
|
422
|
+
* - 模板markdown参数
|
|
423
|
+
*/
|
|
424
|
+
params) {
|
|
407
425
|
return {
|
|
408
|
-
type: '
|
|
409
|
-
custom_template_id
|
|
426
|
+
type: 'markdown_tpl',
|
|
427
|
+
custom_template_id,
|
|
410
428
|
params,
|
|
411
429
|
}
|
|
412
430
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-karin",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.13",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "基于 Kritor 进行开发的nodejs机器人框架",
|
|
6
6
|
"homepage": "https://github.com/KarinJS/Karin",
|
|
@@ -58,7 +58,6 @@
|
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@grpc/grpc-js": "1.10.10",
|
|
60
60
|
"@grpc/proto-loader": "0.7.13",
|
|
61
|
-
"@inquirer/prompts": "^5.0.7",
|
|
62
61
|
"art-template": "4.13.2",
|
|
63
62
|
"axios": "1.7.2",
|
|
64
63
|
"chalk": "5.3.0",
|