koishi-plugin-twitter-fetcher 2.0.0 → 2.0.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.
Files changed (3) hide show
  1. package/lib/index.js +12 -2
  2. package/package.json +21 -21
  3. package/readme.md +4 -1
package/lib/index.js CHANGED
@@ -166,6 +166,10 @@ function sanitizeMediaUrl(url) {
166
166
  return url.trim().replace(/&/g, "&").replace(/\\u002F/g, "/").replace(/\\\//g, "/").replace(/[),.;\]]+$/g, "");
167
167
  }
168
168
  __name(sanitizeMediaUrl, "sanitizeMediaUrl");
169
+ function hasPotentialMediaGate(text) {
170
+ return /(age-restricted|adult content|sensitive content|potentially sensitive|sign in to confirm|年龄|成人内容|敏感内容|可能包含敏感)/i.test(text);
171
+ }
172
+ __name(hasPotentialMediaGate, "hasPotentialMediaGate");
169
173
  function mimeToExtension(mime = "") {
170
174
  if (mime.includes("png")) return ".png";
171
175
  if (mime.includes("webp")) return ".webp";
@@ -346,7 +350,9 @@ async function getTweetDataByBrowser(puppeteer, tweetUrl, cookie, useOriginal, l
346
350
  text: textEl?.textContent?.trim() || "",
347
351
  author: authorNameEl?.textContent?.trim() || "",
348
352
  userScreenName: authorIdHref ? authorIdHref.slice(1) : "",
349
- urls
353
+ urls,
354
+ gateText: `${article.textContent || ""}
355
+ ${document.body.textContent || ""}`
350
356
  };
351
357
  }, tweetId);
352
358
  const domKeys = /* @__PURE__ */ new Set();
@@ -360,7 +366,11 @@ async function getTweetDataByBrowser(puppeteer, tweetUrl, cookie, useOriginal, l
360
366
  addMedia(url, mediaType);
361
367
  }
362
368
  }
363
- const media = Array.from(captured.entries()).filter(([key]) => !domKeys.size || domKeys.has(key)).map(([, value]) => value);
369
+ if (!domKeys.size && captured.size) {
370
+ const gateHint = data?.gateText && hasPotentialMediaGate(data.gateText) ? "检测到页面可能存在年龄墙或敏感内容遮挡。" : "";
371
+ log?.(`${gateHint}目标推文 DOM 未确认任何媒体,已拒绝发送 ${captured.size} 个浏览器捕获资源,避免误发头像或页面图标。`, true);
372
+ }
373
+ const media = Array.from(captured.entries()).filter(([key]) => domKeys.has(key)).map(([, value]) => value);
364
374
  log?.(`浏览器解析完成: text=${data?.text ? "yes" : "no"}, domMedia=${domKeys.size}, capturedMedia=${captured.size}, media=${media.length}`);
365
375
  return {
366
376
  text: data?.text || "",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-twitter-fetcher",
3
3
  "description": "一个推特/Twitter/X内容获取与订阅插件,支持链接实时解析和用户后台订阅推送。",
4
- "version": "2.0.0",
4
+ "version": "2.0.2",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
@@ -34,12 +34,12 @@
34
34
  "ffmpeg",
35
35
  "browser"
36
36
  ],
37
- "peerDependencies": {
38
- "@koishijs/plugin-console": "^5.30.0",
39
- "koishi": "^4.18.7",
40
- "koishi-plugin-ffmpeg": "^1.1.0",
41
- "koishi-plugin-puppeteer": "*"
42
- },
37
+ "peerDependencies": {
38
+ "@koishijs/plugin-console": "^5.30.0",
39
+ "koishi": "^4.18.7",
40
+ "koishi-plugin-ffmpeg": "^1.1.0",
41
+ "koishi-plugin-puppeteer": "*"
42
+ },
43
43
  "koishi": {
44
44
  "description": {
45
45
  "zh": "自动解析推特/Twitter/X链接,聚合内容。支持订阅推送、浏览器原生获取、真 GIF 和多种媒体发送方式。"
@@ -49,21 +49,21 @@
49
49
  "puppeteer",
50
50
  "database"
51
51
  ],
52
- "optional": [
53
- "console",
54
- "ffmpeg"
55
- ]
56
- }
57
- },
52
+ "optional": [
53
+ "console",
54
+ "ffmpeg"
55
+ ]
56
+ }
57
+ },
58
58
  "scripts": {
59
59
  "build": "esbuild src/index.ts --bundle --platform=node --format=cjs --target=node18 --external:koishi --external:koishi-plugin-puppeteer --external:@koishijs/plugin-console --outfile=lib/index.js && tsc --emitDeclarationOnly"
60
60
  },
61
61
  "peerDependenciesMeta": {
62
- "@koishijs/plugin-console": {
63
- "optional": true
64
- },
65
- "koishi-plugin-ffmpeg": {
66
- "optional": true
67
- }
68
- }
69
- }
62
+ "@koishijs/plugin-console": {
63
+ "optional": true
64
+ },
65
+ "koishi-plugin-ffmpeg": {
66
+ "optional": true
67
+ }
68
+ }
69
+ }
package/readme.md CHANGED
@@ -117,7 +117,8 @@
117
117
 
118
118
  * API 模式依赖 `vxtwitter.com` 的可用性。
119
119
  * 浏览器模式依赖 X 前端页面结构,X 页面更新可能导致提取失败。
120
- * 浏览器媒体模式对图片较稳,对视频只能尽量提取页面和网络响应中可见的候选地址。
120
+ * 浏览器媒体模式只会发送目标推文 DOM 中确认过的媒体。遇到年龄墙、敏感内容遮挡或登录墙导致目标媒体不可见时,会返回空媒体,避免误发头像、图标或页面资源。
121
+ * 浏览器媒体模式对图片较稳,对视频只能尽量提取目标推文页面和网络响应中可确认属于该推文的候选地址。
121
122
  * 真 GIF 模式需要启用 `koishi-plugin-ffmpeg`,转换会增加 CPU 和发送时间。插件只调用 Koishi 上下文中的 `ffmpeg` 服务。
122
123
  * 非 `file` 模式下,下载和 GIF 转换产生的临时输入、输出文件会在发送元素生成后删除。`file` 模式需要给适配器读取本地文件的时间,因此会延迟清理。
123
124
  * `buffer` 和 `base64` 对大视频不友好,OneBot WebSocket 可能因消息体过大断开。
@@ -132,6 +133,8 @@
132
133
 
133
134
  ## 更新日志
134
135
 
136
+ * **v2.0.2**: 修复 v2.0.1 中浏览器媒体安全日志类型不匹配导致的 TypeScript 编译错误。
137
+ * **v2.0.1**: 修复浏览器媒体模式在年龄墙、敏感内容遮挡或登录墙下可能误发头像、图标等页面资源的问题。现在只会发送目标推文 DOM 中确认过的媒体。
135
138
  * **v2.0.0**: 新增右侧悬浮侧边栏、推文/媒体获取方式选择、浏览器媒体原图策略、GIF 转换、图片/视频文件发送方式设置、媒体独立发送开关。
136
139
  * **v1.1.6**: 新增原图下载功能,支持在解析和推送时分别配置是否下载最高画质原图。
137
140
  * **v1.1.5**: 新增静默解析选项,可关闭解析链接时的加载提示。