karin-plugin-kkk 1.4.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # 变更日志
2
2
 
3
+ ## [1.4.1](https://github.com/ikenxuan/karin-plugin-kkk/compare/v1.4.0...v1.4.1) (2025-05-03)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * 描述错误 ([26cf7a5](https://github.com/ikenxuan/karin-plugin-kkk/commit/26cf7a569450fbadaf646d6313677103ca9e27b1))
9
+
3
10
  ## [1.4.0](https://github.com/ikenxuan/karin-plugin-kkk/compare/v1.3.0...v1.4.0) (2025-05-03)
4
11
 
5
12
 
package/lib/apps/admin.js CHANGED
@@ -1,206 +1,53 @@
1
- import fs from "node:fs";
2
- import karin, { handler, segment, logger } from "node-karin";
3
- import require$$1 from "path";
4
- import "sequelize";
5
- import { d as Common, C as Config } from "../chunk/douyin-CpQOEMNX.js";
6
- import { Version } from "../Version.js";
7
- import "stream/promises";
8
- import "node:path";
9
- import { b as bilibiliLogin } from "../chunk/index-BoFo2rq6.js";
10
- import "../chunk/index-BDlGFCbK.js";
11
- import { execSync, spawn } from "node:child_process";
12
- import { chromium } from "playwright";
13
- const startXvfb = async () => {
14
- if (process.platform !== "linux") return;
15
- const DISPLAY_NUMBER = ":150";
16
- const LOCK_FILE = "/tmp/.X150-lock";
17
- try {
18
- execSync(`xdpyinfo -display ${DISPLAY_NUMBER}`, { stdio: "ignore" });
19
- logger.debug(`检测到 DISPLAY ${DISPLAY_NUMBER} 已经在运行,无需启动新的 Xvfb。`);
20
- return;
21
- } catch (err) {
22
- logger.debug(logger.red(`未检测到 DISPLAY ${DISPLAY_NUMBER},尝试启动 Xvfb...`));
23
- }
24
- if (fs.existsSync(LOCK_FILE)) {
25
- logger.debug(logger.red(`检测到锁文件 ${LOCK_FILE},可能存在冲突。尝试清理...`));
26
- try {
27
- fs.unlinkSync(LOCK_FILE);
28
- logger.debug(`成功清理锁文件 ${LOCK_FILE}`);
29
- } catch (err) {
30
- logger.debug(logger.red(`无法清理锁文件 ${LOCK_FILE},请检查权限或手动处理。`));
31
- throw err;
32
- }
33
- }
34
- const xvfb = spawn("Xvfb", [DISPLAY_NUMBER, "-ac", "-screen", "0", "1280x1024x24"], {
35
- stdio: "inherit"
36
- });
37
- xvfb.unref();
38
- process.env.DISPLAY = DISPLAY_NUMBER;
39
- let retries = 5;
40
- while (retries > 0) {
41
- try {
42
- execSync(`xdpyinfo -display ${DISPLAY_NUMBER}`, { stdio: "ignore" });
43
- logger.debug(`Xvfb (${DISPLAY_NUMBER}) 启动成功`);
44
- return;
45
- } catch (err) {
46
- logger.debug(logger.yellow(`Xvfb (${DISPLAY_NUMBER}) 启动失败,正在重试...`));
47
- retries -= 1;
48
- if (retries > 0) {
49
- await new Promise((resolve) => setTimeout(resolve, 1e3));
50
- } else {
51
- logger.debug(logger.red("Xvfb 启动失败,重试多次后仍未成功"));
52
- throw err;
53
- }
54
- }
55
- }
56
- };
57
- const douyinLogin = async (e) => {
58
- const hal = await handler.call("kkk.douyinLogin", { e });
59
- if (hal) return true;
60
- const msg_id = [];
61
- const message1 = await e.reply("免责声明:\n您将通过扫码完成获取抖音网页端的用户登录凭证(ck),该ck将用于请求抖音WEB API接口。\n本BOT不会上传任何有关你的信息到第三方,所配置的 ck 只会用于请求官方 API 接口。\n我方仅提供视频解析及相关抖音内容服务,若您的账号封禁、被盗等处罚与我方无关。\n害怕风险请勿扫码 ~");
62
- try {
63
- startXvfb();
64
- const browser = await chromium.launch({
65
- headless: false,
66
- args: [
67
- "--disable-blink-features=AutomationControlled",
68
- // 禁用自动化控制
69
- "--window-position=-10000,-10000",
70
- // 将窗口移到屏幕外
71
- "--start-minimized",
72
- // 启动时最小化
73
- "--mute-audio",
74
- // 静音
75
- "--no-sandbox"
76
- // 使用无沙箱模式,适合无桌面环境
77
- ]
78
- });
79
- const page = await browser.newPage();
80
- await page.goto("https://www.douyin.com", { timeout: 12e4 });
81
- const timeout = new Promise((resolve) => setTimeout(async () => {
82
- await browser.close();
83
- }, 12e4));
84
- const qrCodePromise = (async () => {
85
- try {
86
- const qrCodeBase64 = await waitQrcode(page);
87
- const base64Data = qrCodeBase64 ? qrCodeBase64.replace(/^data:image\/\w+;base64,/, "") : "";
88
- const buffer = Buffer.from(base64Data, "base64");
89
- fs.writeFileSync(`${Common.tempDri.default}DouyinLoginQrcode.png`, buffer);
90
- const message2 = await e.reply([segment.image("base64://" + base64Data), segment.text("请在120秒内通过抖音APP扫码进行登录")], { reply: true });
91
- msg_id.push(message2.messageId, message1.messageId);
92
- page.on("response", async (response) => {
93
- try {
94
- logger.debug(`接收到响应:${response.url()}`);
95
- if (response.status() === 302 && response.url().includes("/passport/sso/login/callback")) {
96
- const localCookies = await page.context().cookies();
97
- const cookieString = localCookies.map((cookie) => `${cookie.name}=${cookie.value}`).join("; ");
98
- Config.Modify("cookies", "douyin", cookieString);
99
- await e.reply("登录成功!用户登录凭证已保存至cookies.yaml", { reply: true });
100
- await browser.close();
101
- await Promise.all(msg_id.map(async (id) => {
102
- await e.bot.recallMsg(e.contact, id);
103
- }));
104
- } else if (response.headers()["content-type"] && response.headers()["content-type"].includes("application/json") && response.url().includes("https://sso.douyin.com")) {
105
- const responseBody = await response.body();
106
- const jsonResponse = JSON.parse(responseBody.toString());
107
- logger.debug(`SSO 回调 Code:${jsonResponse.error_code}`, `响应内容:${jsonResponse.description}`);
108
- if (jsonResponse.error_code === 2046) {
109
- logger.debug("需要短信验证码");
110
- await page.getByText("接收短信验证").click();
111
- const elements = page.locator(":has-text('为保护账号安全,请输入当前手机号')");
112
- const texts = await elements.allInnerTexts();
113
- await page.getByText("获取验证码").click();
114
- const message3 = await e.reply(segment.text(texts.pop()));
115
- msg_id.push(message3.messageId);
116
- const ctx = await karin.ctx(e, { reply: true });
117
- await page.getByPlaceholder("请输入验证码").click();
118
- await page.getByPlaceholder("请输入验证码").fill(ctx.msg);
119
- await page.getByText("验证", { exact: true }).click();
120
- }
121
- }
122
- } catch (error) {
123
- await browser.close();
124
- await Promise.all(msg_id.map(async (id) => {
125
- await e.bot.recallMsg(e.contact, id);
126
- }));
127
- }
128
- });
129
- } catch (error) {
130
- await browser.close();
131
- await Promise.all(msg_id.map(async (id) => {
132
- await e.bot.recallMsg(e.contact, id);
133
- }));
134
- await e.reply("登录超时!二维码已失效!", { reply: true });
135
- logger.error(error);
136
- }
137
- })();
138
- await Promise.race([qrCodePromise, timeout]);
139
- } catch (error) {
140
- logger.error(error);
141
- if (error.message.includes("npx playwright install")) {
142
- const msg = await e.reply("首次使用,正在初始化 playwright 环境,请稍等片刻...");
143
- execSync("npx playwright install chromium", { cwd: Version.pluginPath, stdio: "inherit" });
144
- await e.reply(`playwright 初始化成功,请再次发送「${e.msg}」`);
145
- await e.bot.recallMsg(e.contact, msg.messageId);
146
- return true;
147
- } else {
148
- await e.reply("chromiun 环境初始化失败,请查看控制台错误日志", { reply: true });
149
- }
150
- }
151
- return true;
152
- };
153
- const waitQrcode = async (page) => {
154
- const qrCodeSelector = ".web-login-scan-code__content__qrcode-wrapper img";
155
- const loginButton = page.getByRole("button", { name: "登录" });
156
- const qrCodeImage = await page.waitForSelector(qrCodeSelector, { state: "attached", timeout: 3e4 });
157
- if (qrCodeImage) {
158
- const qrCodeBase64 = await qrCodeImage.getAttribute("src");
159
- return qrCodeBase64;
160
- } else {
161
- await loginButton.click();
162
- await page.waitForSelector(qrCodeSelector, { timeout: 2e4 });
163
- const qrCodeImage2 = await page.waitForSelector(qrCodeSelector, { timeout: 2e4 });
164
- const qrCodeBase64 = await qrCodeImage2.getAttribute("src");
165
- return qrCodeBase64;
166
- }
167
- };
168
- const task = Config.app.rmmp4 && karin.task("[kkk-视频缓存自动删除]", "0 0 4 * * *", async () => {
1
+ import { createRequire } from 'module';
2
+ import '../chunk-KC7JEOWJ.js';
3
+ import { bilibiliLogin, douyinLogin } from '../chunk-CP4E7FRK.js';
4
+ import '../chunk-YE4KAWHC.js';
5
+ import { Config, Common } from '../chunk-H7UZAYYK.js';
6
+ import { init_esm_shims } from '../chunk-O6MLYFQU.js';
7
+ import fs from 'node:fs';
8
+ import karin, { logger } from 'node-karin';
9
+ import path from 'path';
10
+
11
+ createRequire(import.meta.url);
12
+
13
+ // src/apps/admin.ts
14
+ init_esm_shims();
15
+ var task = Config.app.rmmp4 && karin.task("[kkk-\u89C6\u9891\u7F13\u5B58\u81EA\u52A8\u5220\u9664]", "0 0 4 * * *", async () => {
169
16
  try {
170
17
  await removeAllFiles(Common.tempDri.video);
171
- logger.mark(Common.tempDri.video + "目录下所有文件已删除");
18
+ logger.mark(Common.tempDri.video + "\u76EE\u5F55\u4E0B\u6240\u6709\u6587\u4EF6\u5DF2\u5220\u9664");
172
19
  } catch (err) {
173
- console.error("删除文件时出错:", err);
20
+ console.error("\u5220\u9664\u6587\u4EF6\u65F6\u51FA\u9519:", err);
174
21
  }
175
22
  });
176
- const biLogin = karin.command(/^#?(kkk)?\s*B站\s*(扫码)?\s*登录$/i, async (e) => {
23
+ var biLogin = karin.command(/^#?(kkk)?\s*B站\s*(扫码)?\s*登录$/i, async (e) => {
177
24
  await bilibiliLogin(e);
178
25
  return true;
179
- }, { perm: Config.bilibili.loginPerm, name: "kkk-ck管理" });
180
- const dylogin = karin.command(/^#?(kkk)?抖音(扫码)?登录$/, async (e) => {
26
+ }, { perm: Config.bilibili.loginPerm, name: "kkk-ck\u7BA1\u7406" });
27
+ var dylogin = karin.command(/^#?(kkk)?抖音(扫码)?登录$/, async (e) => {
181
28
  await douyinLogin(e);
182
29
  return true;
183
- }, { perm: Config.douyin.loginPerm, name: "kkk-ck管理" });
184
- const setdyck = karin.command(/^#?(kkk)?s*设置抖音ck$/i, async (e) => {
185
- const msg = await e.reply("请发在120秒内送抖音ck\n教程:https://ikenxuan.github.io/kkkkkk-10086/docs/intro/other#%E9%85%8D%E7%BD%AE%E4%B8%8D%E5%90%8C%E5%B9%B3%E5%8F%B0%E7%9A%84-cookies\n");
30
+ }, { perm: Config.douyin.loginPerm, name: "kkk-ck\u7BA1\u7406" });
31
+ var setdyck = karin.command(/^#?(kkk)?s*设置抖音ck$/i, async (e) => {
32
+ const msg = await e.reply("\u8BF7\u53D1\u5728120\u79D2\u5185\u9001\u6296\u97F3ck\n\u6559\u7A0B\uFF1Ahttps://ikenxuan.github.io/kkkkkk-10086/docs/intro/other#%E9%85%8D%E7%BD%AE%E4%B8%8D%E5%90%8C%E5%B9%B3%E5%8F%B0%E7%9A%84-cookies\n");
186
33
  const context = await karin.ctx(e);
187
34
  Config.Modify("cookies", "douyin", context.msg);
188
35
  await e.bot.recallMsg(e.contact, msg.messageId);
189
- await e.reply("设置成功!", { at: true });
36
+ await e.reply("\u8BBE\u7F6E\u6210\u529F\uFF01", { at: true });
190
37
  return true;
191
- }, { perm: "master", name: "kkk-ck管理", event: "message.friend" });
192
- const setbilick = karin.command(/^#?(kkk)?s*设置s*(B站)ck$/i, async (e) => {
193
- const msg = await e.reply("请发在120秒内送B站ck\n教程:https://ikenxuan.github.io/kkkkkk-10086/docs/intro/other#%E9%85%8D%E7%BD%AE%E4%B8%8D%E5%90%8C%E5%B9%B3%E5%8F%B0%E7%9A%84-cookies\n");
38
+ }, { perm: "master", name: "kkk-ck\u7BA1\u7406", event: "message.friend" });
39
+ var setbilick = karin.command(/^#?(kkk)?s*设置s*(B站)ck$/i, async (e) => {
40
+ const msg = await e.reply("\u8BF7\u53D1\u5728120\u79D2\u5185\u9001B\u7AD9ck\n\u6559\u7A0B\uFF1Ahttps://ikenxuan.github.io/kkkkkk-10086/docs/intro/other#%E9%85%8D%E7%BD%AE%E4%B8%8D%E5%90%8C%E5%B9%B3%E5%8F%B0%E7%9A%84-cookies\n");
194
41
  const context = await karin.ctx(e);
195
42
  Config.Modify("cookies", "bilibili", context.msg);
196
43
  await e.bot.recallMsg(e.contact, msg.messageId);
197
- await e.reply("设置成功!", { at: true });
44
+ await e.reply("\u8BBE\u7F6E\u6210\u529F\uFF01", { at: true });
198
45
  return true;
199
- }, { perm: "master", name: "kkk-ck管理", event: "message.friend" });
46
+ }, { perm: "master", name: "kkk-ck\u7BA1\u7406", event: "message.friend" });
200
47
  async function removeAllFiles(dir) {
201
48
  const files = await fs.promises.readdir(dir);
202
49
  for (const file of files) {
203
- const filePath = require$$1.join(dir, file);
50
+ const filePath = path.join(dir, file);
204
51
  const stats = await fs.promises.stat(filePath);
205
52
  if (stats.isDirectory()) {
206
53
  await removeAllFiles(filePath);
@@ -210,10 +57,5 @@ async function removeAllFiles(dir) {
210
57
  }
211
58
  }
212
59
  }
213
- export {
214
- biLogin,
215
- dylogin,
216
- setbilick,
217
- setdyck,
218
- task
219
- };
60
+
61
+ export { biLogin, dylogin, setbilick, setdyck, task };
package/lib/apps/help.js CHANGED
@@ -1,19 +1,22 @@
1
- import { execSync } from "node:child_process";
2
- import fs from "node:fs";
3
- import { m as markdown } from "../chunk/index-BDlGFCbK.js";
4
- import karin, { mkdirSync, render, segment, isPackaged, updatePkg, updateGitPlugin, logger, common, restart } from "node-karin";
5
- import { karinPathTemp } from "node-karin/root";
6
- import "sequelize";
7
- import { C as Config, d as Common } from "../chunk/douyin-CpQOEMNX.js";
8
- import { Version } from "../Version.js";
9
- import "stream/promises";
10
- import { R as Render } from "../chunk/Render-CCORwrkI.js";
11
- const help = karin.command(/^#?kkk帮助$/, async (e) => {
1
+ import { createRequire } from 'module';
2
+ import { markdown } from '../chunk-YE4KAWHC.js';
3
+ import { Render, Config, Version, Common } from '../chunk-H7UZAYYK.js';
4
+ import { init_esm_shims } from '../chunk-O6MLYFQU.js';
5
+ import { execSync } from 'node:child_process';
6
+ import fs from 'node:fs';
7
+ import karin, { mkdirSync, render, segment, isPackaged, updatePkg, updateGitPlugin, logger, common, restart } from 'node-karin';
8
+ import { karinPathTemp } from 'node-karin/root';
9
+
10
+ createRequire(import.meta.url);
11
+
12
+ // src/apps/help.ts
13
+ init_esm_shims();
14
+ var help = karin.command(/^#?kkk帮助$/, async (e) => {
12
15
  const img = await Render("help/index");
13
16
  await e.reply(img);
14
17
  return true;
15
- }, { name: "kkk-帮助" });
16
- const version = karin.command(/^#?kkk版本$/, async (e) => {
18
+ }, { name: "kkk-\u5E2E\u52A9" });
19
+ var version = karin.command(/^#?kkk版本$/, async (e) => {
17
20
  Config.douyin.push.switch = false;
18
21
  const changelogs2 = fs.readFileSync(Version.pluginPath + "/CHANGELOG.md", "utf8");
19
22
  const html = markdown(changelogs2, {
@@ -25,8 +28,8 @@ const version = karin.command(/^#?kkk版本$/, async (e) => {
25
28
  const img = await render.renderHtml(htmlPath);
26
29
  await e.reply(segment.image("base64://" + img));
27
30
  return true;
28
- }, { name: "kkk-版本" });
29
- const changelogs = karin.command(/^#?kkk更新日志$/, async (e) => {
31
+ }, { name: "kkk-\u7248\u672C" });
32
+ var changelogs = karin.command(/^#?kkk更新日志$/, async (e) => {
30
33
  const commits = getLatestCommitsSync();
31
34
  let htmlString = "";
32
35
  for (const commit of commits) {
@@ -47,12 +50,12 @@ const changelogs = karin.command(/^#?kkk更新日志$/, async (e) => {
47
50
  const img = await render.renderHtml(htmlPath);
48
51
  await e.reply(segment.image("base64://" + img));
49
52
  return true;
50
- }, { name: "kkk-更新日志" });
51
- const update = karin.command(/^#?kkk更新(预览版)?$/, async (e) => {
53
+ }, { name: "kkk-\u66F4\u65B0\u65E5\u5FD7" });
54
+ var update = karin.command(/^#?kkk更新(预览版)?$/, async (e) => {
52
55
  let status = "failed";
53
56
  let data = "";
54
57
  if (isPackaged) {
55
- if (e.msg.includes("预览版")) {
58
+ if (e.msg.includes("\u9884\u89C8\u7248")) {
56
59
  const resolve = await updatePkg(Version.pluginName, "beta");
57
60
  status = resolve.status;
58
61
  data = resolve.data;
@@ -63,7 +66,7 @@ const update = karin.command(/^#?kkk更新(预览版)?$/, async (e) => {
63
66
  }
64
67
  } else {
65
68
  let cmd = "git pull";
66
- if (e.msg.includes("强制")) {
69
+ if (e.msg.includes("\u5F3A\u5236")) {
67
70
  cmd = "git reset --hard && git pull --allow-unrelated-histories";
68
71
  }
69
72
  const resolve = await updateGitPlugin(Version.pluginPath, cmd);
@@ -71,21 +74,21 @@ const update = karin.command(/^#?kkk更新(预览版)?$/, async (e) => {
71
74
  data = resolve.data;
72
75
  }
73
76
  logger.debug(data);
74
- await e.bot.sendForwardMsg(e.contact, common.makeForward([segment.text(`更新 ${Version.pluginName}...
77
+ await e.bot.sendForwardMsg(e.contact, common.makeForward([segment.text(`\u66F4\u65B0 ${Version.pluginName}...
75
78
  ${JSON.stringify(data)}`)], e.sender.userId, e.sender.nick));
76
79
  if (status === "ok") {
77
80
  try {
78
81
  await e.reply(`
79
- 更新完成,开始重启 本次运行时间:${common.uptime()}`, { at: true });
82
+ \u66F4\u65B0\u5B8C\u6210\uFF0C\u5F00\u59CB\u91CD\u542F \u672C\u6B21\u8FD0\u884C\u65F6\u95F4\uFF1A${common.uptime()}`, { at: true });
80
83
  await restart(e.selfId, e.contact, e.messageId);
81
84
  return true;
82
85
  } catch (error) {
83
- await e.reply(`${Version.pluginName}重启失败,请手动重启以应用更新!`);
86
+ await e.reply(`${Version.pluginName}\u91CD\u542F\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u91CD\u542F\u4EE5\u5E94\u7528\u66F4\u65B0\uFF01`);
84
87
  }
85
88
  }
86
89
  return true;
87
- }, { name: "kkk-更新", perm: "master" });
88
- const getLatestCommitsSync = () => {
90
+ }, { name: "kkk-\u66F4\u65B0", perm: "master" });
91
+ var getLatestCommitsSync = () => {
89
92
  const command = 'git log -150 --pretty=format:"%h %an %s"';
90
93
  const output = execSync(command, { cwd: Version.pluginPath }).toString();
91
94
  const commits = output.trim().split("\n");
@@ -98,7 +101,7 @@ const getLatestCommitsSync = () => {
98
101
  return { sha, committer, message };
99
102
  }).slice(0, 50);
100
103
  };
101
- const setColor = (message) => {
104
+ var setColor = (message) => {
102
105
  switch (true) {
103
106
  case message.includes("feat"):
104
107
  return "10px solid #a9ffb9";
@@ -112,9 +115,5 @@ const setColor = (message) => {
112
115
  return "2px solid";
113
116
  }
114
117
  };
115
- export {
116
- changelogs,
117
- help,
118
- update,
119
- version
120
- };
118
+
119
+ export { changelogs, help, update, version };