koishi-plugin-weibo-post-monitor 0.0.1
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 +11 -0
- package/lib/index.js +249 -0
- package/package.json +25 -0
- package/readme.md +5 -0
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Context, Schema } from 'koishi';
|
|
2
|
+
export declare const name = "weibo-post-monitor";
|
|
3
|
+
export interface Config {
|
|
4
|
+
account: string;
|
|
5
|
+
plantform: string;
|
|
6
|
+
waitMinutes: number;
|
|
7
|
+
sendINFO: any;
|
|
8
|
+
}
|
|
9
|
+
export declare const Config: Schema<Config>;
|
|
10
|
+
export declare function to<T, U = Error>(promise: Promise<T>, errorExt?: object): Promise<[U, undefined] | [null, T]>;
|
|
11
|
+
export declare function apply(ctx: Context, config: Config): void;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name2 in all)
|
|
10
|
+
__defProp(target, name2, { get: all[name2], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to2, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to2, key) && key !== except)
|
|
16
|
+
__defProp(to2, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to2;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var src_exports = {};
|
|
32
|
+
__export(src_exports, {
|
|
33
|
+
Config: () => Config,
|
|
34
|
+
apply: () => apply,
|
|
35
|
+
name: () => name,
|
|
36
|
+
to: () => to
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(src_exports);
|
|
39
|
+
var import_koishi = require("koishi");
|
|
40
|
+
var import_https = __toESM(require("https"));
|
|
41
|
+
var name = "weibo-post-monitor";
|
|
42
|
+
var Config = import_koishi.Schema.object({
|
|
43
|
+
account: import_koishi.Schema.string().description("账号(qq号)"),
|
|
44
|
+
plantform: import_koishi.Schema.string().default("onebot").description("账号平台"),
|
|
45
|
+
waitMinutes: import_koishi.Schema.number().default(3).min(1).description("隔多久拉取一次最新微博 (分钟)"),
|
|
46
|
+
sendINFO: import_koishi.Schema.array(import_koishi.Schema.object({
|
|
47
|
+
weiboUID: import_koishi.Schema.string().description("微博用户UID"),
|
|
48
|
+
forward: import_koishi.Schema.boolean().default(false).description("是否监听转发"),
|
|
49
|
+
keywords: import_koishi.Schema.array(import_koishi.Schema.string()).description("关键词(多个关键词用分号分隔)"),
|
|
50
|
+
groupID: import_koishi.Schema.string().description("需要发送的群组"),
|
|
51
|
+
sendAll: import_koishi.Schema.boolean().default(false).description("@全体成员")
|
|
52
|
+
})).description("监听&发送配置")
|
|
53
|
+
});
|
|
54
|
+
function to(promise, errorExt) {
|
|
55
|
+
return promise.then((data) => [null, data]).catch((err) => {
|
|
56
|
+
if (errorExt) {
|
|
57
|
+
const parsedError = Object.assign({}, err, errorExt);
|
|
58
|
+
return [parsedError, void 0];
|
|
59
|
+
}
|
|
60
|
+
return [err, void 0];
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
__name(to, "to");
|
|
64
|
+
function apply(ctx, config) {
|
|
65
|
+
const commonConfig = {
|
|
66
|
+
account: config.account,
|
|
67
|
+
plantform: config.plantform,
|
|
68
|
+
waitMinutes: config.waitMinutes
|
|
69
|
+
};
|
|
70
|
+
ctx.setInterval(async () => {
|
|
71
|
+
for (const singleConfig of config.sendINFO) {
|
|
72
|
+
const params = { ...commonConfig, ...singleConfig };
|
|
73
|
+
getWeiboAndSendMessageToGroup(ctx, params);
|
|
74
|
+
}
|
|
75
|
+
}, config.waitMinutes > 0 ? config.waitMinutes * 60 * 1e3 : 6e4);
|
|
76
|
+
}
|
|
77
|
+
__name(apply, "apply");
|
|
78
|
+
var getWeiboAndSendMessageToGroup = /* @__PURE__ */ __name(async (ctx, params) => {
|
|
79
|
+
const [err, res] = await to(getWeibo(params));
|
|
80
|
+
if (err) {
|
|
81
|
+
ctx.logger.error(err);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const data = res.data || {};
|
|
85
|
+
const weiboList = data.list || [];
|
|
86
|
+
const result = getLastPost(params, weiboList);
|
|
87
|
+
if (!result) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
let message = result;
|
|
91
|
+
if (params.sendAll) {
|
|
92
|
+
message = '<at id="all"/> ' + message;
|
|
93
|
+
}
|
|
94
|
+
ctx.bots[`${params.plantform}:${params.account}`].sendMessage(params.groupID, message);
|
|
95
|
+
}, "getWeiboAndSendMessageToGroup");
|
|
96
|
+
var getMessage = /* @__PURE__ */ __name((params, wbPost) => {
|
|
97
|
+
if (!wbPost) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
const { created_at, user } = wbPost;
|
|
101
|
+
const time = parseDateString(created_at);
|
|
102
|
+
const lastCheckTime = Date.now() - (params.waitMinutes > 0 ? params.waitMinutes * 60 * 1e3 : 6e4);
|
|
103
|
+
if (time.getTime() < lastCheckTime) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
const screenName = user?.screen_name || "";
|
|
107
|
+
let weiboType = -1;
|
|
108
|
+
if ("page_info" in wbPost) {
|
|
109
|
+
weiboType = 0;
|
|
110
|
+
}
|
|
111
|
+
if ("pic_infos" in wbPost) {
|
|
112
|
+
weiboType = 2;
|
|
113
|
+
}
|
|
114
|
+
if ("topic_struct" in wbPost || "retweeted_status" in wbPost) {
|
|
115
|
+
weiboType = 1;
|
|
116
|
+
}
|
|
117
|
+
let message = "";
|
|
118
|
+
let keywordsList = params.keywords.split(";") || [];
|
|
119
|
+
if (weiboType == 0) {
|
|
120
|
+
const pageInfo = wbPost?.page_info;
|
|
121
|
+
if (!pageInfo) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
const objType = pageInfo?.object_type || "";
|
|
125
|
+
if (objType == "video") {
|
|
126
|
+
const text = wbPost?.text_raw || "";
|
|
127
|
+
const video = pageInfo?.media_info?.h5_url || "";
|
|
128
|
+
message += screenName + " 发布了微博:\n" + text + "\n" + video || "";
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (weiboType == 1) {
|
|
132
|
+
if (params.forward) {
|
|
133
|
+
message += screenName + " 转发了微博:\n" + wbPost?.text_raw || "";
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (weiboType == 2) {
|
|
137
|
+
const text = wbPost?.text_raw || "";
|
|
138
|
+
const picIds = wbPost?.pic_ids || [];
|
|
139
|
+
const picInfos = wbPost?.pic_infos || {};
|
|
140
|
+
const firstPicUrl = picInfos?.[picIds[0]]?.large?.url || "";
|
|
141
|
+
const picture = `<img src="${firstPicUrl}"/>`;
|
|
142
|
+
message += screenName + " 发布了微博:\n" + text + "\n" + picture || "";
|
|
143
|
+
}
|
|
144
|
+
const mid = wbPost?.mid || "";
|
|
145
|
+
const url = `
|
|
146
|
+
链接:https://m.weibo.cn/status/${mid}`;
|
|
147
|
+
if (keywordsList.length > 0) {
|
|
148
|
+
let hasKeywords = false;
|
|
149
|
+
for (const keyword of keywordsList) {
|
|
150
|
+
if (message.includes(keyword)) {
|
|
151
|
+
hasKeywords = true;
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (!hasKeywords) {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
const wbpost = message ? message + url : screenName + " 发布了微博:\n" + wbPost?.text_raw + url || "";
|
|
160
|
+
return { post: wbpost, islast: true };
|
|
161
|
+
}, "getMessage");
|
|
162
|
+
var getWeibo = /* @__PURE__ */ __name(async (config, callback) => {
|
|
163
|
+
const { weiboUID } = config;
|
|
164
|
+
if (!weiboUID) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const headers = {
|
|
168
|
+
"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",
|
|
169
|
+
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
|
|
170
|
+
"cache-control": "no-cache",
|
|
171
|
+
"cookie": "XSRF-TOKEN=mgVY3WMp8U-T6Wbu24ifdazm; SUBP=0033WrSXqPxfM72-Ws9jqgMF55529P9D9WhizH8r9Hyn870HzJo4TQoB; SUB=_2AkMSf_1df8NxqwJRmfATxWrlaIV_ywjEieKkIwyGJRMxHRl-yj8XqksbtRB6Of_Tsj1wFglssEkNvyqikP19B0UlIrd8; WBPSESS=NcA3pTjBP9SOtpsXaAXWlx_1aL3IfVadLkk5h-hKiZrhJi_NyNc2r5RbB0ZE0gYuG6ZSJmF8k26JJ46ltyme0fAcMSF9VPonnDU1TPvBjVADJPPa99vi0TVPQDCUKIMU",
|
|
172
|
+
"referer": "https://passport.weibo.com/",
|
|
173
|
+
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
|
|
174
|
+
"x-xsrf-token": "mgVY3WMp8U-T6Wbu24ifdazm"
|
|
175
|
+
};
|
|
176
|
+
const options = {
|
|
177
|
+
hostname: "weibo.com",
|
|
178
|
+
path: "/ajax/statuses/mymblog?uid=" + weiboUID,
|
|
179
|
+
method: "GET",
|
|
180
|
+
headers
|
|
181
|
+
};
|
|
182
|
+
return new Promise((resolve, reject) => {
|
|
183
|
+
import_https.default.get(options, (res) => {
|
|
184
|
+
let body = "";
|
|
185
|
+
res.on("data", (chunk) => {
|
|
186
|
+
body += chunk;
|
|
187
|
+
});
|
|
188
|
+
res.on("end", () => {
|
|
189
|
+
try {
|
|
190
|
+
const returnData = JSON.parse(body);
|
|
191
|
+
callback?.(returnData);
|
|
192
|
+
resolve(returnData);
|
|
193
|
+
} catch (error) {
|
|
194
|
+
reject({ error, body });
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
res.on("error", (error) => {
|
|
198
|
+
reject({ error, body });
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
}, "getWeibo");
|
|
203
|
+
var parseDateString = /* @__PURE__ */ __name((dateString) => {
|
|
204
|
+
const regex = /(\w+) (\w+) (\d+) (\d+):(\d+):(\d+) ([+-]\d{4}) (\d{4})/;
|
|
205
|
+
const match = dateString.match(regex);
|
|
206
|
+
if (!match) {
|
|
207
|
+
throw new Error("Invalid date format");
|
|
208
|
+
}
|
|
209
|
+
const [, , month, day, hour, minute, second, timezone, year] = match;
|
|
210
|
+
const monthMap = {
|
|
211
|
+
Jan: 0,
|
|
212
|
+
Feb: 1,
|
|
213
|
+
Mar: 2,
|
|
214
|
+
Apr: 3,
|
|
215
|
+
May: 4,
|
|
216
|
+
Jun: 5,
|
|
217
|
+
Jul: 6,
|
|
218
|
+
Aug: 7,
|
|
219
|
+
Sep: 8,
|
|
220
|
+
Oct: 9,
|
|
221
|
+
Nov: 10,
|
|
222
|
+
Dec: 11
|
|
223
|
+
};
|
|
224
|
+
const date = new Date(Date.UTC(year, monthMap[month], day, hour, minute, second));
|
|
225
|
+
const timezoneOffsetHours = parseInt(timezone.slice(0, 3), 10);
|
|
226
|
+
const timezoneOffsetMinutes = parseInt(timezone.slice(0, 1) + timezone.slice(3), 10);
|
|
227
|
+
const timezoneOffset = timezoneOffsetHours * 60 + timezoneOffsetMinutes;
|
|
228
|
+
date.setUTCMinutes(date.getUTCMinutes() - timezoneOffset);
|
|
229
|
+
return date;
|
|
230
|
+
}, "parseDateString");
|
|
231
|
+
var getLastPost = /* @__PURE__ */ __name((params, weiboList) => {
|
|
232
|
+
for (const wb_element of weiboList) {
|
|
233
|
+
const result = getMessage(params, wb_element);
|
|
234
|
+
if (!result) {
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
if (result.islast) {
|
|
238
|
+
return result.post;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return null;
|
|
242
|
+
}, "getLastPost");
|
|
243
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
244
|
+
0 && (module.exports = {
|
|
245
|
+
Config,
|
|
246
|
+
apply,
|
|
247
|
+
name,
|
|
248
|
+
to
|
|
249
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "koishi-plugin-weibo-post-monitor",
|
|
3
|
+
"description": "微博帖子更新推送插件,用于获取指定微博用户的最新帖子推送到指定群聊,参考代码https://github.com/moehuhu/weibo-monitor",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"typings": "lib/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"lib",
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"scripts": {},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"chatbot",
|
|
15
|
+
"koishi",
|
|
16
|
+
"plugin"
|
|
17
|
+
],
|
|
18
|
+
"devDependencies": {},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"koishi": "^4.18.7"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"https": "^1.0.0"
|
|
24
|
+
}
|
|
25
|
+
}
|