karin-plugin-kkk 2.40.3 → 2.41.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.
@@ -571,6 +571,15 @@ var BilibiliAPI = class {
571
571
  getUserCard(data) {
572
572
  return `https://api.bilibili.com/x/web-interface/card?mid=${data.host_mid}&photo=true`;
573
573
  }
574
+ /**
575
+ * 按用户 UID 获取直播状态。
576
+ *
577
+ * @remarks
578
+ * 该接口直接返回用户当前直播状态,不依赖空间动态中的直播推荐卡片。
579
+ */
580
+ getUserLiveStatus(data) {
581
+ return `https://api.live.bilibili.com/room/v1/Room/getRoomInfoOld?mid=${data.host_mid}`;
582
+ }
574
583
  /** 获取直播间信息 */
575
584
  getLiveRoomInfo(data) {
576
585
  return `https://api.live.bilibili.com/room/v1/Room/get_info?room_id=${data.room_id}`;
@@ -1016,6 +1025,7 @@ var BilibiliUserParamsSchema = zod_default.object({
1016
1025
  methodType: zod_default.enum([
1017
1026
  "userCard",
1018
1027
  "userDynamicList",
1028
+ "userLiveStatus",
1019
1029
  "uploaderTotalViews",
1020
1030
  "userSpaceInfo"
1021
1031
  ], { error: "方法类型必须是指定的枚举值之一" }),
@@ -1116,6 +1126,7 @@ var BilibiliValidationSchemas = {
1116
1126
  commentReplies: BilibiliCommentReplyParamsSchema,
1117
1127
  userCard: BilibiliUserParamsSchema,
1118
1128
  userDynamicList: BilibiliUserParamsSchema,
1129
+ userLiveStatus: BilibiliUserParamsSchema,
1119
1130
  userSpaceInfo: BilibiliUserParamsSchema,
1120
1131
  emojiList: BilibiliEmojiParamsSchema,
1121
1132
  bangumiInfo: BilibiliBangumiInfoParamsSchema,
@@ -1146,6 +1157,7 @@ var BilibiliMethodRoutes = {
1146
1157
  commentReplies: "/fetch_comment_reply",
1147
1158
  userCard: "/fetch_user_profile",
1148
1159
  userDynamicList: "/fetch_user_dynamic",
1160
+ userLiveStatus: "/fetch_user_live_status",
1149
1161
  userSpaceInfo: "/fetch_user_space_info",
1150
1162
  emojiList: "/fetch_emoji_list",
1151
1163
  bangumiInfo: "/fetch_bangumi_video_info",
@@ -2417,6 +2429,27 @@ async function fetchUserDynamicList(options, cookie, requestConfig) {
2417
2429
  });
2418
2430
  }
2419
2431
  /**
2432
+ * 按用户 UID 获取B站直播状态
2433
+ * @param options - 用户参数
2434
+ * @param options.host_mid - 用户 UID
2435
+ * @param cookie - B站 Cookie (可选)
2436
+ * @param requestConfig - 请求配置 (可选)
2437
+ * @returns 用户直播状态与直播间基础信息
2438
+ * @example
2439
+ * ```typescript
2440
+ * const result = await fetchUserLiveStatus({ host_mid: 123456, typeMode: 'strict' }, cookie)
2441
+ * if (result.success && result.data.data.liveStatus === 1) {
2442
+ * console.log(result.data.data.roomid) // 正在直播的房间 ID
2443
+ * }
2444
+ * ```
2445
+ */
2446
+ async function fetchUserLiveStatus(options, cookie, requestConfig) {
2447
+ return fetchBilibiliInternal("userLiveStatus", options, {
2448
+ cookie,
2449
+ requestConfig
2450
+ });
2451
+ }
2452
+ /**
2420
2453
  * 获取B站用户空间详细信息
2421
2454
  * @param options - 用户参数
2422
2455
  * @param options.host_mid - 用户 UID
@@ -2574,6 +2607,37 @@ async function fetchVideoDanmaku(options, cookie, requestConfig) {
2574
2607
  });
2575
2608
  }
2576
2609
  //#endregion
2610
+ //#region ../amagi/packages/core/src/model/fetchers/shared/request-config.ts
2611
+ /**
2612
+ * 合并 Fetcher 的实例级请求配置与单次请求配置。
2613
+ *
2614
+ * 单次配置优先,请求头单独合并。函数不会修改任一入参,因此同一绑定
2615
+ * Fetcher 可以安全地在并发任务中为不同请求使用不同配置。
2616
+ */
2617
+ var mergeRequestConfig = (base, override) => {
2618
+ if (!override) return base;
2619
+ return {
2620
+ ...base ?? {},
2621
+ ...override,
2622
+ headers: {
2623
+ ...base?.headers ?? {},
2624
+ ...override.headers ?? {}
2625
+ }
2626
+ };
2627
+ };
2628
+ /**
2629
+ * 解析绑定 Fetcher 当前调用实际使用的 cookie 与请求配置。
2630
+ *
2631
+ * 实例级或单次配置显式提供大写 `headers.Cookie` 时,合并后的值同时替换
2632
+ * 底层 Fetcher 的 cookie 参数,确保平台签名、前置请求和最终请求处于同一身份状态。
2633
+ */
2634
+ var resolveBoundRequest = (boundCookie, base, override) => {
2635
+ const requestConfig = mergeRequestConfig(base, override);
2636
+ const headers = requestConfig?.headers;
2637
+ const cookieOverride = Boolean(headers && Object.prototype.hasOwnProperty.call(headers, "Cookie")) ? headers.Cookie : void 0;
2638
+ return [typeof cookieOverride === "string" ? cookieOverride : boundCookie, requestConfig];
2639
+ };
2640
+ //#endregion
2577
2641
  //#region ../amagi/packages/core/src/model/fetchers/bilibili/bound.ts
2578
2642
  /**
2579
2643
  * 创建绑定了 Cookie 和请求配置的 B站 Fetcher
@@ -2589,35 +2653,37 @@ async function fetchVideoDanmaku(options, cookie, requestConfig) {
2589
2653
  * ```
2590
2654
  */
2591
2655
  function createBoundBilibiliFetcher(cookie, requestConfig) {
2656
+ const resolveRequest = (override) => resolveBoundRequest(cookie, requestConfig, override);
2592
2657
  return {
2593
- fetchVideoInfo: (options) => fetchVideoInfo(options, cookie, requestConfig),
2594
- fetchVideoStreamUrl: (options) => fetchVideoStreamUrl(options, cookie, requestConfig),
2595
- fetchVideoDanmaku: (options) => fetchVideoDanmaku(options, cookie, requestConfig),
2596
- fetchComments: (options) => fetchComments(options, cookie, requestConfig),
2597
- fetchCommentReplies: (options) => fetchCommentReplies$1(options, cookie, requestConfig),
2598
- fetchUserCard: (options) => fetchUserCard(options, cookie, requestConfig),
2599
- fetchUserDynamicList: (options) => fetchUserDynamicList(options, cookie, requestConfig),
2600
- fetchUserSpaceInfo: (options) => fetchUserSpaceInfo(options, cookie, requestConfig),
2601
- fetchUploaderTotalViews: (options) => fetchUploaderTotalViews(options, cookie, requestConfig),
2602
- fetchDynamicDetail: (options) => fetchDynamicDetail(options, cookie, requestConfig),
2658
+ fetchVideoInfo: (options, override) => fetchVideoInfo(options, ...resolveRequest(override)),
2659
+ fetchVideoStreamUrl: (options, override) => fetchVideoStreamUrl(options, ...resolveRequest(override)),
2660
+ fetchVideoDanmaku: (options, override) => fetchVideoDanmaku(options, ...resolveRequest(override)),
2661
+ fetchComments: (options, override) => fetchComments(options, ...resolveRequest(override)),
2662
+ fetchCommentReplies: (options, override) => fetchCommentReplies$1(options, ...resolveRequest(override)),
2663
+ fetchUserCard: (options, override) => fetchUserCard(options, ...resolveRequest(override)),
2664
+ fetchUserDynamicList: (options, override) => fetchUserDynamicList(options, ...resolveRequest(override)),
2665
+ fetchUserLiveStatus: (options, override) => fetchUserLiveStatus(options, ...resolveRequest(override)),
2666
+ fetchUserSpaceInfo: (options, override) => fetchUserSpaceInfo(options, ...resolveRequest(override)),
2667
+ fetchUploaderTotalViews: (options, override) => fetchUploaderTotalViews(options, ...resolveRequest(override)),
2668
+ fetchDynamicDetail: (options, override) => fetchDynamicDetail(options, ...resolveRequest(override)),
2603
2669
  /** @deprecated v6.1.3 已废弃,调用将返回错误信息 */
2604
- fetchDynamicCard: (options) => fetchDynamicCard(options, cookie, requestConfig),
2605
- fetchBangumiInfo: (options) => fetchBangumiInfo(options, cookie, requestConfig),
2606
- fetchBangumiStreamUrl: (options) => fetchBangumiStreamUrl(options, cookie, requestConfig),
2607
- fetchLiveRoomInfo: (options) => fetchLiveRoomInfo$2(options, cookie, requestConfig),
2608
- fetchLiveRoomInitInfo: (options) => fetchLiveRoomInitInfo(options, cookie, requestConfig),
2609
- fetchArticleContent: (options) => fetchArticleContent(options, cookie, requestConfig),
2610
- fetchArticleCards: (options) => fetchArticleCards(options, cookie, requestConfig),
2611
- fetchArticleInfo: (options) => fetchArticleInfo(options, cookie, requestConfig),
2612
- fetchArticleListInfo: (options) => fetchArticleListInfo(options, cookie, requestConfig),
2613
- fetchLoginStatus: (options) => fetchLoginStatus(options, cookie, requestConfig),
2614
- requestLoginQrcode: (options) => requestLoginQrcode$1(options, cookie, requestConfig),
2615
- checkQrcodeStatus: (options) => checkQrcodeStatus(options, cookie, requestConfig),
2616
- requestCaptchaFromVoucher: (options) => requestCaptchaFromVoucher(options, cookie, requestConfig),
2617
- validateCaptchaResult: (options) => validateCaptchaResult(options, cookie, requestConfig),
2618
- convertAvToBv: (options) => convertAvToBv(options, cookie, requestConfig),
2619
- convertBvToAv: (options) => convertBvToAv(options, cookie, requestConfig),
2620
- fetchEmojiList: (options) => fetchEmojiList$3(options, cookie, requestConfig)
2670
+ fetchDynamicCard: (options, override) => fetchDynamicCard(options, ...resolveRequest(override)),
2671
+ fetchBangumiInfo: (options, override) => fetchBangumiInfo(options, ...resolveRequest(override)),
2672
+ fetchBangumiStreamUrl: (options, override) => fetchBangumiStreamUrl(options, ...resolveRequest(override)),
2673
+ fetchLiveRoomInfo: (options, override) => fetchLiveRoomInfo$2(options, ...resolveRequest(override)),
2674
+ fetchLiveRoomInitInfo: (options, override) => fetchLiveRoomInitInfo(options, ...resolveRequest(override)),
2675
+ fetchArticleContent: (options, override) => fetchArticleContent(options, ...resolveRequest(override)),
2676
+ fetchArticleCards: (options, override) => fetchArticleCards(options, ...resolveRequest(override)),
2677
+ fetchArticleInfo: (options, override) => fetchArticleInfo(options, ...resolveRequest(override)),
2678
+ fetchArticleListInfo: (options, override) => fetchArticleListInfo(options, ...resolveRequest(override)),
2679
+ fetchLoginStatus: (options, override) => fetchLoginStatus(options, ...resolveRequest(override)),
2680
+ requestLoginQrcode: (options, override) => requestLoginQrcode$1(options, ...resolveRequest(override)),
2681
+ checkQrcodeStatus: (options, override) => checkQrcodeStatus(options, ...resolveRequest(override)),
2682
+ requestCaptchaFromVoucher: (options, override) => requestCaptchaFromVoucher(options, ...resolveRequest(override)),
2683
+ validateCaptchaResult: (options, override) => validateCaptchaResult(options, ...resolveRequest(override)),
2684
+ convertAvToBv: (options, override) => convertAvToBv(options, ...resolveRequest(override)),
2685
+ convertBvToAv: (options, override) => convertBvToAv(options, ...resolveRequest(override)),
2686
+ fetchEmojiList: (options, override) => fetchEmojiList$3(options, ...resolveRequest(override))
2621
2687
  };
2622
2688
  }
2623
2689
  //#endregion
@@ -2644,6 +2710,7 @@ var bilibiliFetcher$1 = {
2644
2710
  fetchCommentReplies: fetchCommentReplies$1,
2645
2711
  fetchUserCard,
2646
2712
  fetchUserDynamicList,
2713
+ fetchUserLiveStatus,
2647
2714
  fetchUserSpaceInfo,
2648
2715
  fetchUploaderTotalViews,
2649
2716
  fetchDynamicDetail,
@@ -5196,26 +5263,27 @@ async function fetchDanmakuList(options, cookie, requestConfig) {
5196
5263
  * ```
5197
5264
  */
5198
5265
  function createBoundDouyinFetcher(cookie, requestConfig) {
5266
+ const resolveRequest = (override) => resolveBoundRequest(cookie, requestConfig, override);
5199
5267
  return {
5200
- fetchVideoWork: (options, reqConfig) => fetchVideoWork$1(options, cookie, reqConfig ?? requestConfig),
5201
- fetchImageAlbumWork: (options, reqConfig) => fetchImageAlbumWork(options, cookie, reqConfig ?? requestConfig),
5202
- fetchSlidesWork: (options, reqConfig) => fetchSlidesWork(options, cookie, reqConfig ?? requestConfig),
5203
- fetchTextWork: (options, reqConfig) => fetchTextWork(options, cookie, reqConfig ?? requestConfig),
5204
- parseWork: (options, reqConfig) => parseWork(options, cookie, reqConfig ?? requestConfig),
5205
- fetchDanmakuList: (options, reqConfig) => fetchDanmakuList(options, cookie, reqConfig ?? requestConfig),
5206
- fetchWorkComments: (options, reqConfig) => fetchWorkComments$1(options, cookie, reqConfig ?? requestConfig),
5207
- fetchCommentReplies: (options, reqConfig) => fetchCommentReplies(options, cookie, reqConfig ?? requestConfig),
5208
- fetchUserProfile: (options, reqConfig) => fetchUserProfile$2(options, cookie, reqConfig ?? requestConfig),
5209
- fetchUserVideoList: (options, reqConfig) => fetchUserVideoList(options, cookie, reqConfig ?? requestConfig),
5210
- fetchUserFavoriteList: (options, reqConfig) => fetchUserFavoriteList(options, cookie, reqConfig ?? requestConfig),
5211
- fetchUserRecommendList: (options, reqConfig) => fetchUserRecommendList(options, cookie, reqConfig ?? requestConfig),
5212
- searchContent: (options, reqConfig) => searchContent(options, cookie, reqConfig ?? requestConfig),
5213
- fetchSuggestWords: (options, reqConfig) => fetchSuggestWords(options, cookie, reqConfig ?? requestConfig),
5214
- fetchMusicInfo: (options, reqConfig) => fetchMusicInfo(options, cookie, reqConfig ?? requestConfig),
5215
- fetchLiveRoomInfo: (options, reqConfig) => fetchLiveRoomInfo$1(options, cookie, reqConfig ?? requestConfig),
5216
- requestLoginQrcode: (options, reqConfig) => requestLoginQrcode(options, cookie, reqConfig ?? requestConfig),
5217
- fetchEmojiList: (options, reqConfig) => fetchEmojiList$2(options, cookie, reqConfig ?? requestConfig),
5218
- fetchDynamicEmojiList: (options, reqConfig) => fetchDynamicEmojiList(options, cookie, reqConfig ?? requestConfig)
5268
+ fetchVideoWork: (options, override) => fetchVideoWork$1(options, ...resolveRequest(override)),
5269
+ fetchImageAlbumWork: (options, override) => fetchImageAlbumWork(options, ...resolveRequest(override)),
5270
+ fetchSlidesWork: (options, override) => fetchSlidesWork(options, ...resolveRequest(override)),
5271
+ fetchTextWork: (options, override) => fetchTextWork(options, ...resolveRequest(override)),
5272
+ parseWork: (options, override) => parseWork(options, ...resolveRequest(override)),
5273
+ fetchDanmakuList: (options, override) => fetchDanmakuList(options, ...resolveRequest(override)),
5274
+ fetchWorkComments: (options, override) => fetchWorkComments$1(options, ...resolveRequest(override)),
5275
+ fetchCommentReplies: (options, override) => fetchCommentReplies(options, ...resolveRequest(override)),
5276
+ fetchUserProfile: (options, override) => fetchUserProfile$2(options, ...resolveRequest(override)),
5277
+ fetchUserVideoList: (options, override) => fetchUserVideoList(options, ...resolveRequest(override)),
5278
+ fetchUserFavoriteList: (options, override) => fetchUserFavoriteList(options, ...resolveRequest(override)),
5279
+ fetchUserRecommendList: (options, override) => fetchUserRecommendList(options, ...resolveRequest(override)),
5280
+ searchContent: (options, override) => searchContent(options, ...resolveRequest(override)),
5281
+ fetchSuggestWords: (options, override) => fetchSuggestWords(options, ...resolveRequest(override)),
5282
+ fetchMusicInfo: (options, override) => fetchMusicInfo(options, ...resolveRequest(override)),
5283
+ fetchLiveRoomInfo: (options, override) => fetchLiveRoomInfo$1(options, ...resolveRequest(override)),
5284
+ requestLoginQrcode: (options, override) => requestLoginQrcode(options, ...resolveRequest(override)),
5285
+ fetchEmojiList: (options, override) => fetchEmojiList$2(options, ...resolveRequest(override)),
5286
+ fetchDynamicEmojiList: (options, override) => fetchDynamicEmojiList(options, ...resolveRequest(override))
5219
5287
  };
5220
5288
  }
5221
5289
  //#endregion
@@ -7608,13 +7676,14 @@ var kuaishouFetcher$1 = {
7608
7676
  * ```
7609
7677
  */
7610
7678
  function createBoundKuaishouFetcher(cookie, requestConfig) {
7679
+ const resolveRequest = (override) => resolveBoundRequest(cookie, requestConfig, override);
7611
7680
  return {
7612
- fetchVideoWork: (options, reqConfig) => fetchVideoWork(options, cookie, reqConfig ?? requestConfig),
7613
- fetchWorkComments: (options, reqConfig) => fetchWorkComments(options, cookie, reqConfig ?? requestConfig),
7614
- fetchUserProfile: (options, reqConfig) => fetchUserProfile$1(options, cookie, reqConfig ?? requestConfig),
7615
- fetchUserWorkList: (options, reqConfig) => fetchUserWorkList(options, cookie, reqConfig ?? requestConfig),
7616
- fetchLiveRoomInfo: (options, reqConfig) => fetchLiveRoomInfo(options, cookie, reqConfig ?? requestConfig),
7617
- fetchEmojiList: (options, reqConfig) => fetchEmojiList$1(options, cookie, reqConfig ?? requestConfig)
7681
+ fetchVideoWork: (options, override) => fetchVideoWork(options, ...resolveRequest(override)),
7682
+ fetchWorkComments: (options, override) => fetchWorkComments(options, ...resolveRequest(override)),
7683
+ fetchUserProfile: (options, override) => fetchUserProfile$1(options, ...resolveRequest(override)),
7684
+ fetchUserWorkList: (options, override) => fetchUserWorkList(options, ...resolveRequest(override)),
7685
+ fetchLiveRoomInfo: (options, override) => fetchLiveRoomInfo(options, ...resolveRequest(override)),
7686
+ fetchEmojiList: (options, override) => fetchEmojiList$1(options, ...resolveRequest(override))
7618
7687
  };
7619
7688
  }
7620
7689
  //#endregion
@@ -8053,14 +8122,15 @@ var xiaohongshuFetcher$1 = {
8053
8122
  * ```
8054
8123
  */
8055
8124
  function createBoundXiaohongshuFetcher(cookie, requestConfig) {
8125
+ const resolveRequest = (override) => resolveBoundRequest(cookie, requestConfig, override);
8056
8126
  return {
8057
- fetchHomeFeed: (options = {}, reqConfig) => fetchHomeFeed(options, cookie, reqConfig ?? requestConfig),
8058
- fetchNoteDetail: (options, reqConfig) => fetchNoteDetail(options, cookie, reqConfig ?? requestConfig),
8059
- fetchNoteComments: (options, reqConfig) => fetchNoteComments(options, cookie, reqConfig ?? requestConfig),
8060
- fetchUserProfile: (options, reqConfig) => fetchUserProfile(options, cookie, reqConfig ?? requestConfig),
8061
- fetchUserNoteList: (options, reqConfig) => fetchUserNoteList(options, cookie, reqConfig ?? requestConfig),
8062
- searchNotes: (options, reqConfig) => searchNotes(options, cookie, reqConfig ?? requestConfig),
8063
- fetchEmojiList: (options, reqConfig) => fetchEmojiList(options, cookie, reqConfig ?? requestConfig)
8127
+ fetchHomeFeed: (options = {}, override) => fetchHomeFeed(options, ...resolveRequest(override)),
8128
+ fetchNoteDetail: (options, override) => fetchNoteDetail(options, ...resolveRequest(override)),
8129
+ fetchNoteComments: (options, override) => fetchNoteComments(options, ...resolveRequest(override)),
8130
+ fetchUserProfile: (options, override) => fetchUserProfile(options, ...resolveRequest(override)),
8131
+ fetchUserNoteList: (options, override) => fetchUserNoteList(options, ...resolveRequest(override)),
8132
+ searchNotes: (options, override) => searchNotes(options, ...resolveRequest(override)),
8133
+ fetchEmojiList: (options, override) => fetchEmojiList(options, ...resolveRequest(override))
8064
8134
  };
8065
8135
  }
8066
8136
  //#endregion
@@ -8823,6 +8893,10 @@ var fetchBilibili = async (data, cookie, requestConfig) => {
8823
8893
  url: bilibiliApiUrls.getUserCard({ host_mid })
8824
8894
  });
8825
8895
  }
8896
+ case "userLiveStatus": return await GlobalGetData(data.methodType, {
8897
+ ...baseRequestConfig,
8898
+ url: bilibiliApiUrls.getUserLiveStatus({ host_mid: data.host_mid })
8899
+ });
8826
8900
  case "userSpaceInfo": {
8827
8901
  const wbiSignQuery = await wbi_sign(bilibiliApiUrls.getUserSpaceInfo({ host_mid: data.host_mid }), baseRequestConfig.headers?.cookie);
8828
8902
  return await GlobalGetData(data.methodType, {
@@ -9910,6 +9984,7 @@ var BilibiliInternalMethods = {
9910
9984
  COMMENT_REPLIES: "指定评论的回复",
9911
9985
  USER_CARD: "用户主页数据",
9912
9986
  USER_DYNAMICS: "用户主页动态列表数据",
9987
+ USER_LIVE_STATUS: "用户直播状态",
9913
9988
  USER_SPACE_INFO: "用户空间详细信息",
9914
9989
  USER_TOTAL_VIEWS: "获取UP主总播放量",
9915
9990
  DYNAMIC_DETAIL: "动态详情数据",
@@ -9940,6 +10015,7 @@ var BilibiliFetcherMethods = {
9940
10015
  COMMENT_REPLIES: "fetchCommentReplies",
9941
10016
  USER_CARD: "fetchUserCard",
9942
10017
  USER_DYNAMICS: "fetchUserDynamicList",
10018
+ USER_LIVE_STATUS: "fetchUserLiveStatus",
9943
10019
  USER_SPACE_INFO: "fetchUserSpaceInfo",
9944
10020
  USER_TOTAL_VIEWS: "fetchUploaderTotalViews",
9945
10021
  DYNAMIC_DETAIL: "fetchDynamicDetail",
@@ -10048,6 +10124,7 @@ var BilibiliMethodToFetcher = {
10048
10124
  [BilibiliInternalMethods.COMMENT_REPLIES]: BilibiliFetcherMethods.COMMENT_REPLIES,
10049
10125
  [BilibiliInternalMethods.USER_CARD]: BilibiliFetcherMethods.USER_CARD,
10050
10126
  [BilibiliInternalMethods.USER_DYNAMICS]: BilibiliFetcherMethods.USER_DYNAMICS,
10127
+ [BilibiliInternalMethods.USER_LIVE_STATUS]: BilibiliFetcherMethods.USER_LIVE_STATUS,
10051
10128
  [BilibiliInternalMethods.USER_SPACE_INFO]: BilibiliFetcherMethods.USER_SPACE_INFO,
10052
10129
  [BilibiliInternalMethods.USER_TOTAL_VIEWS]: BilibiliFetcherMethods.USER_TOTAL_VIEWS,
10053
10130
  [BilibiliInternalMethods.DYNAMIC_DETAIL]: BilibiliFetcherMethods.DYNAMIC_DETAIL,
@@ -10179,6 +10256,7 @@ var BilibiliMethodMapping = {
10179
10256
  指定评论的回复: "fetchCommentReplies",
10180
10257
  用户主页数据: "fetchUserCard",
10181
10258
  用户主页动态列表数据: "fetchUserDynamicList",
10259
+ 用户直播状态: "fetchUserLiveStatus",
10182
10260
  用户空间详细信息: "fetchUserSpaceInfo",
10183
10261
  获取UP主总播放量: "fetchUploaderTotalViews",
10184
10262
  动态详情数据: "fetchDynamicDetail",
@@ -10261,6 +10339,7 @@ var BilibiliApiRoutes = {
10261
10339
  commentReplies: "/comment-replies",
10262
10340
  userCard: "/user",
10263
10341
  userDynamicList: "/user/dynamics",
10342
+ userLiveStatus: "/user/live-status",
10264
10343
  userSpaceInfo: "/user/space",
10265
10344
  uploaderTotalViews: "/user/total-views",
10266
10345
  dynamicDetail: "/dynamic",
@@ -10334,7 +10413,7 @@ function getApiRoute(platform, methodType) {
10334
10413
  * 构建后使用 __VERSION__,开发环境从 package.json 读取
10335
10414
  */
10336
10415
  var getVersion = () => {
10337
- return "6.2.0";
10416
+ return "6.4.0";
10338
10417
  };
10339
10418
  var VERSION = getVersion();
10340
10419
  /**
@@ -35035,6 +35114,8 @@ var buildBilibiliRichTextForwardMessage = async (document, options = {}) => {
35035
35114
  //#endregion
35036
35115
  //#region src/platform/bilibili/bilibili.ts
35037
35116
  var img$1;
35117
+ /** 评论请求统一使用匿名态,避免账号 Cookie 改变评论热度池结果。 */
35118
+ var bilibiliAnonymousRequestConfig = { headers: { Cookie: "" } };
35038
35119
  var Bilibili = class extends Base {
35039
35120
  e;
35040
35121
  type;
@@ -35158,7 +35239,7 @@ var Bilibili = class extends Base {
35158
35239
  type: 1,
35159
35240
  oid: infoData.data.data.aid.toString(),
35160
35241
  typeMode: "strict"
35161
- }), [SOFT_ERROR_CODES.BILIBILI_COMMENTS_DISABLED]);
35242
+ }, bilibiliAnonymousRequestConfig), [SOFT_ERROR_CODES.BILIBILI_COMMENTS_DISABLED]);
35162
35243
  if (commentsData.code === SOFT_ERROR_CODES.BILIBILI_COMMENTS_DISABLED) this.e.reply("UP主已关闭评论区,无法获取评论");
35163
35244
  else {
35164
35245
  const { comments: commentsdata, image_urls } = bilibiliComments(commentsData.data, infoData.data.data.owner.mid.toString());
@@ -35786,7 +35867,7 @@ var Bilibili = class extends Base {
35786
35867
  oid: oid(dynamicInfo.data.data.item.type, dynamicInfo.data),
35787
35868
  number: Config.bilibili.numcomment,
35788
35869
  typeMode: "strict"
35789
- }), [SOFT_ERROR_CODES.BILIBILI_COMMENTS_DISABLED]);
35870
+ }, bilibiliAnonymousRequestConfig), [SOFT_ERROR_CODES.BILIBILI_COMMENTS_DISABLED]);
35790
35871
  if (commentsData.code === SOFT_ERROR_CODES.BILIBILI_COMMENTS_DISABLED) this.e.reply("UP主已关闭评论区,无法获取评论");
35791
35872
  else {
35792
35873
  const { comments: commentsdata, image_urls } = bilibiliComments(commentsData.data, dynamicInfo.data.data.item.modules.module_author.mid.toString());
@@ -36822,6 +36903,43 @@ var bilibiliLogin = async (e) => {
36822
36903
  }
36823
36904
  };
36824
36905
  //#endregion
36906
+ //#region src/platform/bilibili/live-status.ts
36907
+ var invalidLiveTimes = /* @__PURE__ */ new Set([
36908
+ "",
36909
+ "-62170012800",
36910
+ "0000-00-00 00:00:00"
36911
+ ]);
36912
+ /**
36913
+ * 将B站返回的东八区开播时间转换为数据库可比较的 ISO 时间。
36914
+ *
36915
+ * @param liveTime B站直播间详情返回的开播时间。
36916
+ * @returns 有效的 UTC ISO 时间;无法解析时返回 `null`。
36917
+ */
36918
+ var parseBilibiliLiveStartedAt = (liveTime) => {
36919
+ const normalizedLiveTime = liveTime.trim();
36920
+ if (invalidLiveTimes.has(normalizedLiveTime)) return null;
36921
+ const zonedLiveTime = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(normalizedLiveTime) ? `${normalizedLiveTime.replace(" ", "T")}+08:00` : normalizedLiveTime;
36922
+ const timestamp = Date.parse(zonedLiveTime);
36923
+ return Number.isNaN(timestamp) ? null : new Date(timestamp).toISOString();
36924
+ };
36925
+ /**
36926
+ * 使用直播间和开播时间构造跨检测源稳定的场次缓存键。
36927
+ *
36928
+ * @remarks
36929
+ * 定时推送可能先从 UID 直播状态接口发现开播,也可能在接口异常时回退到动态列表。
36930
+ * 两条路径必须使用同一个场次键,才能避免同一场直播被重复推送。
36931
+ *
36932
+ * @param hostMid UP 主 UID。
36933
+ * @param roomId 直播间长号。
36934
+ * @param liveTime B站直播间详情返回的本场开播时间。
36935
+ * @returns 可用于 `DynamicCaches` 的场次键;开播时间无效时返回 `null`。
36936
+ */
36937
+ var buildBilibiliLiveSessionId = (hostMid, roomId, liveTime) => {
36938
+ const normalizedLiveTime = liveTime.trim();
36939
+ if (!parseBilibiliLiveStartedAt(normalizedLiveTime)) return null;
36940
+ return `bilibili-live:${hostMid}:${roomId}:${normalizedLiveTime}`;
36941
+ };
36942
+ //#endregion
36825
36943
  //#region src/platform/bilibili/push.ts
36826
36944
  /** BilibiliPushType 到 DynamicType 的映射 */
36827
36945
  var pushTypeToDynamicType = {
@@ -36929,6 +37047,88 @@ var Bilibilipush = class extends Base {
36929
37047
  }
36930
37048
  return filteredList;
36931
37049
  }
37050
+ /** 将 UID 直播状态接口的结果接入原有动态推送列表。 */
37051
+ async getDirectLivePushItems(userList) {
37052
+ const handledUids = /* @__PURE__ */ new Set();
37053
+ const willBePushList = {};
37054
+ const liveSubscriptions = userList.filter((item) => item.switch !== false && (item.pushTypes || allBilibiliPushTypes).includes("live"));
37055
+ for (const item of liveSubscriptions) {
37056
+ let liveStatus;
37057
+ try {
37058
+ const liveStatusResult = await this.amagi.bilibili.fetcher.fetchUserLiveStatus({
37059
+ host_mid: item.host_mid,
37060
+ typeMode: "strict"
37061
+ });
37062
+ if (!liveStatusResult.success) throw new Error(`code=${liveStatusResult.code}:${liveStatusResult.message}`);
37063
+ liveStatus = liveStatusResult.data.data;
37064
+ } catch (error) {
37065
+ logger.warn(`[Bilibili 推送] UP主 ${item.remark}(${item.host_mid})直播状态直查失败,本轮停止直查并让剩余订阅回退到直播动态检测:${formatErrorMessage(error)}`);
37066
+ break;
37067
+ }
37068
+ if (liveStatus.roomStatus !== 1 || liveStatus.liveStatus !== 1 || liveStatus.roomid <= 0) {
37069
+ handledUids.add(item.host_mid);
37070
+ continue;
37071
+ }
37072
+ try {
37073
+ const liveInfo = (await this.amagi.bilibili.fetcher.fetchLiveRoomInfo({
37074
+ room_id: String(liveStatus.roomid),
37075
+ typeMode: "strict"
37076
+ })).data.data;
37077
+ /** 两个直播接口状态不一致时,以直播间详情为准。 */
37078
+ if (liveInfo.live_status !== 1) {
37079
+ handledUids.add(item.host_mid);
37080
+ continue;
37081
+ }
37082
+ const sessionId = buildBilibiliLiveSessionId(item.host_mid, liveInfo.room_id, liveInfo.live_time);
37083
+ const liveStartedAt = parseBilibiliLiveStartedAt(liveInfo.live_time);
37084
+ if (!sessionId || !liveStartedAt) throw new Error(`直播间 ${liveInfo.room_id} 未返回可用于场次去重的开播时间`);
37085
+ const dynamic = createLiveDynamicItem(sessionId, liveStartedAt, liveInfo, liveStatus);
37086
+ willBePushList[sessionId] = {
37087
+ remark: item.remark,
37088
+ host_mid: item.host_mid,
37089
+ create_time: dynamic.modules.module_author.pub_ts,
37090
+ targets: item.group_id.map((groupWithBot) => {
37091
+ const [groupId, botId] = groupWithBot.split(":");
37092
+ return {
37093
+ groupId,
37094
+ botId
37095
+ };
37096
+ }),
37097
+ Dynamic_Data: dynamic,
37098
+ avatar_img: "",
37099
+ dynamic_type: DynamicType.LIVE_RCMD
37100
+ };
37101
+ handledUids.add(item.host_mid);
37102
+ } catch (error) {
37103
+ logger.warn(`[Bilibili 推送] UP主 ${item.remark}(${item.host_mid})直播场次信息不完整,本轮回退到直播动态检测:${formatErrorMessage(error)}`);
37104
+ }
37105
+ }
37106
+ return {
37107
+ handledUids,
37108
+ willBePushList
37109
+ };
37110
+ }
37111
+ /**
37112
+ * 为降级路径中的直播动态解析与直查路径一致的场次缓存键。
37113
+ *
37114
+ * @param dynamic B站空间动态中的直播推荐项。
37115
+ * @param hostMid UP 主 UID。
37116
+ * @returns 可用时返回直播场次键,否则退回原始动态ID。
37117
+ */
37118
+ async resolveLiveDynamicCacheId(dynamic, hostMid) {
37119
+ try {
37120
+ const liveData = JSON.parse(dynamic.modules.module_dynamic.major.live_rcmd.content);
37121
+ const roomId = Number(liveData.live_play_info.room_id);
37122
+ const liveInfo = await this.amagi.bilibili.fetcher.fetchLiveRoomInfo({
37123
+ room_id: String(roomId),
37124
+ typeMode: "strict"
37125
+ });
37126
+ return buildBilibiliLiveSessionId(hostMid, liveInfo.data.data.room_id, liveInfo.data.data.live_time) || dynamic.id_str;
37127
+ } catch (error) {
37128
+ logger.warn(`[Bilibili 推送] 直播动态 ${dynamic.id_str} 无法解析统一场次键,将使用动态ID去重:${formatErrorMessage(error)}`);
37129
+ return dynamic.id_str;
37130
+ }
37131
+ }
36932
37132
  /**
36933
37133
  * 同步配置文件中的订阅信息到数据库
36934
37134
  */
@@ -37580,18 +37780,22 @@ var Bilibilipush = class extends Base {
37580
37780
  }
37581
37781
  /**
37582
37782
  * 根据配置文件获取UP当天的动态列表。
37783
+ * @param userList B站订阅列表。
37583
37784
  * @returns
37584
37785
  */
37585
37786
  async getDynamicList(userList) {
37586
- const willbepushlist = {};
37787
+ const directLiveItems = await this.getDirectLivePushItems(userList);
37788
+ const willbepushlist = { ...directLiveItems.willBePushList };
37587
37789
  try {
37588
37790
  /** 过滤掉不启用的订阅项 */
37589
37791
  const filteredUserList = userList.filter((item) => item.switch !== false);
37590
37792
  for (const item of filteredUserList) {
37591
- await common.sleep(2e3);
37592
- logger.debug(`[Bilibili 推送] 开始获取UP: ${item.remark}(${item.host_mid}) 的动态列表`);
37593
37793
  const pushTypes = item.pushTypes || allBilibiliPushTypes;
37594
37794
  const allowedDynamicTypes = new Set(pushTypes.map((pt) => pushTypeToDynamicType[pt]));
37795
+ if (directLiveItems.handledUids.has(item.host_mid)) allowedDynamicTypes.delete(DynamicType.LIVE_RCMD);
37796
+ if (allowedDynamicTypes.size === 0) continue;
37797
+ await common.sleep(2e3);
37798
+ logger.debug(`[Bilibili 推送] 开始获取UP: ${item.remark}(${item.host_mid}) 的动态列表`);
37595
37799
  const dynamic_list = await this.amagi.bilibili.fetcher.fetchUserDynamicList({
37596
37800
  host_mid: item.host_mid,
37597
37801
  typeMode: "strict"
@@ -37630,7 +37834,8 @@ var Bilibilipush = class extends Base {
37630
37834
  botId
37631
37835
  };
37632
37836
  });
37633
- if (!willbepushlist[dynamic.id_str]) willbepushlist[dynamic.id_str] = {
37837
+ const pushId = dynamic.type === DynamicType.LIVE_RCMD ? await this.resolveLiveDynamicCacheId(dynamic, item.host_mid) : dynamic.id_str;
37838
+ if (!willbepushlist[pushId]) willbepushlist[pushId] = {
37634
37839
  remark: item.remark,
37635
37840
  host_mid: item.host_mid,
37636
37841
  create_time: dynamic.modules.module_author.pub_ts,
@@ -37812,6 +38017,44 @@ var Bilibilipush = class extends Base {
37812
38017
  }
37813
38018
  };
37814
38019
  /**
38020
+ * 把直播状态接口的数据适配为现有直播动态分支实际读取的字段。
38021
+ *
38022
+ * 后续过滤、渲染、发送和缓存均继续使用统一的动态推送链路。
38023
+ */
38024
+ var createLiveDynamicItem = (sessionId, liveStartedAt, liveInfo, liveStatus) => {
38025
+ const content = JSON.stringify({ live_play_info: {
38026
+ area_name: liveInfo.area_name,
38027
+ cover: liveInfo.user_cover || liveStatus.cover,
38028
+ room_id: liveInfo.room_id,
38029
+ title: liveInfo.title || liveStatus.title
38030
+ } });
38031
+ return {
38032
+ id_str: sessionId,
38033
+ type: DynamicType.LIVE_RCMD,
38034
+ modules: {
38035
+ module_author: {
38036
+ face: "",
38037
+ pendant: { image: "" },
38038
+ pub_ts: Math.floor(Date.parse(liveStartedAt) / 1e3)
38039
+ },
38040
+ module_dynamic: {
38041
+ additional: null,
38042
+ desc: null,
38043
+ major: {
38044
+ live_rcmd: {
38045
+ content,
38046
+ reserve_type: 0
38047
+ },
38048
+ type: MajorType.LIVE_RCMD
38049
+ },
38050
+ topic: null
38051
+ }
38052
+ }
38053
+ };
38054
+ };
38055
+ /** 将未知异常转换为适合业务日志展示的文本。 */
38056
+ var formatErrorMessage = (error) => error instanceof Error ? error.message : String(error);
38057
+ /**
37815
38058
  * 将换行符替换为HTML的<br>标签。
37816
38059
  * @param data 需要进行换行符替换的字符串。
37817
38060
  * @returns 替换后的字符串,其中的换行符\n被<br>替换。
@@ -38630,6 +38873,18 @@ function getWorkTypeDisplayName(workTypeInfo) {
38630
38873
  if (workTypeInfo.isLive) return "直播";
38631
38874
  return "未知";
38632
38875
  }
38876
+ /**
38877
+ * 抖音图文里的 clip_type=5 才能生成系统实况图;clip_type=4 是短片。
38878
+ * 用户选择仅发送实况图时,短片仍需兜底成视频节点,避免生成空合并转发。
38879
+ */
38880
+ function getDouyinLiveImageSendPolicy(clipType, livePhotoMode = "video_and_livephoto") {
38881
+ const isStaticImage = clipType === 2 || clipType === void 0;
38882
+ const canGenerateLivePhoto = clipType === 5;
38883
+ return {
38884
+ shouldGenerateVideo: livePhotoMode === "video_and_livephoto" || livePhotoMode === "video_only" || livePhotoMode === "livephoto_only" && !isStaticImage && !canGenerateLivePhoto,
38885
+ shouldGenerateLivePhoto: canGenerateLivePhoto && (livePhotoMode === "video_and_livephoto" || livePhotoMode === "livephoto_only")
38886
+ };
38887
+ }
38633
38888
  //#endregion
38634
38889
  //#region src/platform/douyin/push/render.ts
38635
38890
  /**
@@ -39244,9 +39499,7 @@ var DouYin = class DouYin extends Base {
39244
39499
  });
39245
39500
  staticImgPath = staticImg.filepath ?? "";
39246
39501
  }
39247
- const livePhotoMode = Config.app.livePhotoMode ?? "video_and_livephoto";
39248
- const shouldGenerateVideo = livePhotoMode === "video_and_livephoto" || livePhotoMode === "video_only";
39249
- const shouldGenerateLivePhoto = livePhotoMode === "video_and_livephoto" || livePhotoMode === "livephoto_only";
39502
+ const { shouldGenerateVideo, shouldGenerateLivePhoto } = getDouyinLiveImageSendPolicy(imageItem.clip_type, Config.app.livePhotoMode ?? "video_and_livephoto");
39250
39503
  if (shouldGenerateVideo) {
39251
39504
  const transitionEnabled = loopCount > 1 && Boolean(staticImgPath);
39252
39505
  const safeStaticPath = staticImgPath || liveimg.filepath;
@@ -39308,14 +39561,17 @@ var DouYin = class DouYin extends Base {
39308
39561
  });
39309
39562
  processedImages.push(...tipImg);
39310
39563
  }
39311
- const Element = common.makeForward(processedImages, Config.app.fakeForward ? this.e.sender.userId : this.e.bot.account.selfId, Config.app.fakeForward ? this.e.sender.nick : this.e.bot.account.name);
39312
39564
  try {
39313
- await this.e.bot.sendForwardMsg(this.e.contact, Element, {
39314
- source: "图集内容",
39315
- summary: `查看${Element.length}张图片/视频消息`,
39316
- prompt: "抖音图集解析结果",
39317
- news: [{ text: "点击查看解析结果" }]
39318
- });
39565
+ if (processedImages.length === 0) logger.warn(`抖音图集解析未生成可发送内容,aweme_id=${VideoData.data.aweme_detail.aweme_id}`);
39566
+ else {
39567
+ const Element = common.makeForward(processedImages, Config.app.fakeForward ? this.e.sender.userId : this.e.bot.account.selfId, Config.app.fakeForward ? this.e.sender.nick : this.e.bot.account.name);
39568
+ await this.e.bot.sendForwardMsg(this.e.contact, Element, {
39569
+ source: "图集内容",
39570
+ summary: `查看${Element.length}张图片/视频消息`,
39571
+ prompt: "抖音图集解析结果",
39572
+ news: [{ text: "点击查看解析结果" }]
39573
+ });
39574
+ }
39319
39575
  } finally {
39320
39576
  for (const item of temp) await Common.removeFile(item.filepath, true);
39321
39577
  }
@@ -39399,9 +39655,7 @@ var DouYin = class DouYin extends Base {
39399
39655
  });
39400
39656
  staticImgPath = staticImg.filepath ?? "";
39401
39657
  }
39402
- const livePhotoMode = Config.app.livePhotoMode ?? "video_and_livephoto";
39403
- const shouldGenerateVideo = livePhotoMode === "video_and_livephoto" || livePhotoMode === "video_only";
39404
- const shouldGenerateLivePhoto = livePhotoMode === "video_and_livephoto" || livePhotoMode === "livephoto_only";
39658
+ const { shouldGenerateVideo, shouldGenerateLivePhoto } = getDouyinLiveImageSendPolicy(item.clip_type, Config.app.livePhotoMode ?? "video_and_livephoto");
39405
39659
  if (shouldGenerateVideo) {
39406
39660
  const transitionEnabled = loopCount > 1 && Boolean(staticImgPath);
39407
39661
  const safeStaticPath = staticImgPath || livePhoto.filepath;
@@ -39463,14 +39717,17 @@ var DouYin = class DouYin extends Base {
39463
39717
  });
39464
39718
  images.push(...tipImg);
39465
39719
  }
39466
- const Element = common.makeForward(images, Config.app.fakeForward ? this.e.sender.userId : this.e.bot.account.selfId, Config.app.fakeForward ? this.e.sender.nick : this.e.bot.account.name);
39467
39720
  try {
39468
- await this.e.bot.sendForwardMsg(this.e.contact, Element, {
39469
- source: "合辑内容",
39470
- summary: `查看${Element.length}张图片/视频消息`,
39471
- prompt: "抖音合辑解析结果",
39472
- news: [{ text: "点击查看解析结果" }]
39473
- });
39721
+ if (images.length === 0) logger.warn(`抖音合辑解析未生成可发送内容,aweme_id=${VideoData.data.aweme_detail.aweme_id}`);
39722
+ else {
39723
+ const Element = common.makeForward(images, Config.app.fakeForward ? this.e.sender.userId : this.e.bot.account.selfId, Config.app.fakeForward ? this.e.sender.nick : this.e.bot.account.name);
39724
+ await this.e.bot.sendForwardMsg(this.e.contact, Element, {
39725
+ source: "合辑内容",
39726
+ summary: `查看${Element.length}张图片/视频消息`,
39727
+ prompt: "抖音合辑解析结果",
39728
+ news: [{ text: "点击查看解析结果" }]
39729
+ });
39730
+ }
39474
39731
  } finally {
39475
39732
  for (const item of temp) await Common.removeFile(item.filepath, true);
39476
39733
  }
@@ -40614,9 +40871,7 @@ var DouYinpush = class extends Base {
40614
40871
  });
40615
40872
  staticImgPath = staticImg.filepath ?? "";
40616
40873
  }
40617
- const livePhotoMode = Config.app.livePhotoMode ?? "video_and_livephoto";
40618
- const shouldGenerateVideo = livePhotoMode === "video_and_livephoto" || livePhotoMode === "video_only";
40619
- const shouldGenerateLivePhoto = livePhotoMode === "video_and_livephoto" || livePhotoMode === "livephoto_only";
40874
+ const { shouldGenerateVideo, shouldGenerateLivePhoto } = getDouyinLiveImageSendPolicy(item.clip_type, Config.app.livePhotoMode ?? "video_and_livephoto");
40620
40875
  if (shouldGenerateVideo) {
40621
40876
  const transitionEnabled = loopCount > 1 && Boolean(staticImgPath);
40622
40877
  const safeStaticPath = staticImgPath || liveimg.filepath;
@@ -40679,14 +40934,17 @@ var DouYinpush = class extends Base {
40679
40934
  images.push(...tipImg);
40680
40935
  }
40681
40936
  const bot = karin.getBot(botId);
40682
- const Element = common.makeForward(images, botId, bot.account.name);
40683
40937
  try {
40684
- await bot.sendForwardMsg(Contact, Element, {
40685
- source: "合辑内容",
40686
- summary: `查看${Element.length}张图片/视频消息`,
40687
- prompt: "抖音合辑解析结果",
40688
- news: [{ text: "点击查看解析结果" }]
40689
- });
40938
+ if (images.length === 0) logger.warn(`抖音合辑推送解析未生成可发送内容,aweme_id=${Detail_Data.aweme_id}`);
40939
+ else {
40940
+ const Element = common.makeForward(images, botId, bot.account.name);
40941
+ await bot.sendForwardMsg(Contact, Element, {
40942
+ source: "合辑内容",
40943
+ summary: `查看${Element.length}张图片/视频消息`,
40944
+ prompt: "抖音合辑解析结果",
40945
+ news: [{ text: "点击查看解析结果" }]
40946
+ });
40947
+ }
40690
40948
  } catch (error) {
40691
40949
  logger.error(`发送合辑失败: ${error}`);
40692
40950
  } finally {
@@ -40737,9 +40995,7 @@ var DouYinpush = class extends Base {
40737
40995
  });
40738
40996
  staticImgPath = staticImg.filepath ?? "";
40739
40997
  }
40740
- const livePhotoMode = Config.app.livePhotoMode ?? "video_and_livephoto";
40741
- const shouldGenerateVideo = livePhotoMode === "video_and_livephoto" || livePhotoMode === "video_only";
40742
- const shouldGenerateLivePhoto = livePhotoMode === "video_and_livephoto" || livePhotoMode === "livephoto_only";
40998
+ const { shouldGenerateVideo, shouldGenerateLivePhoto } = getDouyinLiveImageSendPolicy(item.clip_type, Config.app.livePhotoMode ?? "video_and_livephoto");
40743
40999
  if (shouldGenerateVideo) {
40744
41000
  const transitionEnabled = loopCount > 1 && Boolean(staticImgPath);
40745
41001
  const safeStaticPath = staticImgPath || liveimg.filepath;
@@ -40802,14 +41058,17 @@ var DouYinpush = class extends Base {
40802
41058
  processedImages.push(...tipImg);
40803
41059
  }
40804
41060
  const bot = karin.getBot(botId);
40805
- const Element = common.makeForward(processedImages, botId, bot.account.name);
40806
41061
  try {
40807
- await bot.sendForwardMsg(Contact, Element, {
40808
- source: "图集内容",
40809
- summary: `查看${Element.length}张图片/视频消息`,
40810
- prompt: "抖音图集解析结果",
40811
- news: [{ text: "点击查看解析结果" }]
40812
- });
41062
+ if (processedImages.length === 0) logger.warn(`抖音图集推送解析未生成可发送内容,aweme_id=${Detail_Data.aweme_id}`);
41063
+ else {
41064
+ const Element = common.makeForward(processedImages, botId, bot.account.name);
41065
+ await bot.sendForwardMsg(Contact, Element, {
41066
+ source: "图集内容",
41067
+ summary: `查看${Element.length}张图片/视频消息`,
41068
+ prompt: "抖音图集解析结果",
41069
+ news: [{ text: "点击查看解析结果" }]
41070
+ });
41071
+ }
40813
41072
  } catch (error) {
40814
41073
  logger.error(`发送图集失败: ${error}`);
40815
41074
  } finally {