karin-plugin-kkk 2.21.1 → 2.22.0

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
@@ -2,6 +2,18 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [2.22.0](https://github.com/ikenxuan/karin-plugin-kkk/compare/v2.21.1...v2.22.0) (2026-03-07)
6
+
7
+
8
+ ### ✨ 新功能
9
+
10
+ * **douyin:** 初步支持解析文章作品 ([d8b9243](https://github.com/ikenxuan/karin-plugin-kkk/commit/d8b92435d35e56693ceb37f18c451ef51ef86bee))
11
+
12
+
13
+ ### 💯 细节优化
14
+
15
+ * **bilibili:** 解析图文动态时添加标题 close [#260](https://github.com/ikenxuan/karin-plugin-kkk/issues/260) ([2d61705](https://github.com/ikenxuan/karin-plugin-kkk/commit/2d617051aab57c92c9f06d81b5e45b338555fa5b))
16
+
5
17
  ## [2.21.1](https://github.com/ikenxuan/karin-plugin-kkk/compare/v2.21.0...v2.21.1) (2026-03-02)
6
18
 
7
19
 
package/lib/apps/admin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import "../core_chunk/rolldown-runtime-BMXAG3ag.js";
2
- import { C as removeOldFiles, S as dylogin, w as task, x as biLogin } from "../core_chunk/main-B-QVNIL7.js";
3
- import "../core_chunk/vendor-CYCcUtqE.js";
4
- import "../core_chunk/template-n3eb7E79.js";
2
+ import { C as removeOldFiles, S as dylogin, w as task, x as biLogin } from "../core_chunk/main-DgimuYt0.js";
3
+ import "../core_chunk/vendor-BcMLByns.js";
4
+ import "../core_chunk/template-B9tgdrVz.js";
5
5
  export { biLogin, dylogin, removeOldFiles, task };
package/lib/apps/help.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import "../core_chunk/rolldown-runtime-BMXAG3ag.js";
2
- import { b as version, y as help } from "../core_chunk/main-B-QVNIL7.js";
3
- import "../core_chunk/vendor-CYCcUtqE.js";
4
- import "../core_chunk/template-n3eb7E79.js";
2
+ import { b as version, y as help } from "../core_chunk/main-DgimuYt0.js";
3
+ import "../core_chunk/vendor-BcMLByns.js";
4
+ import "../core_chunk/template-B9tgdrVz.js";
5
5
  export { help, version };
package/lib/apps/push.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import "../core_chunk/rolldown-runtime-BMXAG3ag.js";
2
- import { _ as setdyPush, d as bilibiliPushList, f as changeBotID, g as setbiliPush, h as forcePush, m as douyinPushList, p as douyinPush, u as bilibiliPush, v as testDouyinPush } from "../core_chunk/main-B-QVNIL7.js";
3
- import "../core_chunk/vendor-CYCcUtqE.js";
4
- import "../core_chunk/template-n3eb7E79.js";
2
+ import { _ as setdyPush, d as bilibiliPushList, f as changeBotID, g as setbiliPush, h as forcePush, m as douyinPushList, p as douyinPush, u as bilibiliPush, v as testDouyinPush } from "../core_chunk/main-DgimuYt0.js";
3
+ import "../core_chunk/vendor-BcMLByns.js";
4
+ import "../core_chunk/template-B9tgdrVz.js";
5
5
  export { bilibiliPush, bilibiliPushList, changeBotID, douyinPush, douyinPushList, forcePush, setbiliPush, setdyPush, testDouyinPush };
@@ -1,5 +1,5 @@
1
1
  import "../core_chunk/rolldown-runtime-BMXAG3ag.js";
2
- import { l as qrLogin } from "../core_chunk/main-B-QVNIL7.js";
3
- import "../core_chunk/vendor-CYCcUtqE.js";
4
- import "../core_chunk/template-n3eb7E79.js";
2
+ import { l as qrLogin } from "../core_chunk/main-DgimuYt0.js";
3
+ import "../core_chunk/vendor-BcMLByns.js";
4
+ import "../core_chunk/template-B9tgdrVz.js";
5
5
  export { qrLogin };
package/lib/apps/tools.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import "../core_chunk/rolldown-runtime-BMXAG3ag.js";
2
- import { a as douyinAPP, c as xiaohongshuAPP, i as bilibiliAPP, o as kuaishouAPP, s as prefix } from "../core_chunk/main-B-QVNIL7.js";
3
- import "../core_chunk/vendor-CYCcUtqE.js";
4
- import "../core_chunk/template-n3eb7E79.js";
2
+ import { a as douyinAPP, c as xiaohongshuAPP, i as bilibiliAPP, o as kuaishouAPP, s as prefix } from "../core_chunk/main-DgimuYt0.js";
3
+ import "../core_chunk/vendor-BcMLByns.js";
4
+ import "../core_chunk/template-B9tgdrVz.js";
5
5
  export { bilibiliAPP, douyinAPP, kuaishouAPP, prefix, xiaohongshuAPP };
@@ -1,5 +1,5 @@
1
1
  import "../core_chunk/rolldown-runtime-BMXAG3ag.js";
2
- import { n as kkkUpdateCommand, r as update, t as kkkUpdate } from "../core_chunk/main-B-QVNIL7.js";
3
- import "../core_chunk/vendor-CYCcUtqE.js";
4
- import "../core_chunk/template-n3eb7E79.js";
2
+ import { n as kkkUpdateCommand, r as update, t as kkkUpdate } from "../core_chunk/main-DgimuYt0.js";
3
+ import "../core_chunk/vendor-BcMLByns.js";
4
+ import "../core_chunk/template-B9tgdrVz.js";
5
5
  export { kkkUpdate, kkkUpdateCommand, update };
@@ -1,10 +1,10 @@
1
1
  {
2
- "version": "2.21.1",
3
- "buildTime": "2026-03-02T12:56:19.212Z",
4
- "buildTimestamp": 1772456179213,
2
+ "version": "2.22.0",
3
+ "buildTime": "2026-03-07T00:12:10.720Z",
4
+ "buildTimestamp": 1772842330720,
5
5
  "name": "karin-plugin-kkk",
6
6
  "description": "Karin 的「抖音」「B 站」视频解析/动态推送插件",
7
7
  "homepage": "https://github.com/ikenxuan/karin-plugin-kkk",
8
- "commitHash": "e43173f44582ab306a63ac13df2c7a3c4fb33200",
9
- "shortCommitHash": "e43173f4"
8
+ "commitHash": "ce16c435af4230a3e270c42addc04391849b58a2",
9
+ "shortCommitHash": "ce16c435"
10
10
  }
@@ -1,6 +1,6 @@
1
1
  import { n as __esmMin, o as __toESM, r as __export } from "./rolldown-runtime-BMXAG3ag.js";
2
- import { $ as init_date_fns, T as zhCN, _n as init_dist, a as Window, an as require_png, cn as require_heic_decode, dn as Chalk, et as fromUnixTime, fn as init_source, gn as Xhshow, hn as axios_default, i as init_lib, ln as require_express, mn as init_axios, n as require_lib, nt as format, on as require_jsQR, pn as AxiosError$1, r as require_qr_code_styling, rt as differenceInSeconds, sn as require_jpeg_js, t as require_dist, tt as formatDistanceToNow, un as require_protobufjs, vn as init_zod, w as init_locale, yn as zod_default } from "./vendor-CYCcUtqE.js";
3
- import { n as init_client, r as reactServerRender } from "./template-n3eb7E79.js";
2
+ import { $ as init_date_fns, C as zhCN, S as init_locale, _n as init_dist, a as Window, an as require_png, cn as require_heic_decode, dn as Chalk, et as fromUnixTime, fn as init_source, gn as Xhshow, hn as axios_default, i as init_lib, ln as require_express, mn as init_axios, n as require_lib, nt as format, on as require_jsQR, pn as AxiosError$1, r as require_qr_code_styling, rt as differenceInSeconds, sn as require_jpeg_js, t as require_dist, tt as formatDistanceToNow, un as require_protobufjs, vn as init_zod, yn as zod_default } from "./vendor-BcMLByns.js";
3
+ import { n as init_client, r as reactServerRender } from "./template-B9tgdrVz.js";
4
4
  import { createRequire } from "node:module";
5
5
  import karin$1, { BOT_CONNECT, app, authMiddleware, checkPkgUpdate, checkPort, common, components, config, copyConfigSync, createBadRequestResponse, createNotFoundResponse, createServerErrorResponse, createSuccessResponse, db, defineConfig, ffmpeg, ffprobe, filesByExt, getBot, hooks, karin, karinPathHtml, karinPathTemp, logger, logs, mkdirSync, range, render, requireFileSync, restart, segment, updatePkg, watch } from "node-karin";
6
6
  import fs from "node:fs";
@@ -5473,6 +5473,7 @@ var init_Bilibili = __esmMin(() => {
5473
5473
  init_VideoPlayurlNoLogin();
5474
5474
  init_WorkComments$2();
5475
5475
  });
5476
+ var init_ArticleWork = __esmMin(() => {});
5476
5477
  var init_CommentReply = __esmMin(() => {});
5477
5478
  var init_DyDanmakuList = __esmMin(() => {});
5478
5479
  var init_EmojiList$1 = __esmMin(() => {});
@@ -5489,13 +5490,13 @@ var init_SearchInfo = __esmMin(() => {
5489
5490
  });
5490
5491
  var init_SlidesWork = __esmMin(() => {});
5491
5492
  var init_SuggestWords = __esmMin(() => {});
5492
- var init_TextWork = __esmMin(() => {});
5493
5493
  var init_UserInfo = __esmMin(() => {});
5494
5494
  var init_UserLiveVideos = __esmMin(() => {});
5495
5495
  var init_UserPostVideos = __esmMin(() => {});
5496
5496
  var init_VideoWork = __esmMin(() => {});
5497
5497
  var init_WorkComments$1 = __esmMin(() => {});
5498
5498
  var init_Douyin = __esmMin(() => {
5499
+ init_ArticleWork();
5499
5500
  init_CommentReply();
5500
5501
  init_DyDanmakuList();
5501
5502
  init_EmojiList$1();
@@ -5505,7 +5506,6 @@ var init_Douyin = __esmMin(() => {
5505
5506
  init_SearchInfo();
5506
5507
  init_SlidesWork();
5507
5508
  init_SuggestWords();
5508
- init_TextWork();
5509
5509
  init_UserInfo();
5510
5510
  init_UserLiveVideos();
5511
5511
  init_UserPostVideos();
@@ -15706,6 +15706,7 @@ var Bilibili = class extends Base {
15706
15706
  }
15707
15707
  this.e.reply(await Render("bilibili/dynamic/DYNAMIC_TYPE_DRAW", {
15708
15708
  image_url: dynamicCARD$1.item.pictures && cover(dynamicCARD$1.item.pictures),
15709
+ title: dynamicInfo.data.data.item.modules.module_dynamic.major.opus.title ?? void 0,
15709
15710
  text: dynamicInfo.data.data.item.modules.module_dynamic.major ? replacetext(br$3(dynamicInfo.data.data.item.modules.module_dynamic.major.opus?.summary?.text ?? ""), dynamicInfo.data.data.item.modules.module_dynamic.major.opus?.summary?.rich_text_nodes ?? []) : "",
15710
15711
  dianzan: Count(dynamicInfo.data.data.item.modules.module_stat.like.count),
15711
15712
  pinglun: Count(dynamicInfo.data.data.item.modules.module_stat.comment.count),
@@ -17097,6 +17098,7 @@ var Bilibilipush = class extends Base {
17097
17098
  }
17098
17099
  img$2 = await Render("bilibili/dynamic/DYNAMIC_TYPE_DRAW", {
17099
17100
  image_url: dycrad.item.pictures && cover(dycrad.item.pictures),
17101
+ title: data$1[dynamicId].Dynamic_Data.modules.module_dynamic.major?.opus?.title ?? void 0,
17100
17102
  text: replacetext(br$1(data$1[dynamicId].Dynamic_Data.modules.module_dynamic.major?.opus?.summary?.text ?? ""), data$1[dynamicId].Dynamic_Data.modules.module_dynamic.major?.opus?.summary?.rich_text_nodes ?? []),
17101
17103
  dianzan: Count(data$1[dynamicId].Dynamic_Data.modules.module_stat.like.count),
17102
17104
  pinglun: Count(data$1[dynamicId].Dynamic_Data.modules.module_stat.comment.count),
@@ -17875,6 +17877,7 @@ var getRelativeTimeFromTimestamp$2 = (timestamp) => {
17875
17877
  });
17876
17878
  return format(commentDate, "yyyy-MM-dd");
17877
17879
  };
17880
+ await init_date_fns();
17878
17881
  await init_utils$1();
17879
17882
  await init_Config();
17880
17883
  await init_danmaku();
@@ -17899,6 +17902,34 @@ var DouYin = class extends Base {
17899
17902
  this.forceBurnDanmaku = options?.forceBurnDanmaku ?? false;
17900
17903
  this.hasProcessedLiveImage = false;
17901
17904
  }
17905
+ async handleArticleWork(VideoData, _data) {
17906
+ const aweme = VideoData.data.aweme_detail;
17907
+ const content = JSON.parse(aweme.article_info.article_content);
17908
+ const fe_data = JSON.parse(aweme.article_info.fe_data);
17909
+ logger.debug("文章数据提取完成");
17910
+ logger.debug(`文章标题: ${aweme.article_info.article_title}`);
17911
+ logger.debug(`图片数量: ${fe_data.image_list?.length || 0}`);
17912
+ const img$2 = await Render("douyin/article-work", {
17913
+ title: aweme.article_info.article_title,
17914
+ markdown: content.markdown,
17915
+ images: fe_data.image_list || [],
17916
+ read_time: fe_data.read_time || 0,
17917
+ dianzan: Count(aweme.statistics.digg_count),
17918
+ pinglun: Count(aweme.statistics.comment_count),
17919
+ shouchang: Count(aweme.statistics.collect_count),
17920
+ share: Count(aweme.statistics.share_count),
17921
+ create_time: format(fromUnixTime(aweme.create_time), "yyyy-MM-dd HH:mm"),
17922
+ avater_url: aweme.author.avatar_thumb.url_list[0],
17923
+ username: aweme.author.nickname,
17924
+ "抖音号": aweme.author.unique_id || aweme.author.short_id,
17925
+ "获赞": Count(aweme.author.total_favorited),
17926
+ "关注": Count(aweme.author.following_count),
17927
+ "粉丝": Count(aweme.author.follower_count),
17928
+ share_url: `https://www.douyin.com/article/${aweme.aweme_id}`
17929
+ });
17930
+ await this.e.reply(img$2);
17931
+ return true;
17932
+ }
17902
17933
  async DouyinHandler(data$1) {
17903
17934
  Config.app.parseTip && this.e.reply("检测到抖音链接,开始解析");
17904
17935
  switch (this.type) {
@@ -17907,6 +17938,10 @@ var DouYin = class extends Base {
17907
17938
  aweme_id: data$1.aweme_id,
17908
17939
  typeMode: "strict"
17909
17940
  });
17941
+ const aweme_type = VideoData.data.aweme_detail.aweme_type;
17942
+ const isArticle = aweme_type === 163;
17943
+ const isVideo = aweme_type === 0;
17944
+ if (this.is_mp4 === void 0) this.is_mp4 = isVideo;
17910
17945
  const CommentsData = await this.amagi.douyin.fetcher.fetchWorkComments({
17911
17946
  aweme_id: data$1.aweme_id,
17912
17947
  number: Config.douyin.numcomment,
@@ -17917,7 +17952,7 @@ var DouYin = class extends Base {
17917
17952
  let g_title;
17918
17953
  let imagenum = 0;
17919
17954
  const image_res = [];
17920
- if (this.is_mp4 === false) switch (true) {
17955
+ if (this.is_mp4 === false && !isArticle) switch (true) {
17921
17956
  case this.is_slides === false && VideoData.data.aweme_detail.images !== null: {
17922
17957
  const image_data = [];
17923
17958
  const imageres = [];
@@ -18146,7 +18181,7 @@ var DouYin = class extends Base {
18146
18181
  } catch (error) {
18147
18182
  console.log(error);
18148
18183
  }
18149
- music_url && this.is_mp4 === false && music_url !== void 0 && !this.hasProcessedLiveImage && await this.e.reply(segment.record(music_url, false));
18184
+ music_url && (this.is_mp4 === false || isArticle) && music_url !== void 0 && !this.hasProcessedLiveImage && await this.e.reply(segment.record(music_url, false));
18150
18185
  }
18151
18186
  let FPS;
18152
18187
  let video = null;
@@ -18168,7 +18203,7 @@ var DouYin = class extends Base {
18168
18203
  if (Config.douyin.sendContent.includes("info")) if (Config.douyin.videoInfoMode === "text") {
18169
18204
  const replyContent = [];
18170
18205
  const { digg_count, share_count, collect_count, comment_count, recommend_count } = VideoData.data.aweme_detail.statistics;
18171
- const coverUrl = await processImageUrl(this.is_mp4 ? VideoData.data.aweme_detail.video.animated_cover?.url_list[0] ?? VideoData.data.aweme_detail.video.cover.url_list[0] : VideoData.data.aweme_detail.images[0].url_list[0], VideoData.data.aweme_detail.desc);
18206
+ const coverUrl = await processImageUrl(isArticle ? VideoData.data.aweme_detail.video.origin_cover.url_list[0] : this.is_mp4 ? VideoData.data.aweme_detail.video.animated_cover?.url_list[0] ?? VideoData.data.aweme_detail.video.cover.url_list[0] : VideoData.data.aweme_detail.images[0].url_list[0], VideoData.data.aweme_detail.desc);
18172
18207
  const contentMap = {
18173
18208
  cover: segment.image(coverUrl),
18174
18209
  title: segment.text(`\n📺 标题: ${VideoData.data.aweme_detail.desc}\n`),
@@ -18190,7 +18225,7 @@ var DouYin = class extends Base {
18190
18225
  typeMode: "strict"
18191
18226
  });
18192
18227
  const videoInfoImg = await Render("douyin/videoInfo", {
18193
- desc: VideoData.data.aweme_detail.desc,
18228
+ desc: isArticle ? VideoData.data.aweme_detail.preview_title : VideoData.data.aweme_detail.desc,
18194
18229
  statistics: VideoData.data.aweme_detail.statistics,
18195
18230
  aweme_id: VideoData.data.aweme_detail.aweme_id,
18196
18231
  author: {
@@ -18206,8 +18241,11 @@ var DouYin = class extends Base {
18206
18241
  gender: userProfile.data.user.gender ?? 0,
18207
18242
  user_age: userProfile.data.user.user_age ?? 0
18208
18243
  } : void 0,
18209
- image_url: this.is_mp4 ? VideoData.data.aweme_detail.video.animated_cover?.url_list[0] ?? VideoData.data.aweme_detail.video.cover_original_scale?.url_list[0] ?? VideoData.data.aweme_detail.video.cover.url_list[0] : VideoData.data.aweme_detail.images[0].url_list[0],
18210
- cover_size: this.is_mp4 ? VideoData.data.aweme_detail.video.cover ? {
18244
+ image_url: isArticle ? VideoData.data.aweme_detail.video.origin_cover.url_list[0] : this.is_mp4 ? VideoData.data.aweme_detail.video.animated_cover?.url_list[0] ?? VideoData.data.aweme_detail.video.cover_original_scale?.url_list[0] ?? VideoData.data.aweme_detail.video.cover.url_list[0] : VideoData.data.aweme_detail.images[0].url_list[0],
18245
+ cover_size: isArticle ? VideoData.data.aweme_detail.video.origin_cover ? {
18246
+ width: VideoData.data.aweme_detail.video.origin_cover.width,
18247
+ height: VideoData.data.aweme_detail.video.origin_cover.height
18248
+ } : void 0 : this.is_mp4 ? VideoData.data.aweme_detail.video.cover ? {
18211
18249
  width: VideoData.data.aweme_detail.video.cover_original_scale.width,
18212
18250
  height: VideoData.data.aweme_detail.video.cover_original_scale.height
18213
18251
  } : void 0 : VideoData.data.aweme_detail.images?.[0] ? {
@@ -18229,6 +18267,7 @@ var DouYin = class extends Base {
18229
18267
  });
18230
18268
  this.e.reply(videoInfoImg);
18231
18269
  }
18270
+ if (isArticle) await this.handleArticleWork(VideoData, data$1);
18232
18271
  if (Config.douyin.sendContent.includes("comment")) {
18233
18272
  const douyinCommentsRes = await douyinComments(CommentsData, Emoji((await this.amagi.douyin.fetcher.fetchEmojiList({ typeMode: "loose" })).data));
18234
18273
  if (!douyinCommentsRes.CommentsData.length) await this.e.reply("这个作品没有评论 ~");
@@ -18238,7 +18277,7 @@ var DouYin = class extends Base {
18238
18277
  for (const item of VideoData.data.aweme_detail.suggest_words.suggest_words) if (item.words && item.scene === "comment_top_rec") for (const v of item.words) v.word && suggest.push(v.word);
18239
18278
  }
18240
18279
  const img$2 = await Render("douyin/comment", {
18241
- Type: this.is_mp4 ? "视频" : this.is_slides ? "合辑" : "图集",
18280
+ Type: isArticle ? "文章" : this.is_mp4 ? "视频" : this.is_slides ? "合辑" : "图集",
18242
18281
  CommentsData: douyinCommentsRes.CommentsData,
18243
18282
  CommentLength: Config.douyin.realCommentCount ? VideoData.data.aweme_detail.statistics.comment_count : douyinCommentsRes.CommentsData.length ?? 0,
18244
18283
  share_url: this.is_mp4 ? `https://aweme.snssdk.com/aweme/v1/play/?video_id=${VideoData.data.aweme_detail.video.play_addr.uri}&ratio=1080p&line=0` : VideoData.data.aweme_detail.share_url,
@@ -18267,7 +18306,7 @@ var DouYin = class extends Base {
18267
18306
  this.e.reply(img$2);
18268
18307
  }
18269
18308
  }
18270
- if (this.is_mp4 && Config.douyin.sendContent.includes("video")) {
18309
+ if (this.is_mp4 && !isArticle && Config.douyin.sendContent.includes("video")) {
18271
18310
  let danmakuList = [];
18272
18311
  if ((this.forceBurnDanmaku || Config.douyin.burnDanmaku) && video) try {
18273
18312
  const duration = video.duration;
@@ -18577,8 +18616,69 @@ var getStringDisplayWidth = (str) => {
18577
18616
  }
18578
18617
  return width;
18579
18618
  };
18619
+ let DouyinWorkMainType = function(DouyinWorkMainType$1) {
18620
+ DouyinWorkMainType$1["VIDEO"] = "video";
18621
+ DouyinWorkMainType$1["IMAGE"] = "image";
18622
+ DouyinWorkMainType$1["ARTICLE"] = "article";
18623
+ DouyinWorkMainType$1["LIVE"] = "live";
18624
+ DouyinWorkMainType$1["MUSIC"] = "music";
18625
+ DouyinWorkMainType$1["UNKNOWN"] = "unknown";
18626
+ return DouyinWorkMainType$1;
18627
+ }({});
18628
+ let DouyinImageSubType = function(DouyinImageSubType$1) {
18629
+ DouyinImageSubType$1["GALLERY"] = "gallery";
18630
+ DouyinImageSubType$1["COLLECTION"] = "collection";
18631
+ return DouyinImageSubType$1;
18632
+ }({});
18633
+ function getWorkTypeInfo(data$1) {
18634
+ if (data$1.aweme_type === 163 || data$1.article_info) return {
18635
+ mainType: DouyinWorkMainType.ARTICLE,
18636
+ isVideo: false,
18637
+ isImage: false,
18638
+ isArticle: true,
18639
+ isGallery: false,
18640
+ isCollection: false,
18641
+ templatePath: "douyin/article-work"
18642
+ };
18643
+ if (data$1.images && data$1.images.length > 0) {
18644
+ const subType = data$1.is_slides === true ? DouyinImageSubType.COLLECTION : DouyinImageSubType.GALLERY;
18645
+ return {
18646
+ mainType: DouyinWorkMainType.IMAGE,
18647
+ subType,
18648
+ isVideo: false,
18649
+ isImage: true,
18650
+ isArticle: false,
18651
+ isGallery: subType === DouyinImageSubType.GALLERY,
18652
+ isCollection: subType === DouyinImageSubType.COLLECTION,
18653
+ templatePath: "douyin/image-work"
18654
+ };
18655
+ }
18656
+ return {
18657
+ mainType: DouyinWorkMainType.VIDEO,
18658
+ isVideo: true,
18659
+ isImage: false,
18660
+ isArticle: false,
18661
+ isGallery: false,
18662
+ isCollection: false,
18663
+ templatePath: "douyin/video-work"
18664
+ };
18665
+ }
18666
+ function getWorkCoverUrl(workTypeInfo, data$1) {
18667
+ if (workTypeInfo.isVideo && data$1.video) return data$1.video.animated_cover?.url_list[0] ?? data$1.video.cover_original_scale?.url_list[0] ?? data$1.video.cover?.url_list[0] ?? "";
18668
+ if (workTypeInfo.isImage && data$1.images && data$1.images.length > 0) return data$1.images[0].url_list[0] ?? "";
18669
+ if (workTypeInfo.isArticle && data$1.article_info?.article_content) try {
18670
+ return JSON.parse(data$1.article_info.article_content).head_poster_list?.url_list?.[0] ?? "";
18671
+ } catch {
18672
+ return "";
18673
+ }
18674
+ return "";
18675
+ }
18580
18676
  const getDouyinID = async (event, url, log = true) => {
18581
- const longLink = (await axios.get(url, { headers: { "User-Agent": "Apifox/1.0.0 (https://apifox.com)" } })).request.res.responseUrl;
18677
+ const resp = await axios.get(url, {
18678
+ headers: { "User-Agent": "Apifox/1.0.0 (https://apifox.com)" },
18679
+ maxRedirects: 10
18680
+ });
18681
+ const longLink = resp.request?.res?.responseUrl || resp.request?.responseURL || url;
18582
18682
  let result = {};
18583
18683
  switch (true) {
18584
18684
  case longLink.includes("webcast.amemv.com"):
@@ -18594,21 +18694,13 @@ const getDouyinID = async (event, url, log = true) => {
18594
18694
  room_id: longLink.split("/").pop()
18595
18695
  };
18596
18696
  break;
18597
- case /video\/(\d+)/.test(longLink): {
18598
- const videoMatch = /video\/(\d+)/.exec(longLink);
18599
- result = {
18600
- type: "one_work",
18601
- aweme_id: videoMatch ? videoMatch[1] : void 0,
18602
- is_mp4: true
18603
- };
18604
- break;
18605
- }
18697
+ case /video\/(\d+)/.test(longLink):
18698
+ case /article\/(\d+)/.test(longLink):
18606
18699
  case /note\/(\d+)/.test(longLink): {
18607
- const noteMatch = /note\/(\d+)/.exec(longLink);
18700
+ const match = /(?:video|article|note)\/(\d+)/.exec(longLink);
18608
18701
  result = {
18609
18702
  type: "one_work",
18610
- aweme_id: noteMatch ? noteMatch[1] : void 0,
18611
- is_mp4: false
18703
+ aweme_id: match ? match[1] : void 0
18612
18704
  };
18613
18705
  break;
18614
18706
  }
@@ -18617,7 +18709,8 @@ const getDouyinID = async (event, url, log = true) => {
18617
18709
  result = {
18618
18710
  type: "one_work",
18619
18711
  aweme_id: modalMatch ? modalMatch[1] : void 0,
18620
- is_mp4: true
18712
+ is_mp4: true,
18713
+ work_type: DouyinWorkMainType.VIDEO
18621
18714
  };
18622
18715
  break;
18623
18716
  }
@@ -18960,7 +19053,7 @@ var DouYinpush = class extends Base {
18960
19053
  if (pushItem.pushType === "favorite") {
18961
19054
  const authorUserInfo = "author_user_info" in Detail_Data ? Detail_Data.author_user_info : void 0;
18962
19055
  img$2 = await Render("douyin/favorite-list", {
18963
- image_url: iddata.is_mp4 ? Detail_Data.video.animated_cover?.url_list[0] ?? Detail_Data.video.cover_original_scale?.url_list[0] ?? Detail_Data.video.cover.url_list[0] : Detail_Data.images[0].url_list[0],
19056
+ image_url: getWorkCoverUrl(getWorkTypeInfo(Detail_Data), Detail_Data),
18964
19057
  desc: this.desc(Detail_Data, Detail_Data.desc),
18965
19058
  dianzan: this.count(Detail_Data.statistics.digg_count),
18966
19059
  pinglun: this.count(Detail_Data.statistics.comment_count),
@@ -18979,7 +19072,7 @@ var DouYinpush = class extends Base {
18979
19072
  } else if (pushItem.pushType === "recommend") {
18980
19073
  const authorUserInfo = "author_user_info" in Detail_Data ? Detail_Data.author_user_info : void 0;
18981
19074
  img$2 = await Render("douyin/recommend-list", {
18982
- image_url: iddata.is_mp4 ? Detail_Data.video.animated_cover?.url_list[0] ?? Detail_Data.video.cover_original_scale?.url_list[0] ?? Detail_Data.video.cover.url_list[0] : Detail_Data.images[0].url_list[0],
19075
+ image_url: getWorkCoverUrl(getWorkTypeInfo(Detail_Data), Detail_Data),
18983
19076
  desc: this.desc(Detail_Data, Detail_Data.desc),
18984
19077
  dianzan: this.count(Detail_Data.statistics.digg_count),
18985
19078
  pinglun: this.count(Detail_Data.statistics.comment_count),
@@ -18995,45 +19088,72 @@ var DouYinpush = class extends Base {
18995
19088
  author_douyin_id: authorUserInfo.data.user.unique_id === "" ? authorUserInfo.data.user.short_id : authorUserInfo.data.user.unique_id,
18996
19089
  share_url: Config.douyin.push.shareType === "web" ? realUrl : `https://aweme.snssdk.com/aweme/v1/play/?video_id=${Detail_Data.video.play_addr.uri}&ratio=1080p&line=0`
18997
19090
  });
18998
- } else img$2 = await Render("douyin/dynamic", {
18999
- image_url: iddata.is_mp4 ? Detail_Data.video.animated_cover?.url_list[0] ?? Detail_Data.video.cover.url_list[0] : Detail_Data.images[0].url_list[0],
19000
- desc: this.desc(Detail_Data, Detail_Data.desc),
19001
- dianzan: this.count(Detail_Data.statistics.digg_count),
19002
- pinglun: this.count(Detail_Data.statistics.comment_count),
19003
- share: this.count(Detail_Data.statistics.share_count),
19004
- shouchang: this.count(Detail_Data.statistics.collect_count),
19005
- create_time: format(fromUnixTime(pushItem.create_time), "yyyy-MM-dd HH:mm"),
19006
- avater_url: "https://p3-pc.douyinpic.com/aweme/1080x1080/" + Detail_Data.user_info.data.user.avatar_larger.uri,
19007
- share_url: Config.douyin.push.shareType === "web" ? realUrl : `https://aweme.snssdk.com/aweme/v1/play/?video_id=${Detail_Data.video.play_addr.uri}&ratio=1080p&line=0`,
19008
- username: Detail_Data.author.nickname,
19009
- "抖音号": Detail_Data.user_info.data.user.unique_id === "" ? Detail_Data.user_info.data.user.short_id : Detail_Data.user_info.data.user.unique_id,
19010
- "粉丝": this.count(Detail_Data.user_info.data.user.follower_count),
19011
- "获赞": this.count(Detail_Data.user_info.data.user.total_favorited),
19012
- "关注": this.count(Detail_Data.user_info.data.user.following_count),
19013
- dynamicTYPE: "作品动态推送",
19014
- cooperation_info: (() => {
19015
- const raw = Detail_Data.cooperation_info;
19016
- if (!raw) return void 0;
19017
- const rawCreators = Array.isArray(raw.co_creators) ? raw.co_creators : [];
19018
- const author = Detail_Data.author;
19019
- const authorUid = author?.uid;
19020
- const authorSecUid = author?.sec_uid;
19021
- const authorNickname = author?.nickname;
19022
- const authorInCreators = rawCreators.some((c) => authorUid && c.uid && c.uid === authorUid || authorSecUid && c.sec_uid && c.sec_uid === authorSecUid || authorNickname && c.nickname && c.nickname === authorNickname);
19023
- const co_creators = rawCreators.map((c) => {
19024
- const firstUrl = c.avatar_thumb?.url_list?.[0] ?? (c.avatar_thumb?.uri ? `https://p3.douyinpic.com/${c.avatar_thumb.uri}` : void 0);
19091
+ } else {
19092
+ const dynamicTypeLabel = "作品动态推送";
19093
+ const workTypeInfo = getWorkTypeInfo(Detail_Data);
19094
+ const coverUrl = getWorkCoverUrl(workTypeInfo, Detail_Data);
19095
+ if (workTypeInfo.isArticle) {
19096
+ const content = JSON.parse(Detail_Data.article_info.article_content);
19097
+ const fe_data = JSON.parse(Detail_Data.article_info.fe_data);
19098
+ img$2 = await Render("douyin/article-work", {
19099
+ title: Detail_Data.article_info.article_title,
19100
+ markdown: content.markdown,
19101
+ images: fe_data.image_list || [],
19102
+ read_time: fe_data.read_time || 0,
19103
+ dianzan: this.count(Detail_Data.statistics.digg_count),
19104
+ pinglun: this.count(Detail_Data.statistics.comment_count),
19105
+ shouchang: this.count(Detail_Data.statistics.collect_count),
19106
+ share: this.count(Detail_Data.statistics.share_count),
19107
+ create_time: format(fromUnixTime(pushItem.create_time), "yyyy-MM-dd HH:mm"),
19108
+ avater_url: "https://p3-pc.douyinpic.com/aweme/1080x1080/" + Detail_Data.user_info.data.user.avatar_larger.uri,
19109
+ username: Detail_Data.author.nickname,
19110
+ "抖音号": Detail_Data.user_info.data.user.unique_id === "" ? Detail_Data.user_info.data.user.short_id : Detail_Data.user_info.data.user.unique_id,
19111
+ "获赞": this.count(Detail_Data.user_info.data.user.total_favorited),
19112
+ "关注": this.count(Detail_Data.user_info.data.user.following_count),
19113
+ "粉丝": this.count(Detail_Data.user_info.data.user.follower_count),
19114
+ share_url: Detail_Data.share_url,
19115
+ useDarkTheme: false
19116
+ });
19117
+ } else img$2 = await Render(workTypeInfo.templatePath, {
19118
+ image_url: coverUrl,
19119
+ desc: this.desc(Detail_Data, Detail_Data.desc),
19120
+ dianzan: this.count(Detail_Data.statistics.digg_count),
19121
+ pinglun: this.count(Detail_Data.statistics.comment_count),
19122
+ share: this.count(Detail_Data.statistics.share_count),
19123
+ shouchang: this.count(Detail_Data.statistics.collect_count),
19124
+ create_time: format(fromUnixTime(pushItem.create_time), "yyyy-MM-dd HH:mm"),
19125
+ avater_url: "https://p3-pc.douyinpic.com/aweme/1080x1080/" + Detail_Data.user_info.data.user.avatar_larger.uri,
19126
+ share_url: Config.douyin.push.shareType === "web" ? realUrl : `https://aweme.snssdk.com/aweme/v1/play/?video_id=${Detail_Data.video.play_addr.uri}&ratio=1080p&line=0`,
19127
+ username: Detail_Data.author.nickname,
19128
+ "抖音号": Detail_Data.user_info.data.user.unique_id === "" ? Detail_Data.user_info.data.user.short_id : Detail_Data.user_info.data.user.unique_id,
19129
+ "粉丝": this.count(Detail_Data.user_info.data.user.follower_count),
19130
+ "获赞": this.count(Detail_Data.user_info.data.user.total_favorited),
19131
+ "关注": this.count(Detail_Data.user_info.data.user.following_count),
19132
+ dynamicTYPE: dynamicTypeLabel,
19133
+ cooperation_info: (() => {
19134
+ const raw = Detail_Data.cooperation_info;
19135
+ if (!raw) return void 0;
19136
+ const rawCreators = Array.isArray(raw.co_creators) ? raw.co_creators : [];
19137
+ const author = Detail_Data.author;
19138
+ const authorUid = author?.uid;
19139
+ const authorSecUid = author?.sec_uid;
19140
+ const authorNickname = author?.nickname;
19141
+ const authorInCreators = rawCreators.some((c) => authorUid && c.uid && c.uid === authorUid || authorSecUid && c.sec_uid && c.sec_uid === authorSecUid || authorNickname && c.nickname && c.nickname === authorNickname);
19142
+ const co_creators = rawCreators.map((c) => {
19143
+ const firstUrl = c.avatar_thumb?.url_list?.[0] ?? (c.avatar_thumb?.uri ? `https://p3.douyinpic.com/${c.avatar_thumb.uri}` : void 0);
19144
+ return {
19145
+ avatar_thumb: firstUrl ? { url_list: [firstUrl] } : void 0,
19146
+ nickname: c.nickname,
19147
+ role_title: c.role_title
19148
+ };
19149
+ });
19025
19150
  return {
19026
- avatar_thumb: firstUrl ? { url_list: [firstUrl] } : void 0,
19027
- nickname: c.nickname,
19028
- role_title: c.role_title
19151
+ co_creator_nums: Math.max(Number(raw.co_creator_nums || 0), co_creators.length) + (authorInCreators ? 0 : 1),
19152
+ co_creators
19029
19153
  };
19030
- });
19031
- return {
19032
- co_creator_nums: Math.max(Number(raw.co_creator_nums || 0), co_creators.length) + (authorInCreators ? 0 : 1),
19033
- co_creators
19034
- };
19035
- })()
19036
- });
19154
+ })()
19155
+ });
19156
+ }
19037
19157
  }
19038
19158
  for (const target of pushItem.targets) {
19039
19159
  let status = { message_id: "" };
@@ -20339,8 +20459,35 @@ var handleTestDouyinPush = wrapWithErrorHandler(async (e) => {
20339
20459
  Connection: "keep-alive"
20340
20460
  }
20341
20461
  }).getLocation();
20342
- const img$2 = await Render("douyin/dynamic", {
20343
- image_url: iddata.is_mp4 ? workInfo.data.aweme_detail.video.animated_cover?.url_list[0] ?? workInfo.data.aweme_detail.video.cover.url_list[0] : workInfo.data.aweme_detail.images[0].url_list[0],
20462
+ const workTypeInfo = getWorkTypeInfo(workInfo.data.aweme_detail);
20463
+ const coverUrl = getWorkCoverUrl(workTypeInfo, workInfo.data.aweme_detail);
20464
+ if (workTypeInfo.isArticle) {
20465
+ const content = JSON.parse(workInfo.data.aweme_detail.article_info.article_content);
20466
+ const fe_data = JSON.parse(workInfo.data.aweme_detail.article_info.fe_data);
20467
+ const img$3 = await Render("douyin/article-work", {
20468
+ title: workInfo.data.aweme_detail.article_info.article_title,
20469
+ markdown: content.markdown,
20470
+ images: fe_data.image_list || [],
20471
+ read_time: fe_data.read_time || 0,
20472
+ dianzan: Common.count(workInfo.data.aweme_detail.statistics.digg_count),
20473
+ pinglun: Common.count(workInfo.data.aweme_detail.statistics.comment_count),
20474
+ shouchang: Common.count(workInfo.data.aweme_detail.statistics.collect_count),
20475
+ share: Common.count(workInfo.data.aweme_detail.statistics.share_count),
20476
+ create_time: format(fromUnixTime(workInfo.data.aweme_detail.create_time), "yyyy-MM-dd HH:mm"),
20477
+ avater_url: "https://p3-pc.douyinpic.com/aweme/1080x1080/" + userProfile.data.user.avatar_larger.uri,
20478
+ username: workInfo.data.aweme_detail.author.nickname,
20479
+ "抖音号": userProfile.data.user.unique_id === "" ? userProfile.data.user.short_id : userProfile.data.user.unique_id,
20480
+ "获赞": Common.count(userProfile.data.user.total_favorited),
20481
+ "关注": Common.count(userProfile.data.user.following_count),
20482
+ "粉丝": Common.count(userProfile.data.user.follower_count),
20483
+ share_url: workInfo.data.aweme_detail.share_url,
20484
+ useDarkTheme: false
20485
+ });
20486
+ e.reply(img$3);
20487
+ return true;
20488
+ }
20489
+ const img$2 = await Render(workTypeInfo.templatePath, {
20490
+ image_url: coverUrl,
20344
20491
  desc: workInfo.data.aweme_detail.desc,
20345
20492
  dianzan: Common.count(workInfo.data.aweme_detail.statistics.digg_count),
20346
20493
  pinglun: Common.count(workInfo.data.aweme_detail.statistics.comment_count),