koishi-plugin-kkk 3.10.1 → 3.10.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # 更新日志
2
2
 
3
+ ## 3.10.2
4
+
5
+ > 修小红书图文笔记的图集一次解析发两遍的问题。
6
+
7
+ ### 修小红书图集发两遍
8
+
9
+ - 图文笔记的图集有**两个发送点**:一个不看「发送内容」开关、直接发一条 markdown 全套图,
10
+ 另一个按 `sendContent` 里的「图片」发(含实况图处理)。两个都命中时就是**两套图集**。
11
+ - 删掉前面那个不看开关的,图集统一由「图片」那处发送;关掉「图片」现在是真的不发了
12
+ (以前关掉照样会发一份)。
13
+ - 顺带给图集发送加了失败兜底:发不出去只记一步失败,后面的视频和错误卡片照常,
14
+ 不再把整条解析掀翻。
15
+
3
16
  ## 3.10.1
4
17
 
5
18
  > B站的复制跳转修一下:3.10.0 改成用用户发的那条链接后,B站 App 复制了反而不跳。
@@ -1,10 +1,10 @@
1
1
  {
2
- "version": "3.10.1",
3
- "buildTime": "2026-09-30T02:30:42.608Z",
4
- "buildTimestamp": 1790735442631,
2
+ "version": "3.10.2",
3
+ "buildTime": "2026-09-30T06:37:26.725Z",
4
+ "buildTimestamp": 1790750246750,
5
5
  "name": "koishi-plugin-kkk",
6
6
  "description": "抖音 / B站 / 快手 / 小红书 视频解析与动态推送,带 QQ 交互面板与弹幕烧录(karin-plugin-kkk 的 Koishi 移植版)",
7
7
  "homepage": "https://github.com/maimai993/koishi-plugin-kkk#readme",
8
- "commitHash": "faa50bc98b4adaa32a0dda5bdf68de39539794f1",
9
- "shortCommitHash": "faa50bc"
8
+ "commitHash": "146e95e8c0f183d42d08beba60a079b6d0b81c07",
9
+ "shortCommitHash": "146e95e"
10
10
  }
@@ -5,7 +5,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.XiaohongshuEmoji = exports.xiaohongshuProcessVideos = exports.xiaohongshuGetLivePhotoVideo = exports.Xiaohongshu = void 0;
7
7
  const node_fs_1 = __importDefault(require("node:fs"));
8
- const ImageSlice_1 = require("../../module/utils/ImageSlice");
9
8
  const QqPanel_1 = require("../../module/utils/QqPanel");
10
9
  const parseTip_1 = require("../../module/utils/parseTip");
11
10
  const date_fns_1 = require("date-fns");
@@ -227,33 +226,12 @@ class Xiaohongshu extends module_1.Base {
227
226
  node_karin_2.logger.mark('[小红书] 详情卡片已发送');
228
227
  }
229
228
  /**
230
- * **图文笔记的图片要发出来**(用户要求)。
229
+ * **图集只发一次,由下面 `sendContent.includes('image')` 那块统一负责**(含实况图处理)。
231
230
  *
232
- * 之前只发了详情卡片,正文里的图片一张都没发 —— 用户看到的就是
233
- * 「解析出来了图文,但图呢?」。这里和抖音图集一样:合并成**一条 markdown**
234
- * (图片紧贴渲染,一条消息装完整套图)。
231
+ * 这里以前还有一段「图文图片合并成一条 markdown 发出去」的兜底,它**不看 sendContent 开关**,
232
+ * 于是勾了「图片」的部署会收到**两套图集**:先一条 markdown 全套图,紧接着又一条合并转发。
233
+ * 现在删掉了 —— 图集由下面那块按开关发,关掉「图片」就真的不发了(原来关掉照样发一份)。
235
234
  */
236
- const noteImages = (noteCard.image_list ?? [])
237
- .map((image) => String(image?.url_default ?? image?.url ?? ''))
238
- .filter(Boolean);
239
- if (!noteCard.video && noteImages.length) {
240
- try {
241
- const mdMessage = await (0, QqPanel_1.buildMarkdownImageMessage)(noteImages, 420, (0, ImageSlice_1.platformOf)(this.e));
242
- if (mdMessage) {
243
- await this.e.reply(mdMessage);
244
- node_karin_2.logger.mark('[小红书] 图文图片已用一条 markdown 发送,共 ' + noteImages.length + ' 张');
245
- }
246
- else {
247
- // md 生成失败就逐张发,总比一张不发好
248
- for (const imageUrl of noteImages)
249
- await this.e.reply(node_karin_1.segment.image(imageUrl));
250
- node_karin_2.logger.mark('[小红书] md 生成失败,图文图片改为逐张发送,共 ' + noteImages.length + ' 张');
251
- }
252
- }
253
- catch (error) {
254
- node_karin_2.logger.warn('[小红书] 发送图文图片失败: ' + String(error?.message ?? error).slice(0, 120));
255
- }
256
- }
257
235
  /**
258
236
  * 带「先提示、再宽限」的超时包装(和图片发送那边同一套口径,见 ImageSlice 的 SEND_* 常量)。
259
237
  *
@@ -517,11 +495,15 @@ class Xiaohongshu extends module_1.Base {
517
495
  processedImages.push(...tipImg);
518
496
  }
519
497
  const res = node_karin_1.common.makeForward(processedImages, Config_1.Config.app.fakeForward ? this.e.sender.userId : this.e.bot.account.selfId, Config_1.Config.app.fakeForward ? this.e.sender.nick : this.e.bot.account.name);
520
- if (processedImages.length === 1) {
521
- await this.e.reply(processedImages[0]);
522
- }
523
- else if (processedImages.length > 1) {
524
- try {
498
+ /**
499
+ * 发图集是**唯一一次**发送图集的地方(另一处已删,见上面注释),所以失败要记进 steps:
500
+ * 让它只跳过这一步、照常走后面的视频 / 错误卡片,而不是把整条解析掀翻。
501
+ */
502
+ try {
503
+ if (processedImages.length === 1) {
504
+ await this.e.reply(processedImages[0]);
505
+ }
506
+ else if (processedImages.length > 1) {
525
507
  await this.e.bot.sendForwardMsg(this.e.contact, res, {
526
508
  source: '图片合集',
527
509
  summary: `查看${res.length}张图片/视频消息`,
@@ -529,10 +511,15 @@ class Xiaohongshu extends module_1.Base {
529
511
  news: [{ text: '点击查看解析结果' }]
530
512
  });
531
513
  }
532
- finally {
533
- for (const item of temp) {
534
- await module_1.Common.removeFile(item.filepath, true);
535
- }
514
+ node_karin_2.logger.mark('[小红书] 图集已发送,共 ' + processedImages.length + ' 张');
515
+ }
516
+ catch (error) {
517
+ steps.fail('发送图集', error);
518
+ }
519
+ finally {
520
+ // 临时文件(实况图生成的视频 / 静态图 / 合成封面)用完就删,失败也要删
521
+ for (const item of temp) {
522
+ await module_1.Common.removeFile(item.filepath, true);
536
523
  }
537
524
  }
538
525
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koishi-plugin-kkk",
3
- "version": "3.10.1",
3
+ "version": "3.10.2",
4
4
  "description": "抖音 / B站 / 快手 / 小红书 视频解析与动态推送,带 QQ 交互面板与弹幕烧录(karin-plugin-kkk 的 Koishi 移植版)",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
@@ -1,6 +1,5 @@
1
1
  import fs from 'node:fs'
2
- import { platformOf } from '@/module/utils/ImageSlice'
3
- import { buildMarkdownImageMessage, sendCopyJumpMessage, xiaohongshuShareUrl } from '@/module/utils/QqPanel'
2
+ import { sendCopyJumpMessage, xiaohongshuShareUrl } from '@/module/utils/QqPanel'
4
3
  import { sendParseTip } from '@/module/utils/parseTip'
5
4
 
6
5
  import type { NoteComments, XiaohongshuEmojiListResponse } from '@ikenxuan/amagi'
@@ -274,30 +273,12 @@ export class Xiaohongshu extends Base {
274
273
  }
275
274
 
276
275
  /**
277
- * **图文笔记的图片要发出来**(用户要求)。
276
+ * **图集只发一次,由下面 `sendContent.includes('image')` 那块统一负责**(含实况图处理)。
278
277
  *
279
- * 之前只发了详情卡片,正文里的图片一张都没发 —— 用户看到的就是
280
- * 「解析出来了图文,但图呢?」。这里和抖音图集一样:合并成**一条 markdown**
281
- * (图片紧贴渲染,一条消息装完整套图)。
278
+ * 这里以前还有一段「图文图片合并成一条 markdown 发出去」的兜底,它**不看 sendContent 开关**,
279
+ * 于是勾了「图片」的部署会收到**两套图集**:先一条 markdown 全套图,紧接着又一条合并转发。
280
+ * 现在删掉了 —— 图集由下面那块按开关发,关掉「图片」就真的不发了(原来关掉照样发一份)。
282
281
  */
283
- const noteImages: string[] = (noteCard.image_list ?? [])
284
- .map((image: any) => String(image?.url_default ?? image?.url ?? ''))
285
- .filter(Boolean)
286
- if (!noteCard.video && noteImages.length) {
287
- try {
288
- const mdMessage = await buildMarkdownImageMessage(noteImages, 420, platformOf(this.e))
289
- if (mdMessage) {
290
- await this.e.reply(mdMessage)
291
- logger.mark('[小红书] 图文图片已用一条 markdown 发送,共 ' + noteImages.length + ' 张')
292
- } else {
293
- // md 生成失败就逐张发,总比一张不发好
294
- for (const imageUrl of noteImages) await this.e.reply(segment.image(imageUrl))
295
- logger.mark('[小红书] md 生成失败,图文图片改为逐张发送,共 ' + noteImages.length + ' 张')
296
- }
297
- } catch (error: any) {
298
- logger.warn('[小红书] 发送图文图片失败: ' + String(error?.message ?? error).slice(0, 120))
299
- }
300
- }
301
282
 
302
283
  /**
303
284
  * 带「先提示、再宽限」的超时包装(和图片发送那边同一套口径,见 ImageSlice 的 SEND_* 常量)。
@@ -585,20 +566,28 @@ export class Xiaohongshu extends Base {
585
566
  Config.app.fakeForward ? this.e.sender.nick : this.e.bot.account.name
586
567
  )
587
568
 
588
- if (processedImages.length === 1) {
589
- await this.e.reply(processedImages[0])
590
- } else if (processedImages.length > 1) {
591
- try {
569
+ /**
570
+ * 发图集是**唯一一次**发送图集的地方(另一处已删,见上面注释),所以失败要记进 steps:
571
+ * 让它只跳过这一步、照常走后面的视频 / 错误卡片,而不是把整条解析掀翻。
572
+ */
573
+ try {
574
+ if (processedImages.length === 1) {
575
+ await this.e.reply(processedImages[0])
576
+ } else if (processedImages.length > 1) {
592
577
  await this.e.bot.sendForwardMsg(this.e.contact, res, {
593
578
  source: '图片合集',
594
579
  summary: `查看${res.length}张图片/视频消息`,
595
580
  prompt: '小红书图集解析结果',
596
581
  news: [{ text: '点击查看解析结果' }]
597
582
  })
598
- } finally {
599
- for (const item of temp) {
600
- await Common.removeFile(item.filepath, true)
601
- }
583
+ }
584
+ logger.mark('[小红书] 图集已发送,共 ' + processedImages.length + ' 张')
585
+ } catch (error: any) {
586
+ steps.fail('发送图集', error)
587
+ } finally {
588
+ // 临时文件(实况图生成的视频 / 静态图 / 合成封面)用完就删,失败也要删
589
+ for (const item of temp) {
590
+ await Common.removeFile(item.filepath, true)
602
591
  }
603
592
  }
604
593
  }