koishi-plugin-video-parser-all 0.9.5 → 0.9.6

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 (3) hide show
  1. package/lib/index.js +12 -22
  2. package/package.json +1 -1
  3. package/readme.md +6 -6
package/lib/index.js CHANGED
@@ -16,7 +16,7 @@ exports.Config = koishi_1.Schema.intersect([
16
16
  debug: koishi_1.Schema.boolean().default(false).description('开启调试模式,在控制台输出详细日志'),
17
17
  }).description('基础设置'),
18
18
  koishi_1.Schema.object({
19
- unifiedMessageFormat: koishi_1.Schema.string().role('textarea').default(`标题:\${标题}\n作者:\${作者}\n简介:\${简介}\n点赞:\${点赞数}\n收藏:\${收藏数}\n转发:\${转发数}\n播放:\${播放数}\n评论:\${评论数}`).description('统一消息格式,可用变量:${标题} ${作者} ${简介} ${点赞数} ${收藏数} ${转发数} ${播放数} ${评论数} ${视频时长} ${发布时间} ${图片数量} ${作者ID} ${封面}'),
19
+ unifiedMessageFormat: koishi_1.Schema.string().role('textarea').default(`标题:\${标题}\n作者:\${作者}\n简介:\${简介}\n点赞:\${点赞数}\n收藏:\${收藏数}\n转发:\${转发数}\n播放:\${播放数}\n评论:\${评论数}\n图片数量:\${图片数量}`).description('统一消息格式,可用变量:${标题} ${作者} ${简介} ${点赞数} ${收藏数} ${转发数} ${播放数} ${评论数} ${视频时长} ${发布时间} ${图片数量} ${作者ID} ${封面}'),
20
20
  }).description('消息格式设置'),
21
21
  koishi_1.Schema.object({
22
22
  showImageText: koishi_1.Schema.boolean().default(true).description('是否发送解析后的文字内容'),
@@ -30,7 +30,7 @@ exports.Config = koishi_1.Schema.intersect([
30
30
  }).description('网络与 API 设置'),
31
31
  koishi_1.Schema.object({
32
32
  ignoreSendError: koishi_1.Schema.boolean().default(true).description('忽略消息发送失败,避免插件崩溃'),
33
- retryTimes: koishi_1.Schema.number().min(0).default(3).description('API 请求重试次数(同时用于消息发送重试)'),
33
+ retryTimes: koishi_1.Schema.number().min(0).default(3).description('API 请求及消息发送失败时的重试次数'),
34
34
  retryInterval: koishi_1.Schema.number().min(0).default(1000).description('重试间隔(毫秒,同时用于消息发送重试)'),
35
35
  }).description('错误与重试设置'),
36
36
  koishi_1.Schema.object({
@@ -41,7 +41,7 @@ exports.Config = koishi_1.Schema.intersect([
41
41
  unsupportedPlatformText: koishi_1.Schema.string().default('不支持该平台链接').description('不支持的平台提示'),
42
42
  invalidLinkText: koishi_1.Schema.string().default('无效的视频链接').description('无效链接提示(parse 指令)'),
43
43
  parseErrorPrefix: koishi_1.Schema.string().default('❌ 解析失败:').description('解析失败消息前缀'),
44
- parseErrorItemFormat: koishi_1.Schema.string().default('【${url}】: ${msg}').description('每条解析失败格式,可用 ${url} ${msg}'),
44
+ parseErrorItemFormat: koishi_1.Schema.string().default('【${url}】: ${msg}').description('每条解析失败格式,可用 ${url}(链接)和 ${msg}(错误信息)'),
45
45
  }).description('界面文字设置'),
46
46
  ]);
47
47
  const logger = new koishi_1.Logger(exports.name);
@@ -277,7 +277,7 @@ function generateFormattedText(p, format) {
277
277
  for (const match of varMatches) {
278
278
  const varName = match.replace(/\$\{|\}/g, '');
279
279
  const val = vars[varName];
280
- if (val !== undefined && val !== '') {
280
+ if (val !== undefined && val !== '' && val !== '0') {
281
281
  allEmpty = false;
282
282
  break;
283
283
  }
@@ -368,20 +368,15 @@ function apply(ctx, config) {
368
368
  const text = generateFormattedText(result.data, config.unifiedMessageFormat);
369
369
  return { success: true, data: { text, parsed: result.data } };
370
370
  }
371
- /**
372
- * 发送消息(支持超时与重试),重试次数与间隔与API重试配置绑定
373
- */
374
371
  async function sendWithTimeout(session, content, customRetries) {
375
372
  const maxRetries = customRetries ?? config.retryTimes ?? 3;
376
373
  const retryDelay = config.retryInterval || 1000;
377
374
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
378
375
  try {
379
376
  if (config.videoSendTimeout <= 0) {
380
- // 无超时限制,直接发送
381
377
  return await session.send(content);
382
378
  }
383
379
  else {
384
- // 设置超时竞争
385
380
  return await Promise.race([
386
381
  session.send(content),
387
382
  new Promise((_, reject) => setTimeout(() => reject(new Error('发送超时')), config.videoSendTimeout))
@@ -396,7 +391,6 @@ function apply(ctx, config) {
396
391
  await delay(retryDelay);
397
392
  }
398
393
  else {
399
- // 最后一次失败,根据配置决定是否抛出
400
394
  if (!config.ignoreSendError)
401
395
  throw err;
402
396
  return null;
@@ -440,7 +434,7 @@ function apply(ctx, config) {
440
434
  await delay(300);
441
435
  }
442
436
  }
443
- if (p.cover && p.type !== 'live_photo') {
437
+ if (p.cover && p.type !== 'live_photo' && !(p.type === 'live' && (p.live_photo?.length || p.images?.length))) {
444
438
  if (enableForward)
445
439
  forwardMessages.push(buildForwardNode(session, koishi_1.h.image(p.cover), botName));
446
440
  else {
@@ -448,7 +442,7 @@ function apply(ctx, config) {
448
442
  await delay(300);
449
443
  }
450
444
  }
451
- if (p.video && config.showVideoFile && (p.type === 'video' || p.type === 'live')) {
445
+ if (p.video && config.showVideoFile && (p.type === 'video' || (p.type === 'live' && !p.live_photo?.length && !p.images?.length))) {
452
446
  const videoMsg = koishi_1.h.video(p.video);
453
447
  if (enableForward) {
454
448
  forwardMessages.push(buildForwardNode(session, videoMsg, botName));
@@ -458,8 +452,8 @@ function apply(ctx, config) {
458
452
  await delay(500);
459
453
  }
460
454
  }
461
- if (p.type === 'image' || p.type === 'live_photo') {
462
- const imageUrls = p.images?.length ? p.images : [];
455
+ if (p.type === 'image' || p.type === 'live_photo' || (p.type === 'live' && (p.live_photo?.length || p.images?.length))) {
456
+ const imageUrls = p.images?.length ? p.images : (p.live_photo?.map(lp => lp.image) ?? []);
463
457
  if (enableForward) {
464
458
  for (const url of imageUrls) {
465
459
  forwardMessages.push(buildForwardNode(session, koishi_1.h.image(url), botName));
@@ -474,21 +468,17 @@ function apply(ctx, config) {
474
468
  }
475
469
  }
476
470
  if (enableForward && forwardMessages.length) {
477
- // 合并转发发送时也使用重试机制,失败后降级逐条发送
478
471
  const forwardMsg = (0, koishi_1.h)('message', { forward: true }, forwardMessages.slice(0, 100));
479
- try {
480
- await sendWithTimeout(session, forwardMsg, config.retryTimes); // 使用相同的重试次数
481
- }
482
- catch {
472
+ await sendWithTimeout(session, forwardMsg, config.retryTimes).catch(() => {
483
473
  debugLog('ERROR', '合并转发发送最终失败,降级为逐条发送');
484
- for (const node of forwardMessages) {
474
+ forwardMessages.forEach(async (node) => {
485
475
  try {
486
476
  await sendWithTimeout(session, node.data.content);
487
477
  await delay(300);
488
478
  }
489
479
  catch { }
490
- }
491
- }
480
+ });
481
+ });
492
482
  }
493
483
  }
494
484
  ctx.on('message', async (session) => {
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.9.5",
4
+ "version": "0.9.6",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
package/readme.md CHANGED
@@ -3,7 +3,7 @@
3
3
  ## 项目介绍 (Project Introduction)
4
4
 
5
5
  ### 中文
6
- 这是一个为 Koishi 机器人框架开发的**全平台视频/图集解析插件**,使用统一API接口,支持自动识别并解析抖音、快手、B站、小红书、微博、YouTube、TikTok、剪映、AcFun、知乎、虎牙等20+主流平台的短视频/图集链接。核心特性:
6
+ 这是一个为 Koishi 机器人框架开发的**全平台视频/图集解析插件**,使用统一API接口,支持自动识别并解析抖音、快手、B站、小红书、微博、YouTube、TikTok、剪映、AcFun、知乎、虎牙等20+主流平台的短视频/图集/实况链接。核心特性:
7
7
  - 🌐 统一API解析,覆盖20+热门平台,无需繁琐配置
8
8
  - 🤖 自动识别链接来源,即丢即用
9
9
  - 🎨 完全自定义的解析结果格式,支持多项变量替换,变量无值自动隐藏行
@@ -13,7 +13,7 @@
13
13
  - 🔁 消息发送支持自动重试,与API重试配置联动,增强稳定性
14
14
 
15
15
  ### English
16
- This is a **multi-platform video/image parsing plugin** developed for the Koishi bot framework, using a unified API interface to automatically recognize and parse short video/image links from 20+ mainstream platforms such as Douyin, Kuaishou, Bilibili, Xiaohongshu, Weibo, YouTube, TikTok, Jianying, AcFun, Zhihu, Huya and more. Core features:
16
+ This is a **multi-platform video/image parsing plugin** developed for the Koishi bot framework, using a unified API interface to automatically recognize and parse short video/image/live photo links from 20+ mainstream platforms such as Douyin, Kuaishou, Bilibili, Xiaohongshu, Weibo, YouTube, TikTok, Jianying, AcFun, Zhihu, Huya and more. Core features:
17
17
  - 🌐 Unified API parsing, covering 20+ popular platforms without complex configuration
18
18
  - 🤖 Auto-detection of link sources, just drop & go
19
19
  - 🎨 Fully customizable parsing result format with variable substitutions, empty variables hide the line automatically
@@ -45,7 +45,7 @@ This is a **multi-platform video/image parsing plugin** developed for the Koishi
45
45
  ### 统一消息格式
46
46
  | 配置项 | 类型 | 默认值 | 说明 |
47
47
  |--------|------|--------|------|
48
- | `unifiedMessageFormat` | string | `标题:${标题}\n作者:${作者}\n简介:${简介}\n点赞:${点赞数}\n收藏:${收藏数}\n转发:${转发数}\n播放:${播放数}\n评论:${评论数}` | 自定义解析结果的输出格式,支持变量替换。某行所有变量为空时自动隐藏该行 |
48
+ | `unifiedMessageFormat` | string | `标题:${标题}\n作者:${作者}\n简介:${简介}\n点赞:${点赞数}\n收藏:${收藏数}\n转发:${转发数}\n播放:${播放数}\n评论:${评论数}\n图片数量:${图片数量}` | 自定义解析结果的输出格式,支持变量替换。某行所有变量为空(或为"0")时自动隐藏该行 |
49
49
 
50
50
  ### 内容显示设置
51
51
  | 配置项 | 类型 | 默认值 | 说明 |
@@ -83,7 +83,7 @@ This is a **multi-platform video/image parsing plugin** developed for the Koishi
83
83
  | `parseErrorItemFormat` | string | 【${url}】: ${msg} | 每条解析失败的展示格式,可用 ${url}(链接)和 ${msg}(错误信息) |
84
84
 
85
85
  ## 支持的变量 (Supported Variables)
86
- 在 `unifiedMessageFormat` 中可使用以下变量进行自定义格式化,某行所有变量均为空时该行不显示:
86
+ 在 `unifiedMessageFormat` 中可使用以下变量进行自定义格式化,某行所有变量均为空(或为"0")时该行不显示:
87
87
 
88
88
  | 变量名 | 说明 | 适用平台 |
89
89
  |--------|------|----------|
@@ -97,11 +97,11 @@ This is a **multi-platform video/image parsing plugin** developed for the Koishi
97
97
  | `${播放数}` | 播放量 | 部分平台 |
98
98
  | `${评论数}` | 评论数量 | 所有平台 |
99
99
  | `${发布时间}` | 发布时间(格式化) | 所有平台 |
100
- | `${图片数量}` | 图集图片数量(live_photo 或 images 的数量) | 图集 |
100
+ | `${图片数量}` | 图集/实况图片数量 | 图集/实况 |
101
101
  | `${作者ID}` | 作者唯一标识ID | 部分平台 |
102
102
  | `${封面}` | 封面图片地址 | 所有平台 |
103
103
 
104
- > 注:部分变量可能因平台API返回数据不同而显示为空,空值行会自动隐藏。
104
+ > 注:部分变量可能因平台API返回数据不同而显示为空,某行所有变量为空(或为"0")时该行会自动隐藏。
105
105
 
106
106
  ## 支持的平台 (Supported Platforms)
107
107
  | 平台名称 | 关键词识别 | 解析能力 |