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

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 +41 -30
  2. package/package.json +1 -1
  3. package/readme.md +5 -3
package/lib/index.js CHANGED
@@ -30,8 +30,8 @@ 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 请求重试次数'),
34
- retryInterval: koishi_1.Schema.number().min(0).default(1000).description('重试间隔(毫秒)'),
33
+ retryTimes: koishi_1.Schema.number().min(0).default(3).description('API 请求重试次数(同时用于消息发送重试)'),
34
+ retryInterval: koishi_1.Schema.number().min(0).default(1000).description('重试间隔(毫秒,同时用于消息发送重试)'),
35
35
  }).description('错误与重试设置'),
36
36
  koishi_1.Schema.object({
37
37
  enableForward: koishi_1.Schema.boolean().default(false).description('启用合并转发(仅 OneBot 平台)'),
@@ -368,28 +368,42 @@ 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
- async function sendWithTimeout(session, content) {
372
- if (config.videoSendTimeout <= 0) {
371
+ /**
372
+ * 发送消息(支持超时与重试),重试次数与间隔与API重试配置绑定
373
+ */
374
+ async function sendWithTimeout(session, content, customRetries) {
375
+ const maxRetries = customRetries ?? config.retryTimes ?? 3;
376
+ const retryDelay = config.retryInterval || 1000;
377
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
373
378
  try {
374
- return await session.send(content);
379
+ if (config.videoSendTimeout <= 0) {
380
+ // 无超时限制,直接发送
381
+ return await session.send(content);
382
+ }
383
+ else {
384
+ // 设置超时竞争
385
+ return await Promise.race([
386
+ session.send(content),
387
+ new Promise((_, reject) => setTimeout(() => reject(new Error('发送超时')), config.videoSendTimeout))
388
+ ]);
389
+ }
375
390
  }
376
391
  catch (err) {
377
- if (!config.ignoreSendError)
378
- throw err;
379
- return null;
392
+ const errMsg = getErrorMessage(err);
393
+ debugLog('ERROR', `第${attempt + 1}次发送失败: ${errMsg}`);
394
+ if (attempt < maxRetries) {
395
+ debugLog('INFO', `等待 ${retryDelay}ms 后进行第 ${attempt + 2} 次重试`);
396
+ await delay(retryDelay);
397
+ }
398
+ else {
399
+ // 最后一次失败,根据配置决定是否抛出
400
+ if (!config.ignoreSendError)
401
+ throw err;
402
+ return null;
403
+ }
380
404
  }
381
405
  }
382
- try {
383
- return await Promise.race([
384
- session.send(content),
385
- new Promise((_, reject) => setTimeout(() => reject(new Error('发送超时')), config.videoSendTimeout))
386
- ]);
387
- }
388
- catch (err) {
389
- if (!config.ignoreSendError)
390
- throw err;
391
- return null;
392
- }
406
+ return null;
393
407
  }
394
408
  async function flush(session, urls) {
395
409
  const items = [];
@@ -407,7 +421,7 @@ function apply(ctx, config) {
407
421
  }
408
422
  }
409
423
  if (errors.length) {
410
- await sendWithTimeout(session, `${texts.parseErrorPrefix}\n${errors.join('\n')}`).catch(() => { });
424
+ await sendWithTimeout(session, `${texts.parseErrorPrefix}\n${errors.join('\n')}`);
411
425
  await delay(500);
412
426
  }
413
427
  if (!items.length)
@@ -440,10 +454,7 @@ function apply(ctx, config) {
440
454
  forwardMessages.push(buildForwardNode(session, videoMsg, botName));
441
455
  }
442
456
  else {
443
- try {
444
- await sendWithTimeout(session, videoMsg);
445
- }
446
- catch { }
457
+ await sendWithTimeout(session, videoMsg).catch(() => { });
447
458
  await delay(500);
448
459
  }
449
460
  }
@@ -456,20 +467,20 @@ function apply(ctx, config) {
456
467
  }
457
468
  else {
458
469
  for (const url of imageUrls) {
459
- try {
460
- await sendWithTimeout(session, koishi_1.h.image(url));
461
- await delay(200);
462
- }
463
- catch { }
470
+ await sendWithTimeout(session, koishi_1.h.image(url)).catch(() => { });
471
+ await delay(200);
464
472
  }
465
473
  }
466
474
  }
467
475
  }
468
476
  if (enableForward && forwardMessages.length) {
477
+ // 合并转发发送时也使用重试机制,失败后降级逐条发送
478
+ const forwardMsg = (0, koishi_1.h)('message', { forward: true }, forwardMessages.slice(0, 100));
469
479
  try {
470
- await sendWithTimeout(session, (0, koishi_1.h)('message', { forward: true }, forwardMessages.slice(0, 100)));
480
+ await sendWithTimeout(session, forwardMsg, config.retryTimes); // 使用相同的重试次数
471
481
  }
472
482
  catch {
483
+ debugLog('ERROR', '合并转发发送最终失败,降级为逐条发送');
473
484
  for (const node of forwardMessages) {
474
485
  try {
475
486
  await sendWithTimeout(session, node.data.content);
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.3",
4
+ "version": "0.9.5",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
package/readme.md CHANGED
@@ -10,6 +10,7 @@
10
10
  - 🐛 内置Debug调试模式,可详细记录所有操作与API交互日志
11
11
  - 📤 支持OneBot平台消息合并转发,优化多图文展示体验
12
12
  - 💬 所有提示文案均可自定义,适配多语言场景
13
+ - 🔁 消息发送支持自动重试,与API重试配置联动,增强稳定性
13
14
 
14
15
  ### English
15
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:
@@ -19,6 +20,7 @@ This is a **multi-platform video/image parsing plugin** developed for the Koishi
19
20
  - 🐛 Built-in Debug mode, recording detailed operations and API interaction logs
20
21
  - 📤 Support OneBot message forwarding for better image/video display
21
22
  - 💬 All prompt texts are customizable for multilingual scenarios
23
+ - 🔁 Message sending supports automatic retries, linked with API retry configuration for improved stability
22
24
 
23
25
  ## 项目仓库 (Repository)
24
26
  - GitHub: `https://github.com/Minecraft-1314/koishi-plugin-video-parser-all`
@@ -63,8 +65,8 @@ This is a **multi-platform video/image parsing plugin** developed for the Koishi
63
65
  | 配置项 | 类型 | 默认值 | 说明 |
64
66
  |--------|------|--------|------|
65
67
  | `ignoreSendError` | boolean | true | 是否忽略消息发送失败,避免插件崩溃 |
66
- | `retryTimes` | number | 3 | API 请求失败时的重试次数 |
67
- | `retryInterval` | number | 1000 | 重试间隔时间(毫秒) |
68
+ | `retryTimes` | number | 3 | API 请求及消息发送失败时的重试次数 |
69
+ | `retryInterval` | number | 1000 | API 请求及消息发送重试的间隔时间(毫秒) |
68
70
 
69
71
  ### 发送方式设置
70
72
  | 配置项 | 类型 | 默认值 | 说明 |
@@ -78,7 +80,7 @@ This is a **multi-platform video/image parsing plugin** developed for the Koishi
78
80
  | `unsupportedPlatformText` | string | 不支持该平台链接 | 不支持的平台提示 |
79
81
  | `invalidLinkText` | string | 无效的视频链接 | 无效链接提示(parse 指令) |
80
82
  | `parseErrorPrefix` | string | ❌ 解析失败: | 解析失败消息前缀 |
81
- | `parseErrorItemFormat` | string | 【${url}】: ${msg} | 每条解析失败格式,可用 `${url}` `${msg}` |
83
+ | `parseErrorItemFormat` | string | 【${url}】: ${msg} | 每条解析失败的展示格式,可用 ${url}(链接)和 ${msg}(错误信息) |
82
84
 
83
85
  ## 支持的变量 (Supported Variables)
84
86
  在 `unifiedMessageFormat` 中可使用以下变量进行自定义格式化,某行所有变量均为空时该行不显示: