koishi-plugin-booth-get 5.2.6 → 5.2.7
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.js +64 -11
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -33,10 +33,45 @@ var inject = ["puppeteer"];
|
|
|
33
33
|
var Config = import_koishi.Schema.object({
|
|
34
34
|
loadTimeout: import_koishi.Schema.natural().role("ms").description("加载页面的最长时间").default(import_koishi.Time.second * 10),
|
|
35
35
|
idleTimeout: import_koishi.Schema.natural().role("ms").description("等待页面空闲的最长时间").default(import_koishi.Time.second * 30),
|
|
36
|
-
proxyServer:
|
|
36
|
+
proxyServer: import_booth.Schema.string().description("代理服务器地址").default("61.216.156.222:60808"),
|
|
37
|
+
enableR18Check: import_koishi.Schema.boolean().description("启用R18内容检测").default(true),
|
|
38
|
+
r18Tags: import_koishi.Schema.array(String).description("R18标签列表").default(["R-18", "R18", "成人向け", "NSFW", "18禁"])
|
|
37
39
|
|
|
38
40
|
}).description("booth-get");
|
|
39
41
|
|
|
42
|
+
// R18内容检测函数
|
|
43
|
+
function checkR18(item, config) {
|
|
44
|
+
if (!config.enableR18Check) return false;
|
|
45
|
+
|
|
46
|
+
// 检查标签
|
|
47
|
+
if (item.tags && Array.isArray(item.tags)) {
|
|
48
|
+
const hasR18Tag = item.tags.some(tag =>
|
|
49
|
+
config.r18Tags.some(r18Tag =>
|
|
50
|
+
tag.name && tag.name.toLowerCase().includes(r18Tag.toLowerCase())
|
|
51
|
+
)
|
|
52
|
+
);
|
|
53
|
+
if (hasR18Tag) return true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// 检查标题
|
|
57
|
+
if (item.title) {
|
|
58
|
+
const hasR18InTitle = config.r18Tags.some(r18Tag =>
|
|
59
|
+
item.title.toLowerCase().includes(r18Tag.toLowerCase())
|
|
60
|
+
);
|
|
61
|
+
if (hasR18InTitle) return true;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// 检查描述
|
|
65
|
+
if (item.description) {
|
|
66
|
+
const hasR18InDesc = config.r18Tags.some(r18Tag =>
|
|
67
|
+
item.description.toLowerCase().includes(r18Tag.toLowerCase())
|
|
68
|
+
);
|
|
69
|
+
if (hasR18InDesc) return true;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
|
|
40
75
|
function generateCardHTML(item, relatedItems = []) {
|
|
41
76
|
return `
|
|
42
77
|
<html>
|
|
@@ -387,11 +422,17 @@ async function fetchRelatedItems(author) {
|
|
|
387
422
|
}
|
|
388
423
|
}
|
|
389
424
|
|
|
390
|
-
async function captureCard(ctx, id) {
|
|
425
|
+
async function captureCard(ctx, id, config) {
|
|
391
426
|
const logger = ctx.logger("booth-get");
|
|
392
427
|
const item = await getBoothItem(id);
|
|
393
428
|
if (!item) return null;
|
|
394
429
|
|
|
430
|
+
// R18内容检测
|
|
431
|
+
if (checkR18(item, config)) {
|
|
432
|
+
logger.warn(`检测到R18内容,已跳过商品: ${id}`);
|
|
433
|
+
return "R18_CONTENT";
|
|
434
|
+
}
|
|
435
|
+
|
|
395
436
|
const relatedItems = await fetchRelatedItems(item.author);
|
|
396
437
|
|
|
397
438
|
const html = generateCardHTML(item, relatedItems);
|
|
@@ -403,7 +444,7 @@ async function captureCard(ctx, id) {
|
|
|
403
444
|
|
|
404
445
|
await page.setContent(html, {
|
|
405
446
|
waitUntil: 'domcontentloaded',
|
|
406
|
-
timeout:
|
|
447
|
+
timeout: config.loadTimeout || import_koishi.Time.second * 10
|
|
407
448
|
});
|
|
408
449
|
|
|
409
450
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
@@ -430,7 +471,8 @@ function apply(ctx, config) {
|
|
|
430
471
|
.action(async ({ session }, id) => {
|
|
431
472
|
if (!id) return "请输入商品ID";
|
|
432
473
|
try {
|
|
433
|
-
const buffer = await captureCard(ctx, id);
|
|
474
|
+
const buffer = await captureCard(ctx, id, config);
|
|
475
|
+
if (buffer === "R18_CONTENT") return "该商品可能包含R18内容,已跳过";
|
|
434
476
|
return buffer ? import_koishi.h.image(buffer, "image/png") : "商品获取失败";
|
|
435
477
|
} catch (error) {
|
|
436
478
|
logger.warn(error);
|
|
@@ -476,7 +518,7 @@ function apply(ctx, config) {
|
|
|
476
518
|
let retries = 3;
|
|
477
519
|
while (retries > 0) {
|
|
478
520
|
try {
|
|
479
|
-
await page.goto(searchUrl, { waitUntil: 'networkidle0', timeout:
|
|
521
|
+
await page.goto(searchUrl, { waitUntil: 'networkidle0', timeout: config.loadTimeout || import_koishi.Time.second * 10 });
|
|
480
522
|
break;
|
|
481
523
|
} catch (error) {
|
|
482
524
|
retries--;
|
|
@@ -543,7 +585,10 @@ function apply(ctx, config) {
|
|
|
543
585
|
}
|
|
544
586
|
|
|
545
587
|
try {
|
|
546
|
-
const buffer = await captureCard(ctx, selectedItemId);
|
|
588
|
+
const buffer = await captureCard(ctx, selectedItemId, config);
|
|
589
|
+
if (buffer === "R18_CONTENT") {
|
|
590
|
+
return "搜索到的商品可能包含R18内容,已跳过";
|
|
591
|
+
}
|
|
547
592
|
if (!buffer) {
|
|
548
593
|
return "卡片生成失败";
|
|
549
594
|
}
|
|
@@ -597,7 +642,7 @@ async function fetchAuthorItems(ctx, authorName, limit = 6) {
|
|
|
597
642
|
|
|
598
643
|
await page.goto(`https://${authorName}.booth.pm/items`, {
|
|
599
644
|
waitUntil: 'networkidle0',
|
|
600
|
-
timeout:
|
|
645
|
+
timeout: config.loadTimeout || import_koishi.Time.second * 10
|
|
601
646
|
});
|
|
602
647
|
await page.waitForSelector('.item-list', { timeout: 5000 });
|
|
603
648
|
|
|
@@ -868,7 +913,7 @@ async function captureAuthorShopCard(ctx, authorName) {
|
|
|
868
913
|
|
|
869
914
|
await page.setContent(html, {
|
|
870
915
|
waitUntil: 'domcontentloaded',
|
|
871
|
-
timeout:
|
|
916
|
+
timeout: config.loadTimeout || import_koishi.Time.second * 10
|
|
872
917
|
});
|
|
873
918
|
|
|
874
919
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
@@ -896,7 +941,11 @@ async function captureAuthorShopCard(ctx, authorName) {
|
|
|
896
941
|
if (match) {
|
|
897
942
|
const itemId = match[1];
|
|
898
943
|
try {
|
|
899
|
-
const buffer = await captureCard(ctx, itemId);
|
|
944
|
+
const buffer = await captureCard(ctx, itemId, config);
|
|
945
|
+
if (buffer === "R18_CONTENT") {
|
|
946
|
+
await session.send("该商品可能包含R18内容,已跳过");
|
|
947
|
+
return "";
|
|
948
|
+
}
|
|
900
949
|
if (buffer) {
|
|
901
950
|
await session.send(import_koishi.h.image(buffer, "image/png"));
|
|
902
951
|
return "";
|
|
@@ -913,7 +962,11 @@ async function captureAuthorShopCard(ctx, authorName) {
|
|
|
913
962
|
|
|
914
963
|
try {
|
|
915
964
|
if (itemId) {
|
|
916
|
-
const buffer = await captureCard(ctx, itemId);
|
|
965
|
+
const buffer = await captureCard(ctx, itemId, config);
|
|
966
|
+
if (buffer === "R18_CONTENT") {
|
|
967
|
+
await session.send("该商品可能包含R18内容,已跳过");
|
|
968
|
+
return "";
|
|
969
|
+
}
|
|
917
970
|
if (buffer) {
|
|
918
971
|
await session.send(import_koishi.h.image(buffer, "image/png"));
|
|
919
972
|
return "";
|
|
@@ -956,7 +1009,7 @@ async function captureAuthorShopCard(ctx, authorName) {
|
|
|
956
1009
|
});
|
|
957
1010
|
|
|
958
1011
|
try {
|
|
959
|
-
await page.goto(searchUrl, { waitUntil: 'networkidle0', timeout:
|
|
1012
|
+
await page.goto(searchUrl, { waitUntil: 'networkidle0', timeout: config.loadTimeout || import_koishi.Time.second * 10 });
|
|
960
1013
|
|
|
961
1014
|
const content = await page.content();
|
|
962
1015
|
|