From 4ed06a0eee618e2363cf1e177aebc8dff75b3e89 Mon Sep 17 00:00:00 2001 From: zhiyu1998 <542716863@qq.com> Date: Mon, 15 Jul 2024 20:31:16 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20=E6=96=B0=E5=A2=9E=E6=90=BA?= =?UTF-8?q?=E5=B8=A6=20dy=20=E8=AF=84=E8=AE=BA=20[#IACU74]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增评论,默认不开启,可以自己配置后开启 --- .github/ISSUE_TEMPLATE/bug.yml | 4 +- apps/tools.js | 201 ++++++++++++++++++++------------- config/tools.yaml | 5 +- constants/tools.js | 6 + guoba.support.js | 25 ++-- 5 files changed, 145 insertions(+), 96 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index dea548d..7f73514 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -48,7 +48,7 @@ body: label: 版本 description: 你当前正在使用我们软件的哪个版本/分支? options: - - 1.7.1 (默认) - - 1.7.1 (最新) + - 1.7.2 (默认) + - 1.7.2 (最新) validations: required: true \ No newline at end of file diff --git a/apps/tools.js b/apps/tools.js index 9846aea..05215f5 100644 --- a/apps/tools.js +++ b/apps/tools.js @@ -56,6 +56,7 @@ import PQueue from 'p-queue'; import { getWbi } from "../utils/biliWbi.js"; import { BILI_SUMMARY, + DY_COMMENT, DY_INFO, DY_TOUTIAO_INFO, GENERAL_REQ_LINK, @@ -203,6 +204,8 @@ export class tools extends plugin { this.douyinCookie = this.toolsConfig.douyinCookie; // 加载抖音是否压缩 this.douyinCompression = this.toolsConfig.douyinCompression; + // 加载抖音是否开启评论 + this.douyinComments = this.toolsConfig.douyinComments; // 翻译引擎 this.translateEngine = new Translate({ translateAppId: this.toolsConfig.translateAppId, @@ -244,90 +247,120 @@ export class tools extends plugin { const urlRex = /(http:|https:)\/\/v.douyin.com\/[A-Za-z\d._?%&+\-=\/#]*/g; const douUrl = urlRex.exec(e.msg.trim())[0]; - await this.douyinRequest(douUrl).then(async res => { - // 当前版本需要填入cookie - if (_.isEmpty(this.douyinCookie)) { - e.reply(`检测到没有Cookie,无法解析抖音${HELP_DOC}`); - return; + const res = await this.douyinRequest(douUrl); + // 当前版本需要填入cookie + if (_.isEmpty(this.douyinCookie)) { + e.reply(`检测到没有Cookie,无法解析抖音${HELP_DOC}`); + return; + } + const douId = /note\/(\d+)/g.exec(res)?.[1] || /video\/(\d+)/g.exec(res)?.[1]; + // 以下是更新了很多次的抖音API历史,且用且珍惜 + // const url = `https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids=${ douId }`; + // 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`; + // 感谢 Evil0ctal(https://github.com/Evil0ctal)提供的header 和 B1gM8c(https://github.com/B1gM8c)的逆向算法X-Bogus + const headers = { + "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", + "User-Agent": + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", + Referer: "https://www.douyin.com/", + cookie: this.douyinCookie, + }; + const dyApi = DY_INFO.replace("{}", douId); + // a-bogus参数 + const abParam = aBogus.generate_a_bogus( + new URLSearchParams(new URL(dyApi).search).toString(), + headers["User-Agent"], + ); + // const param = resp.data.result[0].paramsencode; + const resDyApi = `${ dyApi }&a_bogus=${ abParam }`; + headers['Referer'] = `https://www.douyin.com/video/${ douId }` + // 定义一个dy请求 + const dyResponse = () => axios.get(resDyApi, { + headers, + }); + // 如果失败进行3次重试 + const data = await retryAxiosReq(dyResponse) + // logger.info(data) + const item = await data.aweme_detail; + e.reply(`识别:抖音, ${ item.desc }`); + const urlTypeCode = item.aweme_type; + const urlType = douyinTypeMap[urlTypeCode]; + if (urlType === "video") { + // logger.info(item.video); + // 多位面选择:play_addr、play_addr_265、play_addr_h264 + const { play_addr: { uri: videoAddrURI } } = item.video; + const resolution = this.douyinCompression ? "720p" : "1080p"; + // 使用今日头条 CDN 进一步加快解析速度 + const resUrl = DY_TOUTIAO_INFO.replace("1080p", resolution).replace("{}", videoAddrURI); + + // ⚠️ 暂时废弃代码 + /*if (this.douyinCompression) { + // H.265压缩率更高、流量省一半. 相对于H.264 + // 265 和 264 随机均衡负载 + const videoAddrList = Math.random() > 0.5 ? play_addr_265.url_list : play_addr_h264.url_list; + resUrl = videoAddrList[videoAddrList.length - 1] || videoAddrList[0]; + } else { + // 原始格式,ps. videoAddrList这里[0]、[1]是 http,[最后一个]是 https + const videoAddrList = play_addr.url_list; + resUrl = videoAddrList[videoAddrList.length - 1] || videoAddrList[0]; + }*/ + + // logger.info(resUrl); + const path = `${ this.getCurDownloadPath(e) }/temp.mp4`; + await this.downloadVideo(resUrl).then(() => { + this.sendVideoToUpload(e, path) + }); + } else if (urlType === "image") { + // 无水印图片列表 + let no_watermark_image_list = []; + // 有水印图片列表 + // let watermark_image_list = []; + for (let i of item.images) { + // 无水印图片列表 + no_watermark_image_list.push({ + message: segment.image(i.url_list[0]), + nickname: this.e.sender.card || this.e.user_id, + user_id: this.e.user_id, + }); + // 有水印图片列表 + // watermark_image_list.push(i.download_url_list[0]); + // e.reply(segment.image(i.url_list[0])); } - const douId = /note\/(\d+)/g.exec(res)?.[1] || /video\/(\d+)/g.exec(res)?.[1]; - // 以下是更新了很多次的抖音API历史,且用且珍惜 - // const url = `https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids=${ douId }`; - // 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`; - // 感谢 Evil0ctal(https://github.com/Evil0ctal)提供的header 和 B1gM8c(https://github.com/B1gM8c)的逆向算法X-Bogus - const headers = { - "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", + // console.log(no_watermark_image_list) + await this.reply(await Bot.makeForwardMsg(no_watermark_image_list)); + } + // 如果开启评论的就调用 + if (this.douyinComments) { + const comments = (await this.douyinComment(douId)).unshift({ + message: "前20条热门评论", + nickname: this.e.sender.card || this.e.user_id, + user_id: this.e.user_id, + }); + e.reply(await Bot.makeForwardMsg(comments)); + } + return true; + } + + /** + * 获取 DY 评论,暂时由群友 @慢热 提供 + * @param douId + * @returns {Promise<*>} + */ + async douyinComment(douId) { + const commentsResp = await axios.get(DY_COMMENT.replace("{}", douId), { + headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", - Referer: "https://www.douyin.com/", - cookie: this.douyinCookie, - }; - const dyApi = DY_INFO.replace("{}", douId); - // a-bogus参数 - const abParam = aBogus.generate_a_bogus( - new URLSearchParams(new URL(dyApi).search).toString(), - headers["User-Agent"], - ); - // const param = resp.data.result[0].paramsencode; - const resDyApi = `${ dyApi }&a_bogus=${ abParam }`; - headers['Referer'] = `https://www.douyin.com/video/${ douId }` - // 定义一个dy请求 - const dyResponse = () => axios.get(resDyApi, { - headers, - }); - // 如果失败进行3次重试 - const data = await retryAxiosReq(dyResponse) - // logger.info(data) - const item = await data.aweme_detail; - e.reply(`识别:抖音, ${ item.desc }`); - const urlTypeCode = item.aweme_type; - const urlType = douyinTypeMap[urlTypeCode]; - if (urlType === "video") { - // logger.info(item.video); - // 多位面选择:play_addr、play_addr_265、play_addr_h264 - const { play_addr: { uri: videoAddrURI } } = item.video; - const resolution = this.douyinCompression === 1 ? "720p" : "1080p"; - // 使用今日头条 CDN 进一步加快解析速度 - const resUrl = DY_TOUTIAO_INFO.replace("1080p", resolution).replace("{}", videoAddrURI); - - // ⚠️ 暂时废弃代码 - /*if (this.douyinCompression === 1) { - // H.265压缩率更高、流量省一半. 相对于H.264 - // 265 和 264 随机均衡负载 - const videoAddrList = Math.random() > 0.5 ? play_addr_265.url_list : play_addr_h264.url_list; - resUrl = videoAddrList[videoAddrList.length - 1] || videoAddrList[0]; - } else { - // 原始格式,ps. videoAddrList这里[0]、[1]是 http,[最后一个]是 https - const videoAddrList = play_addr.url_list; - resUrl = videoAddrList[videoAddrList.length - 1] || videoAddrList[0]; - }*/ - - // logger.info(resUrl); - const path = `${ this.getCurDownloadPath(e) }/temp.mp4`; - await this.downloadVideo(resUrl).then(() => { - this.sendVideoToUpload(e, path) - }); - } else if (urlType === "image") { - // 无水印图片列表 - let no_watermark_image_list = []; - // 有水印图片列表 - // let watermark_image_list = []; - for (let i of item.images) { - // 无水印图片列表 - no_watermark_image_list.push({ - message: segment.image(i.url_list[0]), - nickname: this.e.sender.card || this.e.user_id, - user_id: this.e.user_id, - }); - // 有水印图片列表 - // watermark_image_list.push(i.download_url_list[0]); - // e.reply(segment.image(i.url_list[0])); - } - // console.log(no_watermark_image_list) - await this.reply(await Bot.makeForwardMsg(no_watermark_image_list)); } - }); - return true; + }) + const comments = commentsResp.data.data.comments; + return comments.map(item => { + return { + message: item.text, + nickname: this.e.sender.card || this.e.user_id, + user_id: this.e.user_id, + } + }) } // tiktok解析 @@ -1632,7 +1665,13 @@ export class tools extends plugin { try { const resp = await axios.head(url, params); const location = resp.request.res.responseUrl; - return location; + return new Promise((resolve, reject) => { + if (location != null) { + return resolve(location); + } else { + return reject("获取失败"); + } + }); } catch (error) { console.error(error); throw error; diff --git a/config/tools.yaml b/config/tools.yaml index cfc2daf..13a3a24 100644 --- a/config/tools.yaml +++ b/config/tools.yaml @@ -10,7 +10,8 @@ biliIntroLenLimit: 50 # 哔哩哔哩简介长度限制,填 0 或者 -1 可以 biliDuration: 480 # 哔哩哔哩限制的最大视频时长(默认8分钟),单位:秒 douyinCookie: '' # douyin's cookie, 格式:odin_tt=xxx;passport_fe_beating_status=xxx;sid_guard=xxx;uid_tt=xxx;uid_tt_ss=xxx;sid_tt=xxx;sessionid=xxx;sessionid_ss=xxx;sid_ucp_v1=xxx;ssid_ucp_v1=xxx;passport_assist_user=xxx;ttwid=xxx; -douyinCompression: 1 # 1-压缩,0-不压缩;是否使用压缩视频格式的抖音(默认使用),使用后加速视频发送 +douyinCompression: true # true-压缩,false-不压缩;是否使用压缩视频格式的抖音(默认使用),使用后加速视频发送 +douyinComments: false # true-开启评论,false-关闭评论 queueConcurrency: 1 # 【目前只涉及哔哩哔哩的下载】根据服务器性能设置可以并发下载的个数,如果你的服务器比较强劲,就选择4~12,较弱就一个一个下载,选择1 @@ -22,4 +23,4 @@ autoclearTrashtime: '0 0 8 * * ?' #每天早上8点自动清理视频缓存,cr aiBaseURL: '' # 用于识图的接口,kimi默认接口为:https://api.moonshot.cn,其他服务商自己填写 aiApiKey: '' # 用于识图的api key,kimi接口申请:https://platform.moonshot.cn/console/api-keys -aiModel: 'claude-3-haiku-20240307' # 模型,使用kimi不用填写,其他要填写 \ No newline at end of file +aiModel: 'moonshot-v1-8k' # 模型,使用kimi不用填写,其他要填写 \ No newline at end of file diff --git a/constants/tools.js b/constants/tools.js index a72263a..f6ac169 100644 --- a/constants/tools.js +++ b/constants/tools.js @@ -73,6 +73,12 @@ export const XHS_VIDEO = "http://sns-video-bd.xhscdn.com/" */ export const DY_INFO = "https://www.douyin.com/aweme/v1/web/aweme/detail/?device_platform=webapp&aid=6383&channel=channel_pc_web&aweme_id={}&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=118.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" +/** + * DY COMMENT API + * @type {string} + */ +export const DY_COMMENT = "https://bzapi.bzweb.xyz/api/public/dy/video/comment?id={}" + /** * 今日头条 DY API * @type {string} diff --git a/guoba.support.js b/guoba.support.js index 76c1f77..c663474 100644 --- a/guoba.support.js +++ b/guoba.support.js @@ -14,12 +14,14 @@ export function supportGuoba() { isV3: true, isV2: false, description: "专门为朋友们写的Yunzai-Bot插件,专注图片分享和生活的插件!", + // 是否显示在左侧菜单,可选值:auto、true、false + // 当为 auto 时,如果配置项大于等于 3 个,则显示在左侧菜单 + showInMenu: 'auto', // 显示图标,此为个性化配置 // 图标可在 https://icon-sets.iconify.design 这里进行搜索 - // icon: "mdi:share-reviews-sharp", + icon: 'mdi:stove', // 图标颜色,例:#FF0000 或 rgb(255, 0, 0) - // iconColor: "#3498db", - // 如果想要显示成图片,也可以填写图标路径(绝对路径) + iconColor: '#d19f56', iconPath: path.join(_path, "resources/img/rank/top.png"), }, configInfo: { @@ -121,14 +123,15 @@ export function supportGuoba() { }, { field: "tools.douyinCompression", - label: "抖音是否使用压缩格式(1-压缩,0-不压缩)", - bottomHelpMessage: - "1-压缩,0-不压缩;是否使用压缩视频格式的抖音(默认使用),使用后加速视频发送", - component: "Input", + label: "抖音是否使用压缩格式", + component: "Switch", + required: false, + }, + { + field: "tools.douyinComments", + label: "抖音是否开启评论", + component: "Switch", required: false, - componentProps: { - placeholder: "请输入1或者0(默认1)", - }, }, { field: "tools.queueConcurrency", @@ -154,7 +157,7 @@ export function supportGuoba() { }, { field: "tools.lagrangeForwardWebSocket", - label: "拉格朗日正向WebSocket连接地址", + label: "Lagrange.Core-WebSocket连接地址", bottomHelpMessage: "格式:ws://地址:端口/,拉格朗日正向连接地址,用于适配拉格朗日上传群文件,解决部分用户无法查看视频问题", component: "Input",