koishi-plugin-xlon 1.0.2 → 1.0.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 (2) hide show
  1. package/lib/index.js +43 -6
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -114,12 +114,12 @@ async function expandShortLink(ctx, url) {
114
114
  maxRedirects: 0,
115
115
  validateStatus: /* @__PURE__ */ __name(() => true, "validateStatus")
116
116
  });
117
- const location = res?.headers?.location;
118
- return location || url;
117
+ const location2 = res?.headers?.location;
118
+ return location2 || url;
119
119
  } catch (err) {
120
120
  try {
121
- const location = err?.response?.headers?.location;
122
- return location || url;
121
+ const location2 = err?.response?.headers?.location;
122
+ return location2 || url;
123
123
  } catch (_) {
124
124
  return url;
125
125
  }
@@ -439,6 +439,43 @@ function buildVxApiUrl(tweetUrl) {
439
439
  return tweetUrl.replace(/(twitter\.com|x\.com)/i, "api.vxtwitter.com");
440
440
  }
441
441
  __name(buildVxApiUrl, "buildVxApiUrl");
442
+ async function diagnosePage(page) {
443
+ return await page.evaluate(() => {
444
+ const url = location.href;
445
+ const title = document.title || "";
446
+ const bodyText = (document.body && document.body.innerText || "").slice(0, 600);
447
+ let reason = "页面未渲染出推文(可能网络缓慢或 X 页面结构变化)";
448
+ const isLoginWall = /\/i\/flow\/login|\/login|\/i\/flow\/single-sign-on/i.test(url) || !!document.querySelector('input[autocomplete="username"]') || /^(log in|登录|登入|sign in)/i.test(title.trim());
449
+ if (isLoginWall) {
450
+ reason = "Cookie(auth_token) 可能已失效,被重定向到登录页,请更新 cookies 配置";
451
+ } else if (/rate limit|too many requests|请求过于频繁|尝试次数过多/i.test(bodyText)) {
452
+ reason = "触发限流(Rate limit),请调大 updateInterval 或更换账号";
453
+ } else if (/account doesn.?t exist|账号不存在|這個帳號不存在|user not found/i.test(bodyText)) {
454
+ reason = "账号不存在或用户名拼写有误";
455
+ } else if (/suspended|账号已被冻结|帳號已遭凍結/i.test(bodyText)) {
456
+ reason = "账号已被冻结(suspended)";
457
+ } else if (/something went wrong|出错了|发生了一些错误|重试/i.test(bodyText)) {
458
+ reason = "X 返回错误页(Something went wrong),通常为临时故障或限流";
459
+ }
460
+ return { url, reason };
461
+ });
462
+ }
463
+ __name(diagnosePage, "diagnosePage");
464
+ async function waitForArticle(page, timeout = 3e4) {
465
+ const outcome = await Promise.race([
466
+ page.waitForSelector("article", { timeout }).then(() => "article").catch(() => null),
467
+ page.waitForFunction(
468
+ () => /\/i\/flow\/login|\/login|\/i\/flow\/single-sign-on/i.test(location.href) || !!document.querySelector('input[autocomplete="username"]'),
469
+ { timeout }
470
+ ).then(() => "login").catch(() => null)
471
+ ]);
472
+ if (outcome === "article") return;
473
+ const diag = await diagnosePage(page).catch(() => null);
474
+ throw new Error(
475
+ diag ? `未加载到推文(${diag.reason})| URL: ${diag.url}` : "未加载到推文(页面状态未知)"
476
+ );
477
+ }
478
+ __name(waitForArticle, "waitForArticle");
442
479
  async function screenshotTweetArticle(page, selector = 'article[data-testid="tweet"]') {
443
480
  const element = await page.waitForSelector(selector, { timeout: 15e3 });
444
481
  if (!element) throw new Error("未能找到推文容器");
@@ -557,7 +594,7 @@ var XFetcher = class {
557
594
  });
558
595
  await preparePage(page, this.config.cookies);
559
596
  await page.goto(url, { waitUntil: "domcontentloaded", timeout: 6e4 });
560
- await page.waitForSelector("article", { timeout: 3e4 });
597
+ await waitForArticle(page, 3e4);
561
598
  const result = await page.evaluate(() => {
562
599
  const articles = Array.from(document.querySelectorAll("article"));
563
600
  const collected = [];
@@ -641,7 +678,7 @@ var XFetcher = class {
641
678
  });
642
679
  await preparePage(page, this.config.cookies);
643
680
  await page.goto(tweetUrl, { waitUntil: "networkidle2", timeout: 6e4 });
644
- await page.waitForSelector("article", { timeout: 3e4 });
681
+ await waitForArticle(page, 3e4);
645
682
  protectedAccount = await page.evaluate(() => {
646
683
  return !!(document.querySelector('[data-testid="icon-lock"]') || document.querySelector('[aria-label*="rotect"]') || document.querySelector('[aria-label*="保护"]') || document.querySelector('[aria-label*="保護"]'));
647
684
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-xlon",
3
3
  "description": "x subscriber",
4
- "version": "1.0.2",
4
+ "version": "1.0.3",
5
5
  "contributors": [
6
6
  "Logthm <logthm@outlook.com>"
7
7
  ],