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.
- package/CHANGELOG.md +25 -0
- package/lib/apps/admin.js +3 -3
- package/lib/apps/help.js +3 -3
- package/lib/apps/push.js +3 -3
- package/lib/apps/tools.js +3 -3
- package/lib/apps/update.js +3 -3
- package/lib/core_chunk/{main-CkFWdoWk.js → main-CC1I4T4K.js} +286 -31
- package/lib/core_chunk/{template-C0o5wE4d.js → template-DDKjrdui.js} +570 -427
- package/lib/core_chunk/template.d.ts +19 -3
- package/lib/core_chunk/template.js +2 -2
- package/lib/core_chunk/{vendor-DFVZL9Sg.js → vendor-DFtFduyo.js} +15 -3632
- package/lib/index.js +3 -3
- package/lib/karin-plugin-kkk.css +8 -0
- package/lib/root.js +1 -1
- package/lib/web.config.js +3 -3
- package/lib/web_chunk/assets/{Combination-BlTR8rnz.js → Combination-Q_c69_R1.js} +1 -1
- package/lib/web_chunk/assets/{avatar-DZx0Dkp1.js → avatar-PYbrWAdJ.js} +1 -1
- package/lib/web_chunk/assets/{core-CO0KNPJl.js → core-NKKdXH4p.js} +1 -1
- package/lib/web_chunk/assets/{eye-OLZaDgQl.js → eye-CekPnl3c.js} +1 -1
- package/lib/web_chunk/assets/{index-Cu6l33VG.js → index-4CNHxszp.js} +4 -4
- package/lib/web_chunk/assets/{jszip.min-DWxP78tT.js → jszip.min-BuZ0xFJa.js} +1 -1
- package/lib/web_chunk/assets/{page-BNJ_VYNM.js → page-3n8mJkHB.js} +1 -1
- package/lib/web_chunk/assets/{page-DhRTgMWG.js → page-BwzeMCuF.js} +4 -4
- package/lib/web_chunk/assets/{page-C8W3h-4U.js → page-BzahvKk6.js} +1 -1
- package/lib/web_chunk/assets/{page-D2UYm_HV.js → page-CXioB2wm.js} +2 -2
- package/lib/web_chunk/assets/{page-D7dzOjhv.js → page-CaggWngv.js} +1 -1
- package/lib/web_chunk/assets/{parsers-BemnefRk.js → parsers-C7o4jAeL.js} +1 -1
- package/lib/web_chunk/assets/{request-63K6ALwk.js → request-DULvGkjO.js} +1 -1
- package/lib/web_chunk/assets/{select-BUJnEX6X.js → select-BUuQj-91.js} +1 -1
- package/lib/web_chunk/assets/{separator-Bfuy4nsm.js → separator-DI0A-XbO.js} +1 -1
- package/lib/web_chunk/index.html +1 -1
- package/lib/web_chunk/sw.js +1 -1
- package/package.json +5 -3
- 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-
|
|
2
|
-
import { C as setbilick, S as dylogin, T as task, w as setdyck, x as biLogin } from "../core_chunk/main-
|
|
3
|
-
import "../core_chunk/template-
|
|
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-
|
|
2
|
-
import { b as version, y as help } from "../core_chunk/main-
|
|
3
|
-
import "../core_chunk/template-
|
|
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-
|
|
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-
|
|
3
|
-
import "../core_chunk/template-
|
|
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-
|
|
2
|
-
import { a as bilibiliAPP, c as prefix, l as xiaohongshuAPP, o as douyinAPP, s as kuaishouAPP } from "../core_chunk/main-
|
|
3
|
-
import "../core_chunk/template-
|
|
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 };
|
package/lib/apps/update.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "../core_chunk/vendor-
|
|
2
|
-
import { i as update, n as kkkUpdateCommand, r as kkkUpdateTest, t as kkkUpdate } from "../core_chunk/main-
|
|
3
|
-
import "../core_chunk/template-
|
|
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
|
|
3
|
-
import { n as init_client, r as reactServerRender } from "./template-
|
|
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 ||
|
|
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
|
-
|
|
5358
|
-
username: checkvip(data[dynamicId].Dynamic_Data.
|
|
5359
|
-
avatar_url: data[dynamicId].Dynamic_Data.
|
|
5360
|
-
frame: data[dynamicId].Dynamic_Data.
|
|
5361
|
-
create_time: Common.convertTimestampToDateTime(data[dynamicId].Dynamic_Data.
|
|
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 ||
|
|
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
|
|
7150
|
+
await douyinLogin(e);
|
|
6896
7151
|
return true;
|
|
6897
7152
|
}, {
|
|
6898
7153
|
perm: Config.douyin.loginPerm,
|