koishi-plugin-video-parser-all 0.8.2 → 0.8.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.
package/lib/index.d.ts CHANGED
@@ -3,9 +3,6 @@ export declare const name = "video-parser-all";
3
3
  export declare const Config: Schema<{
4
4
  enable?: boolean | null | undefined;
5
5
  botName?: string | null | undefined;
6
- showWaitingTip?: boolean | null | undefined;
7
- waitingTipText?: string | null | undefined;
8
- sameLinkInterval?: number | null | undefined;
9
6
  debug?: boolean | null | undefined;
10
7
  debugFile?: boolean | null | undefined;
11
8
  } & import("cosmokit").Dict & {
@@ -14,7 +11,6 @@ export declare const Config: Schema<{
14
11
  showImageText?: boolean | null | undefined;
15
12
  showVideoFile?: boolean | null | undefined;
16
13
  sendLivePhotoVideos?: boolean | null | undefined;
17
- } & {
18
14
  maxDescLength?: number | null | undefined;
19
15
  } & {
20
16
  timeout?: number | null | undefined;
@@ -33,12 +29,17 @@ export declare const Config: Schema<{
33
29
  messageBufferDelay?: number | null | undefined;
34
30
  } & {
35
31
  autoClearCacheInterval?: number | null | undefined;
32
+ } & {
33
+ waitingTipText?: string | null | undefined;
34
+ duplicateLinkText?: string | null | undefined;
35
+ unsupportedPlatformText?: string | null | undefined;
36
+ invalidLinkText?: string | null | undefined;
37
+ cacheClearedText?: string | null | undefined;
38
+ parseErrorPrefix?: string | null | undefined;
39
+ parseErrorItemFormat?: string | null | undefined;
36
40
  }, {
37
41
  enable: boolean;
38
42
  botName: string;
39
- showWaitingTip: boolean;
40
- waitingTipText: string;
41
- sameLinkInterval: number;
42
43
  debug: boolean;
43
44
  debugFile: boolean;
44
45
  } & import("cosmokit").Dict & {
@@ -47,7 +48,6 @@ export declare const Config: Schema<{
47
48
  showImageText: boolean;
48
49
  showVideoFile: boolean;
49
50
  sendLivePhotoVideos: boolean;
50
- } & {
51
51
  maxDescLength: number;
52
52
  } & {
53
53
  timeout: number;
@@ -66,5 +66,13 @@ export declare const Config: Schema<{
66
66
  messageBufferDelay: number;
67
67
  } & {
68
68
  autoClearCacheInterval: number;
69
+ } & {
70
+ waitingTipText: string;
71
+ duplicateLinkText: string;
72
+ unsupportedPlatformText: string;
73
+ invalidLinkText: string;
74
+ cacheClearedText: string;
75
+ parseErrorPrefix: string;
76
+ parseErrorItemFormat: string;
69
77
  }>;
70
78
  export declare function apply(ctx: Context, config: any): void;
package/lib/index.js CHANGED
@@ -10,52 +10,57 @@ const axios_1 = __importDefault(require("axios"));
10
10
  const crypto_1 = __importDefault(require("crypto"));
11
11
  const fs_1 = __importDefault(require("fs"));
12
12
  const path_1 = __importDefault(require("path"));
13
+ const url_1 = require("url");
13
14
  const promises_1 = require("stream/promises");
14
15
  const worker_threads_1 = require("worker_threads");
15
16
  exports.name = 'video-parser-all';
16
17
  exports.Config = koishi_1.Schema.intersect([
17
18
  koishi_1.Schema.object({
18
19
  enable: koishi_1.Schema.boolean().default(true).description('是否启用视频解析插件'),
19
- botName: koishi_1.Schema.string().default('视频解析机器人').description('机器人显示名称'),
20
- showWaitingTip: koishi_1.Schema.boolean().default(true).description('解析时显示等待提示'),
21
- waitingTipText: koishi_1.Schema.string().default('正在解析视频,请稍候...').description('等待提示文本内容'),
22
- sameLinkInterval: koishi_1.Schema.number().min(0).default(180).description('相同链接重复解析间隔(秒)'),
23
- debug: koishi_1.Schema.boolean().default(false).description('开启调试模式'),
24
- debugFile: koishi_1.Schema.boolean().default(false).description('调试日志写入文件'),
20
+ botName: koishi_1.Schema.string().default('视频解析机器人').description('合并转发消息中显示的机器人名称'),
21
+ debug: koishi_1.Schema.boolean().default(false).description('开启调试模式(详细日志输出至控制台)'),
22
+ debugFile: koishi_1.Schema.boolean().default(false).description('调试日志同时写入本地 debug.log 文件'),
25
23
  }).description('基础设置'),
26
24
  koishi_1.Schema.object({
27
25
  unifiedMessageFormat: koishi_1.Schema.string().role('textarea').default(`标题:\${标题}\n作者:\${作者}\n点赞:\${点赞数}\n视频链接:\${视频链接}`).description('统一消息格式,可用变量:${标题} ${作者} ${简介} ${视频时长} ${点赞数} ${收藏数} ${转发数} ${播放数} ${评论数} ${发布时间} ${图片数量} ${作者ID} ${视频链接} ${封面} ${音乐作者} ${音乐标题}'),
28
- }).description('统一消息格式'),
26
+ }).description('消息格式设置'),
29
27
  koishi_1.Schema.object({
30
- showImageText: koishi_1.Schema.boolean().default(true).description('显示图文内容'),
31
- showVideoFile: koishi_1.Schema.boolean().default(true).description('发送视频文件(关闭则只发链接)'),
32
- sendLivePhotoVideos: koishi_1.Schema.boolean().default(true).description('发送实况图片对应的视频'),
28
+ showImageText: koishi_1.Schema.boolean().default(true).description('是否发送解析后的文字内容'),
29
+ showVideoFile: koishi_1.Schema.boolean().default(true).description('是否发送视频文件(关闭则只发送视频链接)'),
30
+ sendLivePhotoVideos: koishi_1.Schema.boolean().default(true).description('发送实况图集时是否附带短视频'),
31
+ maxDescLength: koishi_1.Schema.number().default(200).description('简介内容最大长度(字符),超出自动截断'),
33
32
  }).description('内容显示设置'),
34
33
  koishi_1.Schema.object({
35
- maxDescLength: koishi_1.Schema.number().default(200).description('简介内容最大长度(字符)'),
36
- }).description('内容长度限制'),
34
+ timeout: koishi_1.Schema.number().min(0).default(180000).description('API 请求超时(毫秒)'),
35
+ videoSendTimeout: koishi_1.Schema.number().min(0).default(60000).description('视频消息发送超时(毫秒,0 为不限制)'),
36
+ userAgent: koishi_1.Schema.string().default('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36').description('API 请求 UA'),
37
+ }).description('网络与 API 设置'),
37
38
  koishi_1.Schema.object({
38
- timeout: koishi_1.Schema.number().min(0).default(180000).description('API请求超时时间(毫秒)'),
39
- videoSendTimeout: koishi_1.Schema.number().min(0).default(60000).description('视频发送超时时间(毫秒,0为不限制)'),
40
- userAgent: koishi_1.Schema.string().default('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36').description('请求UA标识'),
41
- }).description('网络与API设置'),
42
- koishi_1.Schema.object({
43
- ignoreSendError: koishi_1.Schema.boolean().default(true).description('忽略发送失败错误'),
44
- retryTimes: koishi_1.Schema.number().min(0).default(3).description('API请求重试次数'),
45
- retryInterval: koishi_1.Schema.number().min(0).default(1000).description('重试间隔时间(毫秒)'),
39
+ ignoreSendError: koishi_1.Schema.boolean().default(true).description('忽略消息发送失败,避免插件崩溃'),
40
+ retryTimes: koishi_1.Schema.number().min(0).default(3).description('API 请求重试次数'),
41
+ retryInterval: koishi_1.Schema.number().min(0).default(1000).description('重试间隔(毫秒)'),
46
42
  }).description('错误与重试设置'),
47
43
  koishi_1.Schema.object({
48
- enableForward: koishi_1.Schema.boolean().default(false).description('启用合并转发(仅OneBot平台)'),
49
- downloadVideoBeforeSend: koishi_1.Schema.boolean().default(false).description('发送前先下载视频'),
50
- maxVideoSize: koishi_1.Schema.number().min(0).default(0).description('最大视频大小限制(MB,0为不限制)'),
51
- downloadThreads: koishi_1.Schema.number().min(0).max(10).default(0).description('多线程下载线程数(0为不使用多线程)'),
44
+ enableForward: koishi_1.Schema.boolean().default(false).description('启用合并转发(仅 OneBot 平台)'),
45
+ downloadVideoBeforeSend: koishi_1.Schema.boolean().default(false).description('发送前先下载视频到本地'),
46
+ maxVideoSize: koishi_1.Schema.number().min(0).default(0).description('视频下载大小限制(MB,0 为不限制)'),
47
+ downloadThreads: koishi_1.Schema.number().min(0).max(10).default(0).description('多线程下载线程数(0 为单线程)'),
52
48
  }).description('发送方式设置'),
53
49
  koishi_1.Schema.object({
54
50
  messageBufferDelay: koishi_1.Schema.number().min(0).default(0).description('消息缓冲延迟(毫秒)'),
55
- }).description('消息处理设置'),
51
+ }).description('消息缓冲'),
52
+ koishi_1.Schema.object({
53
+ autoClearCacheInterval: koishi_1.Schema.number().min(0).default(0).description('自动清理缓存间隔(分钟,0 为关闭)'),
54
+ }).description('缓存清理'),
56
55
  koishi_1.Schema.object({
57
- autoClearCacheInterval: koishi_1.Schema.number().min(0).default(0).description('自动清理缓存间隔(分钟,0为关闭)'),
58
- }).description('缓存清理设置'),
56
+ waitingTipText: koishi_1.Schema.string().default('正在解析视频,请稍候...').description('解析等待提示'),
57
+ duplicateLinkText: koishi_1.Schema.string().default('请勿重复解析相同链接').description('重复链接提示'),
58
+ unsupportedPlatformText: koishi_1.Schema.string().default('不支持该平台链接').description('不支持的平台提示'),
59
+ invalidLinkText: koishi_1.Schema.string().default('无效的视频链接').description('无效链接提示(parse 指令)'),
60
+ cacheClearedText: koishi_1.Schema.string().default('✅ 缓存已清空').description('缓存清理提示'),
61
+ parseErrorPrefix: koishi_1.Schema.string().default('❌ 解析失败:').description('解析失败消息前缀'),
62
+ parseErrorItemFormat: koishi_1.Schema.string().default('【${url}】: ${msg}').description('每条解析失败格式,可用 ${url} ${msg}'),
63
+ }).description('界面文字设置'),
59
64
  ]);
