koishi-plugin-booth-get 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 +14 -0
- package/lib/index.js +152 -0
- package/package.json +30 -0
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Context, Schema } from 'koishi';
|
|
2
|
+
declare module 'koishi' {
|
|
3
|
+
interface Events {
|
|
4
|
+
'screenshot/validate'(url: string): string;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export declare const name = "booth-get";
|
|
8
|
+
export declare const inject: string[];
|
|
9
|
+
export interface Config {
|
|
10
|
+
loadTimeout?: number;
|
|
11
|
+
idleTimeout?: number;
|
|
12
|
+
}
|
|
13
|
+
export declare const Config: Schema<Config>;
|
|
14
|
+
export declare function apply(ctx: Context, config: Config): void;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name2 in all)
|
|
8
|
+
__defProp(target, name2, { get: all[name2], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
Config: () => Config,
|
|
24
|
+
apply: () => apply,
|
|
25
|
+
inject: () => inject,
|
|
26
|
+
name: () => name
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(src_exports);
|
|
29
|
+
var import_koishi = require("koishi");
|
|
30
|
+
var import_pngjs = require("pngjs");
|
|
31
|
+
var name = "booth-get";
|
|
32
|
+
var inject = ["puppeteer"];
|
|
33
|
+
var Config = import_koishi.Schema.object({
|
|
34
|
+
loadTimeout: import_koishi.Schema.natural().role("ms").description("加载页面的最长时间。当一个页面等待时间超过这个值时,如果此页面主体已经加载完成,则会发送一条提示消息“正在加载中,请稍等片刻”并继续等待加载;否则会直接提示“无法打开页面”并终止加载。").default(import_koishi.Time.second * 5),
|
|
35
|
+
idleTimeout: import_koishi.Schema.natural().role("ms").description("等待页面空闲的最长时间。当一个页面等待时间超过这个值时,将停止进一步的加载并立即发送截图。").default(import_koishi.Time.second * 30)
|
|
36
|
+
}).description("booth-get");
|
|
37
|
+
function apply(ctx, config) {
|
|
38
|
+
const logger = ctx.logger("screenshot");
|
|
39
|
+
const { defaultViewport } = ctx.puppeteer.config;
|
|
40
|
+
const { loadTimeout, idleTimeout } = config;
|
|
41
|
+
const booth_url = "https://booth.pm/zh-cn/items/";
|
|
42
|
+
const maxSize = 1024 * 1024;
|
|
43
|
+
ctx.command("摊位 <id>").action(async ({ session }, id) => {
|
|
44
|
+
if (!id)
|
|
45
|
+
return "请输入ID";
|
|
46
|
+
let url = booth_url + id;
|
|
47
|
+
let selector = "div.u-pt-600";
|
|
48
|
+
const result = ctx.bail("screenshot/validate", url);
|
|
49
|
+
if (typeof result === "string")
|
|
50
|
+
return result;
|
|
51
|
+
let loaded = false;
|
|
52
|
+
const page = await ctx.puppeteer.page();
|
|
53
|
+
page.on("load", () => loaded = true);
|
|
54
|
+
try {
|
|
55
|
+
await new Promise((resolve, reject) => {
|
|
56
|
+
logger.debug(`navigating to ${url}`);
|
|
57
|
+
const _resolve = /* @__PURE__ */ __name(() => {
|
|
58
|
+
clearTimeout(timer);
|
|
59
|
+
resolve();
|
|
60
|
+
}, "_resolve");
|
|
61
|
+
page.goto(url, {
|
|
62
|
+
waitUntil: "networkidle0",
|
|
63
|
+
timeout: idleTimeout
|
|
64
|
+
}).then(_resolve, () => {
|
|
65
|
+
return loaded ? _resolve() : reject(new Error("navigation timeout"));
|
|
66
|
+
});
|
|
67
|
+
const timer = setTimeout(() => {
|
|
68
|
+
return loaded ? session.send("正在加载中,请稍等片刻~") : reject(new Error("navigation timeout"));
|
|
69
|
+
}, loadTimeout);
|
|
70
|
+
});
|
|
71
|
+
} catch (error) {
|
|
72
|
+
page.close();
|
|
73
|
+
logger.debug(error);
|
|
74
|
+
return "无法打开页面。";
|
|
75
|
+
}
|
|
76
|
+
const shooter = selector ? await page.$(selector) : page;
|
|
77
|
+
if (!shooter)
|
|
78
|
+
return "找不到满足该选择器的元素。";
|
|
79
|
+
return shooter.screenshot().then(async (buffer) => {
|
|
80
|
+
if (buffer.byteLength > maxSize) {
|
|
81
|
+
await new Promise((resolve, reject) => {
|
|
82
|
+
const png = new import_pngjs.PNG();
|
|
83
|
+
png.parse(buffer, (error, data) => {
|
|
84
|
+
return error ? reject(error) : resolve(data);
|
|
85
|
+
});
|
|
86
|
+
}).then((data) => {
|
|
87
|
+
const width = data.width;
|
|
88
|
+
const height = data.height * maxSize / buffer.byteLength;
|
|
89
|
+
const png = new import_pngjs.PNG({ width, height });
|
|
90
|
+
data.bitblt(png, 0, 0, width, height, 0, 0);
|
|
91
|
+
buffer = import_pngjs.PNG.sync.write(png);
|
|
92
|
+
}).catch(import_koishi.noop);
|
|
93
|
+
}
|
|
94
|
+
return import_koishi.h.image(buffer, "image/png");
|
|
95
|
+
}, (error) => {
|
|
96
|
+
logger.debug(error);
|
|
97
|
+
return "截图失败。";
|
|
98
|
+
}).finally(() => page.close());
|
|
99
|
+
});
|
|
100
|
+
ctx.command("摊位名称 <query>").action(async ({ session }, query) => {
|
|
101
|
+
if (!query)
|
|
102
|
+
return "请输入搜索关键词";
|
|
103
|
+
|
|
104
|
+
const tags = [
|
|
105
|
+
'3Dモデル',
|
|
106
|
+
'Vrchat'
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
const tagsParams = tags.map(tag => `tags[]=${encodeURIComponent(tag)}`).join('&');
|
|
110
|
+
|
|
111
|
+
let searchUrl = `https://booth.pm/zh-cn/search/${encodeURIComponent(query)}?${tagsParams}&min_price=4500`;
|
|
112
|
+
|
|
113
|
+
const page = await ctx.puppeteer.page();
|
|
114
|
+
try {
|
|
115
|
+
await page.goto(searchUrl, { waitUntil: 'networkidle0' });
|
|
116
|
+
const content = await page.content();
|
|
117
|
+
const regex = /item-card__wrap" id="item_(\d+)"/;
|
|
118
|
+
const match = content.match(regex);
|
|
119
|
+
|
|
120
|
+
if (!match) {
|
|
121
|
+
return "没有找到任何商品。";
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const itemId = match[1];
|
|
125
|
+
const itemUrl = `https://booth.pm/zh-cn/items/${itemId}`;
|
|
126
|
+
|
|
127
|
+
await page.goto(itemUrl, { waitUntil: 'networkidle0' });
|
|
128
|
+
|
|
129
|
+
const shooter = await page.$('div.u-pt-600');
|
|
130
|
+
if (!shooter) {
|
|
131
|
+
return "找不到满足该选择器的元素。";
|
|
132
|
+
}
|
|
133
|
+
const buffer = await shooter.screenshot();
|
|
134
|
+
if (buffer.byteLength > maxSize) {
|
|
135
|
+
}
|
|
136
|
+
return import_koishi.h.image(buffer, "image/png");
|
|
137
|
+
} catch (error) {
|
|
138
|
+
logger.debug(error);
|
|
139
|
+
return "操作失败。";
|
|
140
|
+
} finally {
|
|
141
|
+
await page.close();
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
__name(apply, "apply");
|
|
146
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
147
|
+
0 && (module.exports = {
|
|
148
|
+
Config,
|
|
149
|
+
apply,
|
|
150
|
+
inject,
|
|
151
|
+
name
|
|
152
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "koishi-plugin-booth-get",
|
|
3
|
+
"description": "通过url检查摊位并反馈用户搜索的图片",
|
|
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
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
14
|
+
"build": "echo \"No build script specified\""
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"chatbot",
|
|
18
|
+
"koishi",
|
|
19
|
+
"plugin"
|
|
20
|
+
],
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"koishi": "4.17.9"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"atsc": "^2.1.0",
|
|
26
|
+
"koishi-plugin-puppeteer": "^3.8.4",
|
|
27
|
+
"pngjs": "^7.0.0",
|
|
28
|
+
"puppeteer-core": "^22.12.1"
|
|
29
|
+
}
|
|
30
|
+
}
|