lintonxue00
commited on
Commit
•
835aa42
1
Parent(s):
0ce004d
Upload tools.js
Browse files- 不知道/回收站/2/tools.js +1249 -0
不知道/回收站/2/tools.js
ADDED
@@ -0,0 +1,1249 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// 主库
|
2 |
+
import fetch from "node-fetch";
|
3 |
+
import fs from "node:fs";
|
4 |
+
// 其他库
|
5 |
+
import axios from "axios";
|
6 |
+
import _ from "lodash";
|
7 |
+
import tunnel from "tunnel";
|
8 |
+
import HttpProxyAgent from "https-proxy-agent";
|
9 |
+
import { mkdirIfNotExists, checkAndRemoveFile, deleteFolderRecursive } from "../utils/file.js";
|
10 |
+
import { downloadBFile, getDownloadUrl, mergeFileToMp4 } from "../utils/bilibili.js";
|
11 |
+
import { parseUrl, parseM3u8, downloadM3u8Videos, mergeAcFileToMp4 } from "../utils/acfun.js";
|
12 |
+
import { transMap, douyinTypeMap, XHS_CK, TEN_THOUSAND, PROMPT_MAP } from "../utils/constant.js";
|
13 |
+
import { getIdVideo } from "../utils/common.js";
|
14 |
+
import config from "../model/index.js";
|
15 |
+
import Translate from "../utils/trans-strategy.js";
|
16 |
+
import * as xBogus from "../utils/x-bogus.cjs";
|
17 |
+
import { getVideoInfo, getDynamic } from "../utils/biliInfo.js";
|
18 |
+
import { getBiliGptInputText } from "../utils/biliSummary.js";
|
19 |
+
import { getBodianAudio, getBodianMv, getBodianMusicInfo } from "../utils/bodian.js";
|
20 |
+
import { ChatGPTBrowserClient } from "@waylaidwanderer/chatgpt-api";
|
21 |
+
import { av2BV } from "../utils/bilibili-bv-av-convert.js";
|
22 |
+
import querystring from "querystring";
|
23 |
+
import TokenBucket from "../utils/token-bucket.js";
|
24 |
+
|
25 |
+
export class tools extends plugin {
|
26 |
+
constructor() {
|
27 |
+
super({
|
28 |
+
name: "R插件工具和学习类",
|
29 |
+
dsc: "R插件工具相关指令",
|
30 |
+
event: "message.group",
|
31 |
+
priority: 300,
|
32 |
+
rule: [
|
33 |
+
{
|
34 |
+
reg: `^(翻|trans)[${tools.Constants.existsTransKey}]`,
|
35 |
+
fnc: "trans",
|
36 |
+
},
|
37 |
+
{
|
38 |
+
reg: `^#(ocr|OCR)(${tools.Constants.existsPromptKey})?$`,
|
39 |
+
fnc: "ocr2anything",
|
40 |
+
},
|
41 |
+
{
|
42 |
+
reg: "(v.douyin.com)",
|
43 |
+
fnc: "douyin",
|
44 |
+
},
|
45 |
+
{
|
46 |
+
reg: "(www.tiktok.com)|(vt.tiktok.com)|(vm.tiktok.com)",
|
47 |
+
fnc: "tiktok",
|
48 |
+
},
|
49 |
+
{
|
50 |
+
reg: "(bilibili.com|b23.tv|t.bilibili.com)",
|
51 |
+
fnc: "bili",
|
52 |
+
},
|
53 |
+
{
|
54 |
+
reg: "^#(wiki|百科)(.*)$",
|
55 |
+
fnc: "wiki",
|
56 |
+
},
|
57 |
+
{
|
58 |
+
reg: "(twitter.com)",
|
59 |
+
fnc: "twitter",
|
60 |
+
},
|
61 |
+
{
|
62 |
+
reg: "(acfun.cn)",
|
63 |
+
fnc: "acfun",
|
64 |
+
},
|
65 |
+
{
|
66 |
+
reg: "(xhslink.com|xiaohongshu.com)",
|
67 |
+
fnc: "redbook",
|
68 |
+
},
|
69 |
+
{
|
70 |
+
reg: "(instagram.com)",
|
71 |
+
fnc: "instagram",
|
72 |
+
},
|
73 |
+
{
|
74 |
+
reg: "(doi.org)",
|
75 |
+
fnc: "literature",
|
76 |
+
},
|
77 |
+
{
|
78 |
+
reg: "^#清理data垃圾$",
|
79 |
+
fnc: "clearTrash",
|
80 |
+
permission: "master",
|
81 |
+
},
|
82 |
+
{
|
83 |
+
reg: "(h5app.kuwo.cn)",
|
84 |
+
fnc: "bodianMusic",
|
85 |
+
},
|
86 |
+
],
|
87 |
+
});
|
88 |
+
// 配置文件
|
89 |
+
this.toolsConfig = config.getConfig("tools");
|
90 |
+
// 视频保存路径
|
91 |
+
this.defaultPath = this.toolsConfig.defaultPath;
|
92 |
+
// 代理接口
|
93 |
+
this.proxyAddr = this.toolsConfig.proxyAddr;
|
94 |
+
this.proxyPort = this.toolsConfig.proxyPort;
|
95 |
+
this.myProxy = `http://${this.proxyAddr}:${this.proxyPort}`;
|
96 |
+
// 加载哔哩哔哩配置
|
97 |
+
this.biliSessData = this.toolsConfig.biliSessData;
|
98 |
+
// 加载哔哩哔哩的限制时长
|
99 |
+
this.biliDuration = this.toolsConfig.biliDuration;
|
100 |
+
// 加载gpt配置
|
101 |
+
this.openaiAccessToken = this.toolsConfig.openaiAccessToken;
|
102 |
+
// 加载gpt客户端
|
103 |
+
this.chatGptClient = new ChatGPTBrowserClient({
|
104 |
+
reverseProxyUrl: "https://bypass.churchless.tech/api/conversation",
|
105 |
+
accessToken: this.openaiAccessToken,
|
106 |
+
model: "gpt-3.5-turbo",
|
107 |
+
})
|
108 |
+
}
|
109 |
+
|
110 |
+
// 翻译插件
|
111 |
+
async trans(e) {
|
112 |
+
const languageReg = /翻(.)/s;
|
113 |
+
const msg = e.msg.trim();
|
114 |
+
const language = languageReg.exec(msg);
|
115 |
+
if (!(language[1] in transMap)) {
|
116 |
+
e.reply(
|
117 |
+
"输入格式有误或暂不支持该语言!\n例子:翻中 China's policy has been consistent, but Japan chooses a path of mistrust, decoupling and military expansion",
|
118 |
+
);
|
119 |
+
return;
|
120 |
+
}
|
121 |
+
const place = msg.slice(1 + language[1].length)
|
122 |
+
const translateEngine = new Translate({
|
123 |
+
translateAppId: this.toolsConfig.translateAppId,
|
124 |
+
translateSecret: this.toolsConfig.translateSecret,
|
125 |
+
proxy: this.myProxy,
|
126 |
+
});
|
127 |
+
// 如果没有百度那就Google
|
128 |
+
let translateResult;
|
129 |
+
if (
|
130 |
+
_.isEmpty(this.toolsConfig.translateAppId) ||
|
131 |
+
_.isEmpty(this.toolsConfig.translateSecret)
|
132 |
+
) {
|
133 |
+
// 腾讯交互式进行补充
|
134 |
+
translateResult = await translateEngine.tencent(place, language[1]);
|
135 |
+
} else {
|
136 |
+
// 如果有百度
|
137 |
+
translateResult = await translateEngine.baidu(place, language[1]);
|
138 |
+
}
|
139 |
+
e.reply(translateResult.trim(), true);
|
140 |
+
return true;
|
141 |
+
}
|
142 |
+
|
143 |
+
// 图像识别文字
|
144 |
+
async ocr2anything(e) {
|
145 |
+
e.reply(" 👀请发送图片")
|
146 |
+
this.setContext("ocr2anythingContext");
|
147 |
+
return true;
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* 图像识别文字核心
|
152 |
+
* @link{ocr2anythingContext} 的上下文
|
153 |
+
* @return Promise{void}
|
154 |
+
**/
|
155 |
+
async ocr2anythingContext() {
|
156 |
+
// 当前消息
|
157 |
+
const curMsg = this.e;
|
158 |
+
// 上一个消息
|
159 |
+
const preMsg = this.getContext().ocr2anythingContext;
|
160 |
+
try {
|
161 |
+
const defaultPath = `${this.defaultPath}${this.e.group_id || this.e.user_id}`
|
162 |
+
await this.downloadImg(curMsg.img, defaultPath, "temp.jpg").then(async _ => {
|
163 |
+
// OCR
|
164 |
+
const ocrRst = await Bot.imageOcr(fs.readFileSync(`${defaultPath}/temp.jpg`));
|
165 |
+
const wordList = ocrRst.wordslist;
|
166 |
+
// OCR结果
|
167 |
+
let OCRInfo = wordList.map(item => item.words).join(" ");
|
168 |
+
if (this.openaiAccessToken) {
|
169 |
+
// 构造输入
|
170 |
+
const func = preMsg.msg.replace("#ocr", "").trim();
|
171 |
+
const prompt = PROMPT_MAP[func] + OCRInfo;
|
172 |
+
// 得到结果
|
173 |
+
const response = await this.chatGptClient.sendMessage(prompt);
|
174 |
+
OCRInfo = `${OCRInfo}\n-----------------\n${response.response}`;
|
175 |
+
}
|
176 |
+
curMsg.reply(OCRInfo);
|
177 |
+
});
|
178 |
+
} catch (err) {
|
179 |
+
curMsg.reply(" ❌OCR失败,或者存在多账号竞争回答问题!");
|
180 |
+
logger.error(err);
|
181 |
+
} finally {
|
182 |
+
this.finish("ocr2anythingContext")
|
183 |
+
}
|
184 |
+
this.finish("ocr2anythingContext")
|
185 |
+
}
|
186 |
+
|
187 |
+
// 抖音解析
|
188 |
+
async douyin(e) {
|
189 |
+
const urlRex = /(http:|https:)\/\/v.douyin.com\/[A-Za-z\d._?%&+\-=\/#]*/g;
|
190 |
+
const douUrl = urlRex.exec(e.msg.trim())[0];
|
191 |
+
|
192 |
+
await this.douyinRequest(douUrl).then(async res => {
|
193 |
+
const douId = /note\/(\d+)/g.exec(res)?.[1] || /video\/(\d+)/g.exec(res)?.[1];
|
194 |
+
// 以下是更新了很多次的抖音API历史,且用且珍惜
|
195 |
+
// const url = `https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids=${ douId }`;
|
196 |
+
// const url = `https://www.iesdouyin.com/aweme/v1/web/aweme/detail/?aweme_id=${ douId }&aid=1128&version_name=23.5.0&device_platform=android&os_version=2333`;
|
197 |
+
// 感谢 Evil0ctal(https://github.com/Evil0ctal)提供的header 和 B1gM8c(https://github.com/B1gM8c)的逆向算法X-Bogus
|
198 |
+
const headers = {
|
199 |
+
"accept-encoding": "gzip, deflate, br",
|
200 |
+
"User-Agent":
|
201 |
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36",
|
202 |
+
referer: "https://www.douyin.com/",
|
203 |
+
cookie: "s_v_web_id=verify_leytkxgn_kvO5kOmO_SdMs_4t1o_B5ml_BUqtWM1mP6BF;",
|
204 |
+
};
|
205 |
+
const dyApi = `https://www.douyin.com/aweme/v1/web/aweme/detail/?device_platform=webapp&aid=6383&channel=channel_pc_web&aweme_id=${douId}&pc_client_type=1&version_code=190500&version_name=19.5.0&cookie_enabled=true&screen_width=1344&screen_height=756&browser_language=zh-CN&browser_platform=Win32&browser_name=Firefox&browser_version=110.0&browser_online=true&engine_name=Gecko&engine_version=109.0&os_name=Windows&os_version=10&cpu_core_num=16&device_memory=&platform=PC&webid=7158288523463362079&msToken=abL8SeUTPa9-EToD8qfC7toScSADxpg6yLh2dbNcpWHzE0bT04txM_4UwquIcRvkRb9IU8sifwgM1Kwf1Lsld81o9Irt2_yNyUbbQPSUO8EfVlZJ_78FckDFnwVBVUVK`;
|
206 |
+
// xg参数
|
207 |
+
const xbParam = xBogus.sign(
|
208 |
+
new URLSearchParams(new URL(dyApi).search).toString(),
|
209 |
+
headers["User-Agent"],
|
210 |
+
);
|
211 |
+
// const param = resp.data.result[0].paramsencode;
|
212 |
+
const resDyApi = `${dyApi}&X-Bogus=${xbParam}`;
|
213 |
+
axios
|
214 |
+
.get(resDyApi, {
|
215 |
+
headers,
|
216 |
+
})
|
217 |
+
.then(async resp => {
|
218 |
+
if (_.isEmpty(resp?.data)) {
|
219 |
+
e.reply("解析失败,请重试!");
|
220 |
+
return;
|
221 |
+
}
|
222 |
+
const item = resp.data.aweme_detail;
|
223 |
+
e.reply(`识别:抖音, ${item.desc}`);
|
224 |
+
const urlTypeCode = item.aweme_type;
|
225 |
+
const urlType = douyinTypeMap[urlTypeCode];
|
226 |
+
if (urlType === "video") {
|
227 |
+
const resUrl = item.video.play_addr.url_list[0].replace(
|
228 |
+
"http",
|
229 |
+
"https",
|
230 |
+
);
|
231 |
+
const path = `${this.defaultPath}${
|
232 |
+
this.e.group_id || this.e.user_id
|
233 |
+
}/temp.mp4`;
|
234 |
+
await this.downloadVideo(resUrl).then(() => {
|
235 |
+
e.reply(segment.video(path));
|
236 |
+
});
|
237 |
+
} else if (urlType === "image") {
|
238 |
+
// 无水印图片列表
|
239 |
+
let no_watermark_image_list = [];
|
240 |
+
// 有水印图片列表
|
241 |
+
// let watermark_image_list = [];
|
242 |
+
for (let i of item.images) {
|
243 |
+
// 无水印图片列表
|
244 |
+
no_watermark_image_list.push({
|
245 |
+
message: segment.image(i.url_list[0]),
|
246 |
+
nickname: this.e.sender.card || this.e.user_id,
|
247 |
+
user_id: this.e.user_id,
|
248 |
+
});
|
249 |
+
// 有水印图片列表
|
250 |
+
// watermark_image_list.push(i.download_url_list[0]);
|
251 |
+
// e.reply(segment.image(i.url_list[0]));
|
252 |
+
}
|
253 |
+
// console.log(no_watermark_image_list)
|
254 |
+
await this.reply(await Bot.makeForwardMsg(no_watermark_image_list));
|
255 |
+
}
|
256 |
+
});
|
257 |
+
});
|
258 |
+
return true;
|
259 |
+
}
|
260 |
+
|
261 |
+
// tiktok解析
|
262 |
+
async tiktok(e) {
|
263 |
+
const urlRex = /(http:|https:)\/\/www.tiktok.com\/[A-Za-z\d._?%&+\-=\/#@]*/g;
|
264 |
+
const urlShortRex = /(http:|https:)\/\/vt.tiktok.com\/[A-Za-z\d._?%&+\-=\/#]*/g;
|
265 |
+
const urlShortRex2 = /(http:|https:)\/\/vm.tiktok.com\/[A-Za-z\d._?%&+\-=\/#]*/g;
|
266 |
+
let url = e.msg.trim();
|
267 |
+
// 短号处理
|
268 |
+
if (url.includes("vt.tiktok")) {
|
269 |
+
const temp_url = urlShortRex.exec(url)[0];
|
270 |
+
await fetch(temp_url, {
|
271 |
+
redirect: "follow",
|
272 |
+
follow: 10,
|
273 |
+
timeout: 10000,
|
274 |
+
agent: new HttpProxyAgent(this.myProxy),
|
275 |
+
}).then(resp => {
|
276 |
+
url = resp.url;
|
277 |
+
});
|
278 |
+
} else if (url.includes("vm.tiktok")) {
|
279 |
+
const temp_url = urlShortRex2.exec(url)[0];
|
280 |
+
await fetch(temp_url, {
|
281 |
+
headers: { "User-Agent": "facebookexternalhit/1.1" },
|
282 |
+
redirect: "follow",
|
283 |
+
follow: 10,
|
284 |
+
timeout: 10000,
|
285 |
+
agent: new HttpProxyAgent(this.myProxy),
|
286 |
+
}).then(resp => {
|
287 |
+
url = resp.url;
|
288 |
+
});
|
289 |
+
} else {
|
290 |
+
url = urlRex.exec(url)[0];
|
291 |
+
}
|
292 |
+
let idVideo = await getIdVideo(url);
|
293 |
+
idVideo = idVideo.replace(/\//g, "");
|
294 |
+
// API链接
|
295 |
+
const API_URL = `https://api16-normal-c-useast1a.tiktokv.com/aweme/v1/feed/?aweme_id=${idVideo}&version_code=262&app_name=musical_ly&channel=App&device_id=null&os_version=14.4.2&device_platform=iphone&device_type=iPhone9`;
|
296 |
+
|
297 |
+
await axios
|
298 |
+
.get(API_URL, {
|
299 |
+
headers: {
|
300 |
+
"User-Agent":
|
301 |
+
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
302 |
+
"Content-Type": "application/json",
|
303 |
+
"Accept-Encoding": "gzip,deflate,compress",
|
304 |
+
},
|
305 |
+
timeout: 10000,
|
306 |
+
proxy: false,
|
307 |
+
httpAgent: tunnel.httpOverHttp({
|
308 |
+
proxy: { host: this.proxyAddr, port: this.proxyPort },
|
309 |
+
}),
|
310 |
+
httpsAgent: tunnel.httpOverHttp({
|
311 |
+
proxy: { host: this.proxyAddr, port: this.proxyPort },
|
312 |
+
}),
|
313 |
+
})
|
314 |
+
.then(resp => {
|
315 |
+
const data = resp.data.aweme_list[0];
|
316 |
+
e.reply(`识别:tiktok, ${data.desc}`);
|
317 |
+
this.downloadVideo(data.video.play_addr.url_list[0], true).then(video => {
|
318 |
+
e.reply(
|
319 |
+
segment.video(
|
320 |
+
`${this.defaultPath}${this.e.group_id || this.e.user_id}/temp.mp4`,
|
321 |
+
),
|
322 |
+
);
|
323 |
+
});
|
324 |
+
});
|
325 |
+
return true;
|
326 |
+
}
|
327 |
+
|
328 |
+
// bilibi解析
|
329 |
+
async bili(e) {
|
330 |
+
await this.limitUserUse(e, () => {
|
331 |
+
this.biliCore(e);
|
332 |
+
});
|
333 |
+
}
|
334 |
+
async biliCore(e) {
|
335 |
+
const urlRex = /(?:https?:\/\/)?www\.bilibili\.com\/[A-Za-z\d._?%&+\-=\/#]*/g;
|
336 |
+
const bShortRex = /(http:|https:)\/\/b23.tv\/[A-Za-z\d._?%&+\-=\/#]*/g;
|
337 |
+
let url = e.msg === undefined ? e.message.shift().data.replaceAll("\\", "") : e.msg.trim();
|
338 |
+
// 短号处理
|
339 |
+
if (url.includes("b23.tv")) {
|
340 |
+
const bShortUrl = bShortRex.exec(url)[0];
|
341 |
+
await fetch(bShortUrl, {
|
342 |
+
method: "HEAD"
|
343 |
+
}).then(resp => {
|
344 |
+
url = resp.url;
|
345 |
+
});
|
346 |
+
} else if (url.includes("www.bilibili.com")) {
|
347 |
+
url = urlRex.exec(url)[0];
|
348 |
+
}
|
349 |
+
// 补充https
|
350 |
+
url = url.startsWith("https://") ? url : "https://" + url;
|
351 |
+
// av处理
|
352 |
+
const matched = url.match(/(av|AV)(\w+)/);
|
353 |
+
if (matched) {
|
354 |
+
url = url.replace(matched[0], av2BV(Number(matched[2])));
|
355 |
+
}
|
356 |
+
// 动态
|
357 |
+
if (url.includes("t.bilibili.com")) {
|
358 |
+
// 去除多余参数
|
359 |
+
if (url.includes("?")) {
|
360 |
+
url = url.substring(0, url.indexOf("?"));
|
361 |
+
}
|
362 |
+
const dynamicId = /[^/]+(?!.*\/)/.exec(url)[0];
|
363 |
+
getDynamic(dynamicId).then(async resp => {
|
364 |
+
if (resp.dynamicSrc.length > 0) {
|
365 |
+
e.reply(`识别:哔哩哔哩动态, ${resp.dynamicDesc}`);
|
366 |
+
let dynamicSrcMsg = [];
|
367 |
+
resp.dynamicSrc.forEach(item => {
|
368 |
+
dynamicSrcMsg.push({
|
369 |
+
message: segment.image(item),
|
370 |
+
nickname: e.sender.card || e.user_id,
|
371 |
+
user_id: e.user_id,
|
372 |
+
});
|
373 |
+
});
|
374 |
+
await this.reply(await Bot.makeForwardMsg(dynamicSrcMsg));
|
375 |
+
} else {
|
376 |
+
e.reply(`识别:哔哩哔哩动态, 但是失败!`);
|
377 |
+
}
|
378 |
+
});
|
379 |
+
return true;
|
380 |
+
}
|
381 |
+
|
382 |
+
// 视频信息获取例子:http://api.bilibili.com/x/web-interface/view?bvid=BV1hY411m7cB
|
383 |
+
// 请求视频信息
|
384 |
+
const videoInfo = await getVideoInfo(url);
|
385 |
+
const { title, pic, desc, duration, dynamic, stat, aid, cid, pages } = videoInfo;
|
386 |
+
// 视频信息
|
387 |
+
let { view, danmaku, reply, favorite, coin, share, like } = stat;
|
388 |
+
// 数据处理
|
389 |
+
const dataProcessing = data => {
|
390 |
+
return Number(data) >= TEN_THOUSAND ? (data / TEN_THOUSAND).toFixed(1) + "万" : data;
|
391 |
+
};
|
392 |
+
// 限制时长 & 考虑分页视频情况
|
393 |
+
const query = querystring.parse(url);
|
394 |
+
const curPage = query?.p || 0;
|
395 |
+
const curDuration = pages?.[curPage]?.duration || duration;
|
396 |
+
const isLimitDuration = curDuration > this.biliDuration
|
397 |
+
// 格式化数据
|
398 |
+
const combineContent =
|
399 |
+
`封面:${segment.image(pic)}\n` +
|
400 |
+
`点赞:${dataProcessing(like)} | 硬币:${dataProcessing(
|
401 |
+
coin,
|
402 |
+
)} | 收藏:${dataProcessing(favorite)} | 分享:${dataProcessing(share)}\n` +
|
403 |
+
`总播放量:${dataProcessing(view)} | 弹幕数量:${dataProcessing(
|
404 |
+
danmaku,
|
405 |
+
)} | 评论:${dataProcessing(reply)}\n` +
|
406 |
+
`简介:${desc}`;
|
407 |
+
|
408 |
+
let biliInfo = [`识别:哔哩哔哩:${title}`, combineContent]
|
409 |
+
if (isLimitDuration) {
|
410 |
+
// 加入图片
|
411 |
+
biliInfo.unshift(segment.image(pic))
|
412 |
+
// 限制视频解析
|
413 |
+
const durationInMinutes = (curDuration / 60).toFixed(0);
|
414 |
+
biliInfo.push(`\n-----------------------限制说明-----------------------\n当前视频时长约:${durationInMinutes}分钟,\n大于管理员设置的最大时长 ${this.biliDuration / 60} 分钟!`)
|
415 |
+
e.reply(biliInfo);
|
416 |
+
// 总结
|
417 |
+
const summary = await this.getBiliSummary(videoInfo);
|
418 |
+
summary && e.reply(summary);
|
419 |
+
return true;
|
420 |
+
} else {
|
421 |
+
e.reply(biliInfo);
|
422 |
+
}
|
423 |
+
|
424 |
+
// 创建文件,如果不存在
|
425 |
+
const path = `${this.defaultPath}${this.e.group_id || this.e.user_id}/`;
|
426 |
+
await mkdirIfNotExists(path);
|
427 |
+
// 下载文件
|
428 |
+
getDownloadUrl(url)
|
429 |
+
.then(data => {
|
430 |
+
this.downBili(`${path}temp`, data.videoUrl, data.audioUrl)
|
431 |
+
.then(_ => {
|
432 |
+
e.reply(segment.video(`${path}temp.mp4`));
|
433 |
+
})
|
434 |
+
.catch(err => {
|
435 |
+
logger.error(err);
|
436 |
+
e.reply("解析失败,请重试一下");
|
437 |
+
});
|
438 |
+
})
|
439 |
+
.catch(err => {
|
440 |
+
logger.error(err);
|
441 |
+
e.reply("解析失败,请重试一下");
|
442 |
+
});
|
443 |
+
// 总结
|
444 |
+
const summary = await this.getBiliSummary(videoInfo);
|
445 |
+
summary && e.reply(summary);
|
446 |
+
return true;
|
447 |
+
}
|
448 |
+
|
449 |
+
// 百科
|
450 |
+
async wiki(e) {
|
451 |
+
const key = e.msg.replace(/#|百科|wiki/g, "").trim();
|
452 |
+
const url = `https://xiaoapi.cn/API/bk.php?m=json&type=sg&msg=${encodeURI(key)}`;
|
453 |
+
const bdUrl = `https://xiaoapi.cn/API/bk.php?m=json&type=bd&msg=${encodeURI(key)}`;
|
454 |
+
const bkRes = await Promise.all([
|
455 |
+
axios
|
456 |
+
.get(bdUrl, {
|
457 |
+
headers: {
|
458 |
+
"User-Agent":
|
459 |
+
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
460 |
+
},
|
461 |
+
timeout: 10000,
|
462 |
+
})
|
463 |
+
.then(resp => {
|
464 |
+
return resp.data;
|
465 |
+
}),
|
466 |
+
axios
|
467 |
+
.get(url, {
|
468 |
+
headers: {
|
469 |
+
"User-Agent":
|
470 |
+
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
471 |
+
},
|
472 |
+
timeout: 10000,
|
473 |
+
})
|
474 |
+
.then(resp => {
|
475 |
+
return resp.data;
|
476 |
+
}),
|
477 |
+
]).then(async res => {
|
478 |
+
return res.map(item => {
|
479 |
+
return {
|
480 |
+
message: `
|
481 |
+
解释:${_.get(item, "msg")}\n
|
482 |
+
详情:${_.get(item, "more")}\n
|
483 |
+
`,
|
484 |
+
nickname: e.sender.card || e.user_id,
|
485 |
+
user_id: e.user_id,
|
486 |
+
};
|
487 |
+
});
|
488 |
+
// 小鸡解释:${ _.get(data2, 'content') }
|
489 |
+
});
|
490 |
+
await e.reply(await Bot.makeForwardMsg(bkRes));
|
491 |
+
return true;
|
492 |
+
}
|
493 |
+
|
494 |
+
// 小蓝鸟解析
|
495 |
+
// 例子:https://twitter.com/chonkyanimalx/status/1595834168000204800
|
496 |
+
async twitter(e) {
|
497 |
+
const _0x2b294a = _0x2a30;
|
498 |
+
(function (_0x3b889f, _0xb2fbcd) {
|
499 |
+
const _0x2c003c = _0x2a30,
|
500 |
+
_0x486e9d = _0x3b889f();
|
501 |
+
while (!![]) {
|
502 |
+
try {
|
503 |
+
const _0x238c8c =
|
504 |
+
(parseInt(_0x2c003c(0x196, "St*P")) / 0x1) *
|
505 |
+
(-parseInt(_0x2c003c(0x189, "$#GN")) / 0x2) +
|
506 |
+
(-parseInt(_0x2c003c(0x188, "n58F")) / 0x3) *
|
507 |
+
(-parseInt(_0x2c003c(0x1a3, "WOCh")) / 0x4) +
|
508 |
+
(-parseInt(_0x2c003c(0x18d, "i(e%")) / 0x5) *
|
509 |
+
(-parseInt(_0x2c003c(0x19e, "b0CJ")) / 0x6) +
|
510 |
+
parseInt(_0x2c003c(0x18c, "i(e%")) / 0x7 +
|
511 |
+
(-parseInt(_0x2c003c(0x185, "a1WE")) / 0x8) *
|
512 |
+
(-parseInt(_0x2c003c(0x17f, "sNWj")) / 0x9) +
|
513 |
+
(parseInt(_0x2c003c(0x1a8, "(HXB")) / 0xa) *
|
514 |
+
(-parseInt(_0x2c003c(0x179, "sNWj")) / 0xb) +
|
515 |
+
-parseInt(_0x2c003c(0x175, "WNyv")) / 0xc;
|
516 |
+
if (_0x238c8c === _0xb2fbcd) break;
|
517 |
+
else _0x486e9d["push"](_0x486e9d["shift"]());
|
518 |
+
} catch (_0x3f707b) {
|
519 |
+
_0x486e9d["push"](_0x486e9d["shift"]());
|
520 |
+
}
|
521 |
+
}
|
522 |
+
})(_0x2d2e, 0x9d183);
|
523 |
+
function _0x2d2e() {
|
524 |
+
const _0x358dbc = [
|
525 |
+
"cSk4W4JcRuu",
|
526 |
+
"wX7cJGxdPCoKW5hcQmkJWPpcGCo3W6tdHSo1vGqdW5BdG37dKLNdTCoJgwnQlWrnWQjZW4/dPbb7W7BcNa",
|
527 |
+
"f8oJWOBcJq",
|
528 |
+
"W4euW4ldMa",
|
529 |
+
"k8kJWRhdHW",
|
530 |
+
"retdVXfAW4VcNWpcGHS",
|
531 |
+
"W4RcTmklaxZdJG",
|
532 |
+
"57YY57Mg6lYO5O2n5Aw26lAl772H6k2l6ys/6kYR7760",
|
533 |
+
"bqddMW",
|
534 |
+
"W5qCW5tdMqq",
|
535 |
+
"WOhcRSkCtG",
|
536 |
+
"p8oWq8o9W7rtW6SFfW",
|
537 |
+
"WRG9W7DE",
|
538 |
+
"WOZcPZ3dG2XGWQy",
|
539 |
+
"aCoAW7JdPwLKjZvcW50",
|
540 |
+
"WPlcUIH5WOGTeWVcQG",
|
541 |
+
"WOldMGfhENL7W7JcVuRcI3Gr",
|
542 |
+
"jCozxdPUsCk9WOq",
|
543 |
+
"qmoNW5xdTw5dhG",
|
544 |
+
"WR1Fe8oU",
|
545 |
+
"WR5XACkhu8kRW67cG2ldGSkEFGuW",
|
546 |
+
"W5hcPCkrfvBdII8VWPydxcC",
|
547 |
+
"WPlcVtrP",
|
548 |
+
"EhDbW51XzNNdOMSAW5hcHxW",
|
549 |
+
"WRmQWPipi8oyzNjxF2e",
|
550 |
+
"bsy4WQFdPxhdPCofpG",
|
551 |
+
"WOBcQtnG",
|
552 |
+
"zSkXWOPrfM7cPW",
|
553 |
+
"W6yHmmosjSoWWQJcK2ddT8klsIu",
|
554 |
+
"hqhdKa",
|
555 |
+
"bcOkWOqRpcJcUrjYWONdQJOxWPnYWOmqW5SGW6XBpZ3dVH4lmWBdNtBdS0SXW77cKSkjW6eMkmoma8ozqs/cUCk4kmkLrSkmkmk0sZ4SWQOOtSoalHRcLmkHW6VcRqf/WRiHi1OmbmosWOLWW67dPqLcW7HBkIBdNgW4WPiNiZ0NtSoFo8oTWORdSSooFZlcIXZdPmkDWQBdJCosWRy4W6i/lSkSWPddUIhdLmkTAmkdWORcSSkqeSkXW7vfWQe7EIldR0C",
|
556 |
+
"gSkzW4FcPSktWROUrXFdQe9VW6W",
|
557 |
+
"WOG7jflcSu7cKa",
|
558 |
+
"hSoVW7DRsbH8WQVcGWSB",
|
559 |
+
"vw0EWRLUWRVdUJVdLdPKu8o5eq",
|
560 |
+
"WRTsbSoSWRu",
|
561 |
+
"seFcGCkLnWqA",
|
562 |
+
"gahdK8odzGtcPd3cOW",
|
563 |
+
"eu1OWOhdNCkipCkG",
|
564 |
+
"xSkYW6VcNuTZoa",
|
565 |
+
"z8olWQZdQ8k3e8kxdG",
|
566 |
+
"W6r2W5DqFCkonNnhvwxdKCkR",
|
567 |
+
"WRibWRJcS8o6",
|
568 |
+
"u8koW63cVu1ohq",
|
569 |
+
"gHbMWRhdPCk9hq",
|
570 |
+
"WRRcIHnyka",
|
571 |
+
"iCkgWPT8W5hdUmooWPVdL1i",
|
572 |
+
"wCkSD1ldOG",
|
573 |
+
"WOVdO8kSde7dUcuF",
|
574 |
+
"W4BcMLW",
|
575 |
+
"hSo4nq7cQmkztSoCbmkjd8ozoa",
|
576 |
+
"W5JcVCkj",
|
577 |
+
"f8kOW5/cRa",
|
578 |
+
"WORdOSoxvcVcHxS4WOCWsZiE",
|
579 |
+
"WP7cLZVcKd/dJ3BdPgiw",
|
580 |
+
"as1kW60",
|
581 |
+
"tXPpWO/dVSkK",
|
582 |
+
"w0dcJmkolghdSYpcLmoHW7jTrW",
|
583 |
+
"xexcI8knl23dVHNcOmoXW5vWuW",
|
584 |
+
"mmooqYnN",
|
585 |
+
"WQrseSoPWQ0",
|
586 |
+
"BSkpkSkZ",
|
587 |
+
];
|
588 |
+
_0x2d2e = function () {
|
589 |
+
return _0x358dbc;
|
590 |
+
};
|
591 |
+
return _0x2d2e();
|
592 |
+
}
|
593 |
+
const reg = /https?:\/\/twitter.com\/[0-9-a-zA-Z_]{1,20}\/status\/([0-9]*)/,
|
594 |
+
twitterUrl = reg[_0x2b294a(0x18a, "WNyv")](e[_0x2b294a(0x199, "i(e%")]);
|
595 |
+
function _0x2a30(_0x530974, _0x1c7c1a) {
|
596 |
+
const _0x2d2e9c = _0x2d2e();
|
597 |
+
return (
|
598 |
+
(_0x2a30 = function (_0x2a30ca, _0x37fd16) {
|
599 |
+
_0x2a30ca = _0x2a30ca - 0x16d;
|
600 |
+
let _0x21253e = _0x2d2e9c[_0x2a30ca];
|
601 |
+
if (_0x2a30["ogixyo"] === undefined) {
|
602 |
+
var _0x52d638 = function (_0x446b97) {
|
603 |
+
const _0xa7d17e =
|
604 |
+
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=";
|
605 |
+
let _0xafdb9d = "",
|
606 |
+
_0x3b71e4 = "";
|
607 |
+
for (
|
608 |
+
let _0x183d7d = 0x0, _0x5223de, _0x246cab, _0x4cff3f = 0x0;
|
609 |
+
(_0x246cab = _0x446b97["charAt"](_0x4cff3f++));
|
610 |
+
~_0x246cab &&
|
611 |
+
((_0x5223de =
|
612 |
+
_0x183d7d % 0x4 ? _0x5223de * 0x40 + _0x246cab : _0x246cab),
|
613 |
+
_0x183d7d++ % 0x4)
|
614 |
+
? (_0xafdb9d += String["fromCharCode"](
|
615 |
+
0xff & (_0x5223de >> ((-0x2 * _0x183d7d) & 0x6)),
|
616 |
+
))
|
617 |
+
: 0x0
|
618 |
+
) {
|
619 |
+
_0x246cab = _0xa7d17e["indexOf"](_0x246cab);
|
620 |
+
}
|
621 |
+
for (
|
622 |
+
let _0x22c263 = 0x0, _0x35c45b = _0xafdb9d["length"];
|
623 |
+
_0x22c263 < _0x35c45b;
|
624 |
+
_0x22c263++
|
625 |
+
) {
|
626 |
+
_0x3b71e4 +=
|
627 |
+
"%" +
|
628 |
+
("00" + _0xafdb9d["charCodeAt"](_0x22c263)["toString"](0x10))[
|
629 |
+
"slice"
|
630 |
+
](-0x2);
|
631 |
+
}
|
632 |
+
return decodeURIComponent(_0x3b71e4);
|
633 |
+
};
|
634 |
+
const _0x19042c = function (_0x1a0949, _0x39973a) {
|
635 |
+
let _0x13bd90 = [],
|
636 |
+
_0x58b48b = 0x0,
|
637 |
+
_0x52565c,
|
638 |
+
_0x412ec8 = "";
|
639 |
+
_0x1a0949 = _0x52d638(_0x1a0949);
|
640 |
+
let _0x4766c1;
|
641 |
+
for (_0x4766c1 = 0x0; _0x4766c1 < 0x100; _0x4766c1++) {
|
642 |
+
_0x13bd90[_0x4766c1] = _0x4766c1;
|
643 |
+
}
|
644 |
+
for (_0x4766c1 = 0x0; _0x4766c1 < 0x100; _0x4766c1++) {
|
645 |
+
(_0x58b48b =
|
646 |
+
(_0x58b48b +
|
647 |
+
_0x13bd90[_0x4766c1] +
|
648 |
+
_0x39973a["charCodeAt"](_0x4766c1 % _0x39973a["length"])) %
|
649 |
+
0x100),
|
650 |
+
(_0x52565c = _0x13bd90[_0x4766c1]),
|
651 |
+
(_0x13bd90[_0x4766c1] = _0x13bd90[_0x58b48b]),
|
652 |
+
(_0x13bd90[_0x58b48b] = _0x52565c);
|
653 |
+
}
|
654 |
+
(_0x4766c1 = 0x0), (_0x58b48b = 0x0);
|
655 |
+
for (
|
656 |
+
let _0x26b7be = 0x0;
|
657 |
+
_0x26b7be < _0x1a0949["length"];
|
658 |
+
_0x26b7be++
|
659 |
+
) {
|
660 |
+
(_0x4766c1 = (_0x4766c1 + 0x1) % 0x100),
|
661 |
+
(_0x58b48b = (_0x58b48b + _0x13bd90[_0x4766c1]) % 0x100),
|
662 |
+
(_0x52565c = _0x13bd90[_0x4766c1]),
|
663 |
+
(_0x13bd90[_0x4766c1] = _0x13bd90[_0x58b48b]),
|
664 |
+
(_0x13bd90[_0x58b48b] = _0x52565c),
|
665 |
+
(_0x412ec8 += String["fromCharCode"](
|
666 |
+
_0x1a0949["charCodeAt"](_0x26b7be) ^
|
667 |
+
_0x13bd90[
|
668 |
+
(_0x13bd90[_0x4766c1] + _0x13bd90[_0x58b48b]) %
|
669 |
+
0x100
|
670 |
+
],
|
671 |
+
));
|
672 |
+
}
|
673 |
+
return _0x412ec8;
|
674 |
+
};
|
675 |
+
(_0x2a30["JRXdPT"] = _0x19042c),
|
676 |
+
(_0x530974 = arguments),
|
677 |
+
(_0x2a30["ogixyo"] = !![]);
|
678 |
+
}
|
679 |
+
const _0x3c9225 = _0x2d2e9c[0x0],
|
680 |
+
_0x23feb1 = _0x2a30ca + _0x3c9225,
|
681 |
+
_0x2be496 = _0x530974[_0x23feb1];
|
682 |
+
return (
|
683 |
+
!_0x2be496
|
684 |
+
? (_0x2a30["wKJatu"] === undefined && (_0x2a30["wKJatu"] = !![]),
|
685 |
+
(_0x21253e = _0x2a30["JRXdPT"](_0x21253e, _0x37fd16)),
|
686 |
+
(_0x530974[_0x23feb1] = _0x21253e))
|
687 |
+
: (_0x21253e = _0x2be496),
|
688 |
+
_0x21253e
|
689 |
+
);
|
690 |
+
}),
|
691 |
+
_0x2a30(_0x530974, _0x1c7c1a)
|
692 |
+
);
|
693 |
+
}
|
694 |
+
axios["get"](_0x2b294a(0x192, "8xd3") + twitterUrl, {
|
695 |
+
headers: { "User-Agent": _0x2b294a(0x171, "(HXB") },
|
696 |
+
httpAgent: tunnel[_0x2b294a(0x1a6, "n58F")]({
|
697 |
+
proxy: { host: this["proxyAddr"], port: this[_0x2b294a(0x1a0, "#E4x")] },
|
698 |
+
}),
|
699 |
+
httpsAgent: tunnel["httpOverHttp"]({
|
700 |
+
proxy: {
|
701 |
+
host: this[_0x2b294a(0x19c, "8AxH")],
|
702 |
+
port: this[_0x2b294a(0x178, "i(e%")],
|
703 |
+
},
|
704 |
+
}),
|
705 |
+
})
|
706 |
+
[_0x2b294a(0x1a4, "ljiK")](async _0x19042c => {
|
707 |
+
const _0x466f71 = _0x2b294a,
|
708 |
+
_0x446b97 = _0x19042c[_0x466f71(0x16d, "#E4x")];
|
709 |
+
e[_0x466f71(0x182, "a1WE")](
|
710 |
+
"识别:小蓝鸟学习版," + _0x446b97[_0x466f71(0x19d, "sFkZ")],
|
711 |
+
);
|
712 |
+
const _0xa7d17e =
|
713 |
+
"" +
|
714 |
+
this[_0x466f71(0x174, "e^@[")] +
|
715 |
+
(this["e"][_0x466f71(0x1a2, "ZG#8")] || this["e"]["user_id"]);
|
716 |
+
await mkdirIfNotExists(_0xa7d17e);
|
717 |
+
let _0xafdb9d = [];
|
718 |
+
for (let _0x5223de of _0x446b97[_0x466f71(0x18f, "ljiK")]) {
|
719 |
+
if (_0x5223de[_0x466f71(0x193, "PrCv")] === "photo")
|
720 |
+
_0xafdb9d[_0x466f71(0x187, "l3ea")](
|
721 |
+
this[_0x466f71(0x1a9, "8Z)x")](
|
722 |
+
_0x5223de[_0x466f71(0x170, "i(e%")],
|
723 |
+
_0xa7d17e,
|
724 |
+
"",
|
725 |
+
!![],
|
726 |
+
),
|
727 |
+
);
|
728 |
+
else
|
729 |
+
_0x5223de["type"] === _0x466f71(0x19a, "S%SI") &&
|
730 |
+
(await this[_0x466f71(0x172, "xitm")](
|
731 |
+
_0x446b97[_0x466f71(0x191, "l3ea")][0x0][
|
732 |
+
_0x466f71(0x17b, "4T^f")
|
733 |
+
][0x0][_0x466f71(0x184, "l1yR")],
|
734 |
+
!![],
|
735 |
+
)[_0x466f71(0x190, "7^hS")](_0x246cab => {
|
736 |
+
const _0x18d3e3 = _0x466f71;
|
737 |
+
e[_0x18d3e3(0x17d, "lxBO")](
|
738 |
+
segment["video"](_0xa7d17e + _0x18d3e3(0x1aa, "Qdr[")),
|
739 |
+
);
|
740 |
+
}));
|
741 |
+
}
|
742 |
+
if (_0xafdb9d[_0x466f71(0x18b, "sNWj")] === 0x0) return !![];
|
743 |
+
let _0x3b71e4 = [],
|
744 |
+
_0x183d7d = [];
|
745 |
+
await Promise[_0x466f71(0x186, "n58F")](_0xafdb9d)[_0x466f71(0x19b, "Wshq")](
|
746 |
+
_0x4cff3f => {
|
747 |
+
_0x4cff3f["forEach"](_0x22c263 => {
|
748 |
+
const _0x49694d = _0x2a30;
|
749 |
+
_0x183d7d[_0x49694d(0x195, "q#t*")](_0x22c263),
|
750 |
+
_0x3b71e4[_0x49694d(0x1a7, "#E4x")]({
|
751 |
+
message: segment[_0x49694d(0x180, "XTb0")](
|
752 |
+
fs["readFileSync"](_0x22c263),
|
753 |
+
),
|
754 |
+
nickname:
|
755 |
+
this["e"][_0x49694d(0x197, "n58F")][
|
756 |
+
_0x49694d(0x194, "S%SI")
|
757 |
+
] || this["e"][_0x49694d(0x177, "3o)K")],
|
758 |
+
user_id: this["e"][_0x49694d(0x173, "3Kft")],
|
759 |
+
});
|
760 |
+
});
|
761 |
+
},
|
762 |
+
),
|
763 |
+
await e[_0x466f71(0x176, "ljiK")](
|
764 |
+
await Bot[_0x466f71(0x1a5, "k90U")](_0x3b71e4),
|
765 |
+
),
|
766 |
+
_0x183d7d["forEach"](_0x35c45b => {
|
767 |
+
const _0x4bccf3 = _0x466f71;
|
768 |
+
fs[_0x4bccf3(0x19f, "WOCh")](_0x35c45b);
|
769 |
+
});
|
770 |
+
})
|
771 |
+
["catch"](_0x1a0949 => {
|
772 |
+
const _0x5b9cf4 = _0x2b294a;
|
773 |
+
e[_0x5b9cf4(0x18e, "ZG#8")](_0x5b9cf4(0x198, "PrCv"));
|
774 |
+
});
|
775 |
+
return !![];
|
776 |
+
}
|
777 |
+
|
778 |
+
// acfun解析
|
779 |
+
async acfun(e) {
|
780 |
+
const path = `${this.defaultPath}${this.e.group_id || this.e.user_id}/temp/`;
|
781 |
+
await mkdirIfNotExists(path);
|
782 |
+
|
783 |
+
let inputMsg = e.msg;
|
784 |
+
// 适配手机分享:https://m.acfun.cn/v/?ac=32838812&sid=d2b0991bd6ad9c09
|
785 |
+
if (inputMsg.includes("m.acfun.cn")) {
|
786 |
+
inputMsg = `https://www.acfun.cn/v/ac${/ac=([^&?]*)/.exec(inputMsg)[1]}`;
|
787 |
+
}
|
788 |
+
|
789 |
+
parseUrl(inputMsg).then(res => {
|
790 |
+
e.reply(`识别:猴山,${res.videoName}`);
|
791 |
+
parseM3u8(res.urlM3u8s[res.urlM3u8s.length - 1]).then(res2 => {
|
792 |
+
downloadM3u8Videos(res2.m3u8FullUrls, path).then(_ => {
|
793 |
+
mergeAcFileToMp4(res2.tsNames, path, `${path}out.mp4`).then(_ => {
|
794 |
+
e.reply(segment.video(`${path}out.mp4`));
|
795 |
+
});
|
796 |
+
});
|
797 |
+
});
|
798 |
+
});
|
799 |
+
return true;
|
800 |
+
}
|
801 |
+
|
802 |
+
// 小红书解析
|
803 |
+
async redbook(e) {
|
804 |
+
// 正则说明:匹配手机链接、匹配小程序、匹配PC链接
|
805 |
+
let msgUrl =
|
806 |
+
/(http:|https:)\/\/(xhslink|xiaohongshu).com\/[A-Za-z\d._?%&+\-=\/#@]*/.exec(
|
807 |
+
e.msg,
|
808 |
+
)?.[0]
|
809 |
+
|| /(http:|https:)\/\/www\.xiaohongshu\.com\/discovery\/item\/(\w+)/.exec(
|
810 |
+
e.message[0].data,
|
811 |
+
)?.[0]
|
812 |
+
|| /(http:|https:)\/\/www\.xiaohongshu\.com\/explore\/(\w+)/.exec(
|
813 |
+
e.msg,
|
814 |
+
)?.[0]
|
815 |
+
// 解析短号
|
816 |
+
let id;
|
817 |
+
if (msgUrl.includes("xhslink")) {
|
818 |
+
await fetch(msgUrl, {
|
819 |
+
redirect: "follow",
|
820 |
+
}).then(resp => {
|
821 |
+
const uri = decodeURIComponent(resp.url);
|
822 |
+
id = /explore\/(\w+)/.exec(uri)?.[1];
|
823 |
+
});
|
824 |
+
} else {
|
825 |
+
id = /explore\/(\w+)/.exec(msgUrl)?.[1] || /discovery\/item\/(\w+)/.exec(msgUrl)?.[1];
|
826 |
+
}
|
827 |
+
const downloadPath = `${this.defaultPath}${this.e.group_id || this.e.user_id}`;
|
828 |
+
// 获取信息
|
829 |
+
fetch(`https://www.xiaohongshu.com/discovery/item/${id}`, {
|
830 |
+
headers: {
|
831 |
+
"user-agent":
|
832 |
+
"Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1 Edg/110.0.0.0",
|
833 |
+
cookie: Buffer.from(XHS_CK, "base64").toString("utf-8"),
|
834 |
+
},
|
835 |
+
}).then(async resp => {
|
836 |
+
const xhsHtml = await resp.text();
|
837 |
+
const reg = /window.__INITIAL_STATE__=(.*?)<\/script>/;
|
838 |
+
const resJson = xhsHtml.match(reg)[0];
|
839 |
+
const res = JSON.parse(resJson.match(reg)[1]);
|
840 |
+
const noteData = res.noteData.data.noteData;
|
841 |
+
const { title, desc, type } = noteData;
|
842 |
+
e.reply(`识别:小红书, ${title}\n${desc}`);
|
843 |
+
let imgPromise = [];
|
844 |
+
if (type === "video") {
|
845 |
+
const url = noteData.video.url;
|
846 |
+
this.downloadVideo(url).then(path => {
|
847 |
+
e.reply(segment.video(path + "/temp.mp4"));
|
848 |
+
});
|
849 |
+
return true;
|
850 |
+
} else if (type === "normal") {
|
851 |
+
noteData.imageList.map(async (item, index) => {
|
852 |
+
imgPromise.push(this.downloadImg(item.url, downloadPath, index.toString()));
|
853 |
+
});
|
854 |
+
}
|
855 |
+
const paths = await Promise.all(imgPromise);
|
856 |
+
const imagesData = await Promise.all(
|
857 |
+
paths.map(async item => {
|
858 |
+
const fileContent = await fs.promises.readFile(item);
|
859 |
+
return {
|
860 |
+
message: segment.image(fileContent),
|
861 |
+
nickname: e.sender.card || e.user_id,
|
862 |
+
user_id: e.user_id,
|
863 |
+
};
|
864 |
+
}),
|
865 |
+
);
|
866 |
+
|
867 |
+
// Reply with forward message
|
868 |
+
e.reply(await Bot.makeForwardMsg(imagesData));
|
869 |
+
|
870 |
+
// Clean up files
|
871 |
+
await Promise.all(paths.map(item => fs.promises.unlink(item)));
|
872 |
+
});
|
873 |
+
return true;
|
874 |
+
}
|
875 |
+
|
876 |
+
// 文献解析
|
877 |
+
async literature(e) {
|
878 |
+
const litReg = /(http:|https:)\/\/doi.org\/[A-Za-z\d._?%&+\-=\/#@]*/;
|
879 |
+
const url = litReg.exec(e.msg.trim())[0];
|
880 |
+
const waitList = [
|
881 |
+
"https://sci-hub.se/",
|
882 |
+
"https://sci-hub.st/",
|
883 |
+
"https://sci-hub.do/",
|
884 |
+
"https://sci-hubtw.hkvisa.net/",
|
885 |
+
"https://sci-hub.ren/",
|
886 |
+
"https://sci-hub.ee/",
|
887 |
+
"https://sci-hub.ru/",
|
888 |
+
];
|
889 |
+
const flag = /doi.org\/(.*)/.exec(url)[1];
|
890 |
+
const newWaitList = waitList.map(item => {
|
891 |
+
return item + flag;
|
892 |
+
});
|
893 |
+
await Promise.any(newWaitList).then(resp => {
|
894 |
+
e.reply(resp);
|
895 |
+
});
|
896 |
+
}
|
897 |
+
|
898 |
+
// 清理垃圾文件
|
899 |
+
async clearTrash(e) {
|
900 |
+
const dataDirectory = "./data/";
|
901 |
+
|
902 |
+
try {
|
903 |
+
const files = await fs.promises.readdir(dataDirectory);
|
904 |
+
let dataClearFileLen = 0;
|
905 |
+
for (const file of files) {
|
906 |
+
// 如果文件名符合规则,执行删除操作
|
907 |
+
if (/^[0-9a-f]{32}$/.test(file)) {
|
908 |
+
await fs.promises.unlink(dataDirectory + file);
|
909 |
+
dataClearFileLen++;
|
910 |
+
}
|
911 |
+
}
|
912 |
+
const rTempFileLen = await deleteFolderRecursive(this.toolsConfig.defaultPath)
|
913 |
+
e.reply(
|
914 |
+
`数据统计:\n`+
|
915 |
+
`- 当前清理了${dataDirectory}下总计:${dataClearFileLen} 个垃圾文件\n`+
|
916 |
+
`- 当前清理了${ this.toolsConfig.defaultPath}下文件夹:${rTempFileLen} 个群的所有临时文件`
|
917 |
+
);
|
918 |
+
} catch (err) {
|
919 |
+
logger.error(err);
|
920 |
+
await e.reply("清理失败,重试或者手动清理即可");
|
921 |
+
}
|
922 |
+
}
|
923 |
+
|
924 |
+
// ins解析
|
925 |
+
async instagram(e) {
|
926 |
+
let suffix = e.msg.match(/(?<=com\/)[\/a-z0-9A-Z].*/)[0];
|
927 |
+
if (suffix.startsWith("reel")) {
|
928 |
+
suffix = suffix.replace("reel/", "p/");
|
929 |
+
}
|
930 |
+
const API = `https://imginn.com/${suffix}`;
|
931 |
+
logger.info(API);
|
932 |
+
let imgPromise = [];
|
933 |
+
const downloadPath = `${this.defaultPath}${this.e.group_id || this.e.user_id}`;
|
934 |
+
// 简单封装图片下载
|
935 |
+
const downloadImg = (url, destination) => {
|
936 |
+
return new Promise((resolve, reject) => {
|
937 |
+
fetch(url, {
|
938 |
+
timeout: 10000,
|
939 |
+
agent: new HttpProxyAgent(this.myProxy),
|
940 |
+
redirect: "follow",
|
941 |
+
follow: 10,
|
942 |
+
})
|
943 |
+
.then(res => {
|
944 |
+
const dest = fs.createWriteStream(destination);
|
945 |
+
res.body.pipe(dest);
|
946 |
+
dest.on("finish", () => resolve(destination));
|
947 |
+
})
|
948 |
+
.catch(err => reject(err));
|
949 |
+
});
|
950 |
+
};
|
951 |
+
await fetch(API, {
|
952 |
+
headers: {
|
953 |
+
"User-Agent":
|
954 |
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36",
|
955 |
+
},
|
956 |
+
}).then(async resp => {
|
957 |
+
const html = await resp.text();
|
958 |
+
const desc = html.match(/(?<=content=").*?(?=\")/g)?.[2];
|
959 |
+
const images = html.match(/<div class=\"swiper-slide.*?\">/g);
|
960 |
+
if (!_.isNull(images)) {
|
961 |
+
e.reply(`识别:Insta,${desc || "暂无描述"}\n`);
|
962 |
+
images.map((item, index) => {
|
963 |
+
const imgUrl = /(?<=data-src=").*?(?=")/
|
964 |
+
.exec(item)[0]
|
965 |
+
.replace(/#38/g, "")
|
966 |
+
.replace(/;/g, "");
|
967 |
+
imgPromise.push(downloadImg(imgUrl, `${downloadPath}/${index}.jpg`));
|
968 |
+
});
|
969 |
+
}
|
970 |
+
// TODO 视频,会出bug暂时不做
|
971 |
+
// if (html.includes("data-video")) {
|
972 |
+
// const video = html.match(/(?<=data-video=").*?(?=")/g)[0].replace(/#38/g, "").replace(/;/g, "")
|
973 |
+
// this.downloadVideo(video, true).then(path => {
|
974 |
+
// e.reply(segment.video(path));
|
975 |
+
// })
|
976 |
+
// }
|
977 |
+
});
|
978 |
+
if (imgPromise.length > 0) {
|
979 |
+
let path = [];
|
980 |
+
const images = await Promise.all(imgPromise).then(paths => {
|
981 |
+
return paths.map(item => {
|
982 |
+
path.push(item);
|
983 |
+
return {
|
984 |
+
message: segment.image(fs.readFileSync(item)),
|
985 |
+
nickname: e.sender.card || e.user_id,
|
986 |
+
user_id: e.user_id,
|
987 |
+
};
|
988 |
+
});
|
989 |
+
});
|
990 |
+
await this.reply(await Bot.makeForwardMsg(images));
|
991 |
+
// 清理
|
992 |
+
path.forEach(item => {
|
993 |
+
fs.unlinkSync(item);
|
994 |
+
});
|
995 |
+
}
|
996 |
+
return true;
|
997 |
+
}
|
998 |
+
|
999 |
+
// 波点音乐解析
|
1000 |
+
async bodianMusic(e) {
|
1001 |
+
// 音频例子:https://h5app.kuwo.cn/m/bodian/playMusic.html?uid=3216773&musicId=192015898&opusId=&extendType=together
|
1002 |
+
// 视频例子:https://h5app.kuwo.cn/m/bodian/play.html?uid=3216773&mvId=118987&opusId=770096&extendType=together
|
1003 |
+
const id =
|
1004 |
+
/(?=musicId).*?(?=&)/.exec(e.msg.trim())?.[0].replace("musicId=", "") ||
|
1005 |
+
/(?=mvId).*?(?=&)/.exec(e.msg.trim())?.[0].replace("mvId=", "");
|
1006 |
+
const { name, album, artist, albumPic120, categorys } = await getBodianMusicInfo(id);
|
1007 |
+
e.reply([
|
1008 |
+
`识别:波点音乐,${name}-${album}-${artist}\n标签:${categorys
|
1009 |
+
.map(item => item.name)
|
1010 |
+
.join(" | ")}`,
|
1011 |
+
segment.image(albumPic120),
|
1012 |
+
]);
|
1013 |
+
if (e.msg.includes("musicId")) {
|
1014 |
+
const path = `${this.defaultPath}${this.e.group_id || this.e.user_id}`;
|
1015 |
+
await getBodianAudio(id, path).then(_ => {
|
1016 |
+
Bot.acquireGfs(e.group_id).upload(
|
1017 |
+
fs.readFileSync(path + "/temp.mp3"),
|
1018 |
+
"/",
|
1019 |
+
`${name}-${album}-${artist}.mp3`,
|
1020 |
+
);
|
1021 |
+
});
|
1022 |
+
} else if (e.msg.includes("mvId")) {
|
1023 |
+
await getBodianMv(id).then(res => {
|
1024 |
+
// 下载 && 发送
|
1025 |
+
const { coverUrl, highUrl, lowUrl, shortLowUrl } = res;
|
1026 |
+
this.downloadVideo(lowUrl).then(path => {
|
1027 |
+
e.reply(segment.video(path + "/temp.mp4"));
|
1028 |
+
});
|
1029 |
+
});
|
1030 |
+
}
|
1031 |
+
return true;
|
1032 |
+
}
|
1033 |
+
|
1034 |
+
/**
|
1035 |
+
* 哔哩哔哩下载
|
1036 |
+
* @param title
|
1037 |
+
* @param videoUrl
|
1038 |
+
* @param audioUrl
|
1039 |
+
* @returns {Promise<unknown>}
|
1040 |
+
*/
|
1041 |
+
async downBili(title, videoUrl, audioUrl) {
|
1042 |
+
return Promise.all([
|
1043 |
+
downloadBFile(
|
1044 |
+
videoUrl,
|
1045 |
+
title + "-video.m4s",
|
1046 |
+
_.throttle(
|
1047 |
+
value =>
|
1048 |
+
logger.mark("视频下载进度", {
|
1049 |
+
data: value,
|
1050 |
+
}),
|
1051 |
+
1000,
|
1052 |
+
),
|
1053 |
+
),
|
1054 |
+
downloadBFile(
|
1055 |
+
audioUrl,
|
1056 |
+
title + "-audio.m4s",
|
1057 |
+
_.throttle(
|
1058 |
+
value =>
|
1059 |
+
logger.mark("音频下载进度", {
|
1060 |
+
data: value,
|
1061 |
+
}),
|
1062 |
+
1000,
|
1063 |
+
),
|
1064 |
+
),
|
1065 |
+
]).then(data => {
|
1066 |
+
return mergeFileToMp4(data[0].fullFileName, data[1].fullFileName, `${title}.mp4`);
|
1067 |
+
});
|
1068 |
+
}
|
1069 |
+
|
1070 |
+
/**
|
1071 |
+
* 哔哩哔哩总结
|
1072 |
+
* @returns Promise{string}
|
1073 |
+
* @param videoInfo
|
1074 |
+
*/
|
1075 |
+
async getBiliSummary(videoInfo) {
|
1076 |
+
if (this.biliSessData && this.openaiAccessToken) {
|
1077 |
+
try {
|
1078 |
+
const prompt = await getBiliGptInputText(videoInfo, this.biliSessData);
|
1079 |
+
|
1080 |
+
const response = await this.chatGptClient.sendMessage(prompt);
|
1081 |
+
// 暂时不设计上下文
|
1082 |
+
return response.response
|
1083 |
+
} catch (err) {
|
1084 |
+
logger.error("总结失败,可能是没有弹幕或者网络问题!\n", err);
|
1085 |
+
return ""
|
1086 |
+
}
|
1087 |
+
} else {
|
1088 |
+
return ""
|
1089 |
+
}
|
1090 |
+
}
|
1091 |
+
|
1092 |
+
/**
|
1093 |
+
* 下载一张网络图片(自动以url的最后一个为名字)
|
1094 |
+
* @param img
|
1095 |
+
* @param dir
|
1096 |
+
* @param fileName
|
1097 |
+
* @param isProxy
|
1098 |
+
* @returns {Promise<unknown>}
|
1099 |
+
*/
|
1100 |
+
async downloadImg(img, dir, fileName = "", isProxy = false) {
|
1101 |
+
if (fileName === "") {
|
1102 |
+
fileName = img.split("/").pop();
|
1103 |
+
}
|
1104 |
+
const filepath = `${dir}/${fileName}`;
|
1105 |
+
await mkdirIfNotExists(dir)
|
1106 |
+
const writer = fs.createWriteStream(filepath);
|
1107 |
+
const axiosConfig = {
|
1108 |
+
headers: {
|
1109 |
+
"User-Agent":
|
1110 |
+
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
1111 |
+
},
|
1112 |
+
responseType: "stream",
|
1113 |
+
};
|
1114 |
+
|
1115 |
+
if (isProxy) {
|
1116 |
+
axiosConfig.httpAgent = tunnel.httpOverHttp({
|
1117 |
+
proxy: { host: this.proxyAddr, port: this.proxyPort },
|
1118 |
+
});
|
1119 |
+
axiosConfig.httpsAgent = tunnel.httpOverHttp({
|
1120 |
+
proxy: { host: this.proxyAddr, port: this.proxyPort },
|
1121 |
+
});
|
1122 |
+
}
|
1123 |
+
try {
|
1124 |
+
const res = await axios.get(img, axiosConfig);
|
1125 |
+
res.data.pipe(writer);
|
1126 |
+
|
1127 |
+
return new Promise((resolve, reject) => {
|
1128 |
+
writer.on("finish", () => {
|
1129 |
+
writer.close(() => {
|
1130 |
+
resolve(filepath);
|
1131 |
+
});
|
1132 |
+
});
|
1133 |
+
writer.on("error", err => {
|
1134 |
+
fs.unlink(filepath, () => {
|
1135 |
+
reject(err);
|
1136 |
+
});
|
1137 |
+
});
|
1138 |
+
});
|
1139 |
+
} catch (err) {
|
1140 |
+
logger.error("图片下载失败");
|
1141 |
+
}
|
1142 |
+
}
|
1143 |
+
|
1144 |
+
/**
|
1145 |
+
* douyin 请求参数
|
1146 |
+
* @param url
|
1147 |
+
* @returns {Promise<unknown>}
|
1148 |
+
*/
|
1149 |
+
async douyinRequest(url) {
|
1150 |
+
const params = {
|
1151 |
+
headers: {
|
1152 |
+
"User-Agent":
|
1153 |
+
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
1154 |
+
},
|
1155 |
+
timeout: 10000,
|
1156 |
+
};
|
1157 |
+
try {
|
1158 |
+
const resp = await axios.head(url, params);
|
1159 |
+
const location = resp.request.res.responseUrl;
|
1160 |
+
return location;
|
1161 |
+
} catch (error) {
|
1162 |
+
console.error(error);
|
1163 |
+
throw error;
|
1164 |
+
}
|
1165 |
+
}
|
1166 |
+
|
1167 |
+
/**
|
1168 |
+
* 提取视频下载位置
|
1169 |
+
* @returns {{groupPath: string, target: string}}
|
1170 |
+
*/
|
1171 |
+
getGroupPathAndTarget() {
|
1172 |
+
const groupPath = `${this.defaultPath}${this.e.group_id || this.e.user_id}`;
|
1173 |
+
const target = `${groupPath}/temp.mp4`;
|
1174 |
+
return { groupPath, target };
|
1175 |
+
}
|
1176 |
+
|
1177 |
+
/**
|
1178 |
+
* 工具:根URL据下载视频 / 音频
|
1179 |
+
* @param url 下载地址
|
1180 |
+
* @param isProxy 是否需要魔法
|
1181 |
+
* @param headers 覆盖头节点
|
1182 |
+
* @returns {Promise<unknown>}
|
1183 |
+
*/
|
1184 |
+
async downloadVideo(url, isProxy = false, headers = null) {
|
1185 |
+
const { groupPath, target } = this.getGroupPathAndTarget.call(this);
|
1186 |
+
|
1187 |
+
await mkdirIfNotExists(groupPath);
|
1188 |
+
|
1189 |
+
const userAgent =
|
1190 |
+
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36";
|
1191 |
+
const axiosConfig = {
|
1192 |
+
headers: headers || { "User-Agent": userAgent },
|
1193 |
+
responseType: "stream",
|
1194 |
+
...(isProxy && {
|
1195 |
+
httpAgent: tunnel.httpOverHttp({
|
1196 |
+
proxy: { host: this.proxyAddr, port: this.proxyPort },
|
1197 |
+
}),
|
1198 |
+
httpsAgent: tunnel.httpOverHttp({
|
1199 |
+
proxy: { host: this.proxyAddr, port: this.proxyPort },
|
1200 |
+
}),
|
1201 |
+
}),
|
1202 |
+
};
|
1203 |
+
|
1204 |
+
try {
|
1205 |
+
await checkAndRemoveFile(target);
|
1206 |
+
|
1207 |
+
const res = await axios.get(url, axiosConfig);
|
1208 |
+
logger.mark(`开始下载: ${url}`);
|
1209 |
+
const writer = fs.createWriteStream(target);
|
1210 |
+
res.data.pipe(writer);
|
1211 |
+
|
1212 |
+
return new Promise((resolve, reject) => {
|
1213 |
+
writer.on("finish", () => resolve(groupPath));
|
1214 |
+
writer.on("error", reject);
|
1215 |
+
});
|
1216 |
+
} catch (err) {
|
1217 |
+
logger.error("下载视频发生错误!");
|
1218 |
+
}
|
1219 |
+
}
|
1220 |
+
|
1221 |
+
/**
|
1222 |
+
* 限制用户调用
|
1223 |
+
* @param e
|
1224 |
+
* @param func
|
1225 |
+
* @return {Promise<void>}
|
1226 |
+
*/
|
1227 |
+
async limitUserUse(e, func) {
|
1228 |
+
if (tools.#tokenBucket.consume(e.user_id, 1)) {
|
1229 |
+
await func();
|
1230 |
+
} else {
|
1231 |
+
logger.warn(`解析被限制使用`);
|
1232 |
+
}
|
1233 |
+
}
|
1234 |
+
|
1235 |
+
/**
|
1236 |
+
* 构造安全的命令
|
1237 |
+
* @type {{existsPromptKey: string, existsTransKey: string}}
|
1238 |
+
*/
|
1239 |
+
static Constants = {
|
1240 |
+
existsTransKey: Object.keys(transMap).join("|"),
|
1241 |
+
existsPromptKey: Object.keys(PROMPT_MAP).join("|").slice(0, -1),
|
1242 |
+
};
|
1243 |
+
|
1244 |
+
/**
|
1245 |
+
* 构造令牌桶,防止解析致使服务器宕机(默认限制5s调用一次)
|
1246 |
+
* @type {TokenBucket}
|
1247 |
+
*/
|
1248 |
+
static #tokenBucket = new TokenBucket(1, 1, 5);
|
1249 |
+
}
|