karin-plugin-kkk 2.9.1 → 2.9.3

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 (34) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/lib/apps/admin.js +3 -3
  3. package/lib/apps/help.js +3 -3
  4. package/lib/apps/push.js +3 -3
  5. package/lib/apps/tools.js +3 -3
  6. package/lib/apps/update.js +3 -3
  7. package/lib/core_chunk/{main-CkFWdoWk.js → main-CC1I4T4K.js} +286 -31
  8. package/lib/core_chunk/{template-C0o5wE4d.js → template-DDKjrdui.js} +570 -427
  9. package/lib/core_chunk/template.d.ts +19 -3
  10. package/lib/core_chunk/template.js +2 -2
  11. package/lib/core_chunk/{vendor-DFVZL9Sg.js → vendor-DFtFduyo.js} +15 -3632
  12. package/lib/index.js +3 -3
  13. package/lib/karin-plugin-kkk.css +8 -0
  14. package/lib/root.js +1 -1
  15. package/lib/web.config.js +3 -3
  16. package/lib/web_chunk/assets/{Combination-BlTR8rnz.js → Combination-Q_c69_R1.js} +1 -1
  17. package/lib/web_chunk/assets/{avatar-DZx0Dkp1.js → avatar-PYbrWAdJ.js} +1 -1
  18. package/lib/web_chunk/assets/{core-CO0KNPJl.js → core-NKKdXH4p.js} +1 -1
  19. package/lib/web_chunk/assets/{eye-OLZaDgQl.js → eye-CekPnl3c.js} +1 -1
  20. package/lib/web_chunk/assets/{index-Cu6l33VG.js → index-4CNHxszp.js} +4 -4
  21. package/lib/web_chunk/assets/{jszip.min-DWxP78tT.js → jszip.min-BuZ0xFJa.js} +1 -1
  22. package/lib/web_chunk/assets/{page-BNJ_VYNM.js → page-3n8mJkHB.js} +1 -1
  23. package/lib/web_chunk/assets/{page-DhRTgMWG.js → page-BwzeMCuF.js} +4 -4
  24. package/lib/web_chunk/assets/{page-C8W3h-4U.js → page-BzahvKk6.js} +1 -1
  25. package/lib/web_chunk/assets/{page-D2UYm_HV.js → page-CXioB2wm.js} +2 -2
  26. package/lib/web_chunk/assets/{page-D7dzOjhv.js → page-CaggWngv.js} +1 -1
  27. package/lib/web_chunk/assets/{parsers-BemnefRk.js → parsers-C7o4jAeL.js} +1 -1
  28. package/lib/web_chunk/assets/{request-63K6ALwk.js → request-DULvGkjO.js} +1 -1
  29. package/lib/web_chunk/assets/{select-BUJnEX6X.js → select-BUuQj-91.js} +1 -1
  30. package/lib/web_chunk/assets/{separator-Bfuy4nsm.js → separator-DI0A-XbO.js} +1 -1
  31. package/lib/web_chunk/index.html +1 -1
  32. package/lib/web_chunk/sw.js +1 -1
  33. package/package.json +5 -3
  34. package/resources/image/banner.webp +0 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [2.9.3](https://github.com/ikenxuan/karin-plugin-kkk/compare/v2.9.2...v2.9.3) (2025-10-29)
6
+
7
+
8
+ ### 🐛 错误修复
9
+
10
+ * **bilibili:** Enhance article dynamic rendering and data handling ([705cdbc](https://github.com/ikenxuan/karin-plugin-kkk/commit/705cdbc3c4312a12a08541d0578dd849a16dad3d))
11
+ * **bilibili:** Enhance forward dynamic rendering with title support ([83f9d78](https://github.com/ikenxuan/karin-plugin-kkk/commit/83f9d78b994fd34b1373b4d8230908375115954d))
12
+ * **bilibili:** Enhance image proxy handling in shared component ([491ace8](https://github.com/ikenxuan/karin-plugin-kkk/commit/491ace8a14f0432274a4a757183ec489bb246225))
13
+ * douyin login ([#59](https://github.com/ikenxuan/karin-plugin-kkk/issues/59)) ([b92cc71](https://github.com/ikenxuan/karin-plugin-kkk/commit/b92cc7160396887b71523e5ca99ebf3792292084))
14
+ * 哎呀 ([e100401](https://github.com/ikenxuan/karin-plugin-kkk/commit/e1004018677cddaa6ea1d36b909e495272427e6a))
15
+ * 细优 ([b841b63](https://github.com/ikenxuan/karin-plugin-kkk/commit/b841b63d648a267822a6ae5eb973baf8bef8bc43))
16
+ * 细优 ([fa53e77](https://github.com/ikenxuan/karin-plugin-kkk/commit/fa53e770d8b3b78068206ae799bad4f4fcd0abf3))
17
+
18
+ ## [2.9.2](https://github.com/ikenxuan/karin-plugin-kkk/compare/v2.9.1...v2.9.2) (2025-10-29)
19
+
20
+
21
+ ### 🐛 错误修复
22
+
23
+ * **bilibili:** Enhance comment rendering and add sample data ([53620a1](https://github.com/ikenxuan/karin-plugin-kkk/commit/53620a1fffe20c1588fcfc3775fdb03d74cdd573))
24
+
25
+
26
+ ### 💄 UI 优化
27
+
28
+ * **image:** Update banner image to WebP format ([ac41ecd](https://github.com/ikenxuan/karin-plugin-kkk/commit/ac41ecd8806bbe4e439b800632942282edec319b))
29
+
5
30
  ## [2.9.1](https://github.com/ikenxuan/karin-plugin-kkk/compare/v2.9.0...v2.9.1) (2025-10-28)
6
31
 
7
32
 
package/lib/apps/admin.js CHANGED
@@ -1,4 +1,4 @@
1
- import "../core_chunk/vendor-DFVZL9Sg.js";
2
- import { C as setbilick, S as dylogin, T as task, w as setdyck, x as biLogin } from "../core_chunk/main-CkFWdoWk.js";
3
- import "../core_chunk/template-C0o5wE4d.js";
1
+ import "../core_chunk/vendor-DFtFduyo.js";
2
+ import { C as setbilick, S as dylogin, T as task, w as setdyck, x as biLogin } from "../core_chunk/main-CC1I4T4K.js";
3
+ import "../core_chunk/template-DDKjrdui.js";
4
4
  export { biLogin, dylogin, setbilick, setdyck, task };
package/lib/apps/help.js CHANGED
@@ -1,4 +1,4 @@
1
- import "../core_chunk/vendor-DFVZL9Sg.js";
2
- import { b as version, y as help } from "../core_chunk/main-CkFWdoWk.js";
3
- import "../core_chunk/template-C0o5wE4d.js";
1
+ import "../core_chunk/vendor-DFtFduyo.js";
2
+ import { b as version, y as help } from "../core_chunk/main-CC1I4T4K.js";
3
+ import "../core_chunk/template-DDKjrdui.js";
4
4
  export { help, version };
package/lib/apps/push.js CHANGED
@@ -1,4 +1,4 @@
1
- import "../core_chunk/vendor-DFVZL9Sg.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-CkFWdoWk.js";
3
- import "../core_chunk/template-C0o5wE4d.js";
1
+ import "../core_chunk/vendor-DFtFduyo.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-CC1I4T4K.js";
3
+ import "../core_chunk/template-DDKjrdui.js";
4
4
  export { bilibiliPush, bilibiliPushList, changeBotID, douyinPush, douyinPushList, forcePush, setbiliPush, setdyPush, testDouyinPush };
package/lib/apps/tools.js CHANGED
@@ -1,4 +1,4 @@
1
- import "../core_chunk/vendor-DFVZL9Sg.js";
2
- import { a as bilibiliAPP, c as prefix, l as xiaohongshuAPP, o as douyinAPP, s as kuaishouAPP } from "../core_chunk/main-CkFWdoWk.js";
3
- import "../core_chunk/template-C0o5wE4d.js";
1
+ import "../core_chunk/vendor-DFtFduyo.js";
2
+ import { a as bilibiliAPP, c as prefix, l as xiaohongshuAPP, o as douyinAPP, s as kuaishouAPP } from "../core_chunk/main-CC1I4T4K.js";
3
+ import "../core_chunk/template-DDKjrdui.js";
4
4
  export { bilibiliAPP, douyinAPP, kuaishouAPP, prefix, xiaohongshuAPP };
@@ -1,4 +1,4 @@
1
- import "../core_chunk/vendor-DFVZL9Sg.js";
2
- import { i as update, n as kkkUpdateCommand, r as kkkUpdateTest, t as kkkUpdate } from "../core_chunk/main-CkFWdoWk.js";
3
- import "../core_chunk/template-C0o5wE4d.js";
1
+ import "../core_chunk/vendor-DFtFduyo.js";
2
+ import { i as update, n as kkkUpdateCommand, r as kkkUpdateTest, t as kkkUpdate } from "../core_chunk/main-CC1I4T4K.js";
3
+ import "../core_chunk/template-DDKjrdui.js";
4
4
  export { kkkUpdate, kkkUpdateCommand, kkkUpdateTest, update };
@@ -1,19 +1,22 @@
1
1
  import { n as __esmMin, o as __toESM, r as __export } from "./rolldown-runtime-DWBZqjDW.js";
2
- import { At as init_default, Ct as amagi, Dt as createKuaishouRoutes, Et as createDouyinRoutes, Ft as init_dist, Mt as logger$1, Nt as wbi_sign, Ot as getBilibiliData, Pt as app$1, St as MajorType, Tt as createBilibiliRoutes, _t as require_dist, bt as Client, jt as logMiddleware, kt as getDouyinData, n as require_browser, t as require_heic_convert, vt as require_lib$1, wt as bilibiliApiUrls, xt as DynamicType, yt as require_lib } from "./vendor-DFVZL9Sg.js";
3
- import { n as init_client, r as reactServerRender } from "./template-C0o5wE4d.js";
2
+ import { At as wbi_sign, Ct as createDouyinRoutes, Dt as init_default, Et as getDouyinData, Mt as init_dist, Ot as logMiddleware, St as createBilibiliRoutes, Tt as getBilibiliData, _t as Client, bt as amagi, gt as require_lib, ht as require_lib$1, jt as app$1, kt as logger$1, mt as require_dist, n as require_browser, t as require_heic_convert, vt as DynamicType, wt as createKuaishouRoutes, xt as bilibiliApiUrls, yt as MajorType } from "./vendor-DFtFduyo.js";
3
+ import { n as init_client, r as reactServerRender } from "./template-DDKjrdui.js";
4
4
  import path from "node:path";
5
- import os from "node:os";
5
+ import os, { platform } from "node:os";
6
6
  import { fileURLToPath } from "node:url";
7
7
  import fs from "node:fs";
8
8
  import crypto from "node:crypto";
9
- import karin, { app, authMiddleware, checkPkgUpdate, common, components, config, copyConfigSync, createBadRequestResponse, createNotFoundResponse, createServerErrorResponse, createSuccessResponse, db, defineConfig, ffmpeg, ffprobe, filesByExt, getBot, hooks, karinPathHtml, logger, logs, mkdirSync, range, render, requireFileSync, restart, segment, updatePkg, watch } from "node-karin";
10
- import { karinPathBase, karinPathTemp } from "node-karin/root";
9
+ import karin, { app, authMiddleware, checkPkgUpdate, common, components, config, copyConfigSync, createBadRequestResponse, createNotFoundResponse, createServerErrorResponse, createSuccessResponse, db, defineConfig, ffmpeg, ffprobe, filesByExt, getBot, hooks, karin as karin$1, karinPathHtml, karinPathTemp, logger, logs, mkdirSync, range, render, requireFileSync, restart, segment, updatePkg, watch } from "node-karin";
10
+ import { karinPathBase, karinPathTemp as karinPathTemp$1 } from "node-karin/root";
11
11
  import YAML from "node-karin/yaml";
12
12
  import sqlite3 from "node-karin/sqlite3";
13
13
  import { pipeline } from "node:stream/promises";
14
14
  import axios, { AxiosError } from "node-karin/axios";
15
15
  import template from "node-karin/template";
16
16
  import _ from "node-karin/lodash";
17
+ import { launch } from "@karinjs/puppeteer";
18
+ import { FingerprintGenerator } from "fingerprint-generator";
19
+ import { FingerprintInjector, newInjectedPage } from "fingerprint-injector";
17
20
  import util from "node:util";
18
21
  var resolvePluginRoot, pluginPath, pkg, Root;
19
22
  var init_root = __esmMin(() => {
@@ -220,9 +223,9 @@ var init_Common = __esmMin(() => {
220
223
  tempDri;
221
224
  constructor() {
222
225
  this.tempDri = {
223
- default: `${karinPathTemp}/${Root.pluginName}/`.replace(/\\/g, "/"),
224
- video: `${karinPathTemp}/${Root.pluginName}/kkkdownload/video/`.replace(/\\/g, "/"),
225
- images: `${karinPathTemp}/${Root.pluginName}/kkkdownload/images/`.replace(/\\/g, "/")
226
+ default: `${karinPathTemp$1}/${Root.pluginName}/`.replace(/\\/g, "/"),
227
+ video: `${karinPathTemp$1}/${Root.pluginName}/kkkdownload/video/`.replace(/\\/g, "/"),
228
+ images: `${karinPathTemp$1}/${Root.pluginName}/kkkdownload/images/`.replace(/\\/g, "/")
226
229
  };
227
230
  }
228
231
  async getReplyMessage(e) {
@@ -1788,8 +1791,8 @@ var init_db = __esmMin(async () => {
1788
1791
  };
1789
1792
  douyinDBInstance = await getDouyinDB();
1790
1793
  bilibiliDBInstance = await getBilibiliDB();
1791
- cleanOldDynamicCache = async (platform, days = 7) => {
1792
- if (platform === "douyin") return await (await getDouyinDB()).cleanOldAwemeCache(days);
1794
+ cleanOldDynamicCache = async (platform$1, days = 7) => {
1795
+ if (platform$1 === "douyin") return await (await getDouyinDB()).cleanOldAwemeCache(days);
1793
1796
  else return await (await getBilibiliDB()).cleanOldDynamicCache(days);
1794
1797
  };
1795
1798
  });
@@ -2271,13 +2274,13 @@ const addBilibiliContentRouter = async (req, res) => {
2271
2274
  };
2272
2275
  const deleteContentRouter = async (req, res) => {
2273
2276
  try {
2274
- const { id, platform, groupId } = req.body;
2275
- if (!id || !platform || !groupId) return createBadRequestResponse(res, "请提供内容ID、平台类型和群组ID");
2276
- if (platform === "douyin") await (await getDouyinDB()).awemeCacheRepository.delete({
2277
+ const { id, platform: platform$1, groupId } = req.body;
2278
+ if (!id || !platform$1 || !groupId) return createBadRequestResponse(res, "请提供内容ID、平台类型和群组ID");
2279
+ if (platform$1 === "douyin") await (await getDouyinDB()).awemeCacheRepository.delete({
2277
2280
  aweme_id: id,
2278
2281
  groupId
2279
2282
  });
2280
- else if (platform === "bilibili") await (await getBilibiliDB()).dynamicCacheRepository.delete({
2283
+ else if (platform$1 === "bilibili") await (await getBilibiliDB()).dynamicCacheRepository.delete({
2281
2284
  dynamic_id: id,
2282
2285
  groupId
2283
2286
  });
@@ -2371,16 +2374,16 @@ const getLongLinkRouter = async (req, res) => {
2371
2374
  if (!link || typeof link !== "string") return createBadRequestResponse(res, "请提供有效的链接");
2372
2375
  const finalUrl = (await axios.get(link, { headers: { "User-Agent": "Apifox/1.0.0 (https://apifox.com)" } })).request.res.responseUrl;
2373
2376
  if (finalUrl.includes("获取链接重定向失败") || finalUrl.includes("403 Forbidden")) return createServerErrorResponse(res, "无法获取链接的重定向地址:" + finalUrl);
2374
- let platform = "unknown";
2375
- if (finalUrl.includes("douyin.com") || finalUrl.includes("iesdouyin.com") || finalUrl.includes("webcast.amemv.com") || finalUrl.includes("live.douyin.com")) platform = "douyin";
2376
- else if (finalUrl.includes("bilibili.com") || finalUrl.includes("b23.tv")) platform = "bilibili";
2377
- else if (finalUrl.includes("kuaishou.com") || finalUrl.includes("kwai.com") || finalUrl.includes("chenzhongtech.com")) platform = "kuaishou";
2377
+ let platform$1 = "unknown";
2378
+ if (finalUrl.includes("douyin.com") || finalUrl.includes("iesdouyin.com") || finalUrl.includes("webcast.amemv.com") || finalUrl.includes("live.douyin.com")) platform$1 = "douyin";
2379
+ else if (finalUrl.includes("bilibili.com") || finalUrl.includes("b23.tv")) platform$1 = "bilibili";
2380
+ else if (finalUrl.includes("kuaishou.com") || finalUrl.includes("kwai.com") || finalUrl.includes("chenzhongtech.com")) platform$1 = "kuaishou";
2378
2381
  createSuccessResponse(res, {
2379
2382
  originalUrl: link,
2380
2383
  finalUrl,
2381
- platform
2384
+ platform: platform$1
2382
2385
  });
2383
- logger.debug(`链接重定向获取成功: ${link} -> ${platform}`);
2386
+ logger.debug(`链接重定向获取成功: ${link} -> ${platform$1}`);
2384
2387
  } catch (error) {
2385
2388
  logger.error(`链接重定向获取失败: ${error.message}`);
2386
2389
  res.status(500).json({
@@ -4303,6 +4306,7 @@ var Bilibili = class extends Base {
4303
4306
  });
4304
4307
  const cardData = JSON.parse(dynamicCARD2.data.data.card.card);
4305
4308
  data = {
4309
+ title: dynamicInfo.data.data.item.orig.modules.module_dynamic.major?.opus?.title ?? null,
4306
4310
  username: checkvip$2(dynamicInfo.data.data.item.orig.modules.module_author),
4307
4311
  create_time: Common.convertTimestampToDateTime(dynamicInfo.data.data.item.orig.modules.module_author.pub_ts),
4308
4312
  avatar_url: dynamicInfo.data.data.item.orig.modules.module_author.face,
@@ -4450,7 +4454,8 @@ var Bilibili = class extends Base {
4450
4454
  banner_url: articleData.banner_url || articleData.image_urls && articleData.image_urls[0] || "",
4451
4455
  categories: articleData.categories || [],
4452
4456
  words: articleData.words || 0,
4453
- opus: articleContent.opus || null,
4457
+ opus: articleContent.opus || void 0,
4458
+ content: articleContent.content || void 0,
4454
4459
  stats: articleData.stats,
4455
4460
  render_time: Common.getCurrentTime(),
4456
4461
  share_url: `https://www.bilibili.com/read/cv${articleData.id}`,
@@ -5280,6 +5285,7 @@ var Bilibilipush = class extends Base {
5280
5285
  });
5281
5286
  const cardData = JSON.parse(dynamicCARD.data.data.card.card);
5282
5287
  param = {
5288
+ title: data[dynamicId].Dynamic_Data.orig.modules.module_dynamic.major?.opus?.title ?? null,
5283
5289
  username: checkvip(data[dynamicId].Dynamic_Data.orig.modules.module_author),
5284
5290
  create_time: Common.convertTimestampToDateTime(data[dynamicId].Dynamic_Data.orig.modules.module_author.pub_ts),
5285
5291
  avatar_url: data[dynamicId].Dynamic_Data.orig.modules.module_author.face,
@@ -5349,28 +5355,28 @@ var Bilibilipush = class extends Base {
5349
5355
  typeMode: "strict"
5350
5356
  });
5351
5357
  const articleInfo = await this.amagi.getBilibiliData("专栏正文内容", {
5352
- id: data[dynamicId].Dynamic_Data.rid_str,
5358
+ id: data[dynamicId].Dynamic_Data.basic.rid_str,
5353
5359
  typeMode: "strict"
5354
5360
  });
5355
5361
  const articleData = articleInfoBase.data.data;
5356
5362
  const articleContent = articleInfo.data.data;
5357
- const img$3 = await Render("bilibili/dynamic/DYNAMIC_TYPE_ARTICLE", {
5358
- username: checkvip(data[dynamicId].Dynamic_Data.orig.modules.module_author),
5359
- avatar_url: data[dynamicId].Dynamic_Data.orig.modules.module_author.face,
5360
- frame: data[dynamicId].Dynamic_Data.orig.modules.module_author.pendant.image,
5361
- create_time: Common.convertTimestampToDateTime(data[dynamicId].Dynamic_Data.orig.modules.module_author.pub_ts),
5363
+ img$2 = await Render("bilibili/dynamic/DYNAMIC_TYPE_ARTICLE", {
5364
+ username: checkvip(data[dynamicId].Dynamic_Data.modules.module_author),
5365
+ avatar_url: data[dynamicId].Dynamic_Data.modules.module_author.face,
5366
+ frame: data[dynamicId].Dynamic_Data.modules.module_author.pendant.image,
5367
+ create_time: Common.convertTimestampToDateTime(data[dynamicId].Dynamic_Data.modules.module_author.pub_ts),
5362
5368
  title: articleData.title,
5363
5369
  summary: articleData.summary,
5364
5370
  banner_url: articleData.banner_url || articleData.image_urls && articleData.image_urls[0] || "",
5365
5371
  categories: articleData.categories || [],
5366
5372
  words: articleData.words || 0,
5367
- opus: articleContent.opus || null,
5373
+ opus: articleContent.opus || void 0,
5374
+ content: articleContent.content || void 0,
5368
5375
  stats: articleData.stats,
5369
5376
  render_time: Common.getCurrentTime(),
5370
5377
  share_url: `https://www.bilibili.com/read/cv${articleData.id}`,
5371
- dynamicTYPE: "专栏动态解析"
5378
+ dynamicTYPE: "专栏动态推送"
5372
5379
  });
5373
- this.e.reply(img$3);
5374
5380
  break;
5375
5381
  }
5376
5382
  default:
@@ -6876,6 +6882,255 @@ var Kuaishou = class extends Base {
6876
6882
  };
6877
6883
  await init_module();
6878
6884
  await init_Config();
6885
+ const douyinLogin = async (e) => {
6886
+ const msg_id = [];
6887
+ try {
6888
+ const fingerprint = new FingerprintGenerator({ browsers: [{
6889
+ name: "chrome",
6890
+ minVersion: 141
6891
+ }] }).getFingerprint();
6892
+ const injector = new FingerprintInjector();
6893
+ const { browser } = await launch({
6894
+ headless: true,
6895
+ downloadBrowser: "chrome-headless-shell",
6896
+ args: [
6897
+ "--disable-blink-features=AutomationControlled",
6898
+ "--mute-audio",
6899
+ "--window-size=800,600",
6900
+ "--disable-gpu",
6901
+ "--no-sandbox",
6902
+ "--disable-setuid-sandbox",
6903
+ "--no-zygote",
6904
+ "--disable-extensions",
6905
+ "--disable-dev-shm-usage",
6906
+ "--disable-background-networking",
6907
+ "--disable-sync",
6908
+ "--disable-crash-reporter",
6909
+ "--disable-translate",
6910
+ "--disable-notifications",
6911
+ "--disable-device-discovery-notifications",
6912
+ "--disable-accelerated-2d-canvas",
6913
+ "--autoplay-policy=user-gesture-required",
6914
+ "--disable-web-security",
6915
+ "--disable-features=IsolateOrigins,site-per-process",
6916
+ "--disable-site-isolation-trials",
6917
+ "--disable-features=VizDisplayCompositor",
6918
+ "--js-flags=--max-old-space-size=128",
6919
+ "--disable-software-rasterizer",
6920
+ "--disable-webgl",
6921
+ "--disable-webgl2",
6922
+ "--disable-3d-apis",
6923
+ "--disable-accelerated-video-decode",
6924
+ "--disable-background-timer-throttling",
6925
+ "--disable-backgrounding-occluded-windows",
6926
+ "--disable-breakpad",
6927
+ "--disable-component-extensions-with-background-pages",
6928
+ "--disable-features=TranslateUI,BlinkGenPropertyTrees",
6929
+ "--disable-ipc-flooding-protection",
6930
+ "--disable-renderer-backgrounding"
6931
+ ],
6932
+ ignoreDefaultArgs: ["--enable-automation"]
6933
+ });
6934
+ const getOperatingSystem = () => {
6935
+ const os$1 = platform();
6936
+ if (os$1 === "win32") return "windows";
6937
+ if (os$1 === "darwin") return "macos";
6938
+ return "linux";
6939
+ };
6940
+ const page = await newInjectedPage(browser, { fingerprintOptions: {
6941
+ devices: ["desktop"],
6942
+ operatingSystems: [getOperatingSystem()]
6943
+ } });
6944
+ await injector.attachFingerprintToPuppeteer(page, fingerprint);
6945
+ await page.setRequestInterception(true);
6946
+ page.on("request", async (request) => {
6947
+ const resourceType = request.resourceType();
6948
+ const url = request.url();
6949
+ if (url.includes("passport") || url.includes("login") || url.includes("qrconnect") || url.includes("qrcode")) logger.debug(`[请求] ${resourceType}: ${url}`);
6950
+ if (resourceType === "media" || resourceType === "font" || resourceType === "stylesheet" || /\.(mp4|webm|m3u8|flv|avi|mov|wmv|mkv)(\?|$)/i.test(url) || url.includes("/aweme/") || url.includes("/video/") || url.includes("v.douyin.com") || resourceType === "image" && !url.includes("qrcode") && !url.includes("data:image") && (url.includes(".jpg") || url.includes(".jpeg") || url.includes(".webp"))) {
6951
+ if (url.includes("passport") || url.includes("login") || url.includes("qrconnect")) logger.warn(`[拦截] 登录相关请求被拦截: ${url}`);
6952
+ request.abort();
6953
+ } else request.continue();
6954
+ });
6955
+ await page.evaluateOnNewDocument(() => {
6956
+ HTMLMediaElement.prototype.play = function() {
6957
+ return Promise.reject(/* @__PURE__ */ new Error("Video playback blocked"));
6958
+ };
6959
+ if (window.MediaSource) window.MediaSource = void 0;
6960
+ window.IntersectionObserver = class {
6961
+ observe() {}
6962
+ unobserve() {}
6963
+ disconnect() {}
6964
+ };
6965
+ });
6966
+ await page.goto("https://www.douyin.com", {
6967
+ timeout: 12e4,
6968
+ waitUntil: "domcontentloaded"
6969
+ });
6970
+ let timeoutId;
6971
+ const timeout = new Promise((_resolve) => {
6972
+ timeoutId = setTimeout(async () => {
6973
+ logger.warn("登录超时,关闭浏览器");
6974
+ await page.screenshot({
6975
+ path: path.join(karinPathTemp, Root.pluginName, "DouyinLoginQrcodeError.png"),
6976
+ fullPage: true
6977
+ });
6978
+ await e.reply("登录超时,我也不知道该怎么办了~");
6979
+ await browser.close();
6980
+ }, 12e4);
6981
+ });
6982
+ const qrCodePromise = (async () => {
6983
+ let gcInterval;
6984
+ try {
6985
+ logger.mark("开始等待二维码加载...");
6986
+ const qrCodeBase64 = await waitQrcode(page);
6987
+ logger.mark("二维码获取成功");
6988
+ const loginQRcode = await Render("douyin/qrcodeImg", { qrCodeDataUrl: qrCodeBase64 });
6989
+ const base64Data = loginQRcode[0]?.file;
6990
+ if (!base64Data) throw new Error("生成二维码图片失败");
6991
+ const cleanBase64 = base64Data.replace(/^base64:\/\//, "");
6992
+ const buffer = Buffer.from(cleanBase64, "base64");
6993
+ fs.writeFileSync(`${Common.tempDri.default}DouyinLoginQrcode.png`, buffer);
6994
+ const message2 = await e.reply(loginQRcode, { reply: true });
6995
+ msg_id.push(message2.messageId);
6996
+ gcInterval = setInterval(async () => {
6997
+ try {
6998
+ await page.evaluate(() => {
6999
+ if (window.gc) window.gc();
7000
+ });
7001
+ } catch {}
7002
+ }, 1e4);
7003
+ logger.mark("开始等待用户扫码登录...");
7004
+ await new Promise((resolve) => {
7005
+ const timer = setTimeout(() => {
7006
+ logger.warn("登录超时");
7007
+ clearInterval(gcInterval);
7008
+ resolve(false);
7009
+ }, 120 * 1e3);
7010
+ let secondVerifyHandled = false;
7011
+ let responseCount = 0;
7012
+ page.on("response", async (response) => {
7013
+ responseCount++;
7014
+ const url = response.url();
7015
+ if (responseCount % 10 === 0) logger.debug(`[心跳] 已收到 ${responseCount} 个响应`);
7016
+ if (url.includes("passport") || url.includes("login") || url.includes("qrconnect") || url.includes("qrcode")) logger.debug(`[响应] 登录相关请求: ${url}, status: ${response.status()}`);
7017
+ });
7018
+ logger.mark("响应监听器已注册");
7019
+ page.on("response", async (response) => {
7020
+ try {
7021
+ if (response.url().includes("check_qrconnect")) {
7022
+ logger.debug(`收到登录轮询响应: ${response.url()}`);
7023
+ const hasSidGuard = (response.headers()["set-cookie"] || "").includes("sid_guard");
7024
+ logger.debug(`响应头包含 sid_guard: ${hasSidGuard}`);
7025
+ if (hasSidGuard) {
7026
+ clearTimeout(timer);
7027
+ clearInterval(gcInterval);
7028
+ logger.mark("检测到 sid_guard,登录成功");
7029
+ logger.debug("开始获取 cookies...");
7030
+ const cookies = await browser.cookies();
7031
+ logger.debug(`获取到 ${cookies.length} 个 cookies`);
7032
+ const cookieString = cookies.map((cookie) => `${cookie.name}=${cookie.value}`).join("; ");
7033
+ logger.debug("开始保存 cookies...");
7034
+ Config.Modify("cookies", "douyin", cookieString);
7035
+ logger.debug("cookies 保存完成");
7036
+ await e.reply("登录成功!用户登录凭证已保存至cookies.yaml", { reply: true });
7037
+ try {
7038
+ await Promise.all(msg_id.map(async (id) => {
7039
+ await e.bot.recallMsg(e.contact, id);
7040
+ }));
7041
+ } catch (error) {
7042
+ logger.warn("撤回消息失败:", error);
7043
+ }
7044
+ logger.mark("关闭浏览器...");
7045
+ clearTimeout(timeoutId);
7046
+ await browser.close();
7047
+ logger.mark("浏览器已关闭");
7048
+ resolve(true);
7049
+ return;
7050
+ }
7051
+ const responseBody = await response.text();
7052
+ const jsonResponse = JSON.parse(responseBody);
7053
+ logger.debug(`二维码状态:${jsonResponse.data?.status}, error_code: ${jsonResponse.data?.error_code}`);
7054
+ if (jsonResponse.data?.error_code === 2046 && !secondVerifyHandled) {
7055
+ secondVerifyHandled = true;
7056
+ logger.mark("检测到需要二次验证");
7057
+ (async () => {
7058
+ try {
7059
+ await page.waitForSelector("#uc-second-verify", { timeout: 5e3 });
7060
+ if (!await page.evaluate(() => {
7061
+ const element = document.evaluate("//text()[contains(., '接收短信验证码')]/ancestor::*[1]", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
7062
+ if (element) {
7063
+ element.click();
7064
+ return true;
7065
+ }
7066
+ return false;
7067
+ })) logger.warn("未找到\"接收短信验证码\"按钮");
7068
+ await new Promise((resolve$1) => setTimeout(resolve$1, 2e3));
7069
+ const inputSelector = "#uc-second-verify input";
7070
+ await page.waitForSelector(inputSelector, { timeout: 1e4 });
7071
+ const tipMsg = await e.reply("此次验证需要进行 2FA\n6 位数的验证码已发送至扫码设备绑定的手机号\n请在 60 秒内发送此验证码以通过 2FA", { reply: true });
7072
+ msg_id.push(tipMsg.messageId);
7073
+ const ctx = await karin$1.ctx(e, { reply: true });
7074
+ await page.type(inputSelector, ctx.msg);
7075
+ await page.evaluate(() => {
7076
+ const verifyBtn = Array.from(document.querySelectorAll("*")).find((el) => el.textContent?.trim() === "验证");
7077
+ if (verifyBtn) verifyBtn.click();
7078
+ });
7079
+ logger.mark("已提交验证码,等待验证结果...");
7080
+ } catch (error) {
7081
+ logger.error("二次验证处理失败:", error);
7082
+ }
7083
+ })();
7084
+ }
7085
+ }
7086
+ } catch (error) {
7087
+ logger.error("处理响应时出错:", error);
7088
+ }
7089
+ });
7090
+ });
7091
+ } catch (error) {
7092
+ if (gcInterval) clearInterval(gcInterval);
7093
+ if (timeoutId) clearTimeout(timeoutId);
7094
+ await browser.close();
7095
+ await Promise.all(msg_id.map(async (id) => {
7096
+ await e.bot.recallMsg(e.contact, id);
7097
+ }));
7098
+ await e.reply("登录超时!二维码已失效!", { reply: true });
7099
+ logger.error(error);
7100
+ }
7101
+ })();
7102
+ await Promise.race([qrCodePromise, timeout]);
7103
+ } catch (error) {
7104
+ logger.error(error);
7105
+ if (error.message.includes("npx playwright install")) {
7106
+ await e.reply("首次使用,正在初始化 puppeteer 环境,请稍等片刻...");
7107
+ await e.reply(`请确保已正确安装 puppeteer 依赖,请再次发送「${e.msg}」`);
7108
+ } else await e.reply("浏览器环境初始化失败,请查看控制台错误日志", { reply: true });
7109
+ }
7110
+ return true;
7111
+ };
7112
+ var waitQrcode = async (page) => {
7113
+ const qrCodeSelector = "img[aria-label=\"二维码\"]";
7114
+ try {
7115
+ await page.waitForSelector(qrCodeSelector, { timeout: 6e4 });
7116
+ } catch {
7117
+ await page.screenshot({
7118
+ path: path.join(karinPathTemp, Root.pluginName, "DouyinLoginQrcodeError.png"),
7119
+ fullPage: true
7120
+ });
7121
+ throw new Error("加载超时了,或者遇到验证码了。。。");
7122
+ }
7123
+ logger.debug("二维码加载完成");
7124
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
7125
+ const qrCodeImages = (await page.$$eval("img", (imgs) => imgs.map((img$2) => ({
7126
+ src: img$2.src,
7127
+ ariaLabel: img$2.getAttribute("aria-label")
7128
+ })))).filter((img$2) => img$2.ariaLabel === "二维码");
7129
+ if (qrCodeImages.length === 0) throw new Error("未找到二维码");
7130
+ return qrCodeImages[0].src;
7131
+ };
7132
+ await init_module();
7133
+ await init_Config();
6879
7134
  const task = Config.app.removeCache && karin.task("[kkk-视频缓存自动删除]", "0 0 4 * * *", async () => {
6880
7135
  try {
6881
7136
  await removeAllFiles(Common.tempDri.video);
@@ -6892,7 +7147,7 @@ const biLogin = karin.command(/^#?(kkk)?\s*B站\s*(扫码)?\s*登录$/i, async (
6892
7147
  name: "kkk-ck管理"
6893
7148
  });
6894
7149
  const dylogin = karin.command(/^#?(kkk)?抖音(扫码)?登录$/, async (e) => {
6895
- await e.reply("暂时不可用");
7150
+ await douyinLogin(e);
6896
7151
  return true;
6897
7152
  }, {
6898
7153
  perm: Config.douyin.loginPerm,