diff --git a/README.md b/README.md
index cace263..78d09c9 100644
--- a/README.md
+++ b/README.md
@@ -113,6 +113,9 @@ chmod a+rx ~/.local/bin/yt-dlp
+### ✖️ 小蓝鸟问题
+**2024-2-5**,修复小蓝鸟的时候看到free计划已经[没有给查看Tweet的api](https://developer.twitter.com/en/portal/products/basic),原先[使用的库也出现了403报错](https://github.com/PLhery/node-twitter-api-v2),开通会员要100美元,不值得。目前暂停更新,后续有方案和精力再更新!
+
## 🤺 R插件交流群
扫码不行就:575663150
@@ -161,7 +164,9 @@ chmod a+rx ~/.local/bin/yt-dlp
* [x0rz4](https://gitee.com/x0rz4) 提供依赖掉包解决方案
感谢以下框架的开源:
-YouTube解析参考了:[yt-dlp:A youtube-dl fork with additional features and fixes](https://github.com/yt-dlp/yt-dlp)
+
+YouTube解析参考了:
+- [yt-dlp:A youtube-dl fork with additional features and fixes](https://github.com/yt-dlp/yt-dlp)
## ☕ 请我喝一杯瑞幸咖啡
如果你觉得插件能帮助到你增进好友关系,那么你可以在有条件的情况下[请我喝一杯瑞幸咖啡](https://afdian.net/a/zhiyu1998),这是我开源这个插件的最大动力!
diff --git a/apps/tools.js b/apps/tools.js
index 60c73f5..cfed092 100644
--- a/apps/tools.js
+++ b/apps/tools.js
@@ -16,6 +16,7 @@ import {
DIVIDING_LINE,
XHS_NO_WATERMARK_HEADER,
REDIS_YUNZAI_ISOVERSEA,
+ TWITTER_BEARER_TOKEN,
} from "../constants/constant.js";
import { containsChinese, formatBiliInfo, getIdVideo, secondsToTime } from "../utils/common.js";
import config from "../model/index.js";
@@ -27,8 +28,8 @@ import { av2BV } from "../utils/bilibili-bv-av-convert.js";
import querystring from "querystring";
import TokenBucket from "../utils/token-bucket.js";
import { getWbi } from "../utils/biliWbi.js";
-import { BILI_SUMMARY } from "../constants/bili.js";
-import { XHS_VIDEO } from "../constants/xhs.js";
+import { BILI_SUMMARY, DY_INFO, TIKTOK_INFO, TWITTER_TWEET_INFO, XHS_REQ_LINK } from "../constants/tools.js";
+import { XHS_VIDEO } from "../constants/tools.js";
import child_process from 'node:child_process'
import { getAudio, getVideo } from "../utils/y2b.js";
import { processTikTokUrl } from "../utils/tiktok.js";
@@ -168,7 +169,7 @@ export class tools extends plugin {
Referer: "https://www.douyin.com/",
cookie: this.douyinCookie,
};
- 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=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&webid=7284189800734082615&msToken=B1N9FM825TkvFbayDsDvZxM8r5suLrsfQbC93TciS0O9Iii8iJpAPd__FM2rpLUJi5xtMencSXLeNn8xmOS9q7bP0CUsrt9oVTL08YXLPRzZm0dHKLc9PGRlyEk=`;
+ const dyApi = DY_INFO.replace("{}", douId);
// xg参数
const xbParam = xBogus.sign(
new URLSearchParams(new URL(dyApi).search).toString(),
@@ -236,7 +237,7 @@ export class tools extends plugin {
let tiktokVideoId = await getIdVideo(url);
tiktokVideoId = tiktokVideoId.replace(/\//g, "");
// API链接
- const API_URL = `https://api16-normal-c-useast1a.tiktokv.com/aweme/v1/feed/?aweme_id=${ tiktokVideoId }`;
+ const API_URL = TIKTOK_INFO.replace("{}", tiktokVideoId);
await fetch(API_URL, {
headers: {
"User-Agent":
@@ -491,7 +492,7 @@ export class tools extends plugin {
return true;
}
- // 小蓝鸟解析
+ // 小蓝鸟解析:停止更新
// 例子:https://twitter.com/chonkyanimalx/status/1595834168000204800
async twitter(e) {
// 配置参数及解析
@@ -499,65 +500,70 @@ export class tools extends plugin {
const twitterUrl = reg.exec(e.msg);
const id = twitterUrl[1];
// 判断是否是海外服务器,默认为false
- const isProxy = !(await this.isOverseasServer());
- const httpAgent = new HttpsProxyAgent(this.myProxy);
- const twitterClient = new TwitterApi(Buffer.from(TWITTER_BEARER_TOKEN, "base64").toString(), !isProxy ?? { httpAgent });
+ const isOversea = !(await this.isOverseasServer());
- // Tell typescript it's a readonly app
- const readOnlyClient = twitterClient.readOnly;
- readOnlyClient.v2
- .singleTweet(id, {
- "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"],
- })
- .then(async resp => {
- e.reply(`识别:小蓝鸟学习版,${ resp.data.text }`);
- const downloadPath = `${ this.defaultPath }${ this.e.group_id || this.e.user_id }`;
- // 创建文件夹(如果没有过这个群)
- if (!fs.existsSync(downloadPath)) {
- mkdirsSync(downloadPath);
+ // 请求
+ const params = {
+ "ids": id,
+ "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()}`
+ },
+ ...params,
+ agent: !isOversea ? '' : new HttpProxyAgent(this.myProxy),
+ }).then(async resp => {
+ logger.info(resp)
+ e.reply(`识别:小蓝鸟学习版,${ resp.data.text }`);
+ const downloadPath = `${ this.defaultPath }${ this.e.group_id || this.e.user_id }`;
+ // 创建文件夹(如果没有过这个群)
+ if (!fs.existsSync(downloadPath)) {
+ mkdirsSync(downloadPath);
+ }
+ // 逐个遍历判断
+ let task = [];
+ for (let item of resp.includes.media) {
+ if (item.type === "photo") {
+ // 图片
+ task.push(this.downloadImg(item.url, downloadPath, "", true));
+ } else if (item.type === "video") {
+ // 视频
+ await this.downloadVideo(resp.includes.media[0].variants[0].url, true).then(
+ _ => {
+ e.reply(segment.video(`${ downloadPath }/temp.mp4`));
+ },
+ );
}
- // 逐个遍历判断
- let task = [];
- for (let item of resp.includes.media) {
- if (item.type === "photo") {
- // 图片
- task.push(this.downloadImg(item.url, downloadPath, "", true));
- } else if (item.type === "video") {
- // 视频
- await this.downloadVideo(resp.includes.media[0].variants[0].url, true).then(
- _ => {
- e.reply(segment.video(`${ downloadPath }/temp.mp4`));
- },
- );
- }
- }
- // 如果没有图片直接返回走
- if (task.length === 0) {
- return true;
- }
- // 下面是有图片的情况
- let images = [];
- let path = [];
- // 获取所有图片的promise
- await Promise.all(task).then(resp => {
- // console.log(resp)
- resp.forEach(item => {
- path.push(item);
- images.push({
- message: segment.image(fs.readFileSync(item)),
- nickname: this.e.sender.card || this.e.user_id,
- user_id: this.e.user_id,
- });
+ }
+ // 如果没有图片直接返回走
+ if (task.length === 0) {
+ return true;
+ }
+ // 下面是有图片的情况
+ let images = [];
+ let path = [];
+ // 获取所有图片的promise
+ await Promise.all(task).then(resp => {
+ // console.log(resp)
+ resp.forEach(item => {
+ path.push(item);
+ images.push({
+ message: segment.image(fs.readFileSync(item)),
+ nickname: this.e.sender.card || this.e.user_id,
+ user_id: this.e.user_id,
});
});
- await e.reply(await Bot.makeForwardMsg(images));
- // 清理文件
- path.forEach(item => {
- fs.unlinkSync(item);
- });
});
+ await e.reply(await Bot.makeForwardMsg(images));
+ // 清理文件
+ path.forEach(item => {
+ fs.unlinkSync(item);
+ });
+ });
return true;
}
@@ -615,7 +621,7 @@ export class tools extends plugin {
}
const downloadPath = `${ this.defaultPath }${ this.e.group_id || this.e.user_id }`;
// 获取信息
- fetch(`https://www.xiaohongshu.com/explore/${ id }`, {
+ fetch(`${XHS_REQ_LINK}${ id }`, {
headers: XHS_NO_WATERMARK_HEADER,
}).then(async resp => {
const xhsHtml = await resp.text();
@@ -951,8 +957,8 @@ export class tools extends plugin {
// bestVideo = Array.from(videos).sort((a, b) => a.rate - b.rate)[videos.length - 1];
// 较为有性能的分辨率
- bestVideo = Array.from(videos).filter(item => item.scale.includes("720") || item.scale.includes("360"))[0];
- bestAudio = Array.from(audios).filter(item => item.format === 'm4a')[0];
+ bestVideo = Array.from(videos).find(item => item.scale.includes("720") || item.scale.includes("360"));
+ bestAudio = Array.from(audios).find(item => item.format === 'm4a');
// logger.mark({
// bestVideo,
// bestAudio
@@ -969,7 +975,7 @@ export class tools extends plugin {
let cmd = //`cd '${__dirname}' && (cd tmp > /dev/null || (mkdir tmp && cd tmp)) &&` +
`yt-dlp ${ this.y2bCk !== undefined ? `--cookies ${ this.y2bCk }` : '' } ${url} -f ${ format.replace('x', '+') } ` +
`-o '${ fullpath }/${ v }.%(ext)s' ${ isProxy ? `--proxy ${ this.proxyAddr }:${ this.proxyPort }` : '' } -k --write-info-json`;
- logger.info(cmd)
+ logger.mark(cmd)
try {
await child_process.execSync(cmd);
e.reply(segment.video(`${ fullpath }/${ v }.mp4`))
@@ -1147,6 +1153,11 @@ export class tools extends plugin {
}
}
+ /**
+ * 设置海外模式
+ * @param e
+ * @returns {Promise}
+ */
async setOversea(e) {
// 查看当前设置
let os;
diff --git a/constants/bili.js b/constants/bili.js
deleted file mode 100644
index 8e0c8d9..0000000
--- a/constants/bili.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * AI总结API
- * https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/misc/sign/wbi.md
- * @type {string}
- */
-export const BILI_SUMMARY = "https://api.bilibili.com/x/web-interface/view/conclusion/get"
-
-/**
- * 视频基本信息API
- * https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/video/info.md
- * @type {string}
- */
-export const BILI_VIDEO_INFO = "http://api.bilibili.com/x/web-interface/view"
-
-/**
- * 登录基本信息
- * https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/login/login_info.md#%E5%AF%BC%E8%88%AA%E6%A0%8F%E7%94%A8%E6%88%B7%E4%BF%A1%E6%81%AF
- * @type {string}
- */
-export const BILI_NAV = "https://api.bilibili.com/x/web-interface/nav"
\ No newline at end of file
diff --git a/constants/constant.js b/constants/constant.js
index 105f92e..b89ebc7 100644
--- a/constants/constant.js
+++ b/constants/constant.js
@@ -69,4 +69,6 @@ export const DIVIDING_LINE = "\n------------------{}------------------"
* 保存判断机子是否是海外服务器的key
* @type {string}
*/
-export const REDIS_YUNZAI_ISOVERSEA = "Yz:rconsole:tools:oversea";
\ No newline at end of file
+export const REDIS_YUNZAI_ISOVERSEA = "Yz:rconsole:tools:oversea";
+
+export const TWITTER_BEARER_TOKEN = ""
\ No newline at end of file
diff --git a/constants/tools.js b/constants/tools.js
new file mode 100644
index 0000000..d3026cf
--- /dev/null
+++ b/constants/tools.js
@@ -0,0 +1,50 @@
+/**
+ * AI总结API
+ * https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/misc/sign/wbi.md
+ * @type {string}
+ */
+export const BILI_SUMMARY = "https://api.bilibili.com/x/web-interface/view/conclusion/get"
+
+/**
+ * 视频基本信息API
+ * https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/video/info.md
+ * @type {string}
+ */
+export const BILI_VIDEO_INFO = "http://api.bilibili.com/x/web-interface/view"
+
+/**
+ * 登录基本信息
+ * https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/login/login_info.md#%E5%AF%BC%E8%88%AA%E6%A0%8F%E7%94%A8%E6%88%B7%E4%BF%A1%E6%81%AF
+ * @type {string}
+ */
+export const BILI_NAV = "https://api.bilibili.com/x/web-interface/nav"
+
+/**
+ * 视频请求链接CDN
+ * @type {string}
+ */
+export const XHS_VIDEO = "http://sns-video-bd.xhscdn.com/"
+
+/**
+ * dy API
+ * @type {string}
+ */
+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&webid=7284189800734082615&msToken=B1N9FM825TkvFbayDsDvZxM8r5suLrsfQbC93TciS0O9Iii8iJpAPd__FM2rpLUJi5xtMencSXLeNn8xmOS9q7bP0CUsrt9oVTL08YXLPRzZm0dHKLc9PGRlyEk="
+
+/**
+ * Tiktok API
+ * @type {string}
+ */
+export const TIKTOK_INFO = "https://api16-normal-c-useast1a.tiktokv.com/aweme/v1/feed/?aweme_id={}"
+
+/**
+ * X API
+ * @type {string}
+ */
+export const TWITTER_TWEET_INFO = "https://api.twitter.com/2/tweets?ids={}"
+
+/**
+ * XHS 的请求链接
+ * @type {string}
+ */
+export const XHS_REQ_LINK = "https://www.xiaohongshu.com/explore/"
\ No newline at end of file
diff --git a/constants/xhs.js b/constants/xhs.js
deleted file mode 100644
index 5a305c0..0000000
--- a/constants/xhs.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * 视频请求链接CDN
- * @type {string}
- */
-export const XHS_VIDEO = "http://sns-video-bd.xhscdn.com/"
\ No newline at end of file
diff --git a/utils/biliInfo.js b/utils/biliInfo.js
index 482b3fd..535a87f 100644
--- a/utils/biliInfo.js
+++ b/utils/biliInfo.js
@@ -1,6 +1,6 @@
import fetch from "node-fetch";
import axios from "axios";
-import { BILI_VIDEO_INFO } from "../constants/bili.js";
+import { BILI_VIDEO_INFO } from "../constants/tools.js";
async function getVideoInfo(url) {
// const baseVideoInfo = "http://api.bilibili.com/x/web-interface/view";
diff --git a/utils/biliWbi.js b/utils/biliWbi.js
index a4303b5..71d148a 100644
--- a/utils/biliWbi.js
+++ b/utils/biliWbi.js
@@ -1,5 +1,5 @@
import md5 from 'md5'
-import { BILI_NAV } from "../constants/bili.js";
+import { BILI_NAV } from "../constants/tools.js";
const mixinKeyEncTab = [
46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49,