koishi-plugin-share-links-analysis 0.1.3 → 0.1.5

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/lib/index.js CHANGED
@@ -76,12 +76,6 @@ function apply(ctx, config) {
76
76
  ctx.on('ready', async () => {
77
77
  logger.info('插件已启动,执行一次初始的小红书 Cookie 刷新...');
78
78
  await (0, xiaohongshu_1.refreshXhsCookie)(ctx, config);
79
- // 设置一个定时器,每隔 12 小时刷新一次 Cookie
80
- // 24 * 60 * 60 * 1000 = 24小时
81
- // 12 * 60 * 60 * 1000 = 12小时
82
- ctx.setInterval(async () => {
83
- await (0, xiaohongshu_1.refreshXhsCookie)(ctx, config);
84
- }, 24 * 60 * 60 * 1000);
85
79
  });
86
80
  ctx.middleware(async (session, next) => {
87
81
  if (!session.content || !session.channelId)
@@ -120,28 +114,38 @@ function apply(ctx, config) {
120
114
  }
121
115
  });
122
116
  }
117
+ function escapeHtml(str) {
118
+ if (!str)
119
+ return '';
120
+ return str.replace(/&/g, '&')
121
+ .replace(/</g, '&lt;')
122
+ .replace(/>/g, '&gt;')
123
+ .replace(/"/g, '&quot;')
124
+ .replace(/'/g, '&#39;');
125
+ }
123
126
  async function sendResult(session, config, result, logger) {
124
127
  let message = config.format;
125
- message = message.replace(/{title}/g, result.title || '');
126
- message = message.replace(/{authorName}/g, result.authorName || '');
127
- message = message.replace(/{description}/g, result.description ? result.description : '');
128
- message = message.replace(/{sourceUrl}/g, result.sourceUrl || '');
128
+ // 对所有文本内容进行 HTML 转义
129
+ message = message.replace(/{title}/g, escapeHtml(result.title || ''));
130
+ message = message.replace(/{authorName}/g, escapeHtml(result.authorName || ''));
131
+ message = message.replace(/{description}/g, escapeHtml(result.description ? result.description : ''));
132
+ message = message.replace(/{sourceUrl}/g, escapeHtml(result.sourceUrl || ''));
129
133
  message = message.replace(/{cover}/g, result.coverUrl ? koishi_1.h.image(result.coverUrl).toString() : '');
130
134
  const imagesText = result.images ? result.images.map(img => koishi_1.h.image(img).toString()).join('\n') : '';
131
135
  message = message.replace(/{images}/g, imagesText);
132
- message = message.replace(/{stats}/g, result.stats || '');
136
+ message = message.replace(/{stats}/g, escapeHtml(result.stats || ''));
133
137
  // 【修复】只要 videoUrl 存在就处理,仅当 duration 明确超长时才替换为提示
134
138
  if (result.videoUrl) {
135
139
  // 仅当 duration 是有效数字且超长时,才显示提示
136
140
  if (typeof result.duration === 'number' && result.duration > config.Maximumduration * 60) {
137
- const tip = config.Maximumduration_tip || '';
141
+ const tip = escapeHtml(config.Maximumduration_tip || '');
138
142
  message = message.replace(/{video}/g, tip);
139
143
  message = message.replace(/{videoUrl}/g, '');
140
144
  }
141
145
  else {
142
146
  // 正常发送视频和链接
143
147
  message = message.replace(/{video}/g, koishi_1.h.video(result.videoUrl).toString());
144
- message = message.replace(/{videoUrl}/g, result.videoUrl);
148
+ message = message.replace(/{videoUrl}/g, escapeHtml(result.videoUrl));
145
149
  if (config.logLevel === 'link_only' || config.logLevel === 'full') {
146
150
  logger.info(`视频直链 (${result.platform}): ${result.videoUrl}`);
147
151
  }
@@ -152,6 +156,7 @@ async function sendResult(session, config, result, logger) {
152
156
  message = message.replace(/{video}/g, '');
153
157
  message = message.replace(/{videoUrl}/g, '');
154
158
  }
159
+ // 过滤空行,保留含有 < 的行(如图片、视频标签)
155
160
  const cleanMessage = message.split('\n').filter(line => line.trim() !== '' || line.includes('<')).join('\n');
156
161
  if (cleanMessage) {
157
162
  await session.send(koishi_1.h.quote(session.messageId) + cleanMessage);
@@ -9,6 +9,7 @@ export declare function match(content: string): Link[];
9
9
  /**
10
10
  * 使用 Puppeteer 刷新小红书 Cookie 并存入数据库
11
11
  * @param ctx - Koishi Context
12
+ * @param config
12
13
  */
13
14
  export declare function refreshXhsCookie(ctx: Context, config: PluginConfig): Promise<boolean>;
14
15
  /**
@@ -26,6 +26,7 @@ function match(content) {
26
26
  /**
27
27
  * 使用 Puppeteer 刷新小红书 Cookie 并存入数据库
28
28
  * @param ctx - Koishi Context
29
+ * @param config
29
30
  */
30
31
  async function refreshXhsCookie(ctx, config) {
31
32
  const logger = ctx.logger('share-links-analysis:xiaohongshu');
@@ -51,7 +52,7 @@ async function refreshXhsCookie(ctx, config) {
51
52
  }
52
53
  const initialCookies = await page.cookies();
53
54
  logger.info(`步骤 1 完成, 获取到 ${initialCookies.length} 个初始 Cookie。`);
54
- // --- 步骤 2: 访问 /explore 页面,触发反爬虫验证,获取安全 Cookie (如 acw_tc) ---
55
+ // --- 步骤 2: 访问 /explore 页面,触发反爬虫验证,获取安全 Cookie ---
55
56
  logger.info('步骤 2/2: 访问 /explore 页面以触发并获取安全 Cookie...');
56
57
  try {
57
58
  await page.goto('https://www.xiaohongshu.com/explore', {
@@ -68,16 +69,18 @@ async function refreshXhsCookie(ctx, config) {
68
69
  return false;
69
70
  }
70
71
  const hasWebSession = finalCookies.some((c) => c.name === 'web_session');
71
- const hasAcwTc = finalCookies.some((c) => c.name === 'acw_tc');
72
72
  const hasABRequestId = finalCookies.some((c) => c.name === 'abRequestId');
73
73
  logger.info(`步骤 2 完成, 共获取到 ${finalCookies.length} 个最终 Cookie。`);
74
74
  logger.info(`- 是否包含 'web_session': ${hasWebSession ? '是' : '否'}`);
75
- logger.info(`- 是否包含 'acw_tc': ${hasAcwTc ? '是' : '否'}`);
76
75
  logger.info(`- 是否包含 'abRequestId': ${hasABRequestId ? '是' : '否'}`);
77
- if (!hasWebSession || !hasAcwTc || !hasABRequestId) {
78
- logger.warn('关键 Cookie 缺失,本次刷新可能不完整。仍将尝试保存。');
76
+ if (!hasWebSession || !hasABRequestId) {
77
+ logger.warn('关键 Cookie 缺失,本次刷新可能不完整。将放弃刷新。');
78
+ return false;
79
79
  }
80
- const cookieString = finalCookies.map((c) => `${c.name}=${c.value}`).join('; ');
80
+ // 在这里过滤掉 acw_tc
81
+ const filteredCookies = finalCookies.filter((c) => c.name !== 'acw_tc');
82
+ // 使用过滤后的 cookie 数组来生成字符串
83
+ const cookieString = filteredCookies.map((c) => `${c.name}=${c.value}`).join('; ');
81
84
  await ctx.database.upsert('sla_cookie_cache', [{ platform: platformId, cookie: cookieString }]);
82
85
  logger.info('成功执行两步刷新策略并缓存了小红书 Cookie!');
83
86
  return true;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "koishi-plugin-share-links-analysis",
3
3
  "description": "自用插件",
4
4
  "license": "MIT",
5
- "version": "0.1.3",
5
+ "version": "0.1.5",
6
6
  "main": "lib/index.js",
7
7
  "typings": "lib/index.d.ts",
8
8
  "files": [