koishi-plugin-weibo-post-monitor 1.0.0 → 1.0.1-beta.0

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.d.ts CHANGED
@@ -1,13 +1,5 @@
1
- import { Context, Schema } from 'koishi';
1
+ import { Context } from 'koishi';
2
+ import { Config, type Config as ConfigType } from './services/config';
2
3
  export declare const name = "weibo-post-monitor";
3
- export interface Config {
4
- account: string;
5
- plantform: string;
6
- waitMinutes: number;
7
- sendINFO: any;
8
- is_using_cookie: boolean;
9
- manual_cookie: string;
10
- }
11
- export declare const Config: Schema<Config>;
12
- export declare function to<T, U = Error>(promise: Promise<T>, errorExt?: object): Promise<[U, undefined] | [null, T]>;
13
- export declare function apply(ctx: Context, config: Config): void;
4
+ export { Config };
5
+ export declare function apply(ctx: Context, config: ConfigType): void;
package/lib/index.js CHANGED
@@ -32,17 +32,30 @@ var src_exports = {};
32
32
  __export(src_exports, {
33
33
  Config: () => Config,
34
34
  apply: () => apply,
35
- name: () => name,
36
- to: () => to
35
+ name: () => name
37
36
  });
38
37
  module.exports = __toCommonJS(src_exports);
38
+
39
+ // src/services/config.ts
39
40
  var import_koishi = require("koishi");
40
- var import_https = __toESM(require("https"));
41
- var import_axios = __toESM(require("axios"));
42
- var name = "weibo-post-monitor";
43
- var auto_cookie = null;
44
- var now_user_agent = null;
45
- var user_agent_list = [
41
+ var Config = import_koishi.Schema.object({
42
+ account: import_koishi.Schema.string().description("账号(qq号)"),
43
+ plantform: import_koishi.Schema.string().default("onebot").description("账号平台"),
44
+ waitMinutes: import_koishi.Schema.number().default(3).min(1).description("隔多久拉取一次最新微博 (分钟)"),
45
+ is_using_cookie: import_koishi.Schema.boolean().default(false).description("是否启用输入cookie"),
46
+ manual_cookie: import_koishi.Schema.string().default("").description("输入cookie"),
47
+ sendINFO: import_koishi.Schema.array(import_koishi.Schema.object({
48
+ weiboUID: import_koishi.Schema.string().description("微博用户UID"),
49
+ forward: import_koishi.Schema.boolean().default(false).description("是否监听转发"),
50
+ blockwords: import_koishi.Schema.string().description("屏蔽词(多个屏蔽词用分号分隔)"),
51
+ keywords: import_koishi.Schema.string().description("关键词(多个关键词用分号分隔)"),
52
+ groupID: import_koishi.Schema.string().description("需要发送的群组"),
53
+ sendAll: import_koishi.Schema.boolean().default(false).description("@全体成员")
54
+ })).description("监听&发送配置")
55
+ });
56
+
57
+ // src/services/constant.ts
58
+ var USER_AGENT_LIST = [
46
59
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
47
60
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.5993.90 Safari/537.36",
48
61
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.6045.105 Safari/537.36",
@@ -66,154 +79,111 @@ var user_agent_list = [
66
79
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.149 Safari/537.36",
67
80
  "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.140 Safari/537.36"
68
81
  ];
69
- var Config = import_koishi.Schema.object({
70
- account: import_koishi.Schema.string().description("账号(qq号)"),
71
- plantform: import_koishi.Schema.string().default("onebot").description("账号平台"),
72
- waitMinutes: import_koishi.Schema.number().default(3).min(1).description("隔多久拉取一次最新微博 (分钟)"),
73
- is_using_cookie: import_koishi.Schema.boolean().default(false).description("是否启用输入cookie"),
74
- manual_cookie: import_koishi.Schema.string().default("").description("输入cookie"),
75
- sendINFO: import_koishi.Schema.array(import_koishi.Schema.object({
76
- weiboUID: import_koishi.Schema.string().description("微博用户UID"),
77
- forward: import_koishi.Schema.boolean().default(false).description("是否监听转发"),
78
- blockwords: import_koishi.Schema.string().description("屏蔽词(多个屏蔽词用分号分隔)"),
79
- keywords: import_koishi.Schema.string().description("关键词(多个关键词用分号分隔)"),
80
- groupID: import_koishi.Schema.string().description("需要发送的群组"),
81
- sendAll: import_koishi.Schema.boolean().default(false).description("@全体成员")
82
- })).description("监听&发送配置")
83
- });
84
- function to(promise, errorExt) {
85
- return promise.then((data) => [null, data]).catch((err) => {
86
- if (errorExt) {
87
- const parsedError = Object.assign({}, err, errorExt);
88
- return [parsedError, void 0];
89
- }
90
- return [err, void 0];
91
- });
82
+
83
+ // src/services/cookie.ts
84
+ var import_axios = __toESM(require("axios"));
85
+ var auto_cookie = null;
86
+ var now_user_agent = null;
87
+ function setCookie(cookie) {
88
+ auto_cookie = cookie;
92
89
  }
93
- __name(to, "to");
94
- function apply(ctx, config) {
95
- const commonConfig = {
96
- account: config.account,
97
- plantform: config.plantform,
98
- waitMinutes: config.waitMinutes,
99
- is_using_cookie: config.is_using_cookie
100
- };
101
- auto_cookie = config.manual_cookie;
102
- now_user_agent = user_agent_list[0];
103
- ctx.setInterval(async () => {
104
- for (const singleConfig of config.sendINFO) {
105
- const params = { ...commonConfig, ...singleConfig };
106
- getWeiboAndSendMessageToGroup(ctx, params);
107
- }
108
- }, config.waitMinutes > 0 ? config.waitMinutes * 60 * 1e3 : 6e4);
90
+ __name(setCookie, "setCookie");
91
+ function getCookie() {
92
+ return auto_cookie;
109
93
  }
110
- __name(apply, "apply");
111
- var getWeiboAndSendMessageToGroup = /* @__PURE__ */ __name(async (ctx, params) => {
112
- const [err, res] = await to(getWeibo(params));
113
- if (err) {
114
- ctx.logger.error(err);
115
- return;
116
- }
117
- const data = res.data || {};
118
- const weiboList = data.list || [];
119
- const result = getLastPost(params, weiboList);
120
- if (!result) {
121
- return;
122
- }
123
- let message = result;
124
- if (params.sendAll) {
125
- message = import_koishi.h.at("all") + " " + message;
126
- }
127
- ctx.bots[`${params.plantform}:${params.account}`].sendMessage(params.groupID, message);
128
- console.log(message);
129
- }, "getWeiboAndSendMessageToGroup");
130
- var getLastPost = /* @__PURE__ */ __name((params, weiboList) => {
131
- for (const wb_element of weiboList) {
132
- const result = getMessage(params, wb_element);
133
- if (!result) {
134
- continue;
135
- }
136
- if (result.islast) {
137
- return result.post;
138
- }
139
- }
140
- return null;
141
- }, "getLastPost");
142
- var getMessage = /* @__PURE__ */ __name((params, wbPost) => {
143
- if (!wbPost) {
144
- return null;
145
- }
146
- const { created_at, user } = wbPost;
147
- const time = parseDateString(created_at);
148
- const lastCheckTime = Date.now() - (params.waitMinutes > 0 ? params.waitMinutes * 60 * 1e3 : 6e4);
149
- if (time.getTime() < lastCheckTime) {
150
- return null;
151
- }
152
- const screenName = user?.screen_name || "";
153
- let weiboType = -1;
154
- if ("page_info" in wbPost) {
155
- weiboType = 0;
156
- }
157
- if ("pic_infos" in wbPost) {
158
- weiboType = 2;
159
- }
160
- if ("topic_struct" in wbPost || "retweeted_status" in wbPost) {
161
- weiboType = 1;
94
+ __name(getCookie, "getCookie");
95
+ function setUserAgent(userAgent) {
96
+ now_user_agent = userAgent;
97
+ }
98
+ __name(setUserAgent, "setUserAgent");
99
+ function getUserAgent() {
100
+ return now_user_agent;
101
+ }
102
+ __name(getUserAgent, "getUserAgent");
103
+ function getRandomUserAgent() {
104
+ return USER_AGENT_LIST[Math.floor(Math.random() * USER_AGENT_LIST.length)];
105
+ }
106
+ __name(getRandomUserAgent, "getRandomUserAgent");
107
+ var mergeCookies = /* @__PURE__ */ __name((cookies) => {
108
+ return cookies.map((c) => c.split(";")[0]).join("; ");
109
+ }, "mergeCookies");
110
+ async function fetchCookie() {
111
+ if (!now_user_agent) {
112
+ now_user_agent = USER_AGENT_LIST[0];
162
113
  }
163
- let message = "";
164
- if (weiboType == 0) {
165
- const pageInfo = wbPost?.page_info;
166
- if (!pageInfo) {
167
- return null;
168
- }
169
- const objType = pageInfo?.object_type || "";
170
- if (objType == "video") {
171
- const text = wbPost?.text_raw || "";
172
- const video = pageInfo?.media_info?.h5_url || "";
173
- message += screenName + " 发布了微博:\n" + text + "\n" + video || "";
114
+ const commonHeaders = {
115
+ "user-agent": now_user_agent,
116
+ "accept": "*/*",
117
+ "origin": "https://passport.weibo.com",
118
+ "referer": "https://passport.weibo.com/visitor/visitor"
119
+ };
120
+ let allCookies = [];
121
+ const step1Response = await import_axios.default.post("https://passport.weibo.com/visitor/genvisitor2", "cb=visitor_gray_callback&ver=20250916&request_id=fb15e537349aef3542ed130a47d48eb8&tid=&from=weibo&webdriver=false&rid=01by624JxwbmsPak-53wiC9LGhR6I&return_url=https://weibo.com/", {
122
+ headers: {
123
+ ...commonHeaders,
124
+ "content-type": "application/x-www-form-urlencoded"
125
+ },
126
+ responseType: "text"
127
+ });
128
+ const step1SetCookies = step1Response.headers["set-cookie"] || [];
129
+ allCookies.push(...step1SetCookies);
130
+ const step1Body = step1Response.data;
131
+ let visitorId = "";
132
+ try {
133
+ const jsonMatch = step1Body.match(/visitor_gray_callback\s*\(\s*({[\s\S]*})\s*\)/);
134
+ if (!jsonMatch || !jsonMatch[1]) {
135
+ throw new Error("无法从响应中提取 JSON 对象");
174
136
  }
175
- }
176
- if (weiboType == 1) {
177
- if (params.forward) {
178
- message += screenName + " 转发了微博:\n" + wbPost?.text_raw || "";
137
+ const step1Data = JSON.parse(jsonMatch[1]);
138
+ visitorId = step1Data?.data?.tid || "";
139
+ if (!visitorId) {
140
+ throw new Error("未获取到 visitor id,响应数据: " + JSON.stringify(step1Data));
179
141
  }
142
+ } catch (error) {
143
+ throw new Error("解析 genvisitor2 响应失败: " + error.message + ", 响应体: " + step1Body);
180
144
  }
181
- if (weiboType == 2) {
182
- const text = wbPost?.text_raw || "";
183
- const picIds = wbPost?.pic_ids || [];
184
- const picInfos = wbPost?.pic_infos || {};
185
- const firstPicUrl = picInfos?.[picIds[0]]?.large?.url || "";
186
- const picture = import_koishi.h.image(firstPicUrl);
187
- message += screenName + " 发布了微博:\n" + text + "\n" + picture || "";
188
- }
189
- const mid = wbPost?.mid || "";
190
- const url = `
191
- 链接:https://m.weibo.cn/status/${mid}`;
192
- if (!checkWords(params, wbPost?.text_raw)) {
193
- return null;
194
- }
195
- const wbpost = message ? message + url : screenName + " 发布了微博:\n" + wbPost?.text_raw + url || "";
196
- return { post: wbpost, islast: true };
197
- }, "getMessage");
198
- var getWeibo = /* @__PURE__ */ __name(async (config, callback, retry = false) => {
145
+ const step2Response = await import_axios.default.get(`https://passport.weibo.com/visitor/visitor?a=incarnate&t=${encodeURIComponent(visitorId)}`, {
146
+ headers: {
147
+ ...commonHeaders,
148
+ "cookie": mergeCookies(allCookies)
149
+ },
150
+ responseType: "text"
151
+ });
152
+ const step2SetCookies = step2Response.headers["set-cookie"] || [];
153
+ allCookies.push(...step2SetCookies);
154
+ return mergeCookies(allCookies);
155
+ }
156
+ __name(fetchCookie, "fetchCookie");
157
+
158
+ // src/services/message.ts
159
+ var import_koishi2 = require("koishi");
160
+
161
+ // src/services/weibo.ts
162
+ var import_https = __toESM(require("https"));
163
+ async function getWeibo(config, callback, retry = false) {
199
164
  const { weiboUID, is_using_cookie } = config;
200
165
  if (!weiboUID) {
201
166
  return;
202
167
  }
203
- if (!is_using_cookie && !auto_cookie) {
204
- now_user_agent = user_agent_list[Math.floor(Math.random() * user_agent_list.length)];
205
- auto_cookie = await getCookie();
168
+ let auto_cookie2 = getCookie();
169
+ let now_user_agent2 = getUserAgent();
170
+ if (!is_using_cookie && !auto_cookie2) {
171
+ const randomUserAgent = getRandomUserAgent();
172
+ setUserAgent(randomUserAgent);
173
+ now_user_agent2 = randomUserAgent;
174
+ auto_cookie2 = await fetchCookie();
175
+ setCookie(auto_cookie2);
206
176
  }
207
- if (!auto_cookie) {
177
+ if (!auto_cookie2) {
208
178
  throw new Error("Cookie config is null, please check the config");
209
179
  }
210
180
  const headers = {
211
181
  "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
212
182
  "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
213
183
  "cache-control": "no-cache",
214
- "cookie": auto_cookie,
184
+ "cookie": auto_cookie2,
215
185
  "referer": "https://www.weibo.com/u/" + weiboUID,
216
- "user-agent": now_user_agent
186
+ "user-agent": now_user_agent2 || ""
217
187
  };
218
188
  const options = {
219
189
  hostname: "www.weibo.com",
@@ -235,8 +205,10 @@ var getWeibo = /* @__PURE__ */ __name(async (config, callback, retry = false) =>
235
205
  } catch (error) {
236
206
  if (!retry && !is_using_cookie) {
237
207
  try {
238
- now_user_agent = user_agent_list[Math.floor(Math.random() * user_agent_list.length)];
239
- auto_cookie = await getCookie();
208
+ const randomUserAgent = getRandomUserAgent();
209
+ setUserAgent(randomUserAgent);
210
+ const newCookie = await fetchCookie();
211
+ setCookie(newCookie);
240
212
  const retryResult = await getWeibo(config, callback, true);
241
213
  resolve(retryResult);
242
214
  } catch (retryError) {
@@ -252,8 +224,21 @@ var getWeibo = /* @__PURE__ */ __name(async (config, callback, retry = false) =>
252
224
  });
253
225
  });
254
226
  });
255
- }, "getWeibo");
256
- var parseDateString = /* @__PURE__ */ __name((dateString) => {
227
+ }
228
+ __name(getWeibo, "getWeibo");
229
+
230
+ // src/services/utils.ts
231
+ function to(promise, errorExt) {
232
+ return promise.then((data) => [null, data]).catch((err) => {
233
+ if (errorExt) {
234
+ const parsedError = Object.assign({}, err, errorExt);
235
+ return [parsedError, void 0];
236
+ }
237
+ return [err, void 0];
238
+ });
239
+ }
240
+ __name(to, "to");
241
+ function parseDateString(dateString) {
257
242
  const regex = /(\w+) (\w+) (\d+) (\d+):(\d+):(\d+) ([+-]\d{4}) (\d{4})/;
258
243
  const match = dateString.match(regex);
259
244
  if (!match) {
@@ -274,14 +259,22 @@ var parseDateString = /* @__PURE__ */ __name((dateString) => {
274
259
  Nov: 10,
275
260
  Dec: 11
276
261
  };
277
- const date = new Date(Date.UTC(year, monthMap[month], day, hour, minute, second));
262
+ const date = new Date(Date.UTC(
263
+ parseInt(year, 10),
264
+ monthMap[month],
265
+ parseInt(day, 10),
266
+ parseInt(hour, 10),
267
+ parseInt(minute, 10),
268
+ parseInt(second, 10)
269
+ ));
278
270
  const timezoneOffsetHours = parseInt(timezone.slice(0, 3), 10);
279
271
  const timezoneOffsetMinutes = parseInt(timezone.slice(0, 1) + timezone.slice(3), 10);
280
272
  const timezoneOffset = timezoneOffsetHours * 60 + timezoneOffsetMinutes;
281
273
  date.setUTCMinutes(date.getUTCMinutes() - timezoneOffset);
282
274
  return date;
283
- }, "parseDateString");
284
- var checkWords = /* @__PURE__ */ __name((params, message) => {
275
+ }
276
+ __name(parseDateString, "parseDateString");
277
+ function checkWords(params, message) {
285
278
  if (message == null)
286
279
  return false;
287
280
  let keywordsList = params.keywords?.split(";") || [];
@@ -311,57 +304,216 @@ var checkWords = /* @__PURE__ */ __name((params, message) => {
311
304
  }
312
305
  }
313
306
  return true;
314
- }, "checkWords");
315
- var mergeCookies = /* @__PURE__ */ __name((cookies) => {
316
- return cookies.map((c) => c.split(";")[0]).join("; ");
317
- }, "mergeCookies");
318
- var getCookie = /* @__PURE__ */ __name(async () => {
319
- const commonHeaders = {
320
- "user-agent": now_user_agent,
321
- "accept": "*/*",
322
- "origin": "https://passport.weibo.com",
323
- "referer": "https://passport.weibo.com/visitor/visitor"
324
- };
325
- let allCookies = [];
326
- const step1Response = await import_axios.default.post("https://passport.weibo.com/visitor/genvisitor2", "cb=visitor_gray_callback&ver=20250916&request_id=fb15e537349aef3542ed130a47d48eb8&tid=&from=weibo&webdriver=false&rid=01by624JxwbmsPak-53wiC9LGhR6I&return_url=https://weibo.com/", {
327
- headers: {
328
- ...commonHeaders,
329
- "content-type": "application/x-www-form-urlencoded"
330
- },
331
- responseType: "text"
332
- });
333
- const step1SetCookies = step1Response.headers["set-cookie"] || [];
334
- allCookies.push(...step1SetCookies);
335
- const step1Body = step1Response.data;
336
- let visitorId = "";
307
+ }
308
+ __name(checkWords, "checkWords");
309
+
310
+ // src/services/message.ts
311
+ var import_axios2 = __toESM(require("axios"));
312
+ var import_vm = require("vm");
313
+ async function getWeiboAndSendMessageToGroup(ctx, params) {
314
+ const [err, res] = await to(getWeibo(params));
315
+ if (err) {
316
+ ctx.logger.error(err);
317
+ return;
318
+ }
319
+ const data = res.data || {};
320
+ const weiboList = data.list || [];
321
+ const result = await getLastPost(params, weiboList);
322
+ if (!result) {
323
+ return;
324
+ }
325
+ let message = result;
326
+ if (params.sendAll) {
327
+ message = import_koishi2.h.at("all") + " " + message;
328
+ }
329
+ ctx.bots[`${params.plantform}:${params.account}`].sendMessage(params.groupID, message);
330
+ console.log(message);
331
+ }
332
+ __name(getWeiboAndSendMessageToGroup, "getWeiboAndSendMessageToGroup");
333
+ async function getLastPost(params, weiboList) {
334
+ for (const wb_element of weiboList) {
335
+ const result = await getMessage(params, wb_element);
336
+ if (!result) {
337
+ continue;
338
+ }
339
+ if (result.islast) {
340
+ return result.post;
341
+ }
342
+ }
343
+ return null;
344
+ }
345
+ __name(getLastPost, "getLastPost");
346
+ async function getMessage(params, wbPost) {
347
+ if (!wbPost) {
348
+ return null;
349
+ }
350
+ const { created_at, user } = wbPost;
351
+ const time = parseDateString(created_at);
352
+ const lastCheckTime = Date.now() - (params.waitMinutes > 0 ? params.waitMinutes * 60 * 1e3 : 6e4);
353
+ const screenName = user?.screen_name || "";
354
+ let weiboType = -1;
355
+ if ("page_info" in wbPost) {
356
+ weiboType = 0;
357
+ }
358
+ if ("pic_infos" in wbPost) {
359
+ weiboType = 2;
360
+ }
361
+ if ("topic_struct" in wbPost || "retweeted_status" in wbPost) {
362
+ weiboType = 1;
363
+ }
364
+ let message_text = "";
365
+ let tempMessage = "";
366
+ if (!checkWords(params, wbPost?.text_raw)) {
367
+ return null;
368
+ }
369
+ if (weiboType == 0) {
370
+ const pageInfo = wbPost?.page_info;
371
+ if (!pageInfo) {
372
+ return null;
373
+ }
374
+ const objType = pageInfo?.object_type || "";
375
+ if (objType == "video") {
376
+ const text = wbPost?.text_raw || "";
377
+ const video = pageInfo?.media_info?.h5_url || "";
378
+ tempMessage += screenName + " 发布了微博:\n{temp_text}\n" + video || "";
379
+ }
380
+ }
381
+ if (weiboType == 1) {
382
+ if (params.forward) {
383
+ tempMessage += screenName + " 转发了微博:\n{temp_text}" || "";
384
+ }
385
+ }
386
+ if (weiboType == 2) {
387
+ const text = wbPost?.text_raw || "";
388
+ const picIds = wbPost?.pic_ids || [];
389
+ const picInfos = wbPost?.pic_infos || {};
390
+ const firstPicUrl = picInfos?.[picIds[0]]?.large?.url || "";
391
+ const picture = import_koishi2.h.image(firstPicUrl);
392
+ tempMessage += screenName + " 发布了微博:\n{temp_text}\n" + picture || "";
393
+ }
394
+ const mid = wbPost?.mid || "";
395
+ const url = `https://m.weibo.cn/status/${mid}`;
396
+ const detailMessage = await getDetailMessage(url);
397
+ if (detailMessage) {
398
+ message_text = detailMessage;
399
+ }
400
+ const urlMessage = `
401
+ 微博链接:${url}`;
402
+ if (!checkWords(params, message_text)) {
403
+ return null;
404
+ }
405
+ let message = tempMessage.replace("{temp_text}", message_text);
406
+ const wbpost = message ? message + urlMessage : screenName + " 发布了微博:\n" + wbPost?.text_raw + urlMessage || "";
407
+ return { post: wbpost, islast: true };
408
+ }
409
+ __name(getMessage, "getMessage");
410
+ function stripHtmlTags(html) {
411
+ if (!html) return "";
412
+ let text = html;
413
+ text = text.replace(/<br\s*\/?>/gi, "\n");
414
+ text = text.replace(/<span\s+class=['"]surl-text['"][^>]*>([^<]*)<\/span>/gi, "$1");
415
+ text = text.replace(/<img[^>]*>/gi, "");
416
+ let lastText = "";
417
+ let iterations = 0;
418
+ while (text !== lastText && iterations < 10) {
419
+ lastText = text;
420
+ text = text.replace(/<a[^>]*>([^<]*(?:<[^>]*>[^<]*<\/[^>]*>[^<]*)*)<\/a>/gi, "$1");
421
+ iterations++;
422
+ }
423
+ text = text.replace(/<[^>]+>/g, "");
424
+ text = text.replace(/&nbsp;/g, " ");
425
+ text = text.replace(/&lt;/g, "<");
426
+ text = text.replace(/&gt;/g, ">");
427
+ text = text.replace(/&quot;/g, '"');
428
+ text = text.replace(/&#39;/g, "'");
429
+ text = text.replace(/&apos;/g, "'");
430
+ text = text.replace(/&amp;/g, "&");
431
+ text = text.replace(/[ \t]+/g, " ");
432
+ text = text.replace(/\n[ \t]+/g, "\n");
433
+ text = text.replace(/[ \t]+\n/g, "\n");
434
+ text = text.replace(/\n{3,}/g, "\n\n");
435
+ text = text.trim();
436
+ return text;
437
+ }
438
+ __name(stripHtmlTags, "stripHtmlTags");
439
+ async function getDetailMessage(wb_url) {
337
440
  try {
338
- const jsonMatch = step1Body.match(/visitor_gray_callback\s*\(\s*({[\s\S]*})\s*\)/);
339
- if (!jsonMatch || !jsonMatch[1]) {
340
- throw new Error("无法从响应中提取 JSON 对象");
441
+ const cookie = getCookie();
442
+ const userAgent = getUserAgent();
443
+ if (!cookie) {
444
+ return null;
341
445
  }
342
- const step1Data = JSON.parse(jsonMatch[1]);
343
- visitorId = step1Data?.data?.tid || "";
344
- if (!visitorId) {
345
- throw new Error("未获取到 visitor id,响应数据: " + JSON.stringify(step1Data));
446
+ const headers = {
447
+ "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
448
+ "accept-language": "zh-CN,zh;q=0.9",
449
+ "user-agent": userAgent || "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
450
+ "cookie": cookie
451
+ };
452
+ const response = await import_axios2.default.get(wb_url, {
453
+ headers,
454
+ responseType: "text",
455
+ timeout: 1e4
456
+ });
457
+ const html = response.data;
458
+ const startMarker = "var $render_data = ";
459
+ const startIndex = html.indexOf(startMarker);
460
+ if (startIndex === -1) {
461
+ return null;
462
+ }
463
+ const scriptEndIndex = html.indexOf("</script>", startIndex);
464
+ const nextVarIndex = html.indexOf("\n var ", startIndex + startMarker.length);
465
+ let codeEndIndex = html.length;
466
+ if (scriptEndIndex !== -1 && scriptEndIndex < codeEndIndex) {
467
+ codeEndIndex = scriptEndIndex;
468
+ }
469
+ if (nextVarIndex !== -1 && nextVarIndex < codeEndIndex) {
470
+ codeEndIndex = nextVarIndex;
346
471
  }
472
+ let code = html.substring(startIndex, codeEndIndex).trim();
473
+ if (!code.endsWith(";")) {
474
+ const lastSemicolon = code.lastIndexOf(";");
475
+ if (lastSemicolon !== -1) {
476
+ code = code.substring(0, lastSemicolon + 1);
477
+ }
478
+ }
479
+ const context = (0, import_vm.createContext)({});
480
+ (0, import_vm.runInContext)(code, context);
481
+ const renderData = context.$render_data;
482
+ if (!renderData || !renderData.status || !renderData.status.text) {
483
+ return null;
484
+ }
485
+ const htmlText = renderData.status.text;
486
+ const plainText = stripHtmlTags(htmlText);
487
+ return plainText;
347
488
  } catch (error) {
348
- throw new Error("解析 genvisitor2 响应失败: " + error.message + ", 响应体: " + step1Body);
489
+ console.error("获取微博详情失败:", error);
490
+ return null;
349
491
  }
350
- const step2Response = await import_axios.default.get(`https://passport.weibo.com/visitor/visitor?a=incarnate&t=${encodeURIComponent(visitorId)}`, {
351
- headers: {
352
- ...commonHeaders,
353
- "cookie": mergeCookies(allCookies)
354
- },
355
- responseType: "text"
356
- });
357
- const step2SetCookies = step2Response.headers["set-cookie"] || [];
358
- allCookies.push(...step2SetCookies);
359
- return mergeCookies(allCookies);
360
- }, "getCookie");
492
+ }
493
+ __name(getDetailMessage, "getDetailMessage");
494
+
495
+ // src/index.ts
496
+ var name = "weibo-post-monitor";
497
+ function apply(ctx, config) {
498
+ const commonConfig = {
499
+ account: config.account,
500
+ plantform: config.plantform,
501
+ waitMinutes: config.waitMinutes,
502
+ is_using_cookie: config.is_using_cookie
503
+ };
504
+ setCookie(config.manual_cookie);
505
+ setUserAgent(USER_AGENT_LIST[0]);
506
+ ctx.setInterval(async () => {
507
+ for (const singleConfig of config.sendINFO) {
508
+ const params = { ...commonConfig, ...singleConfig };
509
+ getWeiboAndSendMessageToGroup(ctx, params);
510
+ }
511
+ }, config.waitMinutes > 0 ? config.waitMinutes * 60 * 1e3 : 6e4);
512
+ }
513
+ __name(apply, "apply");
361
514
  // Annotate the CommonJS export names for ESM import in node:
362
515
  0 && (module.exports = {
363
516
  Config,
364
517
  apply,
365
- name,
366
- to
518
+ name
367
519
  });
@@ -0,0 +1,10 @@
1
+ import { Schema } from 'koishi';
2
+ export interface Config {
3
+ account: string;
4
+ plantform: string;
5
+ waitMinutes: number;
6
+ sendINFO: any;
7
+ is_using_cookie: boolean;
8
+ manual_cookie: string;
9
+ }
10
+ export declare const Config: Schema<Config>;
@@ -0,0 +1 @@
1
+ export declare const USER_AGENT_LIST: string[];
@@ -0,0 +1,6 @@
1
+ export declare function setCookie(cookie: string | null): void;
2
+ export declare function getCookie(): string | null;
3
+ export declare function setUserAgent(userAgent: string | null): void;
4
+ export declare function getUserAgent(): string | null;
5
+ export declare function getRandomUserAgent(): string;
6
+ export declare function fetchCookie(): Promise<string>;
@@ -0,0 +1,2 @@
1
+ import { Context } from 'koishi';
2
+ export declare function getWeiboAndSendMessageToGroup(ctx: Context, params: any): Promise<void>;
@@ -0,0 +1,3 @@
1
+ export declare function to<T, U = Error>(promise: Promise<T>, errorExt?: object): Promise<[U, undefined] | [null, T]>;
2
+ export declare function parseDateString(dateString: string): Date;
3
+ export declare function checkWords(params: any, message: string): boolean;
@@ -0,0 +1 @@
1
+ export declare function getWeibo(config: any, callback?: any, retry?: boolean): Promise<any>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-weibo-post-monitor",
3
3
  "description": "微博帖子更新推送插件,用于获取指定微博用户的最新帖子推送到指定群聊,参考代码https://github.com/moehuhu/weibo-monitor",
4
- "version": "1.0.0",
4
+ "version": "1.0.1-beta.0",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [