diff --git a/apps/tools.js b/apps/tools.js index b55fefd..5f6b246 100644 --- a/apps/tools.js +++ b/apps/tools.js @@ -7,12 +7,13 @@ import { Buffer } from 'node:buffer'; import fs from "node:fs"; import PQueue from 'p-queue'; import path from "path"; -import qrcode from "qrcode" +import qrcode from "qrcode"; import querystring from "querystring"; import puppeteer from "../../../lib/puppeteer/puppeteer.js"; import { BILI_CDN_SELECT_LIST, - BILI_DEFAULT_INTRO_LEN_LIMIT, BILI_RESOLUTION_LIST, + BILI_DEFAULT_INTRO_LEN_LIMIT, + BILI_RESOLUTION_LIST, COMMON_USER_AGENT, DIVIDING_LINE, douyinTypeMap, @@ -57,9 +58,9 @@ import { XHS_REQ_LINK } from "../constants/tools.js"; import BiliInfoModel from "../model/bili-info.js"; -import NeteaseMusicInfo from '../model/neteaseMusicInfo.js' import config from "../model/config.js"; import NeteaseModel from "../model/netease.js"; +import NeteaseMusicInfo from '../model/neteaseMusicInfo.js'; import * as aBogus from "../utils/a-bogus.cjs"; import { downloadM3u8Videos, mergeAcFileToMp4, parseM3u8, parseUrl } from "../utils/acfun.js"; import { startBBDown } from "../utils/bbdown-util.js"; @@ -105,8 +106,7 @@ import Translate from "../utils/trans-strategy.js"; import { mid2id } from "../utils/weibo.js"; import { convertToSeconds, removeParams, ytbFormatTime } from "../utils/youtube.js"; import { ytDlpGetDuration, ytDlpGetThumbnail, ytDlpGetTilt, ytDlpHelper } from "../utils/yt-dlp-util.js"; -import { textArrayToMakeForward, sendMusicCard } from "../utils/yunzai-util.js"; - +import { textArrayToMakeForward } from "../utils/yunzai-util.js"; export class tools extends plugin { @@ -126,7 +126,7 @@ export class tools extends plugin { priority: 300, rule: [ { - reg: `^(翻|trans)[${tools.Constants.existsTransKey}]`, + reg: `^(翻|trans)[${ tools.Constants.existsTransKey }]`, fnc: "trans", }, { @@ -241,7 +241,7 @@ export class tools extends plugin { // 魔法接口 this.proxyAddr = this.toolsConfig.proxyAddr; this.proxyPort = this.toolsConfig.proxyPort; - this.myProxy = `http://${this.proxyAddr}:${this.proxyPort}`; + this.myProxy = `http://${ this.proxyAddr }:${ this.proxyPort }`; // 加载识别前缀 this.identifyPrefix = this.toolsConfig.identifyPrefix; // 加载直播录制时长 @@ -324,7 +324,7 @@ export class tools extends plugin { ); return; } - let place = msg.slice(1 + language[1].length) + let place = msg.slice(1 + language[1].length); if (_.isEmpty(place)) { const reply = await e?.getReply(); if (reply !== undefined) { @@ -344,7 +344,7 @@ export class tools extends plugin { const urlRex = /(http:\/\/|https:\/\/)(v|live).douyin.com\/[A-Za-z\d._?%&+\-=\/#]*/; // 检测无效链接,例如:v.douyin.com if (!urlRex.test(e.msg)) { - e.reply(`检测到这是一个无效链接,无法解析抖音${HELP_DOC}`); + e.reply(`检测到这是一个无效链接,无法解析抖音${ HELP_DOC }`); return; } // 获取链接 @@ -353,7 +353,7 @@ export class tools extends plugin { if (douUrl.includes("v.douyin.com")) { const { location, ttwidValue } = await this.douyinRequest(douUrl); ttwid = ttwidValue; - douUrl = location + douUrl = location; } // TODO 如果有新的好解决方案可以删除,如果遇到https://www.iesdouyin.com/share/slides,这类动图暂时交付给其他API解析 if (douUrl.includes("share/slides")) { @@ -368,7 +368,7 @@ export class tools extends plugin { /webcast.amemv.com\/douyin\/webcast\/reflow\/(\d+)/.exec(douUrl)?.[1]; // 当前版本需要填入cookie if (_.isEmpty(this.douyinCookie) || _.isEmpty(douId)) { - e.reply(`检测到没有Cookie 或者 这是一个无效链接,无法解析抖音${HELP_DOC}`); + e.reply(`检测到没有Cookie 或者 这是一个无效链接,无法解析抖音${ HELP_DOC }`); return; } // 以下是更新了很多次的抖音API历史,且用且珍惜 @@ -384,16 +384,16 @@ export class tools extends plugin { let dyApi; if (douUrl.includes("live.douyin.com")) { // 第一类直播类型 - dyApi = DY_LIVE_INFO.replaceAll("{}", douId) + dyApi = DY_LIVE_INFO.replaceAll("{}", douId); } else if (douUrl.includes("webcast.amemv.com")) { // 第二类直播类型,这里必须使用客户端的 fetch 请求 - dyApi = DY_LIVE_INFO_2.replace("{}", douId) + `&verifyFp=${genVerifyFp()}` + `&msToken=${ttwid}`; + dyApi = DY_LIVE_INFO_2.replace("{}", douId) + `&verifyFp=${ genVerifyFp() }` + `&msToken=${ ttwid }`; const webcastResp = await fetch(dyApi); const webcastData = await webcastResp.json(); const item = webcastData.data.room; const { title, cover, user_count, stream_url } = item; - const dySendContent = `${this.identifyPrefix}识别:抖音直播,${title}` - e.reply([segment.image(cover?.url_list?.[0]), dySendContent, `\n🏄‍♂️在线人数:${user_count}人正在观看`]); + const dySendContent = `${ this.identifyPrefix }识别:抖音直播,${ title }`; + e.reply([segment.image(cover?.url_list?.[0]), dySendContent, `\n🏄‍♂️在线人数:${ user_count }人正在观看`]); // 下载10s的直播流 await this.sendStreamSegment(e, stream_url?.flv_pull_url?.HD1 || stream_url?.flv_pull_url?.FULL_HD1 || stream_url?.flv_pull_url?.SD1 || stream_url?.flv_pull_url?.SD2); return; @@ -407,8 +407,8 @@ export class tools extends plugin { headers["User-Agent"], ); // const param = resp.data.result[0].paramsencode; - const resDyApi = `${dyApi}&a_bogus=${abParam}`; - headers['Referer'] = `https://www.douyin.com/` + const resDyApi = `${ dyApi }&a_bogus=${ abParam }`; + headers['Referer'] = `https://www.douyin.com/`; // 定义一个dy请求 const dyResponse = () => axios.get(resDyApi, { headers, @@ -421,8 +421,8 @@ export class tools extends plugin { if (douUrl.includes("live")) { const item = await data.data.data?.[0]; const { title, cover, user_count_str, stream_url } = item; - const dySendContent = `${this.identifyPrefix}识别:抖音直播,${title}` - e.reply([segment.image(cover?.url_list?.[0]), dySendContent, `\n🏄‍♂️在线人数:${user_count_str}人正在观看`]); + const dySendContent = `${ this.identifyPrefix }识别:抖音直播,${ title }`; + e.reply([segment.image(cover?.url_list?.[0]), dySendContent, `\n🏄‍♂️在线人数:${ user_count_str }人正在观看`]); // 下载10s的直播流 await this.sendStreamSegment(e, stream_url?.flv_pull_url?.HD1 || stream_url?.flv_pull_url?.FULL_HD1 || stream_url?.flv_pull_url?.SD1 || stream_url?.flv_pull_url?.SD2); return; @@ -445,20 +445,20 @@ export class tools extends plugin { const dyDuration = Math.trunc(duration / 1000); const durationThreshold = this.biliDuration; // 一些共同发送内容 - let dySendContent = `${this.identifyPrefix}识别:抖音,${item.author.nickname}\n📝 简介:${item.desc}`; + let dySendContent = `${ this.identifyPrefix }识别:抖音,${ item.author.nickname }\n📝 简介:${ item.desc }`; if (dyDuration >= durationThreshold) { // 超过阈值,不发送的情况 // 封面 const dyCover = cover.url_list?.pop(); // logger.info(cover.url_list); dySendContent += `\n - ${DIVIDING_LINE.replace('{}', '限制说明')}\n当前视频时长约:${(dyDuration / 60).toFixed(2).replace(/\.00$/, '')} 分钟,\n大于管理员设置的最大时长 ${(durationThreshold / 60).toFixed(2).replace(/\.00$/, '')} 分钟!`; + ${ DIVIDING_LINE.replace('{}', '限制说明') }\n当前视频时长约:${ (dyDuration / 60).toFixed(2).replace(/\.00$/, '') } 分钟,\n大于管理员设置的最大时长 ${ (durationThreshold / 60).toFixed(2).replace(/\.00$/, '') } 分钟!`; e.reply([segment.image(dyCover), dySendContent]); // 如果开启评论的就调用 await this.douyinComment(e, douId, headers); return; } - e.reply(`${dySendContent}`); + e.reply(`${ dySendContent }`); // 分辨率判断是否压缩 const resolution = this.douyinCompression ? "720p" : "1080p"; // 使用今日头条 CDN 进一步加快解析速度 @@ -477,14 +477,14 @@ export class tools extends plugin { }*/ // logger.info(resUrl); - const path = `${this.getCurDownloadPath(e)}/temp.mp4`; + const path = `${ this.getCurDownloadPath(e) }/temp.mp4`; // 加入队列 await this.downloadVideo(resUrl).then(() => { - this.sendVideoToUpload(e, path) + this.sendVideoToUpload(e, path); }); } else if (urlType === "image") { // 发送描述 - e.reply(`${this.identifyPrefix}识别:抖音, ${item.desc}`); + e.reply(`${ this.identifyPrefix }识别:抖音, ${ item.desc }`); // 无水印图片列表 let no_watermark_image_list = []; // 有水印图片列表 @@ -507,7 +507,7 @@ export class tools extends plugin { await this.douyinComment(e, douId, headers); } catch (err) { logger.error(err); - logger.mark(`Cookie 过期或者 Cookie 没有填写,请参考\n${HELP_DOC}\n尝试无效后可以到官方QQ群[575663150]提出 bug 等待解决`) + logger.mark(`Cookie 过期或者 Cookie 没有填写,请参考\n${ HELP_DOC }\n尝试无效后可以到官方QQ群[575663150]提出 bug 等待解决`); } return true; } @@ -519,7 +519,7 @@ export class tools extends plugin { * @param second */ async sendStreamSegment(e, stream_url, second = this.streamDuration) { - let outputFilePath = `${this.getCurDownloadPath(e)}/stream_${second}s.flv`; + let outputFilePath = `${ this.getCurDownloadPath(e) }/stream_${ second }s.flv`; // 删除临时文件 if (this.streamCompatibility) { await checkAndRemoveFile(outputFilePath.replace("flv", "mp4")); @@ -543,7 +543,7 @@ export class tools extends plugin { // 设置 streamDuration 秒后停止下载 setTimeout(async () => { - logger.info(`[R插件][发送直播流] 直播下载 ${second} 秒钟到,停止下载!`); + logger.info(`[R插件][发送直播流] 直播下载 ${ second } 秒钟到,停止下载!`); // 取消请求 source.cancel('[R插件][发送直播流] 下载时间到,停止请求'); response.data.unpipe(file); // 取消管道连接 @@ -571,7 +571,7 @@ export class tools extends plugin { if (axios.isCancel(error)) { logger.info('请求已取消:', error.message); } else { - logger.error(`下载失败: ${error.message}`); + logger.error(`下载失败: ${ error.message }`); } await fs.promises.unlink(outputFilePath); // 下载失败时删除文件 } @@ -592,9 +592,9 @@ export class tools extends plugin { new URLSearchParams(new URL(dyCommentUrl).search).toString(), headers["User-Agent"], ); - const commentsResp = await axios.get(`${dyCommentUrl}&a_bogus=${abParam}`, { + const commentsResp = await axios.get(`${ dyCommentUrl }&a_bogus=${ abParam }`, { headers - }) + }); // logger.info(headers) // saveJsonToFile(commentsResp.data, "data.json", _); const comments = commentsResp.data.comments; @@ -603,8 +603,8 @@ export class tools extends plugin { message: item.text, nickname: this.e.sender.card || this.e.user_id, user_id: this.e.user_id, - } - }) + }; + }); e.reply(await Bot.makeForwardMsg(replyComments)); } @@ -627,9 +627,9 @@ export class tools extends plugin { const path = this.getCurDownloadPath(e); await checkAndRemoveFile(path + "/temp.mp4"); const title = ytDlpGetTilt(url, isOversea, this.myProxy); - e.reply(`${this.identifyPrefix}识别:TikTok,视频下载中请耐心等待 \n${title}`); + e.reply(`${ this.identifyPrefix }识别:TikTok,视频下载中请耐心等待 \n${ title }`); await ytDlpHelper(path, cleanedTiktokUrl, isOversea, this.myProxy, this.videoDownloadConcurrency); - await this.sendVideoToUpload(e, `${path}/temp.mp4`); + await this.sendVideoToUpload(e, `${ path }/temp.mp4`); return true; } @@ -639,18 +639,18 @@ export class tools extends plugin { e.reply('R插件开源免责声明:\n您将通过扫码完成获取哔哩哔哩refresh_token以及ck。\n本Bot将不会保存您的登录状态。\n我方仅提供视频解析及相关B站内容服务,若您的账号封禁、被盗等处罚与我方无关。\n害怕风险请勿扫码 ~', { recallMsg: 180 }); // 图片发送钩子 const imgSendHook = function (e, path) { - e.reply([segment.image(path), segment.at(e.user_id), '请扫码以完成获取'], { recallMsg: 180 }) + e.reply([segment.image(path), segment.at(e.user_id), '请扫码以完成获取'], { recallMsg: 180 }); }; // 检查路径是否存在文件夹 await mkdirIfNotExists(this.defaultPath); // 发送请求 - const saveCodePath = `${this.defaultPath}qrcode.png`; + const saveCodePath = `${ this.defaultPath }qrcode.png`; - const { SESSDATA, refresh_token } = await getScanCodeData(saveCodePath, 8, () => imgSendHook(e, saveCodePath)) + const { SESSDATA, refresh_token } = await getScanCodeData(saveCodePath, 8, () => imgSendHook(e, saveCodePath)); // 更新到配置文件 config.updateField("tools", "biliSessData", SESSDATA); - e.reply('登录成功!相关信息已保存至配置文件', true) + e.reply('登录成功!相关信息已保存至配置文件', true); return true; } @@ -666,7 +666,7 @@ export class tools extends plugin { try { const res = await fetch(url, { headers: { - Cookie: `SESSDATA=${this.biliSessData}` + Cookie: `SESSDATA=${ this.biliSessData }` } }); const data = await res.json(); @@ -717,8 +717,8 @@ export class tools extends plugin { let url = e.msg === undefined ? e.message.shift().data.replaceAll("\\", "") : e.msg.trim().replaceAll("\\", ""); // 直接发送BV号的处理 if (/^BV[1-9a-zA-Z]{10}$/.exec(url)?.[0]) { - url = `https://www.bilibili.com/video/${url}`; - logger.info(url) + url = `https://www.bilibili.com/video/${ url }`; + logger.info(url); } // 短号处理 if (url.includes("b23.tv")) { @@ -762,11 +762,11 @@ export class tools extends plugin { e.reply([ segment.image(user_cover), segment.image(keyframe), - [`${this.identifyPrefix}识别:哔哩哔哩直播,${title}`, - `${description ? `📝 简述:${description.replace(`<p>`, '').replace(`</p>`, '')}` : ''}`, - `${tags ? `🔖 标签:${tags}` : ''}`, - `📍 分区:${parent_area_name ? `${parent_area_name}` : ''}${area_name ? `-${area_name}` : ''}`, - `${live_time ? `⏰ 直播时间:${live_time}` : ''}`, + [`${ this.identifyPrefix }识别:哔哩哔哩直播,${ title }`, + `${ description ? `📝 简述:${ description.replace(`<p>`, '').replace(`</p>`, '') }` : '' }`, + `${ tags ? `🔖 标签:${ tags }` : '' }`, + `📍 分区:${ parent_area_name ? `${ parent_area_name }` : '' }${ area_name ? `-${ area_name }` : '' }`, + `${ live_time ? `⏰ 直播时间:${ live_time }` : '' }`, ].filter(item => item.trim() !== "").join("\n") ]); const streamData = await this.getBiliStream(streamId); @@ -789,7 +789,7 @@ export class tools extends plugin { return true; } // 创建文件,如果不存在, - const path = `${this.getCurDownloadPath(e)}/`; + const path = `${ this.getCurDownloadPath(e) }/`; await mkdirIfNotExists(path); // 处理番剧 if (url.includes("play\/ep") || url.includes("play\/ss")) { @@ -797,7 +797,7 @@ export class tools extends plugin { // 如果使用了BBDown && 没有填写session 就放开下载 if (this.biliUseBBDown) { // 下载文件 - await this.biliDownloadStrategy(e, `https://www.bilibili.com/bangumi/play/ep${ep}`, path); + await this.biliDownloadStrategy(e, `https://www.bilibili.com/bangumi/play/ep${ ep }`, path); } return true; } @@ -809,7 +809,7 @@ export class tools extends plugin { const query = querystring.parse(url); const curPage = query?.p || 0; const curDuration = pages?.[curPage]?.duration || duration; - const isLimitDuration = curDuration > this.biliDuration + const isLimitDuration = curDuration > this.biliDuration; // 动态构造哔哩哔哩信息 let biliInfo = await this.constructBiliInfo(videoInfo); // 总结 @@ -821,7 +821,7 @@ export class tools extends plugin { // 限制视频解析 if (isLimitDuration) { const durationInMinutes = (curDuration / 60).toFixed(0); - biliInfo.push(`${DIVIDING_LINE.replace('{}', '限制说明')}\n当前视频时长约:${durationInMinutes}分钟,\n大于管理员设置的最大时长 ${(this.biliDuration / 60).toFixed(2).replace(/\.00$/, '')} 分钟!`); + biliInfo.push(`${ DIVIDING_LINE.replace('{}', '限制说明') }\n当前视频时长约:${ durationInMinutes }分钟,\n大于管理员设置的最大时长 ${ (this.biliDuration / 60).toFixed(2).replace(/\.00$/, '') } 分钟!`); e.reply(biliInfo); return true; } else { @@ -853,16 +853,16 @@ export class tools extends plugin { const { title, author_name, origin_image_urls } = articleData; if (origin_image_urls) { const titleMsg = { - message: { type: "text", text: `标题:${title}\n作者:${author_name}` }, + message: { type: "text", text: `标题:${ title }\n作者:${ author_name }` }, nickname: e.sender.card || e.user_id, user_id: e.user_id, - } + }; await e.reply(Bot.makeForwardMsg(origin_image_urls.map(item => { return { message: segment.image(item), nickname: e.sender.card || e.user_id, user_id: e.user_id, - } + }; }).concat(titleMsg))); } } @@ -890,21 +890,21 @@ export class tools extends plugin { "弹幕数量": danmaku, "评论": reply }; - combineContent += `\n${formatBiliInfo(dataProcessMap)}`; + combineContent += `\n${ formatBiliInfo(dataProcessMap) }`; } // 是否显示简介 if (this.biliDisplayIntro) { // 过滤简介中的一些链接 const filteredDesc = await filterBiliDescLink(desc); - combineContent += `\n📝 简介:${truncateString(filteredDesc, this.toolsConfig.biliIntroLenLimit || BILI_DEFAULT_INTRO_LEN_LIMIT)}`; + combineContent += `\n📝 简介:${ truncateString(filteredDesc, this.toolsConfig.biliIntroLenLimit || BILI_DEFAULT_INTRO_LEN_LIMIT) }`; } // 是否显示在线人数 if (this.biliDisplayOnline) { // 拼接在线人数 const onlineTotal = await this.biliOnlineTotal(bvid, cid); - combineContent += `\n🏄‍♂️️ 当前视频有 ${onlineTotal.total} 人在观看,其中 ${onlineTotal.count} 人在网页端观看`; + combineContent += `\n🏄‍♂️️ 当前视频有 ${ onlineTotal.total } 人在观看,其中 ${ onlineTotal.count } 人在网页端观看`; } - let biliInfo = [`${this.identifyPrefix}识别:哔哩哔哩,${title}`, combineContent] + let biliInfo = [`${ this.identifyPrefix }识别:哔哩哔哩,${ title }`, combineContent]; // 是否显示封面 if (this.biliDisplayCover) { // 加入图片 @@ -926,8 +926,8 @@ export class tools extends plugin { const ssid = url.match(/\/ss(\d+)/)?.[1]; let resp = await (await fetch(BILI_SSID_INFO.replace("{}", ssid), { headers: BILI_HEADER - })).json() - ep = (resp.result.main_section.episodes[0].share_url).replace("https://www.bilibili.com/bangumi/play/ep", "") + })).json(); + ep = (resp.result.main_section.episodes[0].share_url).replace("https://www.bilibili.com/bangumi/play/ep", ""); } // 处理普通情况,上述情况无法处理的 if (_.isEmpty(ep)) { @@ -951,10 +951,10 @@ export class tools extends plugin { const title = result.title; e.reply([ segment.image(resp.result.cover), - `${this.identifyPrefix}识别:哔哩哔哩番剧,${title}\n🎯 评分: ${result?.rating?.score ?? '-'} / ${result?.rating?.count ?? '-'}\n📺 ${result.new_ep.desc}, ${result.seasons[0].new_ep.index_show}\n`, - `${formatBiliInfo(dataProcessMap)}`, - `\n\n🪶 在线观看: ${await urlTransformShortLink(ANIME_SERIES_SEARCH_LINK + title)}`, - `\n🌸 在线观看: ${await urlTransformShortLink(ANIME_SERIES_SEARCH_LINK2 + title)}` + `${ this.identifyPrefix }识别:哔哩哔哩番剧,${ title }\n🎯 评分: ${ result?.rating?.score ?? '-' } / ${ result?.rating?.count ?? '-' }\n📺 ${ result.new_ep.desc }, ${ result.seasons[0].new_ep.index_show }\n`, + `${ formatBiliInfo(dataProcessMap) }`, + `\n\n🪶 在线观看: ${ await urlTransformShortLink(ANIME_SERIES_SEARCH_LINK + title) }`, + `\n🌸 在线观看: ${ await urlTransformShortLink(ANIME_SERIES_SEARCH_LINK2 + title) }` ], true); return ep; } @@ -970,7 +970,7 @@ export class tools extends plugin { return this.queue.add(async () => { // =================以下是调用BBDown的逻辑===================== // 下载视频和音频 - const tempPath = `${path}temp`; + const tempPath = `${ path }temp`; // 检测是否开启BBDown if (this.biliUseBBDown) { // 检测环境的 BBDown @@ -978,7 +978,7 @@ export class tools extends plugin { // 存在 BBDown if (isExistBBDown) { // 删除之前的文件 - await checkAndRemoveFile(`${tempPath}.mp4`); + await checkAndRemoveFile(`${ tempPath }.mp4`); // 下载视频 await startBBDown(url, path, { biliSessData: this.biliSessData, @@ -987,7 +987,7 @@ export class tools extends plugin { biliResolution: this.biliResolution, }); // 发送视频 - return this.sendVideoToUpload(e, `${tempPath}.mp4`); + return this.sendVideoToUpload(e, `${ tempPath }.mp4`); } e.reply("🚧 R插件提醒你:开启但未检测到当前环境有【BBDown】,即将使用默认下载方式 ( ◡̀_◡́)ᕤ"); } @@ -1002,7 +1002,7 @@ export class tools extends plugin { await this.downBili(tempPath, data.videoUrl, data.audioUrl); } else { // 处理无音频的情况 - await downloadBFile(data.videoUrl, `${tempPath}.mp4`, _.throttle( + await downloadBFile(data.videoUrl, `${ tempPath }.mp4`, _.throttle( value => logger.mark("视频下载进度", { data: value, @@ -1012,13 +1012,13 @@ export class tools extends plugin { } // 上传视频 - return this.sendVideoToUpload(e, `${tempPath}.mp4`); + return this.sendVideoToUpload(e, `${ tempPath }.mp4`); } catch (err) { // 错误处理 logger.error('[R插件][哔哩哔哩视频发送]下载错误,具体原因为:', err); e.reply("解析失败,请重试一下"); } - }) + }); } /** @@ -1033,7 +1033,7 @@ export class tools extends plugin { return { total: online.total, count: online.count - } + }; } // 下载哔哩哔哩音乐 @@ -1042,14 +1042,14 @@ export class tools extends plugin { this.queue.add(() => { getBiliAudio(videoId, "").then(async audioUrl => { const path = this.getCurDownloadPath(e); - const biliMusicPath = await m4sToMp3(audioUrl, path) + const biliMusicPath = await m4sToMp3(audioUrl, path); // 发送语音 e.reply(segment.record(biliMusicPath)); // 上传群文件 await this.uploadGroupFile(e, biliMusicPath); - }) - }) - return true + }); + }); + return true; } // 发送哔哩哔哩动态的算法 @@ -1061,7 +1061,7 @@ export class tools extends plugin { const dynamicId = /[^/]+(?!.*\/)/.exec(url)[0]; getDynamic(dynamicId, session).then(async resp => { if (resp.dynamicSrc.length > 0 || resp.dynamicDesc) { - e.reply(`${this.identifyPrefix}识别:哔哩哔哩动态\n${resp.dynamicDesc}`); + e.reply(`${ this.identifyPrefix }识别:哔哩哔哩动态\n${ resp.dynamicDesc }`); let dynamicSrcMsg = []; resp.dynamicSrc.forEach(item => { dynamicSrcMsg.push({ @@ -1089,13 +1089,13 @@ export class tools extends plugin { */ async getBiliSummary(bvid, cid, up_mid) { // 这个有点用,但不多 - let wbi = "wts=1701546363&w_rid=1073871926b3ccd99bd790f0162af634" + let wbi = "wts=1701546363&w_rid=1073871926b3ccd99bd790f0162af634"; if (!_.isEmpty(this.biliSessData)) { wbi = await getWbi({ bvid, cid, up_mid }, this.biliSessData); } // 构造API - const summaryUrl = `${BILI_SUMMARY}?${wbi}`; - logger.info(summaryUrl) + const summaryUrl = `${ BILI_SUMMARY }?${ wbi }`; + logger.info(summaryUrl); // 构造结果:https://api.bilibili.com/x/web-interface/view/conclusion/get?bvid=BV1L94y1H7CV&cid=1335073288&up_mid=297242063&wts=1701546363&w_rid=1073871926b3ccd99bd790f0162af634 return axios.get(summaryUrl) .then(resp => { @@ -1106,7 +1106,7 @@ export class tools extends plugin { let resReply = ""; // 总体总结 if (summary) { - resReply = `\n摘要:${summary}\n` + resReply = `\n摘要:${ summary }\n`; } // 分段总结 if (outline) { @@ -1115,16 +1115,16 @@ export class tools extends plugin { const keyPoint = item?.part_outline; // 时间点的总结 const specificContent = keyPoint.map(point => { - const { timestamp, content } = point - const specificTime = secondsToTime(timestamp) - return `${specificTime} ${content}\n`; + const { timestamp, content } = point; + const specificTime = secondsToTime(timestamp); + return `${ specificTime } ${ content }\n`; }).join(""); - return `- ${smallTitle}\n${specificContent}\n`; + return `- ${ smallTitle }\n${ specificContent }\n`; }); resReply += specificTimeSummary.join(""); } return resReply; - }) + }); } /** @@ -1133,7 +1133,7 @@ export class tools extends plugin { * @returns {Promise<*>} */ async getBiliStreamInfo(liveId) { - return axios.get(`${BILI_STREAM_INFO}?room_id=${liveId}`, { + return axios.get(`${ BILI_STREAM_INFO }?room_id=${ liveId }`, { headers: { 'User-Agent': COMMON_USER_AGENT, } @@ -1146,7 +1146,7 @@ export class tools extends plugin { * @returns {Promise<*>} */ async getBiliStream(liveId) { - return axios.get(`${BILI_STREAM_FLV}?cid=${liveId}`, { + return axios.get(`${ BILI_STREAM_FLV }?cid=${ liveId }`, { headers: { 'User-Agent': COMMON_USER_AGENT, } @@ -1171,18 +1171,18 @@ export class tools extends plugin { "media.fields": "duration_ms,height,media_key,preview_image_url,public_metrics,type,url,width,alt_text,variants", "expansions": ["entities.mentions.username", "attachments.media_keys"], - } + }; await fetch(TWITTER_TWEET_INFO.replace("{}", id), { headers: { "User-Agent": "v2TweetLookupJS", - "authorization": `Bearer ${Buffer.from(TWITTER_BEARER_TOKEN, "base64").toString()}` + "authorization": `Bearer ${ Buffer.from(TWITTER_BEARER_TOKEN, "base64").toString() }` }, ...params, agent: !isOversea ? '' : new HttpsProxyAgent(this.myProxy), }).then(async resp => { - logger.info(resp) - e.reply(`${this.identifyPrefix}识别:小蓝鸟学习版,${resp.data.text}`); - const downloadPath = `${this.getCurDownloadPath(e)}`; + logger.info(resp); + e.reply(`${ this.identifyPrefix }识别:小蓝鸟学习版,${ resp.data.text }`); + const downloadPath = `${ this.getCurDownloadPath(e) }`; // 创建文件夹(如果没有过这个群) if (!fs.existsSync(downloadPath)) { mkdirsSync(downloadPath); @@ -1197,7 +1197,7 @@ export class tools extends plugin { // 视频 await this.downloadVideo(resp.includes.media[0].variants[0].url, true).then( _ => { - e.reply(segment.video(`${downloadPath}/temp.mp4`)); + e.reply(segment.video(`${ downloadPath }/temp.mp4`)); }, ); } @@ -1247,7 +1247,7 @@ export class tools extends plugin { } // 提取视频 let videoUrl = GENERAL_REQ_LINK.link.replace("{}", twitterUrl); - e.reply(`${this.identifyPrefix}识别:小蓝鸟学习版`); + e.reply(`${ this.identifyPrefix }识别:小蓝鸟学习版`); const config = { headers: { 'Accept': 'ext/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', @@ -1259,7 +1259,7 @@ export class tools extends plugin { 'User-Agent': COMMON_USER_AGENT, }, timeout: 10000 // 设置超时时间 - } + }; let resp = await axios.get(videoUrl, config); if (resp.data.data == null) { @@ -1284,7 +1284,7 @@ export class tools extends plugin { proxyPort: this.proxyPort }, downloadMethod: this.biliDownloadMethod, - }) + }); e.reply(segment.image(xImgPath)); } } else { @@ -1297,24 +1297,24 @@ export class tools extends plugin { // acfun解析 async acfun(e) { - const path = `${this.getCurDownloadPath(e)}/temp/`; + const path = `${ this.getCurDownloadPath(e) }/temp/`; await mkdirIfNotExists(path); let inputMsg = e.msg; // 适配手机分享:https://m.acfun.cn/v/?ac=32838812&sid=d2b0991bd6ad9c09 if (inputMsg.includes("m.acfun.cn")) { - inputMsg = `https://www.acfun.cn/v/ac${/ac=([^&?]*)/.exec(inputMsg)[1]}`; + inputMsg = `https://www.acfun.cn/v/ac${ /ac=([^&?]*)/.exec(inputMsg)[1] }`; } else if (inputMsg.includes("ac")) { // 如果是 inputMsg = "https://www.acfun.cn/v/" + /ac\d+/.exec(inputMsg)[0]; } parseUrl(inputMsg).then(res => { - e.reply(`${this.identifyPrefix}识别:猴山,${res.videoName}`); + e.reply(`${ this.identifyPrefix }识别:猴山,${ res.videoName }`); parseM3u8(res.urlM3u8s[res.urlM3u8s.length - 1]).then(res2 => { downloadM3u8Videos(res2.m3u8FullUrls, path).then(_ => { - mergeAcFileToMp4(res2.tsNames, path, `${path}out.mp4`).then(_ => { - this.sendVideoToUpload(e, `${path}out.mp4`) + mergeAcFileToMp4(res2.tsNames, path, `${ path }out.mp4`).then(_ => { + this.sendVideoToUpload(e, `${ path }out.mp4`); }); }); }); @@ -1337,7 +1337,7 @@ export class tools extends plugin { )?.[0] || /(http:|https:)\/\/www\.xiaohongshu\.com\/discovery\/item\/(\w+)/.exec( e.msg, - )?.[0] + )?.[0]; // 注入ck XHS_NO_WATERMARK_HEADER.cookie = this.xiaohongshuCookie; // 解析短号 @@ -1370,14 +1370,14 @@ export class tools extends plugin { xsecSource = parsedUrl.searchParams.get("xsec_source") ?? "pc_feed"; xsecToken = parsedUrl.searchParams.get("xsec_token"); } - const downloadPath = `${this.getCurDownloadPath(e)}`; + const downloadPath = `${ this.getCurDownloadPath(e) }`; // 检测没有 cookie 则退出 if (_.isEmpty(this.xiaohongshuCookie) || _.isEmpty(id) || _.isEmpty(xsecToken) || _.isEmpty(xsecSource)) { - e.reply(`请检查以下问题:\n1. 是否填写 Cookie\n2. 链接是否有id\n3. 链接是否有 xsec_token 和 xsec_source\n${HELP_DOC}`); + e.reply(`请检查以下问题:\n1. 是否填写 Cookie\n2. 链接是否有id\n3. 链接是否有 xsec_token 和 xsec_source\n${ HELP_DOC }`); return; } // 获取信息 - const resp = await fetch(`${XHS_REQ_LINK}${id}?xsec_token=${xsecToken}&xsec_source=${xsecSource}`, { + const resp = await fetch(`${ XHS_REQ_LINK }${ id }?xsec_token=${ xsecToken }&xsec_source=${ xsecSource }`, { headers: XHS_NO_WATERMARK_HEADER, }); // 从网页获取数据 @@ -1388,7 +1388,7 @@ export class tools extends plugin { // saveJsonToFile(resJson); // 检测无效 Cookie if (resJson?.note === undefined || resJson?.note?.noteDetailMap?.[id]?.note === undefined) { - e.reply(`检测到无效的小红书 Cookie,可以尝试清除缓存和cookie 或者 换一个浏览器进行获取\n${HELP_DOC}`); + e.reply(`检测到无效的小红书 Cookie,可以尝试清除缓存和cookie 或者 换一个浏览器进行获取\n${ HELP_DOC }`); return; } // 提取出数据 @@ -1397,7 +1397,7 @@ export class tools extends plugin { if (type === "video") { // 封面 const cover = noteData.imageList?.[0].urlDefault; - e.reply([segment.image(cover), `${this.identifyPrefix}识别:小红书, ${title}\n${desc}`]); + e.reply([segment.image(cover), `${ this.identifyPrefix }识别:小红书, ${ title }\n${ desc }`]); // ⚠️ (暂时废弃)构造xhs视频链接(有水印) const xhsVideoUrl = noteData.video.media.stream.h264?.[0]?.masterUrl; @@ -1407,20 +1407,20 @@ export class tools extends plugin { this.downloadVideo(xhsVideoUrl).then(path => { if (path === undefined) { // 创建文件,如果不存在 - path = `${this.getCurDownloadPath(e)}/`; + path = `${ this.getCurDownloadPath(e) }/`; } - this.sendVideoToUpload(e, `${path}/temp.mp4`) + this.sendVideoToUpload(e, `${ path }/temp.mp4`); }); return true; } else if (type === "normal") { - e.reply(`${this.identifyPrefix}识别:小红书, ${title}\n${desc}`); + e.reply(`${ this.identifyPrefix }识别:小红书, ${ title }\n${ desc }`); const imagePromises = []; // 使用 for..of 循环处理异步下载操作 for (let [index, item] of noteData.imageList.entries()) { imagePromises.push(downloadImg({ img: item.urlDefault, dir: downloadPath, - fileName: `${index}.png`, + fileName: `${ index }.png`, downloadMethod: this.biliDownloadMethod, })); } @@ -1454,14 +1454,14 @@ export class tools extends plugin { /(?=mvId).*?(?=&)/.exec(e.msg.trim())?.[0].replace("mvId=", ""); const { name, album, artist, albumPic120, categorys } = await getBodianMusicInfo(id); e.reply([ - `${this.identifyPrefix}识别:波点音乐,${name}-${album}-${artist}\n标签:${categorys + `${ this.identifyPrefix }识别:波点音乐,${ name }-${ album }-${ artist }\n标签:${ categorys .map(item => item.name) - .join(" | ")}`, + .join(" | ") }`, segment.image(albumPic120), ]); if (e.msg.includes("musicId")) { - const path = `${this.getCurDownloadPath(e)}`; - await getBodianAudio(id, path, `${name}-${artist}`).then(sendPath => { + const path = `${ this.getCurDownloadPath(e) }`; + await getBodianAudio(id, path, `${ name }-${ artist }`).then(sendPath => { // 发送语音 e.reply(segment.record(sendPath)); // 上传群文件 @@ -1485,7 +1485,7 @@ export class tools extends plugin { async neteaseStatus(e, reck) { // 优先判断是否使用自建 API let autoSelectNeteaseApi = this.useLocalNeteaseAPI ? this.neteaseCloudAPIServer : (await this.isOverseasServer() ? NETEASE_SONG_DOWNLOAD : NETEASE_API_CN); - const statusUrl = `${autoSelectNeteaseApi}/login/status`; + const statusUrl = `${ autoSelectNeteaseApi }/login/status`; try { const statusResponse = await axios.get(statusUrl, { @@ -1500,7 +1500,7 @@ export class tools extends plugin { return; } - const vipResponse = await axios.get(`${autoSelectNeteaseApi}/vip/info?uid=${userInfo.userId}`, { + const vipResponse = await axios.get(`${ autoSelectNeteaseApi }/vip/info?uid=${ userInfo.userId }`, { headers: { "User-Agent": COMMON_USER_AGENT, "Cookie": reck ? reck : this.neteaseCookie, @@ -1513,7 +1513,7 @@ export class tools extends plugin { if (expireDate > Date.now()) { const vipLevelData = vipLevel.split("\n"); const neteaseData = await new NeteaseModel(e).getData({ - avatarUrl: `${avatarUrl}?param=170y170`, + avatarUrl: `${ avatarUrl }?param=170y170`, nickname, vipLevel: vipLevelData[0], musicQuality: vipLevelData[2], @@ -1526,18 +1526,18 @@ export class tools extends plugin { return false; }; - if (vipInfo.redplus.vipCode !== 0 && await checkVipStatus(`SVIP${vipInfo.redplus.vipLevel}\n最高解析音质:\n jymaster(超清母带)`, vipInfo.redplus.expireTime, userInfo.nickname, userInfo.avatarUrl)) { + if (vipInfo.redplus.vipCode !== 0 && await checkVipStatus(`SVIP${ vipInfo.redplus.vipLevel }\n最高解析音质:\n jymaster(超清母带)`, vipInfo.redplus.expireTime, userInfo.nickname, userInfo.avatarUrl)) { return; } - if (vipInfo.associator.vipCode !== 0 && await checkVipStatus(`VIP${vipInfo.associator.vipLevel}\n最高解析音质:\n jyeffect(高清环绕音)`, vipInfo.associator.expireTime, userInfo.nickname, userInfo.avatarUrl)) { + if (vipInfo.associator.vipCode !== 0 && await checkVipStatus(`VIP${ vipInfo.associator.vipLevel }\n最高解析音质:\n jyeffect(高清环绕音)`, vipInfo.associator.expireTime, userInfo.nickname, userInfo.avatarUrl)) { return; } // 如果都已过期,发送 VIP 已过期信息 const neteaseData = await new NeteaseModel(e).getData({ - avatarUrl: `${userInfo.avatarUrl}?param=170y170`, + avatarUrl: `${ userInfo.avatarUrl }?param=170y170`, nickname: userInfo.nickname, - vipLevel: vipInfo.redplus.vipCode !== 0 ? `SVIP${vipInfo.redplus.vipLevel}(已过期)` : vipInfo.associator.vipCode !== 0 ? `VIP${vipInfo.associator.vipLevel}(已过期)` : '未开通', + vipLevel: vipInfo.redplus.vipCode !== 0 ? `SVIP${ vipInfo.redplus.vipLevel }(已过期)` : vipInfo.associator.vipCode !== 0 ? `VIP${ vipInfo.associator.vipLevel }(已过期)` : '未开通', musicQuality: 'standard(标准)', expireDate: '未开通', }); @@ -1557,7 +1557,7 @@ export class tools extends plugin { const pollRequest = async () => { try { - const pollUrl = `${autoSelectNeteaseApi}/login/qr/check?key=${unikey}×tamp=${Date.now()}`; + const pollUrl = `${ autoSelectNeteaseApi }/login/qr/check?key=${ unikey }×tamp=${ Date.now() }`; const res = await axios.get(pollUrl, { headers: { "User-Agent": COMMON_USER_AGENT } }); if (res.data.code == '800') { @@ -1571,7 +1571,7 @@ export class tools extends plugin { const match = res.data.cookie.match(regex); if (match) { try { - const ck = `${match[0]}; os=pc`; + const ck = `${ match[0] }; os=pc`; await config.updateField("tools", "neteaseCookie", ck); this.neteaseStatus(e, ck); e.reply(`扫码登录成功,ck已自动保存`); @@ -1605,24 +1605,24 @@ export class tools extends plugin { try { // 优先判断是否使用自建 API const isOversea = await this.isOverseasServer(); - let autoSelectNeteaseApi + let autoSelectNeteaseApi; if (this.useLocalNeteaseAPI) { - autoSelectNeteaseApi = this.neteaseCloudAPIServer + autoSelectNeteaseApi = this.neteaseCloudAPIServer; } else { - autoSelectNeteaseApi = (isOversea ? NETEASE_SONG_DOWNLOAD : NETEASE_API_CN) + autoSelectNeteaseApi = (isOversea ? NETEASE_SONG_DOWNLOAD : NETEASE_API_CN); await e.reply('未使用自建服务器,高概率#rnq失败'); } // 获取登录key - const keyUrl = `${autoSelectNeteaseApi}/login/qr/key`; + const keyUrl = `${ autoSelectNeteaseApi }/login/qr/key`; const keyResponse = await axios.get(keyUrl, { headers: { "User-Agent": COMMON_USER_AGENT } }); const unikey = keyResponse.data.data.unikey; // 获取登录二维码 - const qrUrl = `${autoSelectNeteaseApi}/login/qr/create?key=${unikey}&qrimg=true`; + const qrUrl = `${ autoSelectNeteaseApi }/login/qr/create?key=${ unikey }&qrimg=true`; const qrResponse = await axios.get(qrUrl, { headers: { "User-Agent": COMMON_USER_AGENT } }); await mkdirIfNotExists(this.defaultPath); - const saveCodePath = `${this.defaultPath}NeteaseQrcode.png`; + const saveCodePath = `${ this.defaultPath }NeteaseQrcode.png`; await qrcode.toFile(saveCodePath, qrResponse.data.data.qrurl); e.reply([segment.image(saveCodePath), '请在40秒内使用网易云APP进行扫码']); @@ -1631,10 +1631,10 @@ export class tools extends plugin { } catch (error) { if (error.code == 'ERR_INVALID_URL') { logger.error('执行网易云扫码登录时出错:非法地址,请检查API服务地址', error); - e.reply(`执行网易云扫码登录时出错${error.code}请检查API服务器地址`); + e.reply(`执行网易云扫码登录时出错${ error.code }请检查API服务器地址`); } else if (error.code == 'ECONNRESET') { logger.error('执行网易云扫码登录时出错:API请求错误,请检查API服务状态', error); - e.reply(`执行扫码登录时发生错误${error.code}请检查API服务状态`); + e.reply(`执行扫码登录时发生错误${ error.code }请检查API服务状态`); } else { logger.error('执行网易云扫码登录时出错:', error); e.reply('执行扫码登录时发生错误,请稍后再试'); @@ -1648,7 +1648,7 @@ export class tools extends plugin { e.msg === undefined ? e.message.shift().data.replaceAll("\\", "") : e.msg.trim(); // 处理短号,此时会变成y.music.163.com if (message.includes("163cn.tv")) { - message = /(http:|https:)\/\/163cn\.tv\/([a-zA-Z0-9]+)/.exec(message)?.[0] + message = /(http:|https:)\/\/163cn\.tv\/([a-zA-Z0-9]+)/.exec(message)?.[0]; // logger.info(message) message = await axios.head(message).then((resp) => { return resp.request.res.responseUrl; @@ -1666,37 +1666,37 @@ export class tools extends plugin { // 如果没有下载地址跳出if if (_.isEmpty(id)) { e.reply(`识别:网易云音乐,解析失败!`); - logger.error("[R插件][网易云解析] 没有找到id,无法进行下一步!") - return + logger.error("[R插件][网易云解析] 没有找到id,无法进行下一步!"); + return; } // 优先判断是否使用自建 API - let autoSelectNeteaseApi + let autoSelectNeteaseApi; // 判断海外 const isOversea = await this.isOverseasServer(); if (this.useLocalNeteaseAPI) { // 使用自建 API - autoSelectNeteaseApi = this.neteaseCloudAPIServer + autoSelectNeteaseApi = this.neteaseCloudAPIServer; } else { // 自动选择 API autoSelectNeteaseApi = isOversea ? NETEASE_SONG_DOWNLOAD : NETEASE_API_CN; } // 检测ck可用性 - const statusUrl = autoSelectNeteaseApi + '/login/status' + const statusUrl = autoSelectNeteaseApi + '/login/status'; const isCkExpired = await axios.get(statusUrl, { headers: { "User-Agent": COMMON_USER_AGENT, "Cookie": this.neteaseCookie }, }).then(res => { - const userInfo = res.data.data.profile + const userInfo = res.data.data.profile; if (userInfo) { - logger.info('[R插件][netease]ck活着,使用ck进行高音质下载') - return true + logger.info('[R插件][netease]ck活着,使用ck进行高音质下载'); + return true; } else { - logger.info('[R插件][netease]ck失效,将启用临时接口下载') - return false + logger.info('[R插件][netease]ck失效,将启用临时接口下载'); + return false; } - }) + }); // mv截断 if (/mv\?/.test(message)) { const AUTO_NETEASE_MV_DETAIL = autoSelectNeteaseApi + "/mv/detail?mvid={}"; @@ -1719,21 +1719,21 @@ export class tools extends plugin { }) ]); const { name: mvName, artistName: mvArtist, cover: mvCover } = mvDetailData.data?.data; - e.reply([segment.image(mvCover), `${this.identifyPrefix}识别:网易云MV,${mvName} - ${mvArtist}`]); + e.reply([segment.image(mvCover), `${ this.identifyPrefix }识别:网易云MV,${ mvName } - ${ mvArtist }`]); // logger.info(mvUrlData.data) const { url: mvUrl } = mvUrlData.data?.data; this.downloadVideo(mvUrl).then(path => { - this.sendVideoToUpload(e, `${path}/temp.mp4`) + this.sendVideoToUpload(e, `${ path }/temp.mp4`); }); return; } - const songWikiUrl = autoSelectNeteaseApi + '/song/wiki/summary?id=' + id + const songWikiUrl = autoSelectNeteaseApi + '/song/wiki/summary?id=' + id; // 国内解决方案,替换为国内API (其中,NETEASE_API_CN是国内基址) const AUTO_NETEASE_SONG_DOWNLOAD = autoSelectNeteaseApi + "/song/url/v1?id={}&level=" + this.neteaseCloudAudioQuality; const AUTO_NETEASE_SONG_DETAIL = autoSelectNeteaseApi + "/song/detail?ids={}"; // logger.info(AUTO_NETEASE_SONG_DOWNLOAD.replace("{}", id)); - const downloadUrl = AUTO_NETEASE_SONG_DOWNLOAD.replace("{}", id) - const detailUrl = AUTO_NETEASE_SONG_DETAIL.replace("{}", id) + const downloadUrl = AUTO_NETEASE_SONG_DOWNLOAD.replace("{}", id); + const detailUrl = AUTO_NETEASE_SONG_DETAIL.replace("{}", id); // 请求netease数据 axios.get(downloadUrl, { headers: { @@ -1768,8 +1768,8 @@ export class tools extends plugin { } let url = await resp.data.data?.[0]?.url || null; - const AudioLevel = translateToChinese(resp.data.data?.[0]?.level) - const AudioSize = bytesToMB(resp.data.data?.[0]?.size) + const AudioLevel = translateToChinese(resp.data.data?.[0]?.level); + const AudioSize = bytesToMB(resp.data.data?.[0]?.size); // 获取歌曲信息 let { songName, artistName } = await axios.get(detailUrl).then(res => { const song = res.data.songs[0]; @@ -1778,13 +1778,13 @@ export class tools extends plugin { artistName: cleanFilename(song?.ar?.[0].name) }; }); - let title = artistName + '-' + songName + let title = artistName + '-' + songName; // 获取歌曲封面 let coverUrl = await axios.get(detailUrl).then(res => { const song = res.data.songs[0]; - return song?.al?.picUrl + return song?.al?.picUrl; }); - let typelist = [] + let typelist = []; // 歌曲百科API await axios.get(songWikiUrl, { headers: { @@ -1792,37 +1792,37 @@ export class tools extends plugin { // "Cookie": this.neteaseCookie }, }).then(res => { - const wikiData = res.data.data.blocks[1].creatives + const wikiData = res.data.data.blocks[1].creatives; try { - typelist.push(wikiData[0].resources[0]?.uiElement?.mainTitle?.title || "") + typelist.push(wikiData[0].resources[0]?.uiElement?.mainTitle?.title || ""); // 防止数据过深出错 - const recTags = wikiData[1] + const recTags = wikiData[1]; if (recTags?.resources[0]) { for (let i = 0; i < Math.min(3, recTags.resources.length); i++) { if (recTags.resources[i] && recTags.resources[i].uiElement && recTags.resources[i].uiElement.mainTitle.title) { - typelist.push(recTags.resources[i].uiElement.mainTitle.title) + typelist.push(recTags.resources[i].uiElement.mainTitle.title); } } } else { - if (recTags.uiElement.textLinks[0].text) typelist.push(recTags.uiElement.textLinks[0].text) + if (recTags.uiElement.textLinks[0].text) typelist.push(recTags.uiElement.textLinks[0].text); } if (wikiData[2].uiElement.mainTitle.title == 'BPM') { - typelist.push('BPM ' + wikiData[2].uiElement.textLinks[0].text) + typelist.push('BPM ' + wikiData[2].uiElement.textLinks[0].text); } else { - typelist.push(wikiData[2].uiElement.textLinks[0].text || '') + typelist.push(wikiData[2].uiElement.textLinks[0].text || ''); } } catch (error) { - logger.error('获取标签报错:', error) + logger.error('获取标签报错:', error); } - typelist.push(AudioLevel) - }) + typelist.push(AudioLevel); + }); let musicInfo = { 'cover': coverUrl, 'songName': songName, 'singerName': artistName, 'size': AudioSize + " MB", 'musicType': typelist - } + }; // 一般这个情况是VIP歌曲 (如果没有url或者是国内,公用接口暂时不可用,必须自建并且ck可用状态才能进行高质量解析) if (!isCkExpired || url == null) { url = await this.musicTempApi(e, title, "网易云音乐", musicInfo); @@ -1832,13 +1832,13 @@ export class tools extends plugin { if (AudioLevel == '杜比全景声') { audioInfo += '\n(杜比下载文件为MP4,编码格式为AC-4,需要设备支持才可播放)'; } - const data = await new NeteaseMusicInfo(e).getData(musicInfo) + const data = await new NeteaseMusicInfo(e).getData(musicInfo); let img = await puppeteer.screenshot("neteaseMusicInfo", data); await e.reply(img); // e.reply([segment.image(coverUrl), `${this.identifyPrefix}识别:网易云音乐,${title}\n当前下载音质: ${audioInfo}\n预估大小: ${AudioSize}MB`]); } // 动态判断后缀名 - let musicExt = resp.data.data?.[0]?.type + let musicExt = resp.data.data?.[0]?.type; // 下载音乐 downloadAudio(url, this.getCurDownloadPath(e), title, 'follow', musicExt).then(async path => { // 发送群文件 @@ -1850,7 +1850,7 @@ export class tools extends plugin { // 删除文件 await checkAndRemoveFile(path); }).catch(err => { - logger.error(`下载音乐失败,错误信息为: ${err}`); + logger.error(`下载音乐失败,错误信息为: ${ err }`); }); }); return true; @@ -1878,9 +1878,9 @@ export class tools extends plugin { const singer = vipMusicData.data?.singer ?? vipMusicData.data?.data?.song_singer ?? vipMusicData.data?.singer; const id = vipMusicData.data?.id ?? vipMusicData.data?.data?.quality ?? vipMusicData.data?.pay; if (musicType === "网易云音乐") { - musicInfo.size = id - musicInfo.musicType = musicInfo.musicType.slice(0, -1) - const data = await new NeteaseMusicInfo(e).getData(musicInfo) + musicInfo.size = id; + musicInfo.musicType = musicInfo.musicType.slice(0, -1); + const data = await new NeteaseMusicInfo(e).getData(musicInfo); let img = await puppeteer.screenshot("neteaseMusicInfo", data); await e.reply(img); } else { @@ -1890,8 +1890,8 @@ export class tools extends plugin { 'singerName': singer, 'size': id, 'musicType': "" - } - const data = await new NeteaseMusicInfo(e).getData(musicInfo) + }; + const data = await new NeteaseMusicInfo(e).getData(musicInfo); let img = await puppeteer.screenshot("neteaseMusicInfo", data); await e.reply(img); } @@ -1927,13 +1927,13 @@ export class tools extends plugin { "User-Agent": COMMON_USER_AGENT, "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "cookie": "_T_WM=40835919903; WEIBOCN_FROM=1110006030; MLOGIN=0; XSRF-TOKEN=4399c8", - "Referer": `https://m.weibo.cn/detail/${id}`, + "Referer": `https://m.weibo.cn/detail/${ id }`, } }) .then(async resp => { const wbData = resp.data.data; const { text, status_title, source, region_name, pics, page_info } = wbData; - e.reply(`${this.identifyPrefix}识别:微博,${text.replace(/<[^>]+>/g, '')}\n${status_title}\n${source}\t${region_name ?? ''}`); + e.reply(`${ this.identifyPrefix }识别:微博,${ text.replace(/<[^>]+>/g, '') }\n${ status_title }\n${ source }\t${ region_name ?? '' }`); if (pics) { // 下载图片并格式化消息 const imagesPromise = pics.map(item => { @@ -1969,7 +1969,7 @@ export class tools extends plugin { // 视频 const videoUrl = page_info.urls?.mp4_720p_mp4 || page_info.urls?.mp4_hd_mp4; // 文章 - if (!videoUrl) return true + if (!videoUrl) return true; try { // wb 视频只能强制使用 1,由群友@非酋提出 this.downloadVideo(videoUrl, false, { @@ -1977,7 +1977,7 @@ export class tools extends plugin { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "referer": "https://weibo.com/", }, 1).then(path => { - this.sendVideoToUpload(e, `${path}/temp.mp4`) + this.sendVideoToUpload(e, `${ path }/temp.mp4`); }); } catch (err) { e.reply("视频资源获取失败"); @@ -1996,7 +1996,7 @@ export class tools extends plugin { async general(e) { try { const adapter = await GeneralLinkAdapter.create(e.msg); - e.reply(`${this.identifyPrefix}识别:${adapter.name}${adapter.desc ? `, ${adapter.desc}` : ''}`); + e.reply(`${ this.identifyPrefix }识别:${ adapter.name }${ adapter.desc ? `, ${ adapter.desc }` : '' }`); logger.mark(adapter); if (adapter.images && adapter.images.length > 0) { const images = adapter.images.map(item => { @@ -2004,29 +2004,29 @@ export class tools extends plugin { message: segment.image(item), nickname: this.e.sender.card || this.e.user_id, user_id: this.e.user_id, - } - }) + }; + }); e.reply(Bot.makeForwardMsg(images)); } else if (adapter.video && adapter.video !== '') { // 视频:https://www.kuaishou.com/short-video/3xhjgcmir24m4nm const url = adapter.video; this.downloadVideo(url).then(path => { logger.info(path); - this.sendVideoToUpload(e, `${path}/temp.mp4`) + this.sendVideoToUpload(e, `${ path }/temp.mp4`); }); } else { e.reply("解析失败:无法获取到资源"); } } catch (err) { logger.error("解析失败 ", err); - return true + return true; } - return true + return true; } // 油管解析 async sy2b(e) { - const timeRange = ytbFormatTime(this.youtubeClipTime) + const timeRange = ytbFormatTime(this.youtubeClipTime); const isOversea = await this.isOverseasServer(); if (!isOversea && !(await testProxy(this.proxyAddr, this.proxyPort))) { e.reply("检测到没有梯子,无法解析油管"); @@ -2040,31 +2040,31 @@ export class tools extends plugin { const isWindows = process.platform === 'win32'; // 匹配并转义 URL 中的 & 符号(仅对 Windows 进行转义) - let url = removeParams(urlRex.exec(e.msg)?.[0] || url2Rex.exec(e.msg)?.[0]).replace(/&/g, isWindows ? '^&' : '&') + let url = removeParams(urlRex.exec(e.msg)?.[0] || url2Rex.exec(e.msg)?.[0]).replace(/&/g, isWindows ? '^&' : '&'); //非最高画质,就按照设定的来 - let graphics = "" + let graphics = ""; if (this.youtubeGraphicsOptions != 0) { - graphics = `[height<=${this.youtubeGraphicsOptions}]` + graphics = `[height<=${ this.youtubeGraphicsOptions }]`; } const path = this.getCurDownloadPath(e); - await checkAndRemoveFile(path + "/temp.mp4") - await checkAndRemoveFile(path + "/temp.flac") - await checkAndRemoveFile(path + "/thumbnail.png") - await ytDlpGetThumbnail(path, url, isOversea, this.myProxy, this.youtubeCookiePath) + await checkAndRemoveFile(path + "/temp.mp4"); + await checkAndRemoveFile(path + "/temp.flac"); + await checkAndRemoveFile(path + "/thumbnail.png"); + await ytDlpGetThumbnail(path, url, isOversea, this.myProxy, this.youtubeCookiePath); const title = ytDlpGetTilt(url, isOversea, this.myProxy, this.youtubeCookiePath).toString().replace(/\n/g, ''); // 音频逻辑 if (url.includes("music")) { e.reply([ - segment.image(`${path}/thumbnail.png`), - `${this.identifyPrefix}识别:油管音乐\n视频标题:${title}` + segment.image(`${ path }/thumbnail.png`), + `${ this.identifyPrefix }识别:油管音乐\n视频标题:${ title }` ]); await ytDlpHelper(path, url, isOversea, this.myProxy, this.videoDownloadConcurrency, true, graphics, timeRange, this.youtubeCookiePath); - if(this.isSendVocal){ - e.reply(segment.record(`${path}/temp.flac`)); + if (this.isSendVocal) { + e.reply(segment.record(`${ path }/temp.flac`)); } - this.uploadGroupFile(e, `${path}/temp.flac`); + this.uploadGroupFile(e, `${ path }/temp.flac`); // 发送完就截断 return; } @@ -2074,20 +2074,20 @@ export class tools extends plugin { // logger.info('时长------',Duration) if (Duration > this.youtubeDuration) { e.reply([ - segment.image(`${path}/thumbnail.png`), - `${this.identifyPrefix}识别:油管,视频时长超限 \n视频标题:${title}\n⌚${DIVIDING_LINE.replace('{}', '限制说明').replace(/\n/g, '')}⌚\n视频时长:${(Duration / 60).toFixed(2).replace(/\.00$/, '')} 分钟\n大于管理员限定解析时长:${(this.youtubeDuration / 60).toFixed(2).replace(/\.00$/, '')} 分钟` + segment.image(`${ path }/thumbnail.png`), + `${ this.identifyPrefix }识别:油管,视频时长超限 \n视频标题:${ title }\n⌚${ DIVIDING_LINE.replace('{}', '限制说明').replace(/\n/g, '') }⌚\n视频时长:${ (Duration / 60).toFixed(2).replace(/\.00$/, '') } 分钟\n大于管理员限定解析时长:${ (this.youtubeDuration / 60).toFixed(2).replace(/\.00$/, '') } 分钟` ]); } else if (Duration > this.youtubeClipTime && timeRange != '00:00:00-00:00:00') { e.reply([ - segment.image(`${path}/thumbnail.png`), - `${this.identifyPrefix}识别:油管,视频截取中请耐心等待 \n视频标题:${title}\n✂️${DIVIDING_LINE.replace('{}', '截取说明').replace(/\n/g, '')}✂️\n视频时长:${(Duration / 60).toFixed(2).replace(/\.00$/, '')} 分钟\n大于管理员限定截取时长:${(this.youtubeClipTime / 60).toFixed(2).replace(/\.00$/, '')} 分钟\n将截取视频片段` + segment.image(`${ path }/thumbnail.png`), + `${ this.identifyPrefix }识别:油管,视频截取中请耐心等待 \n视频标题:${ title }\n✂️${ DIVIDING_LINE.replace('{}', '截取说明').replace(/\n/g, '') }✂️\n视频时长:${ (Duration / 60).toFixed(2).replace(/\.00$/, '') } 分钟\n大于管理员限定截取时长:${ (this.youtubeClipTime / 60).toFixed(2).replace(/\.00$/, '') } 分钟\n将截取视频片段` ]); await ytDlpHelper(path, url, isOversea, this.myProxy, this.videoDownloadConcurrency, true, graphics, timeRange, this.youtubeCookiePath); - this.sendVideoToUpload(e, `${path}/temp.mp4`); + this.sendVideoToUpload(e, `${ path }/temp.mp4`); } else { - e.reply([segment.image(`${path}/thumbnail.png`), `${this.identifyPrefix}识别:油管,视频下载中请耐心等待 \n视频标题:${title}\n视频时长:${(Duration / 60).toFixed(2).replace(/\.00$/, '')} 分钟`]); + e.reply([segment.image(`${ path }/thumbnail.png`), `${ this.identifyPrefix }识别:油管,视频下载中请耐心等待 \n视频标题:${ title }\n视频时长:${ (Duration / 60).toFixed(2).replace(/\.00$/, '') } 分钟`]); await ytDlpHelper(path, url, isOversea, this.myProxy, this.videoDownloadConcurrency, true, graphics, timeRange, this.youtubeCookiePath); - this.sendVideoToUpload(e, `${path}/temp.mp4`); + this.sendVideoToUpload(e, `${ path }/temp.mp4`); } } catch (error) { logger.error(error); @@ -2134,7 +2134,7 @@ export class tools extends plugin { } catch (e) { realContent = content; } - const normalMsg = `${this.identifyPrefix}识别:米游社,${subject}\n${realContent?.describe || ""}`; + const normalMsg = `${ this.identifyPrefix }识别:米游社,${ subject }\n${ realContent?.describe || "" }`; const replyMsg = cover ? [segment.image(cover), normalMsg] : normalMsg; e.reply(replyMsg); // 图片 @@ -2144,7 +2144,7 @@ export class tools extends plugin { message: segment.image(item), nickname: this.e.sender.card || this.e.user_id, user_id: this.e.user_id, - } + }; }); e.reply(Bot.makeForwardMsg(replyImages)); } @@ -2158,13 +2158,13 @@ export class tools extends plugin { // 暂时选取分辨率较低的video进行解析 const videoUrl = resolutions[i].url; this.downloadVideo(videoUrl).then(path => { - this.sendVideoToUpload(e, `${path}/temp.mp4`) + this.sendVideoToUpload(e, `${ path }/temp.mp4`); }); break; } } } - }) + }); } // 微视 @@ -2185,7 +2185,7 @@ export class tools extends plugin { if (!idMatch || idMatch.length !== 2) { e.reply("识别:微视,但无法完整检测到视频ID"); // 打个日志 方便后面出bug知道位置 - logger.error("[R插件][微视] 无法检测到ID,逻辑大概问题在正则表达式") + logger.error("[R插件][微视] 无法检测到ID,逻辑大概问题在正则表达式"); return true; } @@ -2203,10 +2203,10 @@ export class tools extends plugin { const cover = firstFeed.images[0].url; const noWatermarkDownloadUrl = firstFeed.video_url; - e.reply([segment.image(cover), `${this.identifyPrefix}识别:微视,${title}`]); + e.reply([segment.image(cover), `${ this.identifyPrefix }识别:微视,${ title }`]); this.downloadVideo(noWatermarkDownloadUrl).then(path => { - this.sendVideoToUpload(e, `${path}/temp.mp4`) + this.sendVideoToUpload(e, `${ path }/temp.mp4`); }); } catch (err) { logger.error(err); @@ -2244,7 +2244,7 @@ export class tools extends plugin { imgSrcs.push(match[1]); // Adds the content of the src attribute to the array } - const images = imgSrcs.filter(item => item.includes("\/img\/view\/id")) + const images = imgSrcs.filter(item => item.includes("\/img\/view\/id")); // Construct the response object const shortVideoInfo = { @@ -2255,7 +2255,7 @@ export class tools extends plugin { images, }; - e.reply(`${this.identifyPrefix}识别:最右,${shortVideoInfo.authorName}\n${shortVideoInfo.title}`) + e.reply(`${ this.identifyPrefix }识别:最右,${ shortVideoInfo.authorName }\n${ shortVideoInfo.title }`); if (shortVideoInfo.images.length > 0) { const replyImages = shortVideoInfo.images.map(item => { @@ -2263,13 +2263,13 @@ export class tools extends plugin { message: segment.image(item), nickname: this.e.sender.card || this.e.user_id, user_id: this.e.user_id, - } + }; }); e.reply(Bot.makeForwardMsg(replyImages)); } if (shortVideoInfo.noWatermarkDownloadUrl) { this.downloadVideo(shortVideoInfo.noWatermarkDownloadUrl).then(path => { - this.sendVideoToUpload(e, `${path}/temp.mp4`) + this.sendVideoToUpload(e, `${ path }/temp.mp4`); }); } } catch (error) { @@ -2287,28 +2287,28 @@ export class tools extends plugin { // 找到R插件保存目录 const currentWorkingDirectory = path.resolve(this.getCurDownloadPath(e)); // 如果没有文件夹就创建一个 - await mkdirIfNotExists(currentWorkingDirectory + "/am") + await mkdirIfNotExists(currentWorkingDirectory + "/am"); // 检测是否存在框架 const isExistFreyr = await checkToolInCurEnv("freyr"); if (!isExistFreyr) { - e.reply(`检测到没有${freyrName}需要的环境,无法解析!${HELP_DOC}`); + e.reply(`检测到没有${ freyrName }需要的环境,无法解析!${ HELP_DOC }`); return; } // 执行命令 - const result = await execSync(`freyr -d ${currentWorkingDirectory + "/am/"} get ${message}`); + const result = await execSync(`freyr -d ${ currentWorkingDirectory + "/am/" } get ${ message }`); logger.info(result.toString()); // 获取信息 let { title, album, artist } = await this.parseFreyrLog(result.toString()); // 兜底策略 if (freyrName === "Apple Music" && (title === "N/A" || album === "N/A" || artist === "N/A")) { - const data = await axios.get(`https://api.fabdl.com/apple-music/get?url=${message}`, { + const data = await axios.get(`https://api.fabdl.com/apple-music/get?url=${ message }`, { headers: { "User-Agent": COMMON_USER_AGENT, "Referer": "https://apple-music-downloader.com/", "Origin": "https://apple-music-downloader.com", "Accept": "application/json, text/plain, */*", }, - }) + }); const { name, artists } = data.data.result; title = name; artist = artists; @@ -2318,7 +2318,7 @@ export class tools extends plugin { // 国内服务器解决方案 if (!isOversea) { // 临时接口 - const url = await this.musicTempApi(e, `${title} ${artist}`, freyrName); + const url = await this.musicTempApi(e, `${ title } ${ artist }`, freyrName); // 下载音乐 downloadAudio(url, this.getCurDownloadPath(e), title, 'follow').then(async path => { // 发送语音 @@ -2329,17 +2329,17 @@ export class tools extends plugin { await this.uploadGroupFile(e, path); await checkAndRemoveFile(path); }).catch(err => { - logger.error(`下载音乐失败,错误信息为: ${err.message}`); + logger.error(`下载音乐失败,错误信息为: ${ err.message }`); }); } else { // freyr 逻辑 - e.reply(`${this.identifyPrefix}识别:${freyrName},${title}--${artist}`); + e.reply(`${ this.identifyPrefix }识别:${ freyrName },${ title }--${ artist }`); // 检查目录是否存在 const musicPath = currentWorkingDirectory + "/am/" + artist + "/" + album; // 找到音频文件 const mediaFiles = await getMediaFilesAndOthers(musicPath); for (let other of mediaFiles.others) { - await this.uploadGroupFile(e, `${musicPath}/${other}`); + await this.uploadGroupFile(e, `${ musicPath }/${ other }`); } } return true; @@ -2386,13 +2386,13 @@ export class tools extends plugin { .setModel(this.aiModel) .setPrompt(SUMMARY_PROMPT) .build(); - e.reply(`${this.identifyPrefix}识别:${name},正在为您总结,请稍等...`, true, { recallMsg: MESSAGE_RECALL_TIME }); + e.reply(`${ this.identifyPrefix }识别:${ name },正在为您总结,请稍等...`, true, { recallMsg: MESSAGE_RECALL_TIME }); const { ans: kimiAns, model } = await builder.kimi(summaryLink); // 计算阅读时间 const stats = estimateReadingTime(kimiAns); const titleMatch = kimiAns.match(/(Title|标题)([::])\s*(.*?)\n/)?.[3]; - e.reply(`《${titleMatch}》 预计阅读时间: ${stats.minutes} 分钟,总字数: ${stats.words}`) - const Msg = await Bot.makeForwardMsg(textArrayToMakeForward(e, [`「R插件 x ${model}」联合为您总结内容:`, kimiAns])); + e.reply(`《${ titleMatch }》 预计阅读时间: ${ stats.minutes } 分钟,总字数: ${ stats.words }`); + const Msg = await Bot.makeForwardMsg(textArrayToMakeForward(e, [`「R插件 x ${ model }」联合为您总结内容:`, kimiAns])); await e.reply(Msg); return true; } @@ -2407,7 +2407,7 @@ export class tools extends plugin { async tempSummary(name, summaryLink, e) { const content = await llmRead(summaryLink); const titleMatch = content.match(/Title:\s*(.*?)\n/)?.[1]; - e.reply(`${this.identifyPrefix}识别:${name} - ${titleMatch},正在为您总结,请稍等...`, true); + e.reply(`${ this.identifyPrefix }识别:${ name } - ${ titleMatch },正在为您总结,请稍等...`, true); const summary = await deepSeekChat(content, SUMMARY_PROMPT); const Msg = await Bot.makeForwardMsg(textArrayToMakeForward(e, [`「R插件 x DeepSeek」联合为您总结内容:`, summary])); await e.reply(Msg); @@ -2431,7 +2431,7 @@ export class tools extends plugin { musicInfo = prompt + "-" + desc; // 空判定 if (musicInfo.trim() === "-" || prompt === undefined || desc === undefined) { - logger.info(`没有识别到QQ音乐小程序,帮助文档如下:${HELP_DOC}`) + logger.info(`没有识别到QQ音乐小程序,帮助文档如下:${ HELP_DOC }`); return true; } } else { @@ -2441,7 +2441,7 @@ export class tools extends plugin { } // 删除特殊字符 musicInfo = cleanFilename(musicInfo); - logger.info(`[R插件][qqMusic] 识别音乐为:${musicInfo}`); + logger.info(`[R插件][qqMusic] 识别音乐为:${ musicInfo }`); // 使用临时接口下载 const url = await this.musicTempApi(e, musicInfo, "QQ音乐"); // 下载音乐 @@ -2454,7 +2454,7 @@ export class tools extends plugin { await this.uploadGroupFile(e, path); await checkAndRemoveFile(path); }).catch(err => { - logger.error(`下载音乐失败,错误信息为: ${err.message}`); + logger.error(`下载音乐失败,错误信息为: ${ err.message }`); }); return true; } @@ -2463,7 +2463,7 @@ export class tools extends plugin { async qishuiMusic(e) { const normalRegex = /^(.*?)\s*https?:\/\//; const musicInfo = normalRegex.exec(e.msg)?.[1].trim().replace("@汽水音乐", ""); - logger.info(`[R插件][qishuiMusic] 识别音乐为:${musicInfo}`); + logger.info(`[R插件][qishuiMusic] 识别音乐为:${ musicInfo }`); // 使用临时接口下载 const url = await this.musicTempApi(e, musicInfo, "汽水音乐"); // 下载音乐 @@ -2476,7 +2476,7 @@ export class tools extends plugin { await this.uploadGroupFile(e, path); await checkAndRemoveFile(path); }).catch(err => { - logger.error(`下载音乐失败,错误信息为: ${err.message}`); + logger.error(`下载音乐失败,错误信息为: ${ err.message }`); }); return true; } @@ -2496,7 +2496,7 @@ export class tools extends plugin { // 检查当前环境 const isExistTdl = await checkToolInCurEnv("tdl"); if (!isExistTdl) { - e.reply(`未检测到必要的环境,无法解析小飞机${HELP_DOC}`); + e.reply(`未检测到必要的环境,无法解析小飞机${ HELP_DOC }`); return; } const url = urlRex.exec(e.msg)[0]; @@ -2506,8 +2506,8 @@ export class tools extends plugin { e.reply("文件已保存到 Save Messages!"); return true; } - e.reply(`${this.identifyPrefix}识别:小飞机(学习版)`); - const tgSavePath = `${this.getCurDownloadPath(e)}/tg`; + e.reply(`${ this.identifyPrefix }识别:小飞机(学习版)`); + const tgSavePath = `${ this.getCurDownloadPath(e) }/tg`; // 如果没有文件夹则创建 await mkdirIfNotExists(tgSavePath); // 删除之前的文件 @@ -2517,21 +2517,21 @@ export class tools extends plugin { const mediaFiles = await getMediaFilesAndOthers(tgSavePath); if (mediaFiles.images.length > 0) { const imagesData = mediaFiles.images.map(item => { - const fileContent = fs.readFileSync(`${tgSavePath}/${item}`); + const fileContent = fs.readFileSync(`${ tgSavePath }/${ item }`); return { message: segment.image(fileContent), nickname: e.sender.card || e.user_id, user_id: e.user_id, }; - }) + }); e.reply(await Bot.makeForwardMsg(imagesData), true, { recallMsg: MESSAGE_RECALL_TIME }); } else if (mediaFiles.videos.length > 0) { for (const item of mediaFiles.videos) { - await this.sendVideoToUpload(e, `${tgSavePath}/${item}`); + await this.sendVideoToUpload(e, `${ tgSavePath }/${ item }`); } } else { for (let other of mediaFiles.others) { - await this.uploadGroupFile(e, `${tgSavePath}/${other}`); + await this.uploadGroupFile(e, `${ tgSavePath }/${ other }`); } } return true; @@ -2543,7 +2543,7 @@ export class tools extends plugin { const msg = /https:\/\/tieba\.baidu\.com\/p\/[A-Za-z0-9]+/.exec(e.msg)?.[0]; const id = /\/p\/([A-Za-z0-9]+)/.exec(msg)?.[1]; // 获取帖子详情 - const hibi = HIBI_API_SERVICE + `/tieba/post_detail?tid=${id}`; + const hibi = HIBI_API_SERVICE + `/tieba/post_detail?tid=${ id }`; const hibiResp = await fetch(hibi, { headers: { "User-Agent": COMMON_USER_AGENT, @@ -2554,11 +2554,11 @@ export class tools extends plugin { const top = postList[0]; // 提取标题和内容 const { title, content } = top; - let sendContent = `${this.identifyPrefix}识别:贴吧,${title}` + let sendContent = `${ this.identifyPrefix }识别:贴吧,${ title }`; let extractImages = []; // 如果内容中有图片、文本或视频,它会将它们添加到 sendContent 消息中 if (content && content.length > 0) { - sendContent = [sendContent] + sendContent = [sendContent]; for (const { cdn_src, text, link } of content) { logger.info({ cdn_src, text, link }); // 可以一次性输出多个属性 @@ -2566,12 +2566,12 @@ export class tools extends plugin { if (cdn_src) extractImages.push(segment.image(cdn_src)); // 处理文本 - if (text) sendContent.push(`\n\n📝 简介:${text}`); + if (text) sendContent.push(`\n\n📝 简介:${ text }`); // 处理视频 if (link) { const filePath = await this.downloadVideo(link); - this.sendVideoToUpload(e, `${filePath}/temp.mp4`); + this.sendVideoToUpload(e, `${ filePath }/temp.mp4`); } } } @@ -2649,7 +2649,7 @@ export class tools extends plugin { this.videoDownloadConcurrency ), ]).then(data => { - return mergeFileToMp4(data[0].fullFileName, data[1].fullFileName, `${title}.mp4`); + return mergeFileToMp4(data[0].fullFileName, data[1].fullFileName, `${ title }.mp4`); }); } @@ -2670,7 +2670,7 @@ export class tools extends plugin { const location = resp.request.res.responseUrl; - const setCookieHeaders = resp.headers['set-cookie'] + const setCookieHeaders = resp.headers['set-cookie']; let ttwidValue; if (setCookieHeaders) { setCookieHeaders.forEach(cookie => { @@ -2704,7 +2704,7 @@ export class tools extends plugin { * @returns {string} */ getCurDownloadPath(e) { - return `${this.defaultPath}${e.group_id || e.user_id}` + return `${ this.defaultPath }${ e.group_id || e.user_id }`; } /** @@ -2712,8 +2712,8 @@ export class tools extends plugin { * @returns {{groupPath: string, target: string}} */ getGroupPathAndTarget() { - const groupPath = `${this.defaultPath}${this.e.group_id || this.e.user_id}`; - const target = `${groupPath}/temp.mp4`; + const groupPath = `${ this.defaultPath }${ this.e.group_id || this.e.user_id }`; + const target = `${ groupPath }/temp.mp4`; return { groupPath, target }; } @@ -2735,9 +2735,9 @@ export class tools extends plugin { // 构造代理参数 const proxyOption = { ...(isProxy && { - httpAgent: new HttpsProxyAgent(`http://${this.proxyAddr}:${this.proxyPort}`), + httpAgent: new HttpsProxyAgent(`http://${ this.proxyAddr }:${ this.proxyPort }`), }), - } + }; /** * 构造下载视频参数 @@ -2751,8 +2751,8 @@ export class tools extends plugin { proxyOption, target, groupPath, - } - logger.info(`[R插件][视频下载]:当前队列长度为 ${this.queue.size + 1}`); + }; + logger.info(`[R插件][视频下载]:当前队列长度为 ${ this.queue.size + 1 }`); return await this.queue.add(async () => { // 如果是用户设置了单线程,则不分片下载 if (numThreads === 1) { @@ -2802,7 +2802,7 @@ export class tools extends plugin { const partAxiosConfig = { headers: { "User-Agent": userAgent, - "Range": `bytes=${start}-${end}` + "Range": `bytes=${ start }-${ end }` }, responseType: "stream", ...proxyOption @@ -2810,12 +2810,12 @@ export class tools extends plugin { promises.push(axios.get(url, partAxiosConfig).then(res => { return new Promise((resolve, reject) => { - const partPath = `${target}.part${i}`; - logger.mark(`[R插件][视频下载引擎] 正在下载 part${i}`) + const partPath = `${ target }.part${ i }`; + logger.mark(`[R插件][视频下载引擎] 正在下载 part${ i }`); const writer = fs.createWriteStream(partPath); res.data.pipe(writer); writer.on("finish", () => { - logger.mark(`[R插件][视频下载引擎] part${i + 1} 下载完成`); // 记录线程下载完成 + logger.mark(`[R插件][视频下载引擎] part${ i + 1 } 下载完成`); // 记录线程下载完成 resolve(partPath); }); writer.on("error", reject); @@ -2845,7 +2845,7 @@ export class tools extends plugin { return groupPath; } catch (err) { - logger.error(`下载视频发生错误!\ninfo:${err}`); + logger.error(`下载视频发生错误!\ninfo:${ err }`); } } @@ -2860,39 +2860,39 @@ export class tools extends plugin { // 构造aria2c命令参数 const aria2cArgs = [ - `"${url}"`, + `"${ url }"`, `--out="temp.mp4"`, - `--dir="${groupPath}"`, - `--user-agent="${userAgent}"`, - `--max-connection-per-server=${numThreads}`, // 每个服务器的最大连接数 - `--split=${numThreads}`, // 分成 6 个部分进行下载 + `--dir="${ groupPath }"`, + `--user-agent="${ userAgent }"`, + `--max-connection-per-server=${ numThreads }`, // 每个服务器的最大连接数 + `--split=${ numThreads }`, // 分成 6 个部分进行下载 ]; // 如果有自定义头信息 if (headers) { for (const [key, value] of Object.entries(headers)) { - aria2cArgs.push(`--header="${key}: ${value}"`); + aria2cArgs.push(`--header="${ key }: ${ value }"`); } } // 如果使用代理 if (proxyOption && proxyOption.httpAgent) { const proxyUrl = proxyOption.httpAgent.proxy.href; - aria2cArgs.push(`--all-proxy="${proxyUrl}"`); + aria2cArgs.push(`--all-proxy="${ proxyUrl }"`); } try { await checkAndRemoveFile(target); - logger.mark(`开始下载: ${url}`); + logger.mark(`开始下载: ${ url }`); // 执行aria2c命令 - const command = `aria2c ${aria2cArgs.join(' ')}`; + const command = `aria2c ${ aria2cArgs.join(' ') }`; exec(command, (error, stdout, stderr) => { if (error) { - logger.error(`下载视频发生错误!\ninfo:${stderr}`); + logger.error(`下载视频发生错误!\ninfo:${ stderr }`); throw error; } else { - logger.mark(`下载完成: ${url}`); + logger.mark(`下载完成: ${ url }`); } }); @@ -2900,7 +2900,7 @@ export class tools extends plugin { let count = 0; return new Promise((resolve, reject) => { const checkInterval = setInterval(() => { - logger.info(logger.red(`[R插件][Aria2] 没有检测到文件!重试第${count + 1}次`)); + logger.info(logger.red(`[R插件][Aria2] 没有检测到文件!重试第${ count + 1 }次`)); count += 1; if (fs.existsSync(target)) { logger.info("[R插件][Aria2] 检测到文件!"); @@ -2915,7 +2915,7 @@ export class tools extends plugin { }, DOWNLOAD_WAIT_DETECT_FILE_TIME); }); } catch (err) { - logger.error(`下载视频发生错误!\ninfo:${err}`); + logger.error(`下载视频发生错误!\ninfo:${ err }`); throw err; } } @@ -2931,38 +2931,38 @@ export class tools extends plugin { // 构造axel命令参数 const axelArgs = [ - `-n ${numThreads}`, - `-o "${target}"`, - `-U "${userAgent}"`, + `-n ${ numThreads }`, + `-o "${ target }"`, + `-U "${ userAgent }"`, url ]; // 如果有自定义头信息 if (headers) { for (const [key, value] of Object.entries(headers)) { - axelArgs.push(`-H "${key}: ${value}"`); + axelArgs.push(`-H "${ key }: ${ value }"`); } } // 如果使用代理 if (proxyOption && proxyOption.httpAgent) { const proxyUrl = proxyOption.httpAgent.proxy.href; - axelArgs.push(`--proxy="${proxyUrl}"`); + axelArgs.push(`--proxy="${ proxyUrl }"`); } try { await checkAndRemoveFile(target); - logger.mark(`开始下载: ${url}`); + logger.mark(`开始下载: ${ url }`); // 执行axel命令 - const command = `axel ${axelArgs.join(' ')}`; + const command = `axel ${ axelArgs.join(' ') }`; exec(command, (error, stdout, stderr) => { if (error) { - logger.error(`下载视频发生错误!\ninfo:${stderr}`); + logger.error(`下载视频发生错误!\ninfo:${ stderr }`); throw error; } else { - logger.mark(`下载完成: ${url}`); + logger.mark(`下载完成: ${ url }`); } }); @@ -2970,12 +2970,12 @@ export class tools extends plugin { // 监听文件生成完成 return new Promise((resolve, reject) => { const checkInterval = setInterval(() => { - logger.info(logger.red(`[R插件][Aria2] 没有检测到文件!重试第${count + 1}次`)); + logger.info(logger.red(`[R插件][Aria2] 没有检测到文件!重试第${ count + 1 }次`)); count += 1; if (fs.existsSync(target)) { logger.info("[R插件][Axel] 检测到文件!"); clearInterval(checkInterval); - logger.info(`[R插件][Axel] 下载到${groupPath}`); + logger.info(`[R插件][Axel] 下载到${ groupPath }`); resolve(groupPath); } if (count === 6) { @@ -2986,7 +2986,7 @@ export class tools extends plugin { }, DOWNLOAD_WAIT_DETECT_FILE_TIME); }); } catch (err) { - logger.error(`下载视频发生错误!\ninfo:${err}`); + logger.error(`下载视频发生错误!\ninfo:${ err }`); throw err; } } @@ -3009,7 +3009,7 @@ export class tools extends plugin { await checkAndRemoveFile(target); const res = await axios.get(url, axiosConfig); - logger.mark(`开始下载: ${url}`); + logger.mark(`开始下载: ${ url }`); const writer = fs.createWriteStream(target); res.data.pipe(writer); @@ -3018,7 +3018,7 @@ export class tools extends plugin { writer.on("error", reject); }); } catch (err) { - logger.error(`下载视频发生错误!\ninfo:${err}`); + logger.error(`下载视频发生错误!\ninfo:${ err }`); } } @@ -3031,7 +3031,7 @@ export class tools extends plugin { if (!(await redisExistKey(REDIS_YUNZAI_ISOVERSEA))) { await redisSetKey(REDIS_YUNZAI_ISOVERSEA, { os: false, - }) + }); return true; } // 如果有就取出来 @@ -3072,13 +3072,13 @@ export class tools extends plugin { const videoSize = Math.floor(stats.size / (1024 * 1024)); // 正常发送视频 if (videoSize > videoSizeLimit) { - e.reply(`当前视频大小:${videoSize}MB,\n大于设置的最大限制:${videoSizeLimit}MB,\n改为上传群文件`); + e.reply(`当前视频大小:${ videoSize }MB,\n大于设置的最大限制:${ videoSizeLimit }MB,\n改为上传群文件`); await this.uploadGroupFile(e, path); } else { e.reply(segment.video(path)); } } catch (err) { - logger.error(`[R插件][发送视频判断是否需要上传] 发生错误:\n ${err}`); + logger.error(`[R插件][发送视频判断是否需要上传] 发生错误:\n ${ err }`); // logger.info(logger.yellow(`上传发生错误,R插件正在为你采用备用策略,请稍等,如果发不出来请再次尝试!`)); // e.reply(segment.video(path)); }