koishi-plugin-share-links-analysis 0.1.1 → 0.1.2-fix.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.
package/lib/core.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Context } from 'koishi';
1
+ import { Context, Session } from 'koishi';
2
2
  import { Link, PluginConfig, ParsedInfo } from './types';
3
3
  /**
4
4
  * 从文本中解析出所有支持的链接
@@ -11,6 +11,7 @@ export declare function resolveLinks(content: string): Link[];
11
11
  * @param ctx Koishi Context
12
12
  * @param config 插件配置
13
13
  * @param link 解析出的链接对象
14
+ * @param session 当前会话对象
14
15
  * @returns 处理后的链接结果,如果失败则返回 null
15
16
  */
16
- export declare function processLink(ctx: Context, config: PluginConfig, link: Link): Promise<ParsedInfo | null>;
17
+ export declare function processLink(ctx: Context, config: PluginConfig, link: Link, session: Session): Promise<ParsedInfo | null>;
package/lib/core.js CHANGED
@@ -58,13 +58,13 @@ function resolveLinks(content) {
58
58
  * @param ctx Koishi Context
59
59
  * @param config 插件配置
60
60
  * @param link 解析出的链接对象
61
+ * @param session 当前会话对象
61
62
  * @returns 处理后的链接结果,如果失败则返回 null
62
63
  */
63
- async function processLink(ctx, config, link) {
64
+ async function processLink(ctx, config, link, session) {
64
65
  for (const parser of parsers) {
65
- // 检查这个解析器是否能处理此类型的链接
66
66
  if (parser.match(link.url).length > 0) {
67
- return await parser.process(ctx, config, link);
67
+ return await parser.process(ctx, config, link, session);
68
68
  }
69
69
  }
70
70
  return null;
package/lib/index.d.ts CHANGED
@@ -3,7 +3,7 @@ import { PluginConfig } from './types';
3
3
  export declare const name = "share-links-analysis";
4
4
  export declare const inject: {
5
5
  required: string[];
6
- optional: string[];
6
+ optional: never[];
7
7
  };
8
8
  export declare const usage = "\n\u5F00\u542F\u63D2\u4EF6\u540E\uFF0C\u5373\u53EF\u81EA\u52A8\u89E3\u6790\u5206\u4EAB\u94FE\u63A5\u3002\n\u5411Bot\u53D1\u9001B\u7AD9\u3001\u5C0F\u7EA2\u4E66\u7B49\u652F\u6301\u5E73\u53F0\u7684\u5206\u4EAB\u94FE\u63A5\uFF0C\u4F1A\u8FD4\u56DE\u56FE\u6587\u4FE1\u606F\u4E0E\u89C6\u9891\u3002\n\u60A8\u53EF\u4EE5\u5728\u63D2\u4EF6\u914D\u7F6E\u4E2D\u4E3A\u4E0D\u540C\u5E73\u53F0\u5206\u522B\u8BBE\u7F6E\u8FD4\u56DE\u7684\u56FE\u6587\u6D88\u606F\u683C\u5F0F\u3002\n";
9
9
  export declare const Config: Schema<PluginConfig>;
package/lib/index.js CHANGED
@@ -5,10 +5,11 @@ exports.Config = exports.usage = exports.inject = exports.name = void 0;
5
5
  exports.apply = apply;
6
6
  const koishi_1 = require("koishi");
7
7
  const core_1 = require("./core");
8
+ const xiaohongshu_1 = require("./parsers/xiaohongshu");
8
9
  exports.name = 'share-links-analysis';
9
10
  exports.inject = {
10
- required: ['BiliBiliVideo'],
11
- optional: ['puppeteer'],
11
+ required: ['BiliBiliVideo', 'database', 'puppeteer'],
12
+ optional: [],
12
13
  };
13
14
  exports.usage = `
14
15
  开启插件后,即可自动解析分享链接。
@@ -64,8 +65,24 @@ exports.Config = koishi_1.Schema.intersect([
64
65
  }).description("调试设置"),
65
66
  ]);
66
67
  function apply(ctx, config) {
68
+ ctx.model.extend('sla_cookie_cache', {
69
+ platform: 'string', // 平台名称,如 'xiaohongshu'
70
+ cookie: 'text', // 存储的 cookie 字符串
71
+ }, {
72
+ primary: 'platform' // 使用平台名称作为主键
73
+ });
67
74
  const logger = ctx.logger('share-links-analysis');
68
75
  const lastProcessedUrls = {};
76
+ ctx.on('ready', async () => {
77
+ logger.info('插件已启动,执行一次初始的小红书 Cookie 刷新...');
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
+ });
69
86
  ctx.middleware(async (session, next) => {
70
87
  if (!session.content || !session.channelId)
71
88
  return next();
@@ -91,7 +108,7 @@ function apply(ctx, config) {
91
108
  if (config.waitTip_Switch) {
92
109
  await session.send(config.waitTip_Switch);
93
110
  }
94
- const result = await (0, core_1.processLink)(ctx, config, link);
111
+ const result = await (0, core_1.processLink)(ctx, config, link, session);
95
112
  if (result) {
96
113
  lastProcessedUrls[channelId][link.url] = now;
97
114
  await sendResult(session, config, result, logger);
@@ -1,4 +1,4 @@
1
- import { Context } from 'koishi';
1
+ import { Context, Session } from 'koishi';
2
2
  import { Link, ParsedInfo, PluginConfig } from '../types';
3
3
  /**
4
4
  * 在文本中匹配B站链接 (长链/短链/纯BV号)
@@ -11,6 +11,7 @@ export declare function match(content: string): Link[];
11
11
  * @param ctx Koishi Context
12
12
  * @param config 插件配置
13
13
  * @param link 匹配到的链接对象
14
+ * @param session
14
15
  * @returns 处理后的标准格式对象
15
16
  */
16
- export declare function process(ctx: Context, config: PluginConfig, link: Link): Promise<ParsedInfo | null>;
17
+ export declare function process(ctx: Context, config: PluginConfig, link: Link, session: Session): Promise<ParsedInfo | null>;
@@ -50,9 +50,10 @@ function match(content) {
50
50
  * @param ctx Koishi Context
51
51
  * @param config 插件配置
52
52
  * @param link 匹配到的链接对象
53
+ * @param session
53
54
  * @returns 处理后的标准格式对象
54
55
  */
55
- async function process(ctx, config, link) {
56
+ async function process(ctx, config, link, session) {
56
57
  const logger = ctx.logger('share-links-analysis:bilibili');
57
58
  let videoId = link.id;
58
59
  let videoIdType = link.type;
@@ -1,4 +1,4 @@
1
- import { Context } from 'koishi';
1
+ import { Context, Session } from 'koishi';
2
2
  import { Link, ParsedInfo, PluginConfig } from '../types';
3
3
  /**
4
4
  * 在文本中匹配小红书链接 (长链接或短链接)
@@ -6,11 +6,17 @@ import { Link, ParsedInfo, PluginConfig } from '../types';
6
6
  * @returns 匹配到的链接对象数组
7
7
  */
8
8
  export declare function match(content: string): Link[];
9
+ /**
10
+ * 使用 Puppeteer 刷新小红书 Cookie 并存入数据库
11
+ * @param ctx - Koishi Context
12
+ */
13
+ export declare function refreshXhsCookie(ctx: Context, config: PluginConfig): Promise<boolean>;
9
14
  /**
10
15
  * 处理单个小红书链接
11
16
  * @param ctx Koishi Context
12
17
  * @param config 插件配置
13
18
  * @param link 匹配到的链接对象
19
+ * @param session
14
20
  * @returns 处理后的标准格式对象
15
21
  */
16
- export declare function process(ctx: Context, config: PluginConfig, link: Link): Promise<ParsedInfo | null>;
22
+ export declare function process(ctx: Context, config: PluginConfig, link: Link, session: Session): Promise<ParsedInfo | null>;
@@ -2,6 +2,7 @@
2
2
  // src/parsers/xiaohongshu.ts
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.match = match;
5
+ exports.refreshXhsCookie = refreshXhsCookie;
5
6
  exports.process = process;
6
7
  const cheerio_1 = require("cheerio");
7
8
  const utils_1 = require("../utils");
@@ -22,15 +23,86 @@ function match(content) {
22
23
  url: url
23
24
  }));
24
25
  }
26
+ /**
27
+ * 使用 Puppeteer 刷新小红书 Cookie 并存入数据库
28
+ * @param ctx - Koishi Context
29
+ */
30
+ async function refreshXhsCookie(ctx, config) {
31
+ const logger = ctx.logger('share-links-analysis:xiaohongshu');
32
+ const platformId = 'xiaohongshu';
33
+ if (!ctx.puppeteer) {
34
+ logger.warn('Puppeteer 服务未启用,无法自动刷新 Cookie。');
35
+ return false;
36
+ }
37
+ logger.info('正在执行两步导航策略以刷新小红书 Cookie...');
38
+ let page = null;
39
+ try {
40
+ page = await ctx.puppeteer.page();
41
+ await page.setUserAgent(config.userAgent);
42
+ // --- 步骤 1: 访问首页,获取基础会话 Cookie (如 web_session) ---
43
+ logger.info('步骤 1/2: 访问首页以获取初始会话 Cookie...');
44
+ try {
45
+ await page.goto('https://www.xiaohongshu.com/', {
46
+ waitUntil: 'load',
47
+ timeout: 10000
48
+ });
49
+ }
50
+ catch (error) {
51
+ }
52
+ const initialCookies = await page.cookies();
53
+ logger.info(`步骤 1 完成, 获取到 ${initialCookies.length} 个初始 Cookie。`);
54
+ // --- 步骤 2: 访问 /explore 页面,触发反爬虫验证,获取安全 Cookie (如 acw_tc) ---
55
+ logger.info('步骤 2/2: 访问 /explore 页面以触发并获取安全 Cookie...');
56
+ try {
57
+ await page.goto('https://www.xiaohongshu.com/explore', {
58
+ waitUntil: 'load',
59
+ timeout: 10000
60
+ });
61
+ }
62
+ catch (error) {
63
+ }
64
+ // --- 步骤 3: 收集并验证最终合并的 Cookie ---
65
+ const finalCookies = await page.cookies();
66
+ if (finalCookies.length === 0) {
67
+ logger.warn('执行两步导航后,仍未能获取到任何 Cookie。');
68
+ return false;
69
+ }
70
+ const hasWebSession = finalCookies.some((c) => c.name === 'web_session');
71
+ const hasAcwTc = finalCookies.some((c) => c.name === 'acw_tc');
72
+ const hasABRequestId = finalCookies.some((c) => c.name === 'abRequestId');
73
+ logger.info(`步骤 2 完成, 共获取到 ${finalCookies.length} 个最终 Cookie。`);
74
+ logger.info(`- 是否包含 'web_session': ${hasWebSession ? '是' : '否'}`);
75
+ logger.info(`- 是否包含 'acw_tc': ${hasAcwTc ? '是' : '否'}`);
76
+ logger.info(`- 是否包含 'abRequestId': ${hasABRequestId ? '是' : '否'}`);
77
+ if (!hasWebSession || !hasAcwTc || !hasABRequestId) {
78
+ logger.warn('关键 Cookie 缺失,本次刷新可能不完整。仍将尝试保存。');
79
+ }
80
+ const cookieString = finalCookies.map((c) => `${c.name}=${c.value}`).join('; ');
81
+ await ctx.database.upsert('sla_cookie_cache', [{ platform: platformId, cookie: cookieString }]);
82
+ logger.info('成功执行两步刷新策略并缓存了小红书 Cookie!');
83
+ return true;
84
+ }
85
+ catch (error) {
86
+ logger.error('在执行两步导航刷新 Cookie 时发生错误: ', error);
87
+ return false;
88
+ }
89
+ finally {
90
+ if (page) {
91
+ await page.close();
92
+ }
93
+ }
94
+ }
25
95
  /**
26
96
  * 处理单个小红书链接
27
97
  * @param ctx Koishi Context
28
98
  * @param config 插件配置
29
99
  * @param link 匹配到的链接对象
100
+ * @param session
30
101
  * @returns 处理后的标准格式对象
31
102
  */
32
- async function process(ctx, config, link) {
103
+ async function process(ctx, config, link, session) {
33
104
  const logger = ctx.logger('share-links-analysis:xiaohongshu');
105
+ const platformId = 'xiaohongshu';
34
106
  // 步骤一:从原始分享链接中提取 xsec_token
35
107
  let token = null;
36
108
  try {
@@ -55,17 +127,11 @@ async function process(ctx, config, link) {
55
127
  if (config.logLevel === 'full')
56
128
  logger.info(`小红书短链接解析:尝试获取 ${link.url} 的最终地址`);
57
129
  try {
58
- const response = await ctx.http(link.url, {
130
+ await ctx.http(link.url, {
59
131
  method: 'GET',
60
132
  headers: { 'User-Agent': config.userAgent },
61
133
  redirect: 'manual',
62
134
  });
63
- const location = response.headers.get('location');
64
- if (location) {
65
- finalUrl = location;
66
- if (config.logLevel === 'full')
67
- logger.info(`短链接解析成功,跳转地址: ${finalUrl}`);
68
- }
69
135
  }
70
136
  catch (e) {
71
137
  const location = e.response?.headers?.location;
@@ -85,13 +151,11 @@ async function process(ctx, config, link) {
85
151
  try {
86
152
  const baseUrl = finalUrl.split('?')[0];
87
153
  if (token) {
88
- // 如果有token,构建一个只带token的纯净URL
89
154
  const targetUrl = new URL(baseUrl);
90
155
  targetUrl.searchParams.set('xsec_token', token);
91
156
  urlToFetch = targetUrl.toString();
92
157
  }
93
158
  else {
94
- // 【修正】如果没有token,则直接尝试访问原始最终链接
95
159
  urlToFetch = finalUrl;
96
160
  }
97
161
  }
@@ -102,10 +166,21 @@ async function process(ctx, config, link) {
102
166
  if (config.logLevel === 'full')
103
167
  logger.info(`正在抓取小红书页面: ${urlToFetch}`);
104
168
  try {
105
- const html = await ctx.http.get(urlToFetch, {
106
- headers: { 'User-Agent': config.userAgent }
107
- });
108
- const $ = (0, cheerio_1.load)(html);
169
+ const dbCache = await ctx.database.get('sla_cookie_cache', platformId);
170
+ let currentCookie = (dbCache && dbCache.length > 0) ? dbCache[0].cookie : '';
171
+ const requestHeaders = {
172
+ 'User-Agent': config.userAgent,
173
+ };
174
+ if (currentCookie) {
175
+ requestHeaders['Cookie'] = currentCookie;
176
+ }
177
+ else {
178
+ logger.warn('警告!没有找到缓存的小红书cookie');
179
+ await session.send("小红书 Cookie 未配置或自动刷新失败,无法解析链接。请联系管理员。");
180
+ }
181
+ const fullResponse = await ctx.http(urlToFetch, { method: 'GET', headers: requestHeaders });
182
+ const responseHtml = fullResponse.data;
183
+ const $ = (0, cheerio_1.load)(responseHtml);
109
184
  const scriptContent = $('script:contains("window.__INITIAL_STATE__")').html();
110
185
  if (!scriptContent) {
111
186
  logger.error('在页面中未找到 __INITIAL_STATE__ 数据块,可能是token无效或小红书策略变更。');
package/lib/tmp.json ADDED
@@ -0,0 +1,534 @@
1
+ {
2
+ "global": {
3
+ "appSettings": {
4
+ "notificationInterval": 30,
5
+ "prefetchTimeout": 3001,
6
+ "prefetchRedisExpires": 259200000,
7
+ "searchFilterGuideConfig": {
8
+ "maxDailyShow": 1,
9
+ "maxTotalShow": 3,
10
+ "showInterval": 1,
11
+ "validDays": 15,
12
+ "autoCloseDelay": 5000
13
+ },
14
+ "retryFeeds": true,
15
+ "grayModeConfig": {
16
+ "global": false,
17
+ "dateRange": [
18
+ "2023-08-01 00:00:00",
19
+ "2023-08-19 23:59:59"
20
+ ],
21
+ "greyRule": {
22
+ "layout": {
23
+ "enable": false,
24
+ "pages": [
25
+ "Explore"
26
+ ]
27
+ },
28
+ "pages": [
29
+ "Explore"
30
+ ]
31
+ },
32
+ "disableLikeNotes": [
33
+ "64ce36f7000000000c036ba5"
34
+ ],
35
+ "disableSearchHint": false
36
+ },
37
+ "NIO": true,
38
+ "ICPInfoList": [
39
+ {
40
+ "label": "沪ICP备13030189号",
41
+ "link": "\u002F\u002Fbeian.miit.gov.cn\u002F",
42
+ "title": "小红书_沪ICP备"
43
+ },
44
+ {
45
+ "label": "营业执照",
46
+ "link": "\u002F\u002Ffe-video-qc.xhscdn.com\u002Ffe-platform\u002F5581076bd6b6af2e0e943abb024ad0e16f2ebff6.pdf",
47
+ "title": "小红书_营业执照"
48
+ },
49
+ {
50
+ "label": "2024沪公网安备31010102002533号",
51
+ "link": "\u002F\u002Fwww.beian.gov.cn\u002Fportal\u002FregisterSystemInfo?recordcode=31010102002533",
52
+ "title": "小红书_沪公网安备"
53
+ },
54
+ {
55
+ "label": "增值电信业务经营许可证:沪B2-20150021",
56
+ "link": "\u002F\u002Ffe-video-qc.xhscdn.com\u002Ffe-platform-file\u002F104101b831hhkkll23u0678gtks7tu70004en2n231udpe",
57
+ "title": "小红书_网文"
58
+ },
59
+ {
60
+ "label": "医疗器械网络交易服务第三方平台备案:(沪)网械平台备字[2019]第00006号",
61
+ "link": "\u002F\u002Ffe-video-qc.xhscdn.com\u002Ffe-platform\u002F410dce57bc12a6d7e5808060e47644fbe46f68ff.pdf",
62
+ "title": "小红书_医疗器械网络交易服务"
63
+ },
64
+ {
65
+ "label": "互联网药品信息服务资格证书:(沪)-经营性-2023-0144",
66
+ "link": "\u002F\u002Ffe-video-qc.xhscdn.com\u002Ffe-platform\u002Ff37a08cacc088061beb38329c387c32fc48fc6fe.pdf",
67
+ "title": "小红书_互联网药品信息服务"
68
+ },
69
+ {
70
+ "label": "违法不良信息举报电话:4006676810",
71
+ "link": "\u002F\u002Fwww.shjbzx.cn",
72
+ "title": "小红书_上海市互联网举报中心"
73
+ },
74
+ {
75
+ "label": "上海市互联网举报中心",
76
+ "link": "\u002F\u002Fwww.shjbzx.cn",
77
+ "title": "小红书_上海市互联网举报中心"
78
+ },
79
+ {
80
+ "label": "网上有害信息举报专区",
81
+ "link": "\u002F\u002Fwww.12377.cn",
82
+ "title": "网上有害信息举报专区"
83
+ },
84
+ {
85
+ "label": "自营经营者信息",
86
+ "link": "\u002F\u002Fdc.xhscdn.com\u002F06c2adb0-b353-11e9-9d0c-7be9ff8961c1\u002F自营经营者信息公示.pdf",
87
+ "title": "小红书_沪公网安备"
88
+ },
89
+ {
90
+ "label": "网络文化经营许可证:沪网文(2024)1344-086号",
91
+ "link": "\u002F\u002Ffe-video-qc.xhscdn.com\u002Ffe-platform\u002F7970f6e8b70aedc995ba273d04b6b6751abcd63c.pdf",
92
+ "title": "小红书_网络文化经营许可"
93
+ },
94
+ {
95
+ "label": "个性化推荐算法 网信算备310101216601302230019号",
96
+ "link": "https:\u002F\u002Fbeian.cac.gov.cn\u002Fapi\u002Fstatic\u002FfileUpload\u002FprincipalOrithm\u002Fadditional\u002Fuser_c015445c-80ac-45f7-94d7-3871e961b1fe_d4425f3b-7f35-45af-b8d4-badd4424d6d5.pdf"
97
+ }
98
+ ],
99
+ "disableBanAlert": "false",
100
+ "showAdBlockAlert": 0
101
+ },
102
+ "supportWebp": true,
103
+ "serverTime": 1756328590957,
104
+ "grayMode": false,
105
+ "referer": "",
106
+ "pwaAddDesktopPrompt": undefined,
107
+ "firstVisitUrl": undefined,
108
+ "easyAccessModalVisible": {
109
+ "addDesktopGuide": false,
110
+ "collectGuide": false,
111
+ "keyboardList": false,
112
+ "miniWindowGuide": false
113
+ },
114
+ "currentLayout": "default",
115
+ "fullscreenLocking": false,
116
+ "feedbackPopupVisible": false,
117
+ "trackFps": false,
118
+ "supportAVIF": true,
119
+ "imgFormatCollect": {
120
+ "ssr": [
121
+ "jpg",
122
+ "webp",
123
+ "avif"
124
+ ],
125
+ "csr": [
126
+ "jpg"
127
+ ]
128
+ },
129
+ "isUndertake": false
130
+ },
131
+ "user": {
132
+ "loggedIn": false,
133
+ "activated": false,
134
+ "userInfo": {
135
+ "userId": "6896e5190000000027037870",
136
+ "guest": true
137
+ },
138
+ "follow": [],
139
+ "userPageData": {},
140
+ "activeTab": {
141
+ "key": 0,
142
+ "index": 0,
143
+ "query": "note",
144
+ "label": "笔记",
145
+ "lock": false,
146
+ "subTabs": null,
147
+ "feedType": 0
148
+ },
149
+ "notes": [
150
+ [],
151
+ [],
152
+ [],
153
+ []
154
+ ],
155
+ "isFetchingNotes": [
156
+ false,
157
+ false,
158
+ false,
159
+ false
160
+ ],
161
+ "tabScrollTop": [
162
+ 0,
163
+ 0,
164
+ 0,
165
+ 0
166
+ ],
167
+ "userFetchingStatus": undefined,
168
+ "userNoteFetchingStatus": [
169
+ "",
170
+ "",
171
+ "",
172
+ ""
173
+ ],
174
+ "bannedInfo": {
175
+ "userId": "",
176
+ "serverBanned": false,
177
+ "code": 0,
178
+ "showAlert": false,
179
+ "reason": "",
180
+ "api": ""
181
+ },
182
+ "firstFetchNote": true,
183
+ "noteQueries": [
184
+ {
185
+ "num": 30,
186
+ "cursor": "",
187
+ "userId": "",
188
+ "hasMore": true,
189
+ "page": 1
190
+ },
191
+ {
192
+ "num": 30,
193
+ "cursor": "",
194
+ "userId": "",
195
+ "hasMore": true,
196
+ "page": 1
197
+ },
198
+ {
199
+ "num": 30,
200
+ "cursor": "",
201
+ "userId": "",
202
+ "hasMore": true,
203
+ "page": 1
204
+ },
205
+ {
206
+ "num": 30,
207
+ "cursor": "",
208
+ "userId": "",
209
+ "hasMore": true,
210
+ "page": 1
211
+ }
212
+ ],
213
+ "pageScrolled": 0,
214
+ "activeSubTab": undefined,
215
+ "isOwnBoard": true
216
+ },
217
+ "board": {
218
+ "boardListData": {},
219
+ "isLoadingBoardList": false,
220
+ "boardDetails": {},
221
+ "boardFeedsMap": {},
222
+ "boardPageStatus": "pending",
223
+ "userBoardList": []
224
+ },
225
+ "login": {
226
+ "loginMethod": undefined,
227
+ "from": "",
228
+ "showLogin": false,
229
+ "agreed": false,
230
+ "showTooltip": false,
231
+ "loginData": {
232
+ "phone": "",
233
+ "authCode": ""
234
+ },
235
+ "errors": {
236
+ "phone": "",
237
+ "authCode": ""
238
+ },
239
+ "qrData": {
240
+ "backend": {
241
+ "qrId": "",
242
+ "code": ""
243
+ },
244
+ "image": "",
245
+ "status": "un_scanned"
246
+ },
247
+ "counter": undefined,
248
+ "inAntiSpamChecking": false,
249
+ "recentFrom": "",
250
+ "isObPagesVisible": false,
251
+ "obPageFillInProgress": null,
252
+ "verificationCodeStartTime": 0,
253
+ "ageSelectValue": "21",
254
+ "hobbySelectValue": [],
255
+ "genderSelectValue": undefined,
256
+ "inSpamCheckSendAuthCode": false,
257
+ "isRegFusing": false,
258
+ "loginStep": 0,
259
+ "isLogining": false,
260
+ "loginPadMountedTime": 0,
261
+ "loginTips": "登录后推荐更懂你的笔记",
262
+ "isRiskUser": false,
263
+ "closeLoginModal": false,
264
+ "traceId": "",
265
+ "inAntiSpamCheckLogin": false
266
+ },
267
+ "feed": {
268
+ "query": {
269
+ "cursorScore": "",
270
+ "num": 30,
271
+ "refreshType": 1,
272
+ "noteIndex": 0,
273
+ "unreadBeginNoteId": "",
274
+ "unreadEndNoteId": "",
275
+ "unreadNoteCount": 0,
276
+ "category": "homefeed_recommend",
277
+ "searchKey": "",
278
+ "needNum": 20,
279
+ "imageFormats": [],
280
+ "needFilterImage": false
281
+ },
282
+ "isFetching": false,
283
+ "isError": false,
284
+ "feedsWrapper": undefined,
285
+ "undertakeNote": undefined,
286
+ "feeds": [],
287
+ "currentChannel": "homefeed_recommend",
288
+ "unreadInfo": {
289
+ "cachedFeeds": [],
290
+ "unreadBeginNoteId": "",
291
+ "unreadEndNoteId": "",
292
+ "unreadNoteCount": 0,
293
+ "timestamp": 0
294
+ },
295
+ "validIds": {
296
+ "noteIds": []
297
+ },
298
+ "mfStatistics": {
299
+ "timestamp": 0,
300
+ "visitTimes": 0,
301
+ "readFeedCount": 0
302
+ },
303
+ "channels": undefined,
304
+ "isResourceDisplay": false,
305
+ "isActivityEnd": false,
306
+ "cancelFeedRequest": false,
307
+ "prefetchId": undefined,
308
+ "mfRequestMetaData": {
309
+ "start": null,
310
+ "lasting": null
311
+ },
312
+ "placeholderFeeds": [],
313
+ "feedsCacheLogInfo": {
314
+ "flag": "unknown",
315
+ "errorCode": 0,
316
+ "isHitMfCache": false,
317
+ "SSRDocumentChecked": false,
318
+ "SSRDocumentCheckedSuccess": false
319
+ },
320
+ "isUsingPlaceholderFeeds": false,
321
+ "placeholderFeedsConsumed": false,
322
+ "isReplace": false,
323
+ "isFirstSuccessFetched": false,
324
+ "imgNoteFilterStatus": "unchecked",
325
+ "ssrRequestStatus": 5,
326
+ "ssrRenderExtra": ""
327
+ },
328
+ "layout": {
329
+ "layoutInfoReady": false,
330
+ "columns": 6,
331
+ "columnsWithSidebar": 6,
332
+ "gap": {
333
+ "vertical": 12,
334
+ "horizontal": 24
335
+ },
336
+ "columnWidth": 0,
337
+ "interactionWidth": 0,
338
+ "widthType": "normal",
339
+ "bufferRow": 3
340
+ },
341
+ "search": {
342
+ "state": "auto",
343
+ "searchContext": {
344
+ "keyword": "",
345
+ "page": 1,
346
+ "pageSize": 20,
347
+ "searchId": "",
348
+ "sort": "general",
349
+ "noteType": 0,
350
+ "extFlags": [],
351
+ "filters": [],
352
+ "geo": ""
353
+ },
354
+ "feeds": [],
355
+ "searchValue": "",
356
+ "suggestions": [],
357
+ "userInputSugTrigger": "",
358
+ "keywordFrom": 2,
359
+ "tagSearch": [],
360
+ "activeTagSearch": null,
361
+ "searchFeedsWrapper": undefined,
362
+ "currentSearchType": "all",
363
+ "hintWord": {
364
+ "title": "搜索小红书",
365
+ "searchWord": "小红书网页版",
366
+ "hintWordRequestId": "default",
367
+ "type": "default"
368
+ },
369
+ "sugType": null,
370
+ "queryTrendingInfo": undefined,
371
+ "queryTrendingParams": {
372
+ "source": "ExploreNote",
373
+ "searchType": "trend",
374
+ "lastQuery": "",
375
+ "lastQueryTime": 0,
376
+ "wordRequestSituation": "FIRST_ENTER",
377
+ "hintWord": "",
378
+ "hintWordType": "",
379
+ "hintWordRequestId": ""
380
+ },
381
+ "queryTrendingFetched": false,
382
+ "oneboxInfo": {},
383
+ "hasMore": true,
384
+ "firstEnterSearchPage": true,
385
+ "userLists": [],
386
+ "fetchUserListsStatus": "auto",
387
+ "isFetchingUserLists": false,
388
+ "hasMoreUser": true,
389
+ "searchCplId": undefined,
390
+ "wordRequestId": undefined,
391
+ "historyList": [],
392
+ "searchPageHasPrevRoute": false,
393
+ "searchHotSpots": [],
394
+ "hotspotQueryNoteStep": "display",
395
+ "hotspotQueryNoteIndex": 0,
396
+ "canShowHotspotQueryNote": true,
397
+ "forceHotspotSearch": false,
398
+ "searchCardHotSpots": [],
399
+ "isHotspotSearch": false,
400
+ "filters": undefined,
401
+ "activeFilters": [],
402
+ "filterParams": undefined,
403
+ "sessionId": "",
404
+ "rootSearchId": "",
405
+ "searchUserContext": {
406
+ "keyword": "",
407
+ "searchId": "",
408
+ "page": 1,
409
+ "pageSize": 15,
410
+ "bizType": "web_search_user",
411
+ "requestId": ""
412
+ }
413
+ },
414
+ "activity": {
415
+ "isOpen": false,
416
+ "currentUrl": "",
417
+ "entryList": []
418
+ },
419
+ "note": {
420
+ "prevRouteData": {},
421
+ "prevRoute": "Empty",
422
+ "commentTarget": {},
423
+ "isImgFullscreen": false,
424
+ "gotoPage": "",
425
+ "firstNoteId": "68adb315000000001b023b58",
426
+ "autoOpenNote": false,
427
+ "topCommentId": "",
428
+ "noteDetailMap": {
429
+ "68adb315000000001b023b58": {
430
+ "comments": {
431
+ "list": [],
432
+ "cursor": "",
433
+ "hasMore": true,
434
+ "loading": false,
435
+ "firstRequestFinish": false
436
+ },
437
+ "currentTime": 1756328591014,
438
+ "note": {
439
+ "xsecToken": "CBCoBA_fNbnLQQd-rBHG4DECacPM7Zf-XQSMtI660hn3Q=",
440
+ "interactInfo": {
441
+ "commentCount": "5",
442
+ "shareCount": "7",
443
+ "followed": false,
444
+ "relation": "none",
445
+ "liked": false,
446
+ "likedCount": "10+",
447
+ "collected": false,
448
+ "collectedCount": "10+"
449
+ },
450
+ "atUserList": [],
451
+ "lastUpdateTime": 1756214037000,
452
+ "imageList": [
453
+ {
454
+ "fileId": "",
455
+ "width": 1440,
456
+ "infoList": [
457
+ {
458
+ "imageScene": "WB_PRV",
459
+ "url": "http:\u002F\u002Fsns-webpic-qc.xhscdn.com\u002F202508280503\u002F95301b5052930954a1ab95cb011ba1c8\u002F1040g00831lla30rp5e0g5otfoi3pidets6vatq8!nd_prv_wgth_webp_3"
460
+ },
461
+ {
462
+ "imageScene": "WB_DFT",
463
+ "url": "http:\u002F\u002Fsns-webpic-qc.xhscdn.com\u002F202508280503\u002Fe7f1aa16353c22d9ca6b1030d7b7de07\u002F1040g00831lla30rp5e0g5otfoi3pidets6vatq8!nd_dft_wgth_webp_3"
464
+ }
465
+ ],
466
+ "urlPre": "http:\u002F\u002Fsns-webpic-qc.xhscdn.com\u002F202508280503\u002F95301b5052930954a1ab95cb011ba1c8\u002F1040g00831lla30rp5e0g5otfoi3pidets6vatq8!nd_prv_wgth_webp_3",
467
+ "urlDefault": "http:\u002F\u002Fsns-webpic-qc.xhscdn.com\u002F202508280503\u002Fe7f1aa16353c22d9ca6b1030d7b7de07\u002F1040g00831lla30rp5e0g5otfoi3pidets6vatq8!nd_dft_wgth_webp_3",
468
+ "stream": {},
469
+ "height": 1080,
470
+ "url": "",
471
+ "traceId": "",
472
+ "livePhoto": false
473
+ }
474
+ ],
475
+ "video": {
476
+ "media": {
477
+ "videoId": 137550772773350240,
478
+ "video": {
479
+ "bizName": 110,
480
+ "bizId": "281665961380952920",
481
+ "duration": 37,
482
+ "md5": "be9e4d7520d46c52fe464fc5134c3dd7",
483
+ "hdrType": 0,
484
+ "drmType": 0,
485
+ "streamTypes": [
486
+ 259,
487
+ 114,
488
+ 115
489
+ ]
490
+ },
491
+ "stream": {
492
+ "h264": [
493
+ {
494
+ "width": 1280,
495
+ "qualityType": "HD",
496
+ "format": "mp4",
497
+ "audioBitrate": 64292,
498
+ "duration": 36100,
499
+ "size": 10115137,
500
+ "avgBitrate": 2241581,
501
+ "height": 720,
502
+ "weight": 62,
503
+ "audioDuration": 36083,
504
+ "vmaf": -1,
505
+ "rotate": 0,
506
+ "streamDesc": "WM_X264_MP4",
507
+ "fps": 30,
508
+ "hdrType": 0,
509
+ "defaultStream": 0,
510
+ "backupUrls": [
511
+ "http:\u002F\u002Fsns-bak-v1.xhscdn.com\u002Fstream\u002F79\u002F110\u002F259\u002F01e8adb2f5bc6b600103700398e683cd7c_259.mp4",
512
+ "http:\u002F\u002Fsns-bak-v6.xhscdn.com\u002Fstream\u002F79\u002F110\u002F259\u002F01e8adb2f5bc6b600103700398e683cd7c_259.mp4"
513
+ ],
514
+ "videoBitrate": 2170427,
515
+ "audioCodec": "aac",
516
+ "masterUrl": "http:\u002F\u002Fsns-video-hw.xhscdn.com\u002Fstream\u002F79\u002F110\u002F259\u002F01e8adb2f5bc6b600103700398e683cd7c_259.mp4",
517
+ "streamType": 259,
518
+ "psnr": 0,
519
+ "videoDuration": 36100,
520
+ "audioChannels": 2,
521
+ "ssim": 0,
522
+ "volume": 0,
523
+ "videoCodec": "h264"
524
+ }
525
+ ],
526
+ "h265": [
527
+ {
528
+ "width": 1280,
529
+ "volume": 0,
530
+ "avgBitrate": 1497289,
531
+ "audioChannels": 2,
532
+ "backupUrls": [
533
+ "http:\u002F\u002Fsns-bak-v1.xhscdn.com\u002Fstream\u002F79\u002F110\u002F114\u002F01e8adb2f5bc6b604f03700198e684be49_114.mp4",
534
+ "http:\u002F\u002Fsns-bak-v6.xhscdn.com\u002Fstream\u002F79\u002F110\u002F114\u002F01e8adb2f5bc6b604f03700198e684be49_114.mp4…,
package/lib/types.d.ts CHANGED
@@ -71,6 +71,12 @@ declare module 'koishi' {
71
71
  BiliBiliVideo: any;
72
72
  puppeteer?: any;
73
73
  }
74
+ interface Tables {
75
+ sla_cookie_cache: {
76
+ platform: string;
77
+ cookie: string;
78
+ };
79
+ }
74
80
  }
75
81
  export interface XhsImageInfo {
76
82
  imageScene: string;
package/lib/types.js CHANGED
@@ -1,3 +1,4 @@
1
1
  "use strict";
2
2
  // src/types.ts
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
+ let session_global;
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.1",
5
+ "version": "0.1.2-fix.2",
6
6
  "main": "lib/index.js",
7
7
  "typings": "lib/index.d.ts",
8
8
  "files": [