koishi-plugin-share-links-analysis 0.1.1 → 0.1.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,61 @@ 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('正在尝试使用 Puppeteer 自动刷新小红书 Cookie...');
38
+ try {
39
+ const page = await ctx.puppeteer.page();
40
+ await page.setUserAgent(config.userAgent);
41
+ try {
42
+ await page.goto('https://www.xiaohongshu.com', {
43
+ waitUntil: 'domcontentloaded',
44
+ timeout: 10000
45
+ });
46
+ }
47
+ catch (error) {
48
+ logger.error('Puppeteer 访问小红书首页时发生错误:', error);
49
+ }
50
+ // 获取页面上的所有 Cookie
51
+ const cookies = await page.cookies();
52
+ if (cookies.length === 0) {
53
+ logger.warn('Puppeteer 访问了页面,但未能获取到任何 Cookie。');
54
+ await page.close();
55
+ return false;
56
+ }
57
+ // 将 Cookie 数组格式化为可用的字符串
58
+ const cookieString = cookies.map((c) => `${c.name}=${c.value}`).join('; ');
59
+ // 将新 Cookie 存入数据库
60
+ await ctx.database.upsert('sla_cookie_cache', [{ platform: platformId, cookie: cookieString }]);
61
+ logger.info('成功使用 Puppeteer 刷新并缓存了小红书 Cookie!');
62
+ await page.close();
63
+ return true;
64
+ }
65
+ catch (error) {
66
+ logger.error('使用 Puppeteer 刷新 Cookie 时发生错误: ', error);
67
+ return false;
68
+ }
69
+ }
25
70
  /**
26
71
  * 处理单个小红书链接
27
72
  * @param ctx Koishi Context
28
73
  * @param config 插件配置
29
74
  * @param link 匹配到的链接对象
75
+ * @param session
30
76
  * @returns 处理后的标准格式对象
31
77
  */
32
- async function process(ctx, config, link) {
78
+ async function process(ctx, config, link, session) {
33
79
  const logger = ctx.logger('share-links-analysis:xiaohongshu');
80
+ const platformId = 'xiaohongshu';
34
81
  // 步骤一:从原始分享链接中提取 xsec_token
35
82
  let token = null;
36
83
  try {
@@ -55,17 +102,11 @@ async function process(ctx, config, link) {
55
102
  if (config.logLevel === 'full')
56
103
  logger.info(`小红书短链接解析:尝试获取 ${link.url} 的最终地址`);
57
104
  try {
58
- const response = await ctx.http(link.url, {
105
+ await ctx.http(link.url, {
59
106
  method: 'GET',
60
107
  headers: { 'User-Agent': config.userAgent },
61
108
  redirect: 'manual',
62
109
  });
63
- const location = response.headers.get('location');
64
- if (location) {
65
- finalUrl = location;
66
- if (config.logLevel === 'full')
67
- logger.info(`短链接解析成功,跳转地址: ${finalUrl}`);
68
- }
69
110
  }
70
111
  catch (e) {
71
112
  const location = e.response?.headers?.location;
@@ -85,13 +126,11 @@ async function process(ctx, config, link) {
85
126
  try {
86
127
  const baseUrl = finalUrl.split('?')[0];
87
128
  if (token) {
88
- // 如果有token,构建一个只带token的纯净URL
89
129
  const targetUrl = new URL(baseUrl);
90
130
  targetUrl.searchParams.set('xsec_token', token);
91
131
  urlToFetch = targetUrl.toString();
92
132
  }
93
133
  else {
94
- // 【修正】如果没有token,则直接尝试访问原始最终链接
95
134
  urlToFetch = finalUrl;
96
135
  }
97
136
  }
@@ -102,10 +141,21 @@ async function process(ctx, config, link) {
102
141
  if (config.logLevel === 'full')
103
142
  logger.info(`正在抓取小红书页面: ${urlToFetch}`);
104
143
  try {
105
- const html = await ctx.http.get(urlToFetch, {
106
- headers: { 'User-Agent': config.userAgent }
107
- });
108
- const $ = (0, cheerio_1.load)(html);
144
+ const dbCache = await ctx.database.get('sla_cookie_cache', platformId);
145
+ let currentCookie = (dbCache && dbCache.length > 0) ? dbCache[0].cookie : '';
146
+ const requestHeaders = {
147
+ 'User-Agent': config.userAgent,
148
+ };
149
+ if (currentCookie) {
150
+ requestHeaders['Cookie'] = currentCookie;
151
+ }
152
+ else {
153
+ logger.warn('警告!没有找到缓存的小红书cookie');
154
+ await session.send("小红书 Cookie 未配置或自动刷新失败,无法解析链接。请联系管理员。");
155
+ }
156
+ const fullResponse = await ctx.http(urlToFetch, { method: 'GET', headers: requestHeaders });
157
+ const responseHtml = fullResponse.data;
158
+ const $ = (0, cheerio_1.load)(responseHtml);
109
159
  const scriptContent = $('script:contains("window.__INITIAL_STATE__")').html();
110
160
  if (!scriptContent) {
111
161
  logger.error('在页面中未找到 __INITIAL_STATE__ 数据块,可能是token无效或小红书策略变更。');
@@ -119,6 +169,7 @@ async function process(ctx, config, link) {
119
169
  return null;
120
170
  }
121
171
  const noteData = pageData.note.noteDetailMap[noteKey].note;
172
+ logger.error(pageData.note);
122
173
  // --- 构建结构化数据 ---
123
174
  let videoUrl = null;
124
175
  let coverUrl = undefined;
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",
6
6
  "main": "lib/index.js",
7
7
  "typings": "lib/index.d.ts",
8
8
  "files": [