60
65
  const processed = new Map();
61
66
  const linkBuffer = new Map();
@@ -282,6 +287,7 @@ function pickBestQuality(videoBackup) {
282
287
  .sort((a, b) => (b.bit_rate || 0) - (a.bit_rate || 0));
283
288
  }
284
289
  function parseApiResponse(raw, maxDescLen) {
290
+ debugLog('DEBUG', '原始API返回数据:', raw);
285
291
  const data = raw?.data || {};
286
292
  const extra = data.extra || {};
287
293
  let type = data.type || '';
@@ -356,12 +362,14 @@ function parseApiResponse(raw, maxDescLen) {
356
362
  else if (extra.create_time) {
357
363
  publishTime = extra.create_time * 1000;
358
364
  }
359
- return {
365
+ const result = {
360
366
  type, title, desc, author, uid, avatar, cover,
361
367
  video, videos, images, live_photo, music,
362
368
  like, comment, collect, share, play,
363
369
  duration, publishTime
364
370
  };
371
+ debugLog('DEBUG', '解析后的数据:', result);
372
+ return result;
365
373
  }
366
374
  function generateFormattedText(p, format) {
367
375
  const vars = {
@@ -386,7 +394,9 @@ function generateFormattedText(p, format) {
386
394
  for (const [key, value] of Object.entries(vars)) {
387
395
  result = result.replace(new RegExp(`\\$\\{${key}\\}`, 'g'), value);
388
396
  }
389
- return result.replace(/^\s*\n/gm, '').trim();
397
+ const final = result.replace(/^\s*\n/gm, '').trim();
398
+ debugLog('DEBUG', '生成格式化文本:', final);
399
+ return final;
390
400
  }
391
401
  function clearAllCache() {
392
402
  processed.clear();
@@ -417,16 +427,27 @@ function buildForwardNode(session, content, botName) {
417
427
  function apply(ctx, config) {
418
428
  initDebug(config.debug, config.debugFile);
419
429
  debugLog('INFO', '插件初始化开始');
430
+ debugLog('INFO', '当前配置:', config);
431
+ const texts = {
432
+ waitingTipText: config.waitingTipText || '正在解析视频,请稍候...',
433
+ duplicateLinkText: config.duplicateLinkText || '请勿重复解析相同链接',
434
+ unsupportedPlatformText: config.unsupportedPlatformText || '不支持该平台链接',
435
+ invalidLinkText: config.invalidLinkText || '无效的视频链接',
436
+ cacheClearedText: config.cacheClearedText || '✅ 缓存已清空',
437
+ parseErrorPrefix: config.parseErrorPrefix || '❌ 解析失败:',
438
+ parseErrorItemFormat: config.parseErrorItemFormat || '【${url}】: ${msg}',
439
+ };
420
440
  clearAllCache();
421
441
  const http = axios_1.default.create({
422
442
  timeout: config.timeout,
423
443
  headers: {
424
- 'User-Agent': config.userAgent,
444
+ 'User-Agent': config.userAgent || 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
425
445
  'Referer': 'https://www.baidu.com/',
426
446
  'Content-Type': 'application/x-www-form-urlencoded'
427
447
  }
428
448
  });
429
449
  async function fetchApi(url) {
450
+ debugLog('INFO', `调用API解析: ${url}`);
430
451
  for (let i = 0; i <= config.retryTimes; i++) {
431
452
  try {
432
453
  const res = await http.get('https://api.bugpk.com/api/short_videos', {
@@ -434,6 +455,7 @@ function apply(ctx, config) {
434
455
  timeout: config.timeout
435
456
  });
436
457
  debugLog('INFO', `API响应: code=${res.data?.code}, msg=${res.data?.msg}`);
458
+ debugLog('DEBUG', 'API完整响应:', res.data);
437
459
  if (res.data && (res.data.code === 200 || res.data.code === 0)) {
438
460
  return parseApiResponse(res.data, config.maxDescLength);
439
461
  }
@@ -448,50 +470,53 @@ function apply(ctx, config) {
448
470
  throw new Error('API请求全部失败');
449
471
  }
450
472
  async function parseUrl(url) {
451
- debugLog('INFO', `解析链接: ${url}`);
452
- let realUrl = await resolveShortUrl(url);
453
- realUrl = cleanUrl(realUrl);
454
- debugLog('DEBUG', `实际URL: ${realUrl}`);
473
+ debugLog('INFO', `开始解析链接: ${url}`);
474
+ const realUrl = await resolveShortUrl(url);
475
+ debugLog('DEBUG', `重定向后的URL: ${realUrl}`);
455
476
  const platform = getPlatformType(realUrl);
456
477
  if (!platform) {
457
478
  debugLog('WARN', `不支持的平台: ${realUrl}`);
458
- return { success: false, msg: '不支持该平台链接' };
479
+ return { success: false, msg: texts.unsupportedPlatformText };
459
480
  }
460
- try {
461
- const info = await fetchApi(realUrl);
462
- debugLog('INFO', `解析成功: ${info.title}`);
463
- return { success: true, data: info };
464
- }
465
- catch (error) {
466
- debugLog('ERROR', `解析失败: ${getErrorMessage(error)}`);
467
- return { success: false, msg: getErrorMessage(error) };
481
+ const candidates = [url, realUrl];
482
+ let lastError = null;
483
+ for (const candidate of candidates) {
484
+ try {
485
+ const info = await fetchApi(candidate);
486
+ debugLog('INFO', `解析成功: ${info.title}`);
487
+ return { success: true, data: info };
488
+ }
489
+ catch (error) {
490
+ lastError = getErrorMessage(error);
491
+ debugLog('ERROR', `候选链接解析失败: ${candidate} => ${lastError}`);
492
+ }
468
493
  }
494
+ return { success: false, msg: lastError || '解析失败' };
469
495
  }
470
496
  async function processSingleUrl(session, url) {
497
+ debugLog('INFO', `处理单个URL: ${url}, 用户: ${session.userId}`);
471
498
  const hash = crypto_1.default.createHash('md5').update(url).digest('hex');
472
499
  const now = Date.now();
473
500
  const last = processed.get(hash);
474
501
  if (last && (now - last) < config.sameLinkInterval * 1000) {
475
502
  debugLog('WARN', `重复解析: ${url}`);
476
- return { success: false, msg: '请勿重复解析相同链接' };
503
+ return { success: false, msg: texts.duplicateLinkText };
477
504
  }
478
505
  processed.set(hash, now);
479
506
  const result = await parseUrl(url);
480
- if (!result.success) {
481
- return { success: false, msg: result.msg };
482
- }
507
+ if (!result.success)
508
+ return result;
483
509
  const text = generateFormattedText(result.data, config.unifiedMessageFormat);
484
- return {
485
- success: true,
486
- data: { text, parsed: result.data }
487
- };
510
+ return { success: true, data: { text, parsed: result.data } };
488
511
  }
489
512
  async function sendWithTimeout(session, content) {
513
+ debugLog('DEBUG', `发送消息: ${JSON.stringify(content)}`);
490
514
  if (config.videoSendTimeout <= 0) {
491
515
  try {
492
516
  return await session.send(content);
493
517
  }
494
518
  catch (err) {
519
+ debugLog('ERROR', `发送消息失败: ${getErrorMessage(err)}`);
495
520
  if (!config.ignoreSendError)
496
521
  throw err;
497
522
  return null;
@@ -504,6 +529,7 @@ function apply(ctx, config) {
504
529
  ]);
505
530
  }
506
531
  catch (err) {
532
+ debugLog('ERROR', `发送消息超时或失败: ${getErrorMessage(err)}`);
507
533
  if (!config.ignoreSendError)
508
534
  throw err;
509
535
  return null;
@@ -525,11 +551,14 @@ function apply(ctx, config) {
525
551
  items.push(res.data);
526
552
  }
527
553
  else {
528
- errors.push(`【${url.slice(0, 50)}...】: ${res.msg}`);
554
+ const item = texts.parseErrorItemFormat
555
+ .replace(/\$\{url\}/g, url.length > 50 ? url.slice(0, 50) + '...' : url)
556
+ .replace(/\$\{msg\}/g, res.msg);
557
+ errors.push(item);
529
558
  }
530
559
  }
531
560
  if (errors.length) {
532
- await sendWithTimeout(session, `❌ 解析失败:\n${errors.join('\n')}`).catch(() => { });
561
+ await sendWithTimeout(session, `${texts.parseErrorPrefix}\n${errors.join('\n')}`).catch(() => { });
533
562
  await delay(500);
534
563
  }
535
564
  if (!items.length)
@@ -540,7 +569,9 @@ function apply(ctx, config) {
540
569
  for (const item of items) {
541
570
  const p = item.parsed;
542
571
  const text = item.text;
543
- if (text) {
572
+ debugLog('INFO', `开始发送内容,类型: ${p.type}, 标题: ${p.title}`);
573
+ if (text && config.showImageText) {
574
+ debugLog('DEBUG', '发送文本消息');
544
575
  if (enableForward)
545
576
  forwardMessages.push(buildForwardNode(session, text, botName));
546
577
  else {
@@ -549,6 +580,7 @@ function apply(ctx, config) {
549
580
  }
550
581
  }
551
582
  if (p.cover && p.type !== 'live_photo') {
583
+ debugLog('DEBUG', '发送封面图片:', p.cover);
552
584
  if (enableForward)
553
585
  forwardMessages.push(buildForwardNode(session, koishi_1.h.image(p.cover), botName));
554
586
  else {
@@ -561,9 +593,13 @@ function apply(ctx, config) {
561
593
  if (config.downloadVideoBeforeSend) {
562
594
  const fname = crypto_1.default.createHash('md5').update(p.video).digest('hex');
563
595
  const dl = await downloadVideo(p.video, fname, config.userAgent, config.maxVideoSize, config.downloadThreads);
564
- if (dl.success)
565
- return koishi_1.h.file(dl.filePath);
596
+ if (dl.success) {
597
+ const fileUrl = (0, url_1.pathToFileURL)(dl.filePath).href;
598
+ debugLog('INFO', `视频下载成功,发送文件: ${fileUrl}`);
599
+ return koishi_1.h.file(fileUrl);
600
+ }
566
601
  }
602
+ debugLog('INFO', `发送视频链接: ${p.video}`);
567
603
  return koishi_1.h.video(p.video);
568
604
  };
569
605
  if (enableForward) {
@@ -575,7 +611,8 @@ function apply(ctx, config) {
575
611
  const vMsg = await sendVideo();
576
612
  await sendWithTimeout(session, vMsg);
577
613
  }
578
- catch {
614
+ catch (e) {
615
+ debugLog('ERROR', `发送视频失败: ${getErrorMessage(e)},尝试直接发送链接`);
579
616
  try {
580
617
  await sendWithTimeout(session, koishi_1.h.video(p.video));
581
618
  }
@@ -587,6 +624,7 @@ function apply(ctx, config) {
587
624
  if (p.type === 'image' || p.type === 'live_photo') {
588
625
  const mediaList = [];
589
626
  if (p.type === 'live_photo' && p.live_photo?.length) {
627
+ debugLog('INFO', `发送实况图集,共 ${p.live_photo.length} 张`);
590
628
  for (const lp of p.live_photo) {
591
629
  if (lp.image)
592
630
  mediaList.push({ type: 'image', url: lp.image });
@@ -595,6 +633,7 @@ function apply(ctx, config) {
595
633
  }
596
634
  }
597
635
  else if (p.images?.length) {
636
+ debugLog('INFO', `发送图集,共 ${p.images.length} 张`);
598
637
  p.images.forEach(url => mediaList.push({ type: 'image', url }));
599
638
  }
600
639
  if (enableForward) {
@@ -605,20 +644,25 @@ function apply(ctx, config) {
605
644
  }
606
645
  else {
607
646
  for (const m of mediaList) {
647
+ debugLog('DEBUG', `发送${m.type}: ${m.url}`);
608
648
  try {
609
649
  await sendWithTimeout(session, m.type === 'image' ? koishi_1.h.image(m.url) : koishi_1.h.video(m.url));
610
650
  await delay(200);
611
651
  }
612
- catch { }
652
+ catch (e) {
653
+ debugLog('ERROR', `发送${m.type}失败: ${getErrorMessage(e)}`);
654
+ }
613
655
  }
614
656
  }
615
657
  }
616
658
  }
617
659
  if (enableForward && forwardMessages.length) {
660
+ debugLog('INFO', `合并转发消息,共 ${forwardMessages.length} 条`);
618
661
  try {
619
662
  await sendWithTimeout(session, (0, koishi_1.h)('message', { forward: true }, forwardMessages.slice(0, 100)));
620
663
  }
621
- catch {
664
+ catch (e) {
665
+ debugLog('ERROR', `合并转发失败,降级逐条发送: ${getErrorMessage(e)}`);
622
666
  for (const node of forwardMessages) {
623
667
  try {
624
668
  await sendWithTimeout(session, node.data.content);
@@ -633,28 +677,33 @@ function apply(ctx, config) {
633
677
  if (!config.enable)
634
678
  return;
635
679
  const content = session.content?.trim() || '';
680
+ debugLog('INFO', `收到消息: "${content}"`);
636
681
  const urls = extractUrl(content);
637
- if (!urls.length)
682
+ if (!urls.length) {
683
+ debugLog('DEBUG', '消息中未检测到平台链接');
638
684
  return;
685
+ }
686
+ debugLog('INFO', '检测到链接:', urls);
639
687
  if (config.showWaitingTip) {
640
688
  try {
641
- await sendWithTimeout(session, config.waitingTipText);
689
+ await sendWithTimeout(session, texts.waitingTipText);
642
690
  }
643
691
  catch { }
644
692
  }
645
693
  await flush(session, urls);
646
694
  });
647
695
  ctx.command('parse <url>', '手动解析视频').action(async ({ session }, url) => {
696
+ debugLog('INFO', `手动解析指令: ${url}`);
648
697
  const us = extractUrl(url);
649
698
  if (!us.length) {
650
- await sendWithTimeout(session, '无效的视频链接');
699
+ await sendWithTimeout(session, texts.invalidLinkText);
651
700
  return;
652
701
  }
653
702
  await flush(session, us);
654
703
  });
655
704
  ctx.command('clear-cache', '清空缓存').action(async ({ session }) => {
656
705
  clearAllCache();
657
- await sendWithTimeout(session, '✅ 缓存已清空');
706
+ await sendWithTimeout(session, texts.cacheClearedText);
658
707
  });
659
708
  setInterval(() => {
660
709
  const now = Date.now();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-video-parser-all",
3
3
  "description": "Koishi 全平台视频解析插件,支持抖音/快手/B站/微博/小红书/剪映/YouTube/TikTok等20+平台",
4
- "version": "0.8.2",
4
+ "version": "0.8.3",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [