koishi-plugin-video-parser-all 1.0.8 → 1.1.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 +2 -0
- package/lib/index.js +76 -37
- package/package.json +1 -1
- package/readme.md +2 -2
package/lib/index.d.ts
CHANGED
|
@@ -32,6 +32,7 @@ export declare const Config: Schema<{
|
|
|
32
32
|
customApis?: ({
|
|
33
33
|
platform?: "bilibili" | "douyin" | "kuaishou" | "xiaohongshu" | "weibo" | "xigua" | "youtube" | "tiktok" | "acfun" | "zhihu" | "weishi" | "huya" | "haokan" | "meipai" | "twitter" | "instagram" | "doubao" | null | undefined;
|
|
34
34
|
apiUrl?: string | null | undefined;
|
|
35
|
+
useDedicatedFirst?: boolean | null | undefined;
|
|
35
36
|
} & import("cosmokit").Dict)[] | null | undefined;
|
|
36
37
|
} & {
|
|
37
38
|
waitingTipText?: string | null | undefined;
|
|
@@ -71,6 +72,7 @@ export declare const Config: Schema<{
|
|
|
71
72
|
customApis: Schemastery.ObjectT<{
|
|
72
73
|
platform: Schema<"bilibili" | "douyin" | "kuaishou" | "xiaohongshu" | "weibo" | "xigua" | "youtube" | "tiktok" | "acfun" | "zhihu" | "weishi" | "huya" | "haokan" | "meipai" | "twitter" | "instagram" | "doubao", "bilibili" | "douyin" | "kuaishou" | "xiaohongshu" | "weibo" | "xigua" | "youtube" | "tiktok" | "acfun" | "zhihu" | "weishi" | "huya" | "haokan" | "meipai" | "twitter" | "instagram" | "doubao">;
|
|
73
74
|
apiUrl: Schema<string, string>;
|
|
75
|
+
useDedicatedFirst: Schema<boolean, boolean>;
|
|
74
76
|
}>[];
|
|
75
77
|
} & {
|
|
76
78
|
waitingTipText: string;
|
package/lib/index.js
CHANGED
|
@@ -48,29 +48,30 @@ exports.Config = koishi_1.Schema.intersect([
|
|
|
48
48
|
koishi_1.Schema.object({
|
|
49
49
|
primaryApiUrl: koishi_1.Schema.string().default('https://api.bugpk.com/api/short_videos').description('主 API 地址'),
|
|
50
50
|
backupApiUrl: koishi_1.Schema.string().default('https://api.bugpk.com/api/svparse').description('备用主 API 地址(仅支持抖音/小红书/ins/即梦)'),
|
|
51
|
-
useDedicatedApiFirst: koishi_1.Schema.boolean().default(false).description('
|
|
51
|
+
useDedicatedApiFirst: koishi_1.Schema.boolean().default(false).description('全局默认:是否优先使用平台专属 API(各平台可单独覆盖)'),
|
|
52
52
|
customApis: koishi_1.Schema.array(koishi_1.Schema.object({
|
|
53
53
|
platform: koishi_1.Schema.union([
|
|
54
|
-
'bilibili',
|
|
55
|
-
'douyin',
|
|
56
|
-
'kuaishou',
|
|
57
|
-
'xiaohongshu',
|
|
58
|
-
'weibo',
|
|
59
|
-
'xigua',
|
|
60
|
-
'youtube',
|
|
61
|
-
'tiktok',
|
|
62
|
-
'acfun',
|
|
63
|
-
'zhihu',
|
|
64
|
-
'weishi',
|
|
65
|
-
'huya',
|
|
66
|
-
'haokan',
|
|
67
|
-
'meipai',
|
|
68
|
-
'twitter',
|
|
69
|
-
'instagram',
|
|
70
|
-
'doubao',
|
|
54
|
+
koishi_1.Schema.const('bilibili').description('哔哩哔哩'),
|
|
55
|
+
koishi_1.Schema.const('douyin').description('抖音'),
|
|
56
|
+
koishi_1.Schema.const('kuaishou').description('快手'),
|
|
57
|
+
koishi_1.Schema.const('xiaohongshu').description('小红书'),
|
|
58
|
+
koishi_1.Schema.const('weibo').description('微博'),
|
|
59
|
+
koishi_1.Schema.const('xigua').description('西瓜视频'),
|
|
60
|
+
koishi_1.Schema.const('youtube').description('YouTube'),
|
|
61
|
+
koishi_1.Schema.const('tiktok').description('TikTok'),
|
|
62
|
+
koishi_1.Schema.const('acfun').description('AcFun'),
|
|
63
|
+
koishi_1.Schema.const('zhihu').description('知乎'),
|
|
64
|
+
koishi_1.Schema.const('weishi').description('微视'),
|
|
65
|
+
koishi_1.Schema.const('huya').description('虎牙'),
|
|
66
|
+
koishi_1.Schema.const('haokan').description('好看视频'),
|
|
67
|
+
koishi_1.Schema.const('meipai').description('美拍'),
|
|
68
|
+
koishi_1.Schema.const('twitter').description('Twitter/X'),
|
|
69
|
+
koishi_1.Schema.const('instagram').description('Instagram'),
|
|
70
|
+
koishi_1.Schema.const('doubao').description('豆包'),
|
|
71
71
|
]).description('选择平台'),
|
|
72
72
|
apiUrl: koishi_1.Schema.string().description('API 地址'),
|
|
73
|
-
|
|
73
|
+
useDedicatedFirst: koishi_1.Schema.boolean().default(false).description('该平台优先使用此专属 API'),
|
|
74
|
+
})).default([]).description('自定义平台专属 API,可覆盖默认专属 API,并可单独设定优先策略'),
|
|
74
75
|
}).description('API 选择设置'),
|
|
75
76
|
koishi_1.Schema.object({
|
|
76
77
|
waitingTipText: koishi_1.Schema.string().default('正在解析视频,请稍候...').description('解析等待提示'),
|
|
@@ -99,6 +100,11 @@ function debugLog(level, ...args) {
|
|
|
99
100
|
}).join(' ')}`;
|
|
100
101
|
logger.info(message);
|
|
101
102
|
}
|
|
103
|
+
const urlCache = new lru_cache_1.LRUCache({
|
|
104
|
+
max: 500,
|
|
105
|
+
ttl: 10 * 60 * 1000,
|
|
106
|
+
updateAgeOnGet: false,
|
|
107
|
+
});
|
|
102
108
|
function linkTypeParser(content) {
|
|
103
109
|
content = content.replace(/\\\//g, '/');
|
|
104
110
|
const rules = [
|
|
@@ -147,7 +153,46 @@ function linkTypeParser(content) {
|
|
|
147
153
|
}
|
|
148
154
|
function extractAllUrlsFromMessage(session) {
|
|
149
155
|
const content = session.content?.trim() || '';
|
|
150
|
-
|
|
156
|
+
const matchedLinks = linkTypeParser(content);
|
|
157
|
+
const cardsContent = [];
|
|
158
|
+
if (session.elements) {
|
|
159
|
+
for (const elem of session.elements) {
|
|
160
|
+
if (elem.type === 'xml' && elem.data) {
|
|
161
|
+
cardsContent.push(elem.data);
|
|
162
|
+
}
|
|
163
|
+
else if (elem.type === 'json' && elem.data) {
|
|
164
|
+
try {
|
|
165
|
+
const json = JSON.parse(elem.data);
|
|
166
|
+
const extract = (obj) => {
|
|
167
|
+
if (!obj || typeof obj !== 'object')
|
|
168
|
+
return;
|
|
169
|
+
for (const val of Object.values(obj)) {
|
|
170
|
+
if (typeof val === 'string') {
|
|
171
|
+
cardsContent.push(val);
|
|
172
|
+
}
|
|
173
|
+
else if (typeof val === 'object')
|
|
174
|
+
extract(val);
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
extract(json);
|
|
178
|
+
}
|
|
179
|
+
catch { }
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
for (const cardContent of cardsContent) {
|
|
184
|
+
const cardLinks = linkTypeParser(cardContent);
|
|
185
|
+
matchedLinks.push(...cardLinks);
|
|
186
|
+
}
|
|
187
|
+
const seen = new Set();
|
|
188
|
+
const result = [];
|
|
189
|
+
for (const link of matchedLinks) {
|
|
190
|
+
if (!seen.has(link.url)) {
|
|
191
|
+
seen.add(link.url);
|
|
192
|
+
result.push(link);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return result;
|
|
151
196
|
}
|
|
152
197
|
function cleanUrl(url) {
|
|
153
198
|
try {
|
|
@@ -385,11 +430,6 @@ function buildForwardNode(session, content, botName) {
|
|
|
385
430
|
}
|
|
386
431
|
}, messageContent);
|
|
387
432
|
}
|
|
388
|
-
const urlCache = new lru_cache_1.LRUCache({
|
|
389
|
-
max: 500,
|
|
390
|
-
ttl: 10 * 60 * 1000,
|
|
391
|
-
updateAgeOnGet: false,
|
|
392
|
-
});
|
|
393
433
|
async function downloadVideoFile(videoUrl, tempDir, timeout, maxSizeMB) {
|
|
394
434
|
if (!videoUrl)
|
|
395
435
|
throw new Error('视频链接为空');
|
|
@@ -483,13 +523,13 @@ function apply(ctx, config) {
|
|
|
483
523
|
zuiyou: 'https://api.bugpk.com/api/zuiyou',
|
|
484
524
|
};
|
|
485
525
|
const backupSupportedPlatforms = new Set(['douyin', 'xiaohongshu', 'instagram', 'jimeng']);
|
|
486
|
-
function
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
return found.apiUrl;
|
|
526
|
+
function getPlatformConfig(type) {
|
|
527
|
+
const custom = config.customApis?.find((item) => item.platform === type);
|
|
528
|
+
if (custom && custom.apiUrl) {
|
|
529
|
+
return { apiUrl: custom.apiUrl, dedicatedFirst: custom.useDedicatedFirst ?? false };
|
|
491
530
|
}
|
|
492
|
-
|
|
531
|
+
const defaultUrl = defaultDedicatedApis[type] || null;
|
|
532
|
+
return { apiUrl: defaultUrl, dedicatedFirst: config.useDedicatedApiFirst ?? false };
|
|
493
533
|
}
|
|
494
534
|
async function fetchApi(url, type) {
|
|
495
535
|
const cacheKey = url;
|
|
@@ -498,14 +538,13 @@ function apply(ctx, config) {
|
|
|
498
538
|
debugLog('DEBUG', `使用缓存: ${url}`);
|
|
499
539
|
return cached.data;
|
|
500
540
|
}
|
|
501
|
-
const
|
|
541
|
+
const { apiUrl: dedicatedUrl, dedicatedFirst } = getPlatformConfig(type);
|
|
502
542
|
const primaryApi = config.primaryApiUrl || 'https://api.bugpk.com/api/short_videos';
|
|
503
543
|
const backupApi = config.backupApiUrl || 'https://api.bugpk.com/api/svparse';
|
|
504
544
|
const backupAllowed = backupSupportedPlatforms.has(type);
|
|
505
545
|
const apiList = [];
|
|
506
|
-
if (
|
|
507
|
-
|
|
508
|
-
apiList.push({ url: dedicatedApiUrl, label: `专属API(${type})` });
|
|
546
|
+
if (dedicatedFirst && dedicatedUrl) {
|
|
547
|
+
apiList.push({ url: dedicatedUrl, label: `专属API(${type})` });
|
|
509
548
|
apiList.push({ url: primaryApi, label: '默认主API' });
|
|
510
549
|
if (backupAllowed)
|
|
511
550
|
apiList.push({ url: backupApi, label: '备用主API' });
|
|
@@ -514,8 +553,8 @@ function apply(ctx, config) {
|
|
|
514
553
|
apiList.push({ url: primaryApi, label: '默认主API' });
|
|
515
554
|
if (backupAllowed)
|
|
516
555
|
apiList.push({ url: backupApi, label: '备用主API' });
|
|
517
|
-
if (
|
|
518
|
-
apiList.push({ url:
|
|
556
|
+
if (dedicatedUrl)
|
|
557
|
+
apiList.push({ url: dedicatedUrl, label: `专属API(${type})` });
|
|
519
558
|
}
|
|
520
559
|
let lastError = null;
|
|
521
560
|
for (const api of apiList) {
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -56,8 +56,8 @@ This is a **multi-platform video/image parsing plugin** developed for the Koishi
|
|
|
56
56
|
|--------|------|--------|------|
|
|
57
57
|
| `primaryApiUrl` | string | `https://api.bugpk.com/api/short_videos` | 主 API 地址,解析时优先使用 |
|
|
58
58
|
| `backupApiUrl` | string | `https://api.bugpk.com/api/svparse` | 备用主 API 地址,仅支持抖音、小红书、Instagram、即梦平台解析 |
|
|
59
|
-
| `useDedicatedApiFirst` | boolean | false |
|
|
60
|
-
| `customApis` | array | [] | 自定义平台专属 API
|
|
59
|
+
| `useDedicatedApiFirst` | boolean | false | 全局默认值:是否优先使用平台专属 API,各平台可单独覆盖该行为 |
|
|
60
|
+
| `customApis` | array | [] | 自定义平台专属 API 列表。每项包含:`platform`(平台类型)、`apiUrl`(API 地址)、`useDedicatedFirst`(该平台是否优先使用此专属 API)。可覆盖内置默认专属 API,并独立控制专属 API 的优先策略 |
|
|
61
61
|
|
|
62
62
|
### 错误与重试设置
|
|
63
63
|
| 配置项 | 类型 | 默认值 | 说明 |
|