mirror of
https://github.com/Jerryplusy/rc-plugin.git
synced 2025-10-14 08:09:19 +00:00
🌈 美化代码,不做任何修改
This commit is contained in:
parent
6f28c43880
commit
ea81c265a3
4
.gitignore
vendored
4
.gitignore
vendored
@ -15,4 +15,8 @@ node_modules/
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
.idea
|
||||
.history
|
||||
package.json
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
.prettierrc.json
|
@ -1,67 +1,67 @@
|
||||
import common from '../../../lib/common/common.js'
|
||||
import fetch from 'node-fetch'
|
||||
import schedule from 'node-schedule'
|
||||
import { Group, segment } from 'oicq'
|
||||
import common from "../../../lib/common/common.js";
|
||||
import fetch from "node-fetch";
|
||||
import schedule from "node-schedule";
|
||||
import { Group, segment } from "oicq";
|
||||
|
||||
// 指定定时发送的群号
|
||||
const groupList = [ '169721415' ]
|
||||
const groupList = ["169721415"];
|
||||
|
||||
// 是否开启定时推送,默认为 true
|
||||
let isAutoPush = true
|
||||
function autoTask (func, time) {
|
||||
let isAutoPush = true;
|
||||
function autoTask(func, time) {
|
||||
if (isAutoPush) {
|
||||
schedule.scheduleJob(time, () => {
|
||||
for (let i = 0; i < groupList.length; i++) {
|
||||
let group = Bot.pickGroup(groupList[i])
|
||||
func(group)
|
||||
common.sleep(1000)
|
||||
let group = Bot.pickGroup(groupList[i]);
|
||||
func(group);
|
||||
common.sleep(1000);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 定时任务合集
|
||||
autoTask(pushDailyWorld, '0 30 8 * * ?')
|
||||
autoTask(pushTouchFish, '0 31 8 * * ?')
|
||||
autoTask(pushDailyWorld, "0 30 8 * * ?");
|
||||
autoTask(pushTouchFish, "0 31 8 * * ?");
|
||||
|
||||
export class daily extends plugin {
|
||||
constructor (e) {
|
||||
constructor(e) {
|
||||
super({
|
||||
name: 'rconsole插件帮助',
|
||||
dsc: 'rconsole插件帮助插件帮助',
|
||||
event: 'message',
|
||||
name: "rconsole插件帮助",
|
||||
dsc: "rconsole插件帮助插件帮助",
|
||||
event: "message",
|
||||
priority: 500,
|
||||
rule: [
|
||||
{
|
||||
reg: '^#每天60秒$',
|
||||
fnc: 'dailyWorld'
|
||||
reg: "^#每天60秒$",
|
||||
fnc: "dailyWorld",
|
||||
},
|
||||
{
|
||||
reg: '^#摸鱼人日历$',
|
||||
fnc: 'touchFish'
|
||||
reg: "^#摸鱼人日历$",
|
||||
fnc: "touchFish",
|
||||
},
|
||||
{
|
||||
reg: '^#开关每日推送$',
|
||||
fnc: 'shutdown'
|
||||
reg: "^#开关每日推送$",
|
||||
fnc: "shutdown",
|
||||
},
|
||||
]
|
||||
})
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
async dailyWorld (e) {
|
||||
async dailyWorld(e) {
|
||||
// 定时发送时间,采用 Cron 表达式,当前默认为每日 8:30 分推送
|
||||
await pushDailyWorld(e);
|
||||
return true;
|
||||
}
|
||||
|
||||
async touchFish (e) {
|
||||
async touchFish(e) {
|
||||
await pushTouchFish(e);
|
||||
return true;
|
||||
}
|
||||
|
||||
async shutdown (e) {
|
||||
isAutoPush = !isAutoPush
|
||||
e.reply(`【当前推送状态】:${ isAutoPush ? '开启' : '关闭' }`)
|
||||
async shutdown(e) {
|
||||
isAutoPush = !isAutoPush;
|
||||
e.reply(`【当前推送状态】:${isAutoPush ? "开启" : "关闭"}`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,41 +69,43 @@ export class daily extends plugin {
|
||||
* 推送每天60秒读懂世界
|
||||
* @param e oicq传递的事件参数e
|
||||
*/
|
||||
async function pushDailyWorld (e) {
|
||||
async function pushDailyWorld(e) {
|
||||
// 每天60秒读懂世界接口地址
|
||||
const url = await fetch('https://api.vvhan.com/api/60s?type=json')
|
||||
.catch(err => logger.error(err))
|
||||
const imgUrl = await url.json()
|
||||
const res = await imgUrl.imgUrl
|
||||
const url = await fetch("https://api.vvhan.com/api/60s?type=json").catch(err =>
|
||||
logger.error(err)
|
||||
);
|
||||
const imgUrl = await url.json();
|
||||
const res = await imgUrl.imgUrl;
|
||||
|
||||
// 判断接口是否请求成功
|
||||
if (!res) {
|
||||
e.reply('[60秒读懂世界] 接口请求失败')
|
||||
e.reply("[60秒读懂世界] 接口请求失败");
|
||||
}
|
||||
|
||||
// 回复消息
|
||||
if (e instanceof Group) {
|
||||
e.sendMsg(segment.image(res))
|
||||
e.sendMsg(segment.image(res));
|
||||
} else {
|
||||
e.reply(segment.image(res))
|
||||
e.reply(segment.image(res));
|
||||
}
|
||||
}
|
||||
|
||||
async function pushTouchFish (e) {
|
||||
const url = await fetch('https://api.vvhan.com/api/moyu?type=json')
|
||||
.catch(err => logger.error(err))
|
||||
const imgUrl = await url.json()
|
||||
const res = await imgUrl.url
|
||||
async function pushTouchFish(e) {
|
||||
const url = await fetch("https://api.vvhan.com/api/moyu?type=json").catch(err =>
|
||||
logger.error(err)
|
||||
);
|
||||
const imgUrl = await url.json();
|
||||
const res = await imgUrl.url;
|
||||
|
||||
// 判断接口是否请求成功
|
||||
if (!res) {
|
||||
e.reply('[摸鱼人日历] 接口请求失败')
|
||||
e.reply("[摸鱼人日历] 接口请求失败");
|
||||
}
|
||||
|
||||
// 回复消息
|
||||
if (e instanceof Group) {
|
||||
e.sendMsg(segment.image(res))
|
||||
e.sendMsg(segment.image(res));
|
||||
} else {
|
||||
e.reply(segment.image(res))
|
||||
e.reply(segment.image(res));
|
||||
}
|
||||
}
|
52
apps/help.js
52
apps/help.js
@ -1,42 +1,42 @@
|
||||
import Help from '../model/help.js'
|
||||
import puppeteer from '../../../lib/puppeteer/puppeteer.js'
|
||||
import md5 from 'md5'
|
||||
import Help from "../model/help.js";
|
||||
import puppeteer from "../../../lib/puppeteer/puppeteer.js";
|
||||
import md5 from "md5";
|
||||
|
||||
let helpData = {
|
||||
md5: '',
|
||||
img: ''
|
||||
}
|
||||
md5: "",
|
||||
img: "",
|
||||
};
|
||||
|
||||
export class help extends plugin {
|
||||
constructor (e) {
|
||||
constructor(e) {
|
||||
super({
|
||||
name: 'rconsole插件帮助',
|
||||
dsc: 'rconsole插件帮助插件帮助',
|
||||
event: 'message',
|
||||
name: "rconsole插件帮助",
|
||||
dsc: "rconsole插件帮助插件帮助",
|
||||
event: "message",
|
||||
priority: 500,
|
||||
rule: [
|
||||
{
|
||||
reg: '^#*(R|r)(插件)?(命令|帮助|菜单|help|说明|功能|指令|使用说明)$',
|
||||
fnc: 'help'
|
||||
}
|
||||
]
|
||||
})
|
||||
reg: "^#*(R|r)(插件)?(命令|帮助|菜单|help|说明|功能|指令|使用说明)$",
|
||||
fnc: "help",
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
async help () {
|
||||
let data = await Help.get(this.e)
|
||||
if (!data) return
|
||||
let img = await this.cache(data)
|
||||
await this.reply(img)
|
||||
async help() {
|
||||
let data = await Help.get(this.e);
|
||||
if (!data) return;
|
||||
let img = await this.cache(data);
|
||||
await this.reply(img);
|
||||
}
|
||||
|
||||
async cache (data) {
|
||||
let tmp = md5(JSON.stringify(data))
|
||||
if (helpData.md5 == tmp) return helpData.img
|
||||
async cache(data) {
|
||||
let tmp = md5(JSON.stringify(data));
|
||||
if (helpData.md5 == tmp) return helpData.img;
|
||||
|
||||
helpData.img = await puppeteer.screenshot('help', data)
|
||||
helpData.md5 = tmp
|
||||
helpData.img = await puppeteer.screenshot("help", data);
|
||||
helpData.md5 = tmp;
|
||||
|
||||
return helpData.img
|
||||
return helpData.img;
|
||||
}
|
||||
}
|
||||
|
257
apps/mystery.js
257
apps/mystery.js
@ -1,11 +1,11 @@
|
||||
// 主库
|
||||
import { segment } from 'oicq'
|
||||
import common from '../../../lib/common/common.js'
|
||||
import fetch from 'node-fetch'
|
||||
import { segment } from "oicq";
|
||||
import common from "../../../lib/common/common.js";
|
||||
import fetch from "node-fetch";
|
||||
// 配置文件
|
||||
import config from '../model/index.js'
|
||||
import config from "../model/index.js";
|
||||
// 其他库
|
||||
import _ from 'lodash'
|
||||
import _ from "lodash";
|
||||
// import mongodb from 'mongodb'
|
||||
|
||||
// Mongodb初始化
|
||||
@ -26,42 +26,47 @@ import _ from 'lodash'
|
||||
//
|
||||
// const mongo = initMongo()
|
||||
// 60s后撤回
|
||||
const recallTime = 109
|
||||
const recallTime = 109;
|
||||
|
||||
export class mystery extends plugin {
|
||||
constructor () {
|
||||
constructor() {
|
||||
super({
|
||||
name: '神秘区域',
|
||||
dsc: '神秘指令',
|
||||
event: 'message.group',
|
||||
name: "神秘区域",
|
||||
dsc: "神秘指令",
|
||||
event: "message.group",
|
||||
priority: 500,
|
||||
rule: [
|
||||
{
|
||||
reg: '^#(雀食|确实)$', fnc: 'mystery'
|
||||
reg: "^#(雀食|确实)$",
|
||||
fnc: "mystery",
|
||||
},
|
||||
{
|
||||
reg: '^#*来份涩图 (.*)$', fnc: 'setu'
|
||||
reg: "^#*来份涩图 (.*)$",
|
||||
fnc: "setu",
|
||||
},
|
||||
{
|
||||
reg: '^#(累了)$', fnc: 'cospro'
|
||||
reg: "^#(累了)$",
|
||||
fnc: "cospro",
|
||||
},
|
||||
{
|
||||
reg: '^#(啊?|啊?)$', fnc: 'aaa'
|
||||
}
|
||||
reg: "^#(啊?|啊?)$",
|
||||
fnc: "aaa",
|
||||
},
|
||||
// {
|
||||
// reg: '^#我靠', fnc: 'tuiimg'
|
||||
// }
|
||||
]
|
||||
})
|
||||
this.mysteryConfig = config.getConfig('mystery')
|
||||
],
|
||||
});
|
||||
this.mysteryConfig = config.getConfig("mystery");
|
||||
}
|
||||
|
||||
/** 接受到消息都会先执行一次 */
|
||||
async accept() {
|
||||
if (this.e.isGroup) {
|
||||
let group = this.e.group;
|
||||
if (!group.is_owner && (group.is_admin && group.mute_left > 0)) return;
|
||||
if (!(group.is_owner || group.is_admin) && (group.all_muted || group.mute_left > 0)) return;
|
||||
if (!group.is_owner && group.is_admin && group.mute_left > 0) return;
|
||||
if (!(group.is_owner || group.is_admin) && (group.all_muted || group.mute_left > 0))
|
||||
return;
|
||||
}
|
||||
|
||||
let old_reply = this.e.reply;
|
||||
@ -75,8 +80,11 @@ export class mystery extends plugin {
|
||||
let isxml = false;
|
||||
|
||||
for (let msg of msgs) {
|
||||
if (msg && msg?.type == 'xml' && msg?.data) {
|
||||
msg.data = msg.data.replace(/^<\?xml.*version=.*?>/g, '<?xml version="1.0" encoding="utf-8" ?>');
|
||||
if (msg && msg?.type == "xml" && msg?.data) {
|
||||
msg.data = msg.data.replace(
|
||||
/^<\?xml.*version=.*?>/g,
|
||||
'<?xml version="1.0" encoding="utf-8" ?>'
|
||||
);
|
||||
isxml = true;
|
||||
}
|
||||
}
|
||||
@ -84,172 +92,183 @@ export class mystery extends plugin {
|
||||
if (isxml) {
|
||||
result = await old_reply(msgs, quote, data);
|
||||
} else {
|
||||
let MsgList = [{
|
||||
message: msgs,
|
||||
nickname: Bot.nickname,
|
||||
user_id: Bot.uin
|
||||
}];
|
||||
let MsgList = [
|
||||
{
|
||||
message: msgs,
|
||||
nickname: Bot.nickname,
|
||||
user_id: Bot.uin,
|
||||
},
|
||||
];
|
||||
|
||||
let forwardMsg = await Bot.makeForwardMsg(MsgList);
|
||||
|
||||
forwardMsg.data = forwardMsg.data
|
||||
.replace('<?xml version="1.0" encoding="utf-8"?>', '<?xml version="1.0" encoding="utf-8" ?>')
|
||||
.replace(/\n/g, '')
|
||||
.replace(/<title color="#777777" size="26">(.+?)<\/title>/g, '___')
|
||||
.replace(
|
||||
'<?xml version="1.0" encoding="utf-8"?>',
|
||||
'<?xml version="1.0" encoding="utf-8" ?>'
|
||||
)
|
||||
.replace(/\n/g, "")
|
||||
.replace(/<title color="#777777" size="26">(.+?)<\/title>/g, "___")
|
||||
.replace(/___+/, '<title color="#777777" size="26">请点击查看内容</title>');
|
||||
msgs = forwardMsg;
|
||||
result = await old_reply(msgs, quote, data);
|
||||
}
|
||||
|
||||
if (!result || !result.message_id) {
|
||||
logger.error('风控消息处理失败,请登录手机QQ查看是否可手动解除风控!');
|
||||
logger.error("风控消息处理失败,请登录手机QQ查看是否可手动解除风控!");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async mystery (e) {
|
||||
async mystery(e) {
|
||||
// 最大页数
|
||||
const maxPage = this.mysteryConfig.mystery.maxPage
|
||||
const maxPigObj = this.mysteryConfig.mystery.maxPigObj
|
||||
const maxPage = this.mysteryConfig.mystery.maxPage;
|
||||
const maxPigObj = this.mysteryConfig.mystery.maxPigObj;
|
||||
// 限制最大图片数量
|
||||
const imageCountLimit = this.mysteryConfig.mystery.imageCountLimit
|
||||
const imageCountLimit = this.mysteryConfig.mystery.imageCountLimit;
|
||||
// 随机算法
|
||||
const page = _.random(1, maxPage)
|
||||
const randomIndex = _.random(0, maxPigObj - 1)
|
||||
const page = _.random(1, maxPage);
|
||||
const randomIndex = _.random(0, maxPigObj - 1);
|
||||
// 回复
|
||||
this.reply('确实是吧, 正在探索...')
|
||||
this.reply("确实是吧, 正在探索...");
|
||||
// 请求
|
||||
let url = `https://www.cos6.net/wp-json/wp/v2/posts?page=${ page }`
|
||||
let images = []
|
||||
let url = `https://www.cos6.net/wp-json/wp/v2/posts?page=${page}`;
|
||||
let images = [];
|
||||
await fetch(url)
|
||||
.then((resp) => {
|
||||
return resp.json()
|
||||
.then(resp => {
|
||||
return resp.json();
|
||||
})
|
||||
.then((json) => {
|
||||
.then(json => {
|
||||
const template = {
|
||||
nickname: this.e.sender.card || this.e.user_id,
|
||||
user_id: this.e.user_id
|
||||
}
|
||||
user_id: this.e.user_id,
|
||||
};
|
||||
|
||||
const content = json[randomIndex].content
|
||||
images = this.getCos6Img(content.rendered)
|
||||
const content = json[randomIndex].content;
|
||||
images = this.getCos6Img(content.rendered);
|
||||
// 洗牌
|
||||
images = _.shuffle(images)
|
||||
images = _.shuffle(images);
|
||||
// 限制长度
|
||||
if (images.length > imageCountLimit) {
|
||||
images = images.slice(1, imageCountLimit + 1)
|
||||
images = images.slice(1, imageCountLimit + 1);
|
||||
}
|
||||
// 循环队列
|
||||
for (let i = 0; i < images.length; i++) {
|
||||
images[i] = {
|
||||
message: segment.image(images[i]),
|
||||
...template
|
||||
}
|
||||
...template,
|
||||
};
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
this.e.reply('探索失败,你再我去一次吧')
|
||||
logger.error(err)
|
||||
return false
|
||||
})
|
||||
return !!(await this.reply(await Bot.makeForwardMsg(images)))
|
||||
.catch(err => {
|
||||
this.e.reply("探索失败,你再我去一次吧");
|
||||
logger.error(err);
|
||||
return false;
|
||||
});
|
||||
return !!(await this.reply(await Bot.makeForwardMsg(images)));
|
||||
}
|
||||
|
||||
async cospro (e) {
|
||||
let req = [ ...await fetch('https://imgapi.cn/cos2.php?return=jsonpro').then((resp) => resp.json()).then((json) => json.imgurls), ...await fetch('https://imgapi.cn/cos.php?return=jsonpro').then((resp) => resp.json()).then((json) => json.imgurls) ]
|
||||
e.reply('哪天克火掉一定是在这个群里面...')
|
||||
let images = []
|
||||
async cospro(e) {
|
||||
let req = [
|
||||
...(await fetch("https://imgapi.cn/cos2.php?return=jsonpro")
|
||||
.then(resp => resp.json())
|
||||
.then(json => json.imgurls)),
|
||||
...(await fetch("https://imgapi.cn/cos.php?return=jsonpro")
|
||||
.then(resp => resp.json())
|
||||
.then(json => json.imgurls)),
|
||||
];
|
||||
e.reply("哪天克火掉一定是在这个群里面...");
|
||||
let images = [];
|
||||
req.forEach(item => {
|
||||
images.push({
|
||||
message: segment.image(encodeURI(item)),
|
||||
nickname: this.e.sender.card || this.e.user_id,
|
||||
user_id: this.e.user_id
|
||||
})
|
||||
})
|
||||
return !!(await this.reply(await Bot.makeForwardMsg(images)))
|
||||
user_id: this.e.user_id,
|
||||
});
|
||||
});
|
||||
return !!(await this.reply(await Bot.makeForwardMsg(images)));
|
||||
}
|
||||
|
||||
async aaa (e) {
|
||||
async aaa(e) {
|
||||
// https://yingtall.com/wp-json/wp/v2/posts?page=64
|
||||
// 最大页数
|
||||
const maxPage = this.mysteryConfig.aaa.maxPage
|
||||
const maxPigObj = this.mysteryConfig.aaa.maxPigObj
|
||||
const maxPage = this.mysteryConfig.aaa.maxPage;
|
||||
const maxPigObj = this.mysteryConfig.aaa.maxPigObj;
|
||||
// 限制最大图片数量
|
||||
const imageCountLimit = this.mysteryConfig.aaa.imageCountLimit
|
||||
const imageCountLimit = this.mysteryConfig.aaa.imageCountLimit;
|
||||
// 随机算法
|
||||
const page = _.random(1, maxPage)
|
||||
const randomIndex = _.random(0, maxPigObj - 1)
|
||||
const page = _.random(1, maxPage);
|
||||
const randomIndex = _.random(0, maxPigObj - 1);
|
||||
// 回复
|
||||
this.reply('真变态啊...')
|
||||
this.reply("真变态啊...");
|
||||
// 请求
|
||||
let images = []
|
||||
let imgData = []
|
||||
let url = `https://yingtall.com/wp-json/wp/v2/posts?page=${ page }`
|
||||
let images = [];
|
||||
let imgData = [];
|
||||
let url = `https://yingtall.com/wp-json/wp/v2/posts?page=${page}`;
|
||||
await fetch(url)
|
||||
.then((resp) => {
|
||||
return resp.json()
|
||||
.then(resp => {
|
||||
return resp.json();
|
||||
})
|
||||
.then((json) => {
|
||||
.then(json => {
|
||||
if (!json.length) {
|
||||
e.reply('探索失败,你再我去一次吧')
|
||||
return false
|
||||
e.reply("探索失败,你再我去一次吧");
|
||||
return false;
|
||||
}
|
||||
const content = json[randomIndex].content
|
||||
images = this.getImages2(content.rendered)
|
||||
const content = json[randomIndex].content;
|
||||
images = this.getImages2(content.rendered);
|
||||
// 如果图片为空直接返回
|
||||
if (images.length === 0) {
|
||||
e.reply('探索失败,你再我去一次吧')
|
||||
return false
|
||||
e.reply("探索失败,你再我去一次吧");
|
||||
return false;
|
||||
}
|
||||
// 洗牌
|
||||
images = _.shuffle(images)
|
||||
images = _.shuffle(images);
|
||||
// 限制长度
|
||||
if (images.length > imageCountLimit) {
|
||||
images = images.slice(1, imageCountLimit + 1)
|
||||
images = images.slice(1, imageCountLimit + 1);
|
||||
}
|
||||
// 循环队列
|
||||
images.forEach((item) => {
|
||||
images.forEach(item => {
|
||||
imgData.push({
|
||||
message: segment.image(item),
|
||||
nickname: e.sender.card || e.user_id,
|
||||
user_id: e.user_id
|
||||
})
|
||||
})
|
||||
user_id: e.user_id,
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((err) => logger.error(err))
|
||||
return !!(await this.reply(await Bot.makeForwardMsg(imgData)))
|
||||
.catch(err => logger.error(err));
|
||||
return !!(await this.reply(await Bot.makeForwardMsg(imgData)));
|
||||
}
|
||||
|
||||
async setu (e) {
|
||||
const keyword = e.msg.split(' ')[1]
|
||||
const numb = this.mysteryConfig.setu.count
|
||||
await e.reply('正在给你找图片啦~', true, { recallMsg: 7 });
|
||||
async setu(e) {
|
||||
const keyword = e.msg.split(" ")[1];
|
||||
const numb = this.mysteryConfig.setu.count;
|
||||
await e.reply("正在给你找图片啦~", true, { recallMsg: 7 });
|
||||
|
||||
let url = `https://api.lolicon.app/setu/v2?r18=${ keyword }&num=${ numb }`;//←此处修改图片类型,0为非18,1为18,2为18非18混合
|
||||
let url = `https://api.lolicon.app/setu/v2?r18=${keyword}&num=${numb}`; //←此处修改图片类型,0为非18,1为18,2为18非18混合
|
||||
const response = await fetch(url);
|
||||
const imgJson = await response.json();
|
||||
|
||||
const images = []
|
||||
const images = [];
|
||||
for (let image of imgJson.data) {
|
||||
images.push({
|
||||
message: segment.image(image.urls.original),
|
||||
nickname: e.sender.card || e.user_id,
|
||||
user_id: e.user_id
|
||||
})
|
||||
user_id: e.user_id,
|
||||
});
|
||||
}
|
||||
|
||||
const res = await this.reply(
|
||||
await Bot.makeForwardMsg(images),
|
||||
false,
|
||||
{ recallMsg: 60 })
|
||||
const res = await this.reply(await Bot.makeForwardMsg(images), false, { recallMsg: 60 });
|
||||
|
||||
if (!res) {
|
||||
return e.reply('好、好涩(//// ^ ////)……不、不行啦……被、被吞啦o(≧口≦)o',true,{recallMsg:60});
|
||||
return e.reply("好、好涩(//// ^ ////)……不、不行啦……被、被吞啦o(≧口≦)o", true, {
|
||||
recallMsg: 60,
|
||||
});
|
||||
}
|
||||
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
|
||||
// async tuiimg (e) {
|
||||
@ -274,24 +293,24 @@ export class mystery extends plugin {
|
||||
// }
|
||||
|
||||
// 正则:获取图片
|
||||
getCos6Img (string) {
|
||||
const imgRex = /\/([\w].*?).(jpg|JPG|png|PNG|gif|GIF|jpeg|JPEG|svg)/g
|
||||
const images = []
|
||||
let img
|
||||
getCos6Img(string) {
|
||||
const imgRex = /\/([\w].*?).(jpg|JPG|png|PNG|gif|GIF|jpeg|JPEG|svg)/g;
|
||||
const images = [];
|
||||
let img;
|
||||
while ((img = imgRex.exec(string))) {
|
||||
images.push(`https://www.cos6.net/${ img[1] }.jpg`)
|
||||
images.push(`https://www.cos6.net/${img[1]}.jpg`);
|
||||
}
|
||||
return images
|
||||
return images;
|
||||
}
|
||||
|
||||
// 正则:获取图片
|
||||
getImages2 (string) {
|
||||
const imgRex = /<img.*?src="(.*?)"[^>]+>/g
|
||||
const images = []
|
||||
let img
|
||||
getImages2(string) {
|
||||
const imgRex = /<img.*?src="(.*?)"[^>]+>/g;
|
||||
const images = [];
|
||||
let img;
|
||||
while ((img = imgRex.exec(string))) {
|
||||
images.push(img[1])
|
||||
images.push(img[1]);
|
||||
}
|
||||
return images
|
||||
return images;
|
||||
}
|
||||
}
|
||||
|
376
apps/query.js
376
apps/query.js
@ -1,88 +1,93 @@
|
||||
// 主库
|
||||
import { segment } from 'oicq'
|
||||
import fetch from 'node-fetch'
|
||||
import { segment } from "oicq";
|
||||
import fetch from "node-fetch";
|
||||
// 配置文件
|
||||
import config from '../model/index.js'
|
||||
import config from "../model/index.js";
|
||||
// 爬虫库
|
||||
import puppeteer from '../../../lib/puppeteer/puppeteer.js'
|
||||
import _ from 'lodash'
|
||||
import puppeteer from "../../../lib/puppeteer/puppeteer.js";
|
||||
import _ from "lodash";
|
||||
|
||||
export class query extends plugin {
|
||||
constructor () {
|
||||
constructor() {
|
||||
super({
|
||||
name: '查询类',
|
||||
dsc: '查询相关指令',
|
||||
event: 'message.group',
|
||||
name: "查询类",
|
||||
dsc: "查询相关指令",
|
||||
event: "message.group",
|
||||
priority: 500,
|
||||
rule: [
|
||||
{
|
||||
reg: '^#*医药查询 (.*)$',
|
||||
fnc: 'doctor'
|
||||
reg: "^#*医药查询 (.*)$",
|
||||
fnc: "doctor",
|
||||
},
|
||||
{
|
||||
reg: '^#*评分 (.*)',
|
||||
fnc: 'videoScore'
|
||||
reg: "^#*评分 (.*)",
|
||||
fnc: "videoScore",
|
||||
},
|
||||
{
|
||||
reg: '^#(cat)$',
|
||||
fnc: 'cat'
|
||||
reg: "^#(cat)$",
|
||||
fnc: "cat",
|
||||
},
|
||||
{
|
||||
reg: '^#电脑软件推荐$', /** 执行方法 */
|
||||
fnc: 'computerRecommended'
|
||||
reg: "^#电脑软件推荐$" /** 执行方法 */,
|
||||
fnc: "computerRecommended",
|
||||
},
|
||||
{
|
||||
reg: '^#安卓软件推荐$', /** 执行方法 */
|
||||
fnc: 'androidRecommended'
|
||||
reg: "^#安卓软件推荐$" /** 执行方法 */,
|
||||
fnc: "androidRecommended",
|
||||
},
|
||||
{
|
||||
reg: '^#(热搜)(.*)$',
|
||||
fnc: 'hotSearch'
|
||||
reg: "^#(热搜)(.*)$",
|
||||
fnc: "hotSearch",
|
||||
},
|
||||
{
|
||||
reg: '#买家秀',
|
||||
fnc: 'buyerShow'
|
||||
}
|
||||
]
|
||||
})
|
||||
this.catConfig = config.getConfig('query')
|
||||
reg: "#买家秀",
|
||||
fnc: "buyerShow",
|
||||
},
|
||||
],
|
||||
});
|
||||
this.catConfig = config.getConfig("query");
|
||||
}
|
||||
|
||||
async doctor (e) {
|
||||
let keyword = e.msg.split(' ')[1]
|
||||
const url = `https://api2.dayi.org.cn/api/search2?keyword=${ keyword }&pageNo=1&pageSize=10`
|
||||
async doctor(e) {
|
||||
let keyword = e.msg.split(" ")[1];
|
||||
const url = `https://api2.dayi.org.cn/api/search2?keyword=${keyword}&pageNo=1&pageSize=10`;
|
||||
let res = await fetch(url)
|
||||
.then((resp) => resp.json())
|
||||
.then((resp) => resp.list)
|
||||
let msg = []
|
||||
.then(resp => resp.json())
|
||||
.then(resp => resp.list);
|
||||
let msg = [];
|
||||
for (const element of res) {
|
||||
const title = this.removeTag(element.title)
|
||||
const title = this.removeTag(element.title);
|
||||
const template = `
|
||||
${ title }\n
|
||||
标签:${ element.secondTitle }\n
|
||||
介绍:${ element.introduction }
|
||||
`
|
||||
${title}\n
|
||||
标签:${element.secondTitle}\n
|
||||
介绍:${element.introduction}
|
||||
`;
|
||||
// 如果完全匹配,直接响应页面
|
||||
if (title === keyword) {
|
||||
const browser = await puppeteer.browserInit()
|
||||
const page = await browser.newPage()
|
||||
await page.goto(`https://www.dayi.org.cn/drug/${ element.id }`)
|
||||
const browser = await puppeteer.browserInit();
|
||||
const page = await browser.newPage();
|
||||
await page.goto(`https://www.dayi.org.cn/drug/${element.id}`);
|
||||
let buff = await page.screenshot({
|
||||
fullPage: true, type: 'jpeg', omitBackground: false, quality: 90
|
||||
})
|
||||
browser.close()
|
||||
await e.reply(segment.image(buff))
|
||||
fullPage: true,
|
||||
type: "jpeg",
|
||||
omitBackground: false,
|
||||
quality: 90,
|
||||
});
|
||||
browser.close();
|
||||
await e.reply(segment.image(buff));
|
||||
}
|
||||
msg.push({
|
||||
message: { type: 'text', text: `${ template }` }, nickname: Bot.nickname, user_id: Bot.user_id
|
||||
})
|
||||
message: { type: "text", text: `${template}` },
|
||||
nickname: Bot.nickname,
|
||||
user_id: Bot.user_id,
|
||||
});
|
||||
}
|
||||
/** 最后回复消息 */
|
||||
return !!this.reply(await Bot.makeForwardMsg(msg))
|
||||
return !!this.reply(await Bot.makeForwardMsg(msg));
|
||||
}
|
||||
|
||||
async videoScore(e) {
|
||||
let keyword = e.msg.split(' ')[1]
|
||||
let keyword = e.msg.split(" ")[1];
|
||||
const api = `https://movie.douban.com/j/subject_suggest?q=${encodeURI(keyword)}`;
|
||||
|
||||
let movieId = 30433417;
|
||||
@ -91,182 +96,207 @@ export class query extends plugin {
|
||||
"User-Agent":
|
||||
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
}).then(resp => resp.json()).then(resp => {
|
||||
if (resp.length === 0 || resp === "") {
|
||||
e.reply("没找到!");
|
||||
return true;
|
||||
}
|
||||
movieId = resp[0].id;
|
||||
const doubanApi = `https://movie.querydata.org/api?id=${movieId}`;
|
||||
fetch(doubanApi, {
|
||||
Headers: {
|
||||
"User-Agent":
|
||||
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
}).then(resp => resp.json()).then(resp => {
|
||||
},
|
||||
})
|
||||
.then(resp => resp.json())
|
||||
.then(resp => {
|
||||
if (resp.length === 0 || resp === "") {
|
||||
e.reply("没找到!");
|
||||
return true;
|
||||
}
|
||||
e.reply(`识别:${resp.data[0].name}\n烂番茄评分:${resp.imdbRating}\n豆瓣评分:${resp.doubanRating}\n评分:${resp.imdbRating}`);
|
||||
})
|
||||
})
|
||||
movieId = resp[0].id;
|
||||
const doubanApi = `https://movie.querydata.org/api?id=${movieId}`;
|
||||
fetch(doubanApi, {
|
||||
Headers: {
|
||||
"User-Agent":
|
||||
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.then(resp => resp.json())
|
||||
.then(resp => {
|
||||
if (resp.length === 0 || resp === "") {
|
||||
e.reply("没找到!");
|
||||
return true;
|
||||
}
|
||||
e.reply(
|
||||
`识别:${resp.data[0].name}\n烂番茄评分:${resp.imdbRating}\n豆瓣评分:${resp.doubanRating}\n评分:${resp.imdbRating}`
|
||||
);
|
||||
});
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
async cat (e) {
|
||||
const numb = this.catConfig.count
|
||||
let images = []
|
||||
let reqRes = [ ...await fetch(`https://shibe.online/api/cats?count=${ numb }`).then(data => data.json()), ...await fetch(`https://api.thecatapi.com/v1/images/search?limit=${ numb }`).then(data => data.json()).then(json => json.map(item => item.url)) ]
|
||||
e.reply('涩图也不看了,就看猫是吧, 探索中...')
|
||||
async cat(e) {
|
||||
const numb = this.catConfig.count;
|
||||
let images = [];
|
||||
let reqRes = [
|
||||
...(await fetch(`https://shibe.online/api/cats?count=${numb}`).then(data =>
|
||||
data.json()
|
||||
)),
|
||||
...(await fetch(`https://api.thecatapi.com/v1/images/search?limit=${numb}`)
|
||||
.then(data => data.json())
|
||||
.then(json => json.map(item => item.url))),
|
||||
];
|
||||
e.reply("涩图也不看了,就看猫是吧, 探索中...");
|
||||
reqRes.forEach(item => {
|
||||
images.push({
|
||||
message: segment.image(item), nickname: this.e.sender.card || this.e.user_id, user_id: this.e.user_id
|
||||
})
|
||||
})
|
||||
return !!(await this.reply(await Bot.makeForwardMsg(images)))
|
||||
message: segment.image(item),
|
||||
nickname: this.e.sender.card || this.e.user_id,
|
||||
user_id: this.e.user_id,
|
||||
});
|
||||
});
|
||||
return !!(await this.reply(await Bot.makeForwardMsg(images)));
|
||||
}
|
||||
|
||||
async computerRecommended (e) {
|
||||
let url = 'https://www.ghxi.com/ghapi?type=query&n=pc'
|
||||
async computerRecommended(e) {
|
||||
let url = "https://www.ghxi.com/ghapi?type=query&n=pc";
|
||||
/** 调用接口获取数据 */
|
||||
let res = await fetch(url).catch((err) => logger.error(err))
|
||||
let res = await fetch(url).catch(err => logger.error(err));
|
||||
|
||||
/** 接口结果,json字符串转对象 */
|
||||
res = await res.json()
|
||||
let msg = []
|
||||
res.data.list.forEach((element) => {
|
||||
const template = `推荐软件:${ element.title }\n地址:${ element.url }\n`
|
||||
res = await res.json();
|
||||
let msg = [];
|
||||
res.data.list.forEach(element => {
|
||||
const template = `推荐软件:${element.title}\n地址:${element.url}\n`;
|
||||
msg.push({
|
||||
message: { type: 'text', text: `${ template }` }, nickname: Bot.nickname, user_id: Bot.user_id
|
||||
})
|
||||
})
|
||||
message: { type: "text", text: `${template}` },
|
||||
nickname: Bot.nickname,
|
||||
user_id: Bot.user_id,
|
||||
});
|
||||
});
|
||||
/** 最后回复消息 */
|
||||
return !!this.reply(await Bot.makeForwardMsg(msg))
|
||||
return !!this.reply(await Bot.makeForwardMsg(msg));
|
||||
}
|
||||
|
||||
async androidRecommended (e) {
|
||||
let url = 'https://www.ghxi.com/ghapi?type=query&n=and'
|
||||
let res = await fetch(url).catch((err) => logger.error(err))
|
||||
res = await res.json()
|
||||
let msg = []
|
||||
res.data.list.forEach((element) => {
|
||||
const template = `推荐软件:${ element.title }\n地址:${ element.url }\n`
|
||||
async androidRecommended(e) {
|
||||
let url = "https://www.ghxi.com/ghapi?type=query&n=and";
|
||||
let res = await fetch(url).catch(err => logger.error(err));
|
||||
res = await res.json();
|
||||
let msg = [];
|
||||
res.data.list.forEach(element => {
|
||||
const template = `推荐软件:${element.title}\n地址:${element.url}\n`;
|
||||
msg.push({
|
||||
message: { type: 'text', text: `${ template }` }, nickname: Bot.nickname, user_id: Bot.user_id
|
||||
})
|
||||
})
|
||||
return !!this.reply(await Bot.makeForwardMsg(msg))
|
||||
message: { type: "text", text: `${template}` },
|
||||
nickname: Bot.nickname,
|
||||
user_id: Bot.user_id,
|
||||
});
|
||||
});
|
||||
return !!this.reply(await Bot.makeForwardMsg(msg));
|
||||
}
|
||||
|
||||
async hotSearch (e) {
|
||||
let keyword = e.msg.replace(/#|热搜/g, '').trim()
|
||||
console.log(keyword)
|
||||
async hotSearch(e) {
|
||||
let keyword = e.msg.replace(/#|热搜/g, "").trim();
|
||||
console.log(keyword);
|
||||
// 虎扑/知乎/36氪/百度/哔哩哔哩/贴吧/微博/抖音/豆瓣/少数派/IT资讯/微信
|
||||
let url = 'https://api.vvhan.com/api/hotlist?type='
|
||||
let url = "https://api.vvhan.com/api/hotlist?type=";
|
||||
switch (keyword) {
|
||||
case '虎扑':
|
||||
url += 'huPu'
|
||||
break
|
||||
case '知乎':
|
||||
url += 'zhihuHot'
|
||||
break
|
||||
case '36氪':
|
||||
url += '36Ke'
|
||||
break
|
||||
case '百度':
|
||||
url += 'baiduRD'
|
||||
break
|
||||
case '哔哩哔哩':
|
||||
url += 'bili'
|
||||
break
|
||||
case '贴吧':
|
||||
url += 'baiduRY'
|
||||
break
|
||||
case '微博':
|
||||
url += 'wbHot'
|
||||
break
|
||||
case '抖音':
|
||||
url += 'douyinHot'
|
||||
break
|
||||
case '豆瓣':
|
||||
url += 'douban'
|
||||
break
|
||||
case '少数派':
|
||||
url += 'ssPai'
|
||||
break
|
||||
case 'IT资讯':
|
||||
url += 'itInfo'
|
||||
break
|
||||
case '微信':
|
||||
url += 'wxHot'
|
||||
break
|
||||
case "虎扑":
|
||||
url += "huPu";
|
||||
break;
|
||||
case "知乎":
|
||||
url += "zhihuHot";
|
||||
break;
|
||||
case "36氪":
|
||||
url += "36Ke";
|
||||
break;
|
||||
case "百度":
|
||||
url += "baiduRD";
|
||||
break;
|
||||
case "哔哩哔哩":
|
||||
url += "bili";
|
||||
break;
|
||||
case "贴吧":
|
||||
url += "baiduRY";
|
||||
break;
|
||||
case "微博":
|
||||
url += "wbHot";
|
||||
break;
|
||||
case "抖音":
|
||||
url += "douyinHot";
|
||||
break;
|
||||
case "豆瓣":
|
||||
url += "douban";
|
||||
break;
|
||||
case "少数派":
|
||||
url += "ssPai";
|
||||
break;
|
||||
case "IT资讯":
|
||||
url += "itInfo";
|
||||
break;
|
||||
case "微信":
|
||||
url += "wxHot";
|
||||
break;
|
||||
default:
|
||||
url += 'history'
|
||||
break
|
||||
url += "history";
|
||||
break;
|
||||
}
|
||||
let sendTemplate = {
|
||||
nickname: this.e.sender.card || this.e.user_id, user_id: this.e.user_id
|
||||
}
|
||||
let msg = []
|
||||
nickname: this.e.sender.card || this.e.user_id,
|
||||
user_id: this.e.user_id,
|
||||
};
|
||||
let msg = [];
|
||||
await fetch(url, {
|
||||
headers: {
|
||||
"User-Agent":
|
||||
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.then((resp) => resp.json())
|
||||
.then((resp) => {
|
||||
.then(resp => resp.json())
|
||||
.then(resp => {
|
||||
for (let element of resp.data) {
|
||||
if (_.isUndefined(element)) {
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
const template = `
|
||||
标题:${ _.isNull(element.title) ? '暂无' : element.title }\n
|
||||
简介:${ _.isNull(element.desc) ? '暂无' : element.desc }\n
|
||||
热度:${ _.isNull(element.hot) ? '暂无' : element.hot }\n
|
||||
访问详情:${ _.isNull(element.url) ? '暂无' : element.url }\n
|
||||
标题:${_.isNull(element.title) ? "暂无" : element.title}\n
|
||||
简介:${_.isNull(element.desc) ? "暂无" : element.desc}\n
|
||||
热度:${_.isNull(element.hot) ? "暂无" : element.hot}\n
|
||||
访问详情:${_.isNull(element.url) ? "暂无" : element.url}\n
|
||||
`;
|
||||
msg.push({
|
||||
message: { type: 'text', text: `${ template }` },
|
||||
...sendTemplate
|
||||
})
|
||||
message: { type: "text", text: `${template}` },
|
||||
...sendTemplate,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((err) => logger.error(err))
|
||||
return !!this.reply(await Bot.makeForwardMsg(msg))
|
||||
.catch(err => logger.error(err));
|
||||
return !!this.reply(await Bot.makeForwardMsg(msg));
|
||||
}
|
||||
|
||||
async buyerShow (e) {
|
||||
async buyerShow(e) {
|
||||
// http://3650000.xyz/api/?type=img
|
||||
// https://api.vvhan.com/api/tao
|
||||
// https://api.uomg.com/api/rand.img3?format=json
|
||||
// const randomIndex = Math.floor(Math.random() * urls.length);
|
||||
// const randomElement = urls.splice(randomIndex, 1)[0];
|
||||
const p1 = new Promise((resolve, reject) => {
|
||||
fetch("https://api.vvhan.com/api/tao").then(resp => {
|
||||
return resolve(resp.url)
|
||||
}).catch(err => reject(err))
|
||||
})
|
||||
fetch("https://api.vvhan.com/api/tao")
|
||||
.then(resp => {
|
||||
return resolve(resp.url);
|
||||
})
|
||||
.catch(err => reject(err));
|
||||
});
|
||||
const p2 = new Promise((resolve, reject) => {
|
||||
fetch("https://api.uomg.com/api/rand.img3?format=json").then(resp => resp.json()).then(resp => {
|
||||
return resolve(resp.imgurl)
|
||||
}).catch(err => reject(err))
|
||||
})
|
||||
fetch("https://api.uomg.com/api/rand.img3?format=json")
|
||||
.then(resp => resp.json())
|
||||
.then(resp => {
|
||||
return resolve(resp.imgurl);
|
||||
})
|
||||
.catch(err => reject(err));
|
||||
});
|
||||
Promise.all([p1, p2]).then(res => {
|
||||
res.forEach(item => {
|
||||
e.reply(segment.image(item))
|
||||
})
|
||||
})
|
||||
e.reply(segment.image(item));
|
||||
});
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
// 删除标签
|
||||
removeTag (title) {
|
||||
const titleRex = /<[^>]+>/g
|
||||
return title.replace(titleRex, '')
|
||||
removeTag(title) {
|
||||
const titleRex = /<[^>]+>/g;
|
||||
return title.replace(titleRex, "");
|
||||
}
|
||||
}
|
||||
|
548
apps/tools.js
548
apps/tools.js
@ -5,19 +5,19 @@ import { segment } from "oicq";
|
||||
// 其他库
|
||||
import md5 from "md5";
|
||||
import axios from "axios";
|
||||
import _ from 'lodash'
|
||||
import tunnel from 'tunnel'
|
||||
import { TwitterApi } from 'twitter-api-v2'
|
||||
import HttpProxyAgent from 'https-proxy-agent'
|
||||
import { mkdirsSync } from '../utils/file.js'
|
||||
import { downloadBFile, getDownloadUrl, mergeFileToMp4 } from '../utils/bilibili.js'
|
||||
import { parseUrl, parseM3u8, downloadM3u8Videos, mergeAcFileToMp4 } from '../utils/acfun.js'
|
||||
import _ from "lodash";
|
||||
import tunnel from "tunnel";
|
||||
import { TwitterApi } from "twitter-api-v2";
|
||||
import HttpProxyAgent from "https-proxy-agent";
|
||||
import { mkdirsSync } from "../utils/file.js";
|
||||
import { downloadBFile, getDownloadUrl, mergeFileToMp4 } from "../utils/bilibili.js";
|
||||
import { parseUrl, parseM3u8, downloadM3u8Videos, mergeAcFileToMp4 } from "../utils/acfun.js";
|
||||
// import { get, remove, add } from "../utils/redisu.js";
|
||||
|
||||
const transMap = { "中": "zh", "日": "jp", "文": "wyw", "英": "en" }
|
||||
const transMap = { 中: "zh", 日: "jp", 文: "wyw", 英: "en" };
|
||||
|
||||
export class tools extends plugin {
|
||||
constructor () {
|
||||
constructor() {
|
||||
super({
|
||||
name: "工具和学习类",
|
||||
dsc: "工具相关指令",
|
||||
@ -49,177 +49,197 @@ export class tools extends plugin {
|
||||
fnc: "twitter",
|
||||
},
|
||||
{
|
||||
reg: "https:\/\/(m.)?v.qq.com\/(.*)",
|
||||
fnc: "tx"
|
||||
reg: "https://(m.)?v.qq.com/(.*)",
|
||||
fnc: "tx",
|
||||
},
|
||||
{
|
||||
reg: "(.*)(acfun.cn)",
|
||||
fnc: "acfun"
|
||||
fnc: "acfun",
|
||||
},
|
||||
{
|
||||
reg: "(.*)(xhslink.com|xiaohongshu.com)",
|
||||
fnc: "redbook"
|
||||
}
|
||||
fnc: "redbook",
|
||||
},
|
||||
],
|
||||
});
|
||||
// http://api.tuwei.space/girl
|
||||
// 视频保存路径
|
||||
this.defaultPath = `./data/rcmp4/`;
|
||||
// redis的key
|
||||
this.redisKey = `Yz:tools:cache:${ this.group_id }`;
|
||||
this.redisKey = `Yz:tools:cache:${this.group_id}`;
|
||||
// 代理接口
|
||||
// TODO 填写服务器的内网ID和clash的端口
|
||||
this.proxyAddr = '10.0.8.10';
|
||||
this.proxyPort = '7890'
|
||||
this.proxyAddr = "10.0.8.10";
|
||||
this.proxyPort = "7890";
|
||||
this.myProxy = `http://${this.proxyAddr}:${this.proxyPort}`;
|
||||
|
||||
}
|
||||
|
||||
// 翻译插件
|
||||
async trans (e) {
|
||||
async trans(e) {
|
||||
const languageReg = /翻(.)/g;
|
||||
const msg = e.msg.trim();
|
||||
const language = languageReg.exec(msg);
|
||||
if (!transMap.hasOwnProperty(language[1])) {
|
||||
e.reply("输入格式有误!例子:翻中 China's policy has been consistent, but Japan chooses a path of mistrust, decoupling and military expansion")
|
||||
e.reply(
|
||||
"输入格式有误!例子:翻中 China's policy has been consistent, but Japan chooses a path of mistrust, decoupling and military expansion"
|
||||
);
|
||||
return;
|
||||
}
|
||||
const place = msg.replace(language[0], "").trim();
|
||||
// let url = /[\u4E00-\u9FFF]+/g.test(place)
|
||||
// let url = `http://api.fanyi.baidu.com/api/trans/vip/translate?from=auto&to=${ transMap[language[1]] }&appid=APP ID&salt=自定义&sign=${ md5("APP ID" + place + "自定义" + "密钥") }&q=${ place }`;
|
||||
let url = `http://api.fanyi.baidu.com/api/trans/vip/translate?from=auto&to=${ transMap[language[1]] }&appid=&salt=&sign=${ md5("" + place + "" + "") }&q=${ place }`;
|
||||
let url = `http://api.fanyi.baidu.com/api/trans/vip/translate?from=auto&to=${
|
||||
transMap[language[1]]
|
||||
}&appid=&salt=&sign=${md5("" + place + "" + "")}&q=${place}`;
|
||||
await fetch(url)
|
||||
.then((resp) => resp.json())
|
||||
.then((text) => text.trans_result)
|
||||
.then((res) => this.reply(`${ res[0].dst }`, true))
|
||||
.catch((err) => logger.error(err));
|
||||
.then(resp => resp.json())
|
||||
.then(text => text.trans_result)
|
||||
.then(res => this.reply(`${res[0].dst}`, true))
|
||||
.catch(err => logger.error(err));
|
||||
return true;
|
||||
}
|
||||
|
||||
// 抖音解析
|
||||
async douyin (e) {
|
||||
async douyin(e) {
|
||||
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) => {
|
||||
await this.douyinRequest(douUrl).then(async res => {
|
||||
const douRex = /.*video\/(\d+)\/(.*?)/g;
|
||||
const douId = douRex.exec(res)[1];
|
||||
// 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`
|
||||
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`;
|
||||
const resp = await fetch(url);
|
||||
const json = await resp.json();
|
||||
const item = json.aweme_detail;
|
||||
e.reply(`识别:抖音, ${item.desc}`);
|
||||
const url_2 = item.video.play_addr.url_list[0];
|
||||
this.downloadVideo(url_2).then(video => {
|
||||
e.reply(segment.video(`${this.defaultPath}${this.e.group_id || this.e.user_id}/temp.mp4`));
|
||||
e.reply(
|
||||
segment.video(
|
||||
`${this.defaultPath}${this.e.group_id || this.e.user_id}/temp.mp4`
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
// tiktok解析
|
||||
async tiktok (e) {
|
||||
async tiktok(e) {
|
||||
const urlRex = /(http:|https:)\/\/www.tiktok.com\/[A-Za-z\d._?%&+\-=\/#@]*/g;
|
||||
const urlShortRex = /(http:|https:)\/\/vt.tiktok.com\/[A-Za-z\d._?%&+\-=\/#]*/g;
|
||||
let url = e.msg.trim()
|
||||
let url = e.msg.trim();
|
||||
// 短号处理
|
||||
if (url.includes('vt.tiktok')) {
|
||||
const temp_url = urlShortRex.exec(url)[0]
|
||||
if (url.includes("vt.tiktok")) {
|
||||
const temp_url = urlShortRex.exec(url)[0];
|
||||
await fetch(temp_url, {
|
||||
redirect: "follow",
|
||||
follow: 10,
|
||||
timeout: 10000,
|
||||
agent: new HttpProxyAgent(this.myProxy)
|
||||
}).then((resp) => {
|
||||
url = resp.url
|
||||
})
|
||||
agent: new HttpProxyAgent(this.myProxy),
|
||||
}).then(resp => {
|
||||
url = resp.url;
|
||||
});
|
||||
} else {
|
||||
url = urlRex.exec(url)[0]
|
||||
url = urlRex.exec(url)[0];
|
||||
}
|
||||
const idVideo = await this.getIdVideo(url)
|
||||
const idVideo = await this.getIdVideo(url);
|
||||
// API链接
|
||||
const API_URL = `https://api16-normal-c-useast1a.tiktokv.com/aweme/v1/feed/?aweme_id=${ idVideo }&version_code=262&app_name=musical_ly&channel=App&device_id=null&os_version=14.4.2&device_platform=iphone&device_type=iPhone9`;
|
||||
const API_URL = `https://api16-normal-c-useast1a.tiktokv.com/aweme/v1/feed/?aweme_id=${idVideo}&version_code=262&app_name=musical_ly&channel=App&device_id=null&os_version=14.4.2&device_platform=iphone&device_type=iPhone9`;
|
||||
|
||||
await axios.get(API_URL, {
|
||||
headers: {
|
||||
"User-Agent":
|
||||
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
||||
"Content-Type": "application/json",
|
||||
"Accept-Encoding": "gzip,deflate,compress"
|
||||
},
|
||||
timeout: 10000,
|
||||
proxy: false,
|
||||
httpAgent: tunnel.httpOverHttp({ proxy: { host: this.proxyAddr, port: this.proxyPort } }),
|
||||
httpsAgent: tunnel.httpOverHttp({ proxy: { host: this.proxyAddr, port: this.proxyPort } }),
|
||||
}).then(resp => {
|
||||
const data = resp.data.aweme_list[0];
|
||||
e.reply(`识别:tiktok, ${data.desc}`)
|
||||
this.downloadVideo(data.video.play_addr.url_list[0], true).then(video => {
|
||||
e.reply(segment.video(`${ this.defaultPath }${ this.e.group_id || this.e.user_id }/temp.mp4`));
|
||||
await axios
|
||||
.get(API_URL, {
|
||||
headers: {
|
||||
"User-Agent":
|
||||
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
||||
"Content-Type": "application/json",
|
||||
"Accept-Encoding": "gzip,deflate,compress",
|
||||
},
|
||||
timeout: 10000,
|
||||
proxy: false,
|
||||
httpAgent: tunnel.httpOverHttp({
|
||||
proxy: { host: this.proxyAddr, port: this.proxyPort },
|
||||
}),
|
||||
httpsAgent: tunnel.httpOverHttp({
|
||||
proxy: { host: this.proxyAddr, port: this.proxyPort },
|
||||
}),
|
||||
})
|
||||
})
|
||||
return true
|
||||
.then(resp => {
|
||||
const data = resp.data.aweme_list[0];
|
||||
e.reply(`识别:tiktok, ${data.desc}`);
|
||||
this.downloadVideo(data.video.play_addr.url_list[0], true).then(video => {
|
||||
e.reply(
|
||||
segment.video(
|
||||
`${this.defaultPath}${this.e.group_id || this.e.user_id}/temp.mp4`
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
// bilibi解析
|
||||
async bili (e) {
|
||||
async bili(e) {
|
||||
const urlRex = /(http:|https:)\/\/www.bilibili.com\/[A-Za-z\d._?%&+\-=\/#]*/g;
|
||||
const bShortRex = /(http:|https:)\/\/b23.tv\/[A-Za-z\d._?%&+\-=\/#]*/g;
|
||||
let url = e.msg.trim()
|
||||
let url = e.msg.trim();
|
||||
// 短号处理
|
||||
if (url.includes('b23.tv')) {
|
||||
const bShortUrl = bShortRex.exec(url)[0]
|
||||
if (url.includes("b23.tv")) {
|
||||
const bShortUrl = bShortRex.exec(url)[0];
|
||||
await fetch(bShortUrl).then(resp => {
|
||||
url = resp.url;
|
||||
})
|
||||
});
|
||||
} else {
|
||||
url = urlRex.exec(url)[0];
|
||||
}
|
||||
|
||||
const path = `${ this.defaultPath }${ this.e.group_id || this.e.user_id }/`
|
||||
const path = `${this.defaultPath}${this.e.group_id || this.e.user_id}/`;
|
||||
if (!fs.existsSync(path)) {
|
||||
mkdirsSync(path);
|
||||
}
|
||||
// 视频信息获取例子:http://api.bilibili.com/x/web-interface/view?bvid=BV1hY411m7cB
|
||||
// 请求视频信息
|
||||
(function() {
|
||||
(function () {
|
||||
const baseVideoInfo = "http://api.bilibili.com/x/web-interface/view";
|
||||
const videoId = /video\/[^\?\/ ]+/.exec(url)[0].split("/")[1];
|
||||
// 获取视频信息,然后发送
|
||||
fetch(videoId.startsWith("BV") ? `${baseVideoInfo}?bvid=${videoId}` : `${baseVideoInfo}?aid=${videoId}`)
|
||||
fetch(
|
||||
videoId.startsWith("BV")
|
||||
? `${baseVideoInfo}?bvid=${videoId}`
|
||||
: `${baseVideoInfo}?aid=${videoId}`
|
||||
)
|
||||
.then(resp => resp.json())
|
||||
.then(resp => {
|
||||
e.reply(`识别:哔哩哔哩, ${resp.data.title}`)
|
||||
.catch(err => {
|
||||
e.reply("解析失败,重试一下");
|
||||
console.log(err);
|
||||
})
|
||||
})
|
||||
}())
|
||||
e.reply(`识别:哔哩哔哩, ${resp.data.title}`).catch(err => {
|
||||
e.reply("解析失败,重试一下");
|
||||
console.log(err);
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
await getDownloadUrl(url)
|
||||
.then(data => {
|
||||
this.downBili(`${path}temp`, data.videoUrl, data.audioUrl)
|
||||
.then(data => {
|
||||
e.reply(segment.video(`${ path }temp.mp4`))
|
||||
e.reply(segment.video(`${path}temp.mp4`));
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
e.reply('解析失败,请重试一下')
|
||||
console.log(err);
|
||||
e.reply("解析失败,请重试一下");
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
e.reply('解析失败,请重试一下')
|
||||
console.log(err);
|
||||
e.reply("解析失败,请重试一下");
|
||||
});
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
|
||||
// 百科
|
||||
async wiki (e) {
|
||||
async wiki(e) {
|
||||
const key = e.msg.replace(/#|百科|wiki/g, "").trim();
|
||||
const url = `https://xiaoapi.cn/API/bk.php?m=json&type=sg&msg=${ encodeURI(key) }`
|
||||
const url = `https://xiaoapi.cn/API/bk.php?m=json&type=sg&msg=${encodeURI(key)}`;
|
||||
// const url2 = 'https://api.jikipedia.com/go/auto_complete'
|
||||
Promise.all([
|
||||
// axios.post(url2, {
|
||||
@ -238,98 +258,96 @@ export class tools extends plugin {
|
||||
// }
|
||||
// return data[0].entities[0];
|
||||
// }),
|
||||
axios.get(url, {
|
||||
headers: {
|
||||
"User-Agent":
|
||||
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
||||
},
|
||||
timeout: 10000,
|
||||
})
|
||||
axios
|
||||
.get(url, {
|
||||
headers: {
|
||||
"User-Agent":
|
||||
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
||||
},
|
||||
timeout: 10000,
|
||||
})
|
||||
.then(resp => {
|
||||
return resp.data
|
||||
})
|
||||
])
|
||||
.then(res => {
|
||||
const data = res[0]
|
||||
// const data2 = res[0]
|
||||
const template = `
|
||||
解释:${ _.get(data, 'msg') }\n
|
||||
详情:${ _.get(data, 'more') }\n
|
||||
return resp.data;
|
||||
}),
|
||||
]).then(res => {
|
||||
const data = res[0];
|
||||
// const data2 = res[0]
|
||||
const template = `
|
||||
解释:${_.get(data, "msg")}\n
|
||||
详情:${_.get(data, "more")}\n
|
||||
`;
|
||||
// 小鸡解释:${ _.get(data2, 'content') }
|
||||
e.reply(template)
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
// twitter解析
|
||||
// 例子:https://twitter.com/chonkyanimalx/status/1595834168000204800
|
||||
async twitter (e) {
|
||||
// 配置参数及解析
|
||||
const reg = /https?:\/\/twitter.com\/[0-9-a-zA-Z_]{1,20}\/status\/([0-9]*)/
|
||||
const twitterUrl = reg.exec(e.msg);
|
||||
const id = twitterUrl[1];
|
||||
const httpAgent = new HttpProxyAgent(this.myProxy)
|
||||
const twitterClient = new TwitterApi('', {httpAgent});
|
||||
|
||||
// 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(resp => {
|
||||
e.reply(`识别:腿忒学习版,${resp.data.text}`)
|
||||
const downloadPath = `${ this.defaultPath }${ this.e.group_id || this.e.user_id }`;
|
||||
// 创建文件夹(如果没有过这个群)
|
||||
if (!fs.existsSync(downloadPath)) {
|
||||
mkdirsSync(downloadPath);
|
||||
}
|
||||
// 开始读取数据
|
||||
if (resp.includes.media[0].type === 'photo') {
|
||||
// 图片
|
||||
resp.includes.media.map(item => {
|
||||
const filePath = `${downloadPath}/${item.url.split('/').pop()}`
|
||||
this.downloadImgs(item.url, downloadPath).then(tmp => {
|
||||
e.reply(segment.image(fs.readFileSync(filePath)))
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// 视频
|
||||
this.downloadVideo(resp.includes.media[0].variants[0].url, true).then(video => {
|
||||
e.reply(segment.video(`${downloadPath}/temp.mp4`));
|
||||
});
|
||||
}
|
||||
// 小鸡解释:${ _.get(data2, 'content') }
|
||||
e.reply(template);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
// twitter解析
|
||||
// 例子:https://twitter.com/chonkyanimalx/status/1595834168000204800
|
||||
async twitter(e) {
|
||||
// 配置参数及解析
|
||||
const reg = /https?:\/\/twitter.com\/[0-9-a-zA-Z_]{1,20}\/status\/([0-9]*)/;
|
||||
const twitterUrl = reg.exec(e.msg);
|
||||
const id = twitterUrl[1];
|
||||
const httpAgent = new HttpProxyAgent(this.myProxy);
|
||||
const twitterClient = new TwitterApi("", { httpAgent });
|
||||
|
||||
// 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(resp => {
|
||||
e.reply(`识别:腿忒学习版,${resp.data.text}`);
|
||||
const downloadPath = `${this.defaultPath}${this.e.group_id || this.e.user_id}`;
|
||||
// 创建文件夹(如果没有过这个群)
|
||||
if (!fs.existsSync(downloadPath)) {
|
||||
mkdirsSync(downloadPath);
|
||||
}
|
||||
// 开始读取数据
|
||||
if (resp.includes.media[0].type === "photo") {
|
||||
// 图片
|
||||
resp.includes.media.map(item => {
|
||||
const filePath = `${downloadPath}/${item.url.split("/").pop()}`;
|
||||
this.downloadImgs(item.url, downloadPath).then(tmp => {
|
||||
e.reply(segment.image(fs.readFileSync(filePath)));
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// 视频
|
||||
this.downloadVideo(resp.includes.media[0].variants[0].url, true).then(video => {
|
||||
e.reply(segment.video(`${downloadPath}/temp.mp4`));
|
||||
});
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
// 视频解析
|
||||
async tx( e ) {
|
||||
const url = e.msg
|
||||
const data = await ( await fetch( `https://xian.txma.cn/API/jx_txjx.php?url=${url}` ) )
|
||||
.json()
|
||||
const k = data.url
|
||||
const name = data.title
|
||||
if( k && name ) {
|
||||
e.reply( name + '\n' + k )
|
||||
let forward = await this.makeForwardMsg( url )
|
||||
e.reply( forward )
|
||||
return true
|
||||
async tx(e) {
|
||||
const url = e.msg;
|
||||
const data = await (await fetch(`https://xian.txma.cn/API/jx_txjx.php?url=${url}`)).json();
|
||||
const k = data.url;
|
||||
const name = data.title;
|
||||
if (k && name) {
|
||||
e.reply(name + "\n" + k);
|
||||
let forward = await this.makeForwardMsg(url);
|
||||
e.reply(forward);
|
||||
return true;
|
||||
} else {
|
||||
e.reply( '解析腾讯视频失败~\n去浏览器使用拼接接口吧...' )
|
||||
let forward = await this.makeForwardMsg( url )
|
||||
e.reply( forward )
|
||||
return true
|
||||
e.reply("解析腾讯视频失败~\n去浏览器使用拼接接口吧...");
|
||||
let forward = await this.makeForwardMsg(url);
|
||||
e.reply(forward);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 请求参数
|
||||
async douyinRequest (url) {
|
||||
async douyinRequest(url) {
|
||||
const params = {
|
||||
headers: {
|
||||
"User-Agent":
|
||||
@ -340,23 +358,23 @@ export class tools extends plugin {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
.head(url, params)
|
||||
.then((resp) => {
|
||||
const location = resp.request.res.responseUrl
|
||||
.then(resp => {
|
||||
const location = resp.request.res.responseUrl;
|
||||
resolve(location);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 工具:根URL据下载视频 / 音频
|
||||
async downloadVideo (url, isProxy=false) {
|
||||
const groupPath = `${ this.defaultPath }${ this.e.group_id || this.e.user_id }`;
|
||||
async downloadVideo(url, isProxy = false) {
|
||||
const groupPath = `${this.defaultPath}${this.e.group_id || this.e.user_id}`;
|
||||
if (!fs.existsSync(groupPath)) {
|
||||
mkdirsSync(groupPath);
|
||||
}
|
||||
const target = `${ groupPath }/temp.mp4`;
|
||||
const target = `${groupPath}/temp.mp4`;
|
||||
// 待优化
|
||||
if (fs.existsSync(target)) {
|
||||
console.log(`视频已存在`);
|
||||
@ -378,11 +396,15 @@ export class tools extends plugin {
|
||||
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
||||
},
|
||||
responseType: "stream",
|
||||
httpAgent: tunnel.httpOverHttp({ proxy: { host: this.proxyAddr, port: this.proxyPort } }),
|
||||
httpsAgent: tunnel.httpOverHttp({ proxy: { host: this.proxyAddr, port: this.proxyPort } }),
|
||||
httpAgent: tunnel.httpOverHttp({
|
||||
proxy: { host: this.proxyAddr, port: this.proxyPort },
|
||||
}),
|
||||
httpsAgent: tunnel.httpOverHttp({
|
||||
proxy: { host: this.proxyAddr, port: this.proxyPort },
|
||||
}),
|
||||
});
|
||||
}
|
||||
console.log(`开始下载: ${ url }`);
|
||||
console.log(`开始下载: ${url}`);
|
||||
const writer = fs.createWriteStream(target);
|
||||
res.data.pipe(writer);
|
||||
|
||||
@ -393,19 +415,19 @@ export class tools extends plugin {
|
||||
}
|
||||
|
||||
// 工具:找到tiktok的视频id
|
||||
async getIdVideo (url) {
|
||||
const matching = url.includes("/video/")
|
||||
async getIdVideo(url) {
|
||||
const matching = url.includes("/video/");
|
||||
if (!matching) {
|
||||
this.e.reply("没找到,正在获取随机视频!")
|
||||
return null
|
||||
this.e.reply("没找到,正在获取随机视频!");
|
||||
return null;
|
||||
}
|
||||
const idVideo = url.substring(url.indexOf("/video/") + 7, url.length);
|
||||
return (idVideo.length > 19) ? idVideo.substring(0, idVideo.indexOf("?")) : idVideo;
|
||||
return idVideo.length > 19 ? idVideo.substring(0, idVideo.indexOf("?")) : idVideo;
|
||||
}
|
||||
|
||||
// acfun解析
|
||||
async acfun(e) {
|
||||
const path = `${ this.defaultPath }${ this.e.group_id || this.e.user_id }/temp/`
|
||||
const path = `${this.defaultPath}${this.e.group_id || this.e.user_id}/temp/`;
|
||||
if (!fs.existsSync(path)) {
|
||||
mkdirsSync(path);
|
||||
}
|
||||
@ -413,124 +435,134 @@ export class tools extends plugin {
|
||||
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]}`;
|
||||
}
|
||||
|
||||
parseUrl(inputMsg).then(res => {
|
||||
e.reply(`识别:猴山,${res.videoName}`)
|
||||
parseM3u8(res.urlM3u8s[res.urlM3u8s.length-1]).then(res2 => {
|
||||
e.reply(`识别:猴山,${res.videoName}`);
|
||||
parseM3u8(res.urlM3u8s[res.urlM3u8s.length - 1]).then(res2 => {
|
||||
downloadM3u8Videos(res2.m3u8FullUrls, path).then(_ => {
|
||||
mergeAcFileToMp4( res2.tsNames, path, `${path}out.mp4`).then(_ => {
|
||||
e.reply(segment.video(`${path}out.mp4`))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
mergeAcFileToMp4(res2.tsNames, path, `${path}out.mp4`).then(_ => {
|
||||
e.reply(segment.video(`${path}out.mp4`));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
// 小红书解析
|
||||
async redbook(e) {
|
||||
const msgUrl = /(http:|https:)\/\/(xhslink|xiaohongshu).com\/[A-Za-z\d._?%&+\-=\/#@]*/.exec(e.msg)[0];
|
||||
const url = `https://dlpanda.com/zh-CN/xhs?url=${msgUrl}`
|
||||
const msgUrl = /(http:|https:)\/\/(xhslink|xiaohongshu).com\/[A-Za-z\d._?%&+\-=\/#@]*/.exec(
|
||||
e.msg
|
||||
)[0];
|
||||
const url = `https://dlpanda.com/zh-CN/xhs?url=${msgUrl}`;
|
||||
|
||||
await axios.get(url, {
|
||||
headers: {
|
||||
"User-Agent":
|
||||
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
||||
"Content-Type": "application/json",
|
||||
"Accept-Encoding": "gzip,deflate,compress"
|
||||
},
|
||||
timeout: 10000,
|
||||
proxy: false,
|
||||
}).then((resp) => {
|
||||
const reg = /<img(.*)src="\/\/ci\.xiaohongshu\.com(.*?)"/g
|
||||
let res = '';
|
||||
await axios
|
||||
.get(url, {
|
||||
headers: {
|
||||
"User-Agent":
|
||||
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
||||
"Content-Type": "application/json",
|
||||
"Accept-Encoding": "gzip,deflate,compress",
|
||||
},
|
||||
timeout: 10000,
|
||||
proxy: false,
|
||||
})
|
||||
.then(resp => {
|
||||
const reg = /<img(.*)src="\/\/ci\.xiaohongshu\.com(.*?)"/g;
|
||||
let res = "";
|
||||
|
||||
const downloadPath = `${ this.defaultPath }${ this.e.group_id || this.e.user_id }`;
|
||||
// 创建文件夹(如果没有过这个群)
|
||||
if (!fs.existsSync(downloadPath)) {
|
||||
mkdirsSync(downloadPath);
|
||||
}
|
||||
while (res = reg.exec(resp.data)) {
|
||||
const addr = `https://ci.xiaohongshu.com${res[2]}`
|
||||
axios.get(addr, {
|
||||
headers: {
|
||||
"User-Agent":
|
||||
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
||||
},
|
||||
responseType: "stream",
|
||||
}).then(resp => {
|
||||
const filepath = `${downloadPath}/${/com\/(.*)\?/.exec(addr)[1]}.jpg`
|
||||
const writer = fs.createWriteStream(filepath);
|
||||
resp.data.pipe(writer)
|
||||
return new Promise((resolve, reject) => {
|
||||
writer.on('finish', () => resolve(filepath));
|
||||
writer.on('error', reject);
|
||||
});
|
||||
})
|
||||
.then( filepath => {
|
||||
e.reply(segment.image(fs.readFileSync(filepath)))
|
||||
fs.unlinkSync(filepath)
|
||||
})
|
||||
}
|
||||
})
|
||||
const downloadPath = `${this.defaultPath}${this.e.group_id || this.e.user_id}`;
|
||||
// 创建文件夹(如果没有过这个群)
|
||||
if (!fs.existsSync(downloadPath)) {
|
||||
mkdirsSync(downloadPath);
|
||||
}
|
||||
while ((res = reg.exec(resp.data))) {
|
||||
const addr = `https://ci.xiaohongshu.com${res[2]}`;
|
||||
axios
|
||||
.get(addr, {
|
||||
headers: {
|
||||
"User-Agent":
|
||||
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
||||
},
|
||||
responseType: "stream",
|
||||
})
|
||||
.then(resp => {
|
||||
const filepath = `${downloadPath}/${/com\/(.*)\?/.exec(addr)[1]}.jpg`;
|
||||
const writer = fs.createWriteStream(filepath);
|
||||
resp.data.pipe(writer);
|
||||
return new Promise((resolve, reject) => {
|
||||
writer.on("finish", () => resolve(filepath));
|
||||
writer.on("error", reject);
|
||||
});
|
||||
})
|
||||
.then(filepath => {
|
||||
e.reply(segment.image(fs.readFileSync(filepath)));
|
||||
fs.unlinkSync(filepath);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async downBili (title, videoUrl, audioUrl) {
|
||||
async downBili(title, videoUrl, audioUrl) {
|
||||
return Promise.all([
|
||||
downloadBFile(
|
||||
videoUrl,
|
||||
title + '-video.m4s',
|
||||
title + "-video.m4s",
|
||||
_.throttle(
|
||||
value =>
|
||||
console.log('download-progress', {
|
||||
type: 'video',
|
||||
console.log("download-progress", {
|
||||
type: "video",
|
||||
data: value,
|
||||
}),
|
||||
1000,
|
||||
),
|
||||
1000
|
||||
)
|
||||
),
|
||||
downloadBFile(
|
||||
audioUrl,
|
||||
title + '-audio.m4s',
|
||||
title + "-audio.m4s",
|
||||
_.throttle(
|
||||
value =>
|
||||
console.log('download-progress', {
|
||||
type: 'audio',
|
||||
console.log("download-progress", {
|
||||
type: "audio",
|
||||
data: value,
|
||||
}),
|
||||
1000,
|
||||
),
|
||||
1000
|
||||
)
|
||||
),
|
||||
])
|
||||
.then(data => {
|
||||
return mergeFileToMp4(data[0].fullFileName, data[1].fullFileName, title + '.mp4');
|
||||
})
|
||||
]).then(data => {
|
||||
return mergeFileToMp4(data[0].fullFileName, data[1].fullFileName, title + ".mp4");
|
||||
});
|
||||
}
|
||||
|
||||
// 工具:下载一张网络图片
|
||||
async downloadImgs(img, dir) {
|
||||
|
||||
const filename = img.split('/').pop();
|
||||
const filename = img.split("/").pop();
|
||||
const filepath = `${dir}/${filename}`;
|
||||
const writer = fs.createWriteStream(filepath);
|
||||
return axios.get(img, {
|
||||
headers: {
|
||||
"User-Agent":
|
||||
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
||||
},
|
||||
responseType: "stream",
|
||||
httpAgent: tunnel.httpOverHttp({ proxy: { host: this.proxyAddr, port: this.proxyPort } }),
|
||||
httpsAgent: tunnel.httpOverHttp({ proxy: { host: this.proxyAddr, port: this.proxyPort } }),
|
||||
}).then(res => {
|
||||
res.data.pipe(writer);
|
||||
return new Promise((resolve, reject) => {
|
||||
writer.on('finish', () => resolve(filepath));
|
||||
writer.on('error', reject);
|
||||
return axios
|
||||
.get(img, {
|
||||
headers: {
|
||||
"User-Agent":
|
||||
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
|
||||
},
|
||||
responseType: "stream",
|
||||
httpAgent: tunnel.httpOverHttp({
|
||||
proxy: { host: this.proxyAddr, port: this.proxyPort },
|
||||
}),
|
||||
httpsAgent: tunnel.httpOverHttp({
|
||||
proxy: { host: this.proxyAddr, port: this.proxyPort },
|
||||
}),
|
||||
})
|
||||
.then(res => {
|
||||
res.data.pipe(writer);
|
||||
return new Promise((resolve, reject) => {
|
||||
writer.on("finish", () => resolve(filepath));
|
||||
writer.on("error", reject);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
113
apps/update.js
113
apps/update.js
@ -1,9 +1,9 @@
|
||||
// 主库
|
||||
import Version from '../model/version.js'
|
||||
import config from '../model/index.js'
|
||||
import puppeteer from '../../../lib/puppeteer/puppeteer.js'
|
||||
import Version from "../model/version.js";
|
||||
import config from "../model/index.js";
|
||||
import puppeteer from "../../../lib/puppeteer/puppeteer.js";
|
||||
|
||||
import { exec, execSync } from 'node:child_process'
|
||||
import { exec, execSync } from "node:child_process";
|
||||
|
||||
const _path = process.cwd();
|
||||
|
||||
@ -11,38 +11,36 @@ const _path = process.cwd();
|
||||
* 处理插件更新
|
||||
*/
|
||||
export class update extends plugin {
|
||||
constructor () {
|
||||
constructor() {
|
||||
super({
|
||||
name: '更新插件',
|
||||
dsc: '更新插件代码',
|
||||
event: 'message',
|
||||
name: "更新插件",
|
||||
dsc: "更新插件代码",
|
||||
event: "message",
|
||||
priority: 4000,
|
||||
rule: [
|
||||
{
|
||||
reg: '^#*R(插件)?版本$',
|
||||
fnc: 'version'
|
||||
reg: "^#*R(插件)?版本$",
|
||||
fnc: "version",
|
||||
},
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#(R更新|R强制更新)$',
|
||||
reg: "^#(R更新|R强制更新)$",
|
||||
/** 执行方法 */
|
||||
fnc: 'rconsoleUpdate'
|
||||
fnc: "rconsoleUpdate",
|
||||
},
|
||||
]
|
||||
})
|
||||
],
|
||||
});
|
||||
|
||||
this.versionData = config.getConfig('version')
|
||||
this.versionData = config.getConfig("version");
|
||||
}
|
||||
|
||||
/**
|
||||
* rule - 插件版本信息
|
||||
*/
|
||||
async version () {
|
||||
const data = await new Version(this.e).getData(
|
||||
this.versionData.slice(0, 3)
|
||||
)
|
||||
let img = await puppeteer.screenshot('version', data)
|
||||
this.e.reply(img)
|
||||
async version() {
|
||||
const data = await new Version(this.e).getData(this.versionData.slice(0, 3));
|
||||
let img = await puppeteer.screenshot("version", data);
|
||||
this.e.reply(img);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,38 +63,56 @@ export class update extends plugin {
|
||||
} else {
|
||||
await this.e.reply("正在执行更新操作,请稍等");
|
||||
}
|
||||
const th = this
|
||||
exec(command, { cwd: `${ _path }/plugins/rconsole-plugin/` }, async function (error, stdout, stderr) {
|
||||
if (error) {
|
||||
let isChanges = error.toString().includes("Your local changes to the following files would be overwritten by merge");
|
||||
const th = this;
|
||||
exec(
|
||||
command,
|
||||
{ cwd: `${_path}/plugins/rconsole-plugin/` },
|
||||
async function (error, stdout, stderr) {
|
||||
if (error) {
|
||||
let isChanges = error
|
||||
.toString()
|
||||
.includes(
|
||||
"Your local changes to the following files would be overwritten by merge"
|
||||
);
|
||||
|
||||
let isNetwork = error.toString().includes("fatal: unable to access");
|
||||
let isNetwork = error.toString().includes("fatal: unable to access");
|
||||
|
||||
if (isChanges) {
|
||||
//git stash && git pull && git stash pop stash@{0}
|
||||
//需要设置email和username,暂不做处理
|
||||
await me.e.reply(
|
||||
"失败!\nError code: " +
|
||||
error.code +
|
||||
"\n" +
|
||||
error.stack +
|
||||
"\n\n本地代码与远程代码存在冲突,上面报错信息中包含冲突文件名称及路径,请尝试处理冲突\n如果不想保存本地修改请使用【#强制更新】\n(注意:强制更新命令会忽略所有本地对R插件本身文件的修改,本地修改均不会保存,请注意备份)"
|
||||
);
|
||||
} else if (isNetwork) {
|
||||
await e.reply(
|
||||
"失败!\nError code: " + error.code + "\n" + error.stack + "\n\n可能是网络问题,请关闭加速器之类的网络工具,或请过一会尝试。"
|
||||
);
|
||||
if (isChanges) {
|
||||
//git stash && git pull && git stash pop stash@{0}
|
||||
//需要设置email和username,暂不做处理
|
||||
await me.e.reply(
|
||||
"失败!\nError code: " +
|
||||
error.code +
|
||||
"\n" +
|
||||
error.stack +
|
||||
"\n\n本地代码与远程代码存在冲突,上面报错信息中包含冲突文件名称及路径,请尝试处理冲突\n如果不想保存本地修改请使用【#强制更新】\n(注意:强制更新命令会忽略所有本地对R插件本身文件的修改,本地修改均不会保存,请注意备份)"
|
||||
);
|
||||
} else if (isNetwork) {
|
||||
await e.reply(
|
||||
"失败!\nError code: " +
|
||||
error.code +
|
||||
"\n" +
|
||||
error.stack +
|
||||
"\n\n可能是网络问题,请关闭加速器之类的网络工具,或请过一会尝试。"
|
||||
);
|
||||
} else {
|
||||
await e.reply(
|
||||
"失败!\nError code: " +
|
||||
error.code +
|
||||
"\n" +
|
||||
error.stack +
|
||||
"\n\n出错了。请尝试处理错误"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
await e.reply("失败!\nError code: " + error.code + "\n" + error.stack + "\n\n出错了。请尝试处理错误");
|
||||
if (/Already up to date/.test(stdout)) {
|
||||
e.reply("目前已经是最新了~");
|
||||
return true;
|
||||
}
|
||||
await th.restartApp();
|
||||
}
|
||||
} else {
|
||||
if (/Already up to date/.test(stdout)) {
|
||||
e.reply("目前已经是最新了~");
|
||||
return true;
|
||||
}
|
||||
await th.restartApp();
|
||||
}
|
||||
});
|
||||
);
|
||||
}
|
||||
|
||||
async restartApp() {
|
||||
@ -113,7 +129,6 @@ export class update extends plugin {
|
||||
});
|
||||
|
||||
try {
|
||||
|
||||
await redis.set("Yunzai:rconsole:restart", data, { EX: 120 });
|
||||
|
||||
let cm = `npm run start`;
|
||||
|
Loading…
x
Reference in New Issue
Block a user