♻️ 分离fun.js代码
This commit is contained in:
193
apps/fun.js
193
apps/fun.js
@@ -2,11 +2,8 @@ import _ from 'lodash'
|
||||
import fetch from 'node-fetch'
|
||||
import plugin from '../../../lib/plugins/plugin.js'
|
||||
import { Config } from '../components/index.js'
|
||||
import { faildsImgs, heisiType, pandadiuType, successImgs } from '../constants/fun.js'
|
||||
import { QQApi, common, funApi, memes, uploadRecord } from '../model/index.js'
|
||||
|
||||
/** API请求错误文案 */
|
||||
const API_ERROR = '❎ 出错辣,请稍后重试'
|
||||
import { heisiType, pandadiuType, xiurenTypeId } from '../constants/fun.js'
|
||||
import { common, funApi, uploadRecord } from '../model/index.js'
|
||||
|
||||
/** 开始执行文案 */
|
||||
const START_EXECUTION = '椰奶产出中......'
|
||||
@@ -24,7 +21,7 @@ _.forIn(picApis, (values, key) => {
|
||||
const apiReg = new RegExp(`(${picApiKeys.join('|')}|^jktj$|^接口统计$)`)
|
||||
|
||||
export class Fun extends plugin {
|
||||
constructor() {
|
||||
constructor () {
|
||||
super({
|
||||
name: '椰奶娱乐',
|
||||
event: 'message',
|
||||
@@ -54,10 +51,6 @@ export class Fun extends plugin {
|
||||
reg: '^#?coser$',
|
||||
fnc: 'coser'
|
||||
},
|
||||
// {
|
||||
// reg: `^#?来点(${Object.keys(heisiType).join('|')})$`,
|
||||
// fnc: 'heisiwu'
|
||||
// },
|
||||
{
|
||||
reg: '^#?铃声搜索',
|
||||
fnc: 'lingsheng'
|
||||
@@ -79,7 +72,7 @@ export class Fun extends plugin {
|
||||
fnc: 'acg'
|
||||
},
|
||||
{
|
||||
reg: `^#来点(${Object.keys(funApi.xiurenTypeId).join('|')})$`,
|
||||
reg: `^#来点(${Object.keys(xiurenTypeId).join('|')})$`,
|
||||
fnc: 'xiuren'
|
||||
}
|
||||
|
||||
@@ -88,7 +81,7 @@ export class Fun extends plugin {
|
||||
}
|
||||
|
||||
/** 随机唱鸭 */
|
||||
async Sing(e) {
|
||||
async Sing (e) {
|
||||
let data = await funApi.randomSinging()
|
||||
if (data.error) return e.reply(data.error)
|
||||
await e.reply(await uploadRecord(data.audioUrl, 0, false))
|
||||
@@ -96,7 +89,7 @@ export class Fun extends plugin {
|
||||
}
|
||||
|
||||
/** 支付宝语音 */
|
||||
async ZFB(e) {
|
||||
async ZFB (e) {
|
||||
let amount = parseFloat(e.msg.replace(/#|支付宝到账|元|圆/g, '').trim())
|
||||
|
||||
if (!/^\d+(\.\d{1,2})?$/.test(amount)) return e.reply('你觉得这河里吗!!', true)
|
||||
@@ -108,7 +101,7 @@ export class Fun extends plugin {
|
||||
}
|
||||
|
||||
/** 有道翻译 */
|
||||
async youdao(e) {
|
||||
async youdao (e) {
|
||||
const msg = e.msg.match(/#(([\u4e00-\u9fa5]{2,6})-)?([\u4e00-\u9fa5]{2,6})?翻译(.*)/)
|
||||
// 如果是在群聊中回复,则获取上一条消息作为翻译内容
|
||||
if (e.source) {
|
||||
@@ -125,121 +118,12 @@ export class Fun extends plugin {
|
||||
}
|
||||
|
||||
/** 点赞 */
|
||||
async thumbUp(e) {
|
||||
if (e.msg.includes(`超`, `操`, `草`, `抄`, `吵`, `炒`)) {
|
||||
this.do = `超`
|
||||
} else {
|
||||
this.do = `赞`
|
||||
}
|
||||
/** 判断是赞自己还是赞别人 */
|
||||
if (e.at && e.msg.includes(`他`, `她`, `它`, `TA`, `ta`, `Ta`)) {
|
||||
/** 判断是否为好友 */
|
||||
let isFriend = await (e.bot ?? Bot).fl.get(e.at)
|
||||
let allowLikeByStrangers = Config.whole.Strangers_love
|
||||
if (!isFriend && !allowLikeByStrangers) return e.reply(`不加好友不${this.do}🙄`, true)
|
||||
/** 执行点赞 */
|
||||
let n = 0
|
||||
let failsMsg = `今天已经${this.do}过了,还搁这讨${this.do}呢!!!`
|
||||
for (let i = 0; i < 10; i++) {
|
||||
let res = null
|
||||
try {
|
||||
res = await new QQApi(e).thumbUp(e.at, 10)
|
||||
} catch (error) {
|
||||
logger.error(error)
|
||||
return common.handleException(e, error)
|
||||
}
|
||||
logger.debug(`${e.logFnc}给${e.at}点赞`, res)
|
||||
if (res.code) {
|
||||
if (res.code == 1) {
|
||||
failsMsg = `${this.do}失败,请检查是否开启陌生人点赞或添加好友`
|
||||
} else {
|
||||
if (this.do == `超`) {
|
||||
failsMsg = res.msg.replace(/点赞/g, '超').replace('给', '超').replace('点', '').replace('个赞', '下')
|
||||
} else {
|
||||
failsMsg = res.msg
|
||||
}
|
||||
}
|
||||
break
|
||||
} else {
|
||||
n += 10
|
||||
}
|
||||
}
|
||||
let successMsg = `给${e.at}${this.do}了${n}下哦,记得回我~ ${isFriend ? `` : `(如${this.do}失败请添加好友)`}`
|
||||
const avatar = `https://q1.qlogo.cn/g?b=qq&s=100&nk=${e.at}`
|
||||
const successFn = _.sample(['ganyu', 'zan'])
|
||||
|
||||
/** 判断点赞是否成功 */
|
||||
let msg = n > 0
|
||||
? [
|
||||
`\n${successMsg}`,
|
||||
segment.image((await memes[successFn](avatar)) ||
|
||||
_.sample(successImgs) + e.user_id)
|
||||
]
|
||||
: [
|
||||
`\n${failsMsg}`,
|
||||
segment.image((await memes.crawl(avatar)) ||
|
||||
_.sample(faildsImgs) + e.user_id)
|
||||
]
|
||||
|
||||
/** 回复 */
|
||||
e.reply(msg, true, { at: e.at })
|
||||
} else if (!e.msg.includes(`他`, `她`, `它`, `TA`, `ta`, `Ta`)) {
|
||||
/** 判断是否为好友 */
|
||||
let isFriend = await (e.bot ?? Bot).fl.get(e.user_id)
|
||||
let allowLikeByStrangers = Config.whole.Strangers_love
|
||||
if (!isFriend && !allowLikeByStrangers) return e.reply(`不加好友不${this.do}🙄`, true)
|
||||
|
||||
/** 执行点赞 */
|
||||
let n = 0
|
||||
let failsMsg = `今天已经${this.do}过了,还搁这讨${this.do}呢!!!`
|
||||
for (let i = 0; i < 10; i++) {
|
||||
let res = null
|
||||
try {
|
||||
res = await new QQApi(e).thumbUp(e.user_id, 10)
|
||||
} catch (error) {
|
||||
logger.error(error)
|
||||
return common.handleException(e, error)
|
||||
}
|
||||
logger.debug(`${e.logFnc}给${e.user_id}点赞`, res)
|
||||
if (res.code) {
|
||||
if (res.code == 1) {
|
||||
failsMsg = `${this.do}失败,请检查是否开启陌生人点赞或添加好友`
|
||||
} else {
|
||||
if (this.do == `超`) {
|
||||
failsMsg = res.msg.replace(/点赞/g, '超').replace('给', '超').replace('点', '').replace('个赞', '下')
|
||||
} else {
|
||||
failsMsg = res.msg
|
||||
}
|
||||
}
|
||||
break
|
||||
} else {
|
||||
n += 10
|
||||
}
|
||||
}
|
||||
let successMsg = `给你${this.do}了${n}下哦,记得回我~ ${isFriend ? `` : `(如${this.do}失败请添加好友)`}`
|
||||
const avatar = `https://q1.qlogo.cn/g?b=qq&s=100&nk=${e.user_id}`
|
||||
const successFn = _.sample(['ganyu', 'zan'])
|
||||
|
||||
/** 判断点赞是否成功 */
|
||||
let msg = n > 0
|
||||
? [
|
||||
`\n${successMsg}`,
|
||||
segment.image((await memes[successFn](avatar)) ||
|
||||
_.sample(successImgs) + e.user_id)
|
||||
]
|
||||
: [
|
||||
`\n${failsMsg}`,
|
||||
segment.image((await memes.crawl(avatar)) ||
|
||||
_.sample(faildsImgs) + e.user_id)
|
||||
]
|
||||
|
||||
/** 回复 */
|
||||
e.reply(msg, true, { at: true })
|
||||
}
|
||||
async thumbUp (e) {
|
||||
await funApi.thumbUp(e)
|
||||
}
|
||||
|
||||
// github
|
||||
async GH(e) {
|
||||
async GH (e) {
|
||||
const api = 'https://opengraph.githubassets.com'
|
||||
|
||||
let reg = /github.com\/[a-zA-Z0-9-]{1,39}\/[a-zA-Z0-9_-]{1,100}(?:\/(?:pull|issues)\/\d+)?/
|
||||
@@ -256,7 +140,7 @@ export class Fun extends plugin {
|
||||
}
|
||||
|
||||
// coser
|
||||
async coser(e) {
|
||||
async coser (e) {
|
||||
if (!common.checkSeSePermission(e)) return false
|
||||
|
||||
e.reply(START_EXECUTION)
|
||||
@@ -266,7 +150,7 @@ export class Fun extends plugin {
|
||||
}
|
||||
|
||||
// cos/acg搜索
|
||||
async acg(e) {
|
||||
async acg (e) {
|
||||
if (!common.checkSeSePermission(e)) return false
|
||||
e.reply(START_EXECUTION)
|
||||
const reg = new RegExp(`^#(${Object.keys(pandadiuType).join('|')})?acg(.*)$`)
|
||||
@@ -277,7 +161,7 @@ export class Fun extends plugin {
|
||||
}
|
||||
|
||||
// 黑丝
|
||||
async heisiwu(e) {
|
||||
async heisiwu (e) {
|
||||
if (!common.checkSeSePermission(e, 'sesepro')) return false
|
||||
|
||||
e.reply(START_EXECUTION)
|
||||
@@ -289,7 +173,7 @@ export class Fun extends plugin {
|
||||
}
|
||||
|
||||
// 萌堆
|
||||
async mengdui(e) {
|
||||
async mengdui (e) {
|
||||
if (!common.checkSeSePermission(e, 'sesepro')) return false
|
||||
// 开始执行
|
||||
e.reply(START_EXECUTION)
|
||||
@@ -299,7 +183,7 @@ export class Fun extends plugin {
|
||||
.catch(err => common.handleException(e, err))
|
||||
}
|
||||
|
||||
async xiuren(e) {
|
||||
async xiuren (e) {
|
||||
if (!common.checkSeSePermission(e, 'pro')) return false
|
||||
// 开始执行
|
||||
e.reply(START_EXECUTION)
|
||||
@@ -309,41 +193,24 @@ export class Fun extends plugin {
|
||||
}
|
||||
|
||||
// 铃声多多
|
||||
async lingsheng(e) {
|
||||
let msg = e.msg.replace(/#|铃声搜索/g, '')
|
||||
let num = Math.ceil(Math.random() * 15)
|
||||
if (num == 0) num = 1
|
||||
let api = `http://xiaobai.klizi.cn/API/music/lingsheng.php?msg=${msg}&n=${num}`
|
||||
let res = await fetch(api).then(res => res.json()).catch(err => logger.error(err))
|
||||
if (!res) return e.reply(API_ERROR)
|
||||
if (res.title == null && res.author == null) return e.reply('❎ 没有找到相关的歌曲哦~', true)
|
||||
// async lingsheng (e) {
|
||||
// let msg = e.msg.replace(/#|铃声搜索/g, '')
|
||||
// let num = Math.ceil(Math.random() * 15)
|
||||
// if (num == 0) num = 1
|
||||
// let api = `http://xiaobai.klizi.cn/API/music/lingsheng.php?msg=${msg}&n=${num}`
|
||||
// let res = await fetch(api).then(res => res.json()).catch(err => logger.error(err))
|
||||
// if (!res) return e.reply(API_ERROR)
|
||||
// if (res.title == null && res.author == null) return e.reply('❎ 没有找到相关的歌曲哦~', true)
|
||||
|
||||
await e.reply([
|
||||
`标题:${res.title}\n`,
|
||||
`作者:${res.author}`
|
||||
])
|
||||
await e.reply(await uploadRecord(res.aac, 0, false))
|
||||
}
|
||||
|
||||
/** 半次元话题 */
|
||||
async bcyTopic(e) {
|
||||
let api = 'https://xiaobai.klizi.cn/API/other/bcy_topic.php'
|
||||
let res = await fetch(api).then(res => res.json()).catch(err => logger.error(err))
|
||||
if (!res) return e.reply(API_ERROR)
|
||||
if (res.code != 200) return e.reply('❎ 出错辣' + JSON.stringify(res))
|
||||
if (_.isEmpty(res.data)) return e.reply('请求错误!无数据,请稍后再试')
|
||||
let msg = []
|
||||
for (let i of res.data) {
|
||||
if (!i.title || _.isEmpty(i.image)) continue
|
||||
msg.push(i.title)
|
||||
msg.push(i.image.map(item => segment.image(item)))
|
||||
}
|
||||
if (_.isEmpty(msg)) return this.bcyTopic(e)
|
||||
common.getforwardMsg(e, msg)
|
||||
}
|
||||
// await e.reply([
|
||||
// `标题:${res.title}\n`,
|
||||
// `作者:${res.author}`
|
||||
// ])
|
||||
// await e.reply(await uploadRecord(res.aac, 0, false))
|
||||
// }
|
||||
|
||||
// api大集合
|
||||
async picture(e) {
|
||||
async picture (e) {
|
||||
let { sese, sesepro } = Config.getGroup(e.group_id)
|
||||
if (!sese && !sesepro && !e.isMaster) return false
|
||||
let key = 'yenai:apiAggregate:CD'
|
||||
|
||||
@@ -428,17 +428,17 @@ export default class {
|
||||
*/
|
||||
async thumbUp (uid, times = 1) {
|
||||
let core = this.Bot.icqq?.core
|
||||
if (!core) try {
|
||||
core = (await import('icqq')).core
|
||||
} catch (error) {
|
||||
const thumbUp = this.Bot.pickFriend(uid).thumbUp
|
||||
if (!thumbUp) throw Error('当前协议端不支持点赞,详情查看\nhttps://gitee.com/TimeRainStarSky/Yunzai')
|
||||
const res = { ...await thumbUp(times) }
|
||||
if (res.retcode && !res.code)
|
||||
res.code = res.retcode
|
||||
if (res.message && !res.msg)
|
||||
res.msg = res.message
|
||||
return res
|
||||
if (!core) {
|
||||
try {
|
||||
core = (await import('icqq')).core
|
||||
} catch (error) {
|
||||
const thumbUp = this.Bot.pickFriend(uid).thumbUp
|
||||
if (!thumbUp) throw Error('当前协议端不支持点赞,详情查看\nhttps://gitee.com/TimeRainStarSky/Yunzai')
|
||||
const res = { ...await thumbUp(times) }
|
||||
if (res.retcode && !res.code) { res.code = res.retcode }
|
||||
if (res.message && !res.msg) { res.msg = res.message }
|
||||
return res
|
||||
}
|
||||
}
|
||||
if (times > 20) { times = 20 }
|
||||
let ReqFavorite
|
||||
|
||||
@@ -1,351 +1,12 @@
|
||||
import _ from 'lodash'
|
||||
import md5 from 'md5'
|
||||
import fetch from 'node-fetch'
|
||||
import request from '../../lib/request/request.js'
|
||||
import { puppeteer } from '../index.js'
|
||||
import { xiurenTypeId, youDaoLangType, pandadiuType } from '../../constants/fun.js'
|
||||
|
||||
const API_ERROR = '出了点小问题,待会再试试吧'
|
||||
|
||||
let cheerio = null
|
||||
export default new class {
|
||||
constructor () {
|
||||
this.xiurenTypeId = xiurenTypeId
|
||||
}
|
||||
|
||||
async _importDependency () {
|
||||
if (cheerio) return cheerio
|
||||
cheerio = await import('cheerio')
|
||||
.catch(() => {
|
||||
throw Error('未检测到依赖cheerio,请安装后再使用该功能,安装命令:pnpm add cheerio -w 或 pnpm install -P')
|
||||
})
|
||||
}
|
||||
|
||||
/** 有道翻译 */
|
||||
async youdao (msg, to = 'auto', from = 'auto') {
|
||||
if (to != 'auto') to = youDaoLangType.find(item => item.label == to)?.code
|
||||
if (from != 'auto') from = youDaoLangType.find(item => item.label == from)?.code
|
||||
if (!to || !from) return `未找到翻译的语种,支持的语言为:\n${youDaoLangType.map(item => item.label).join(',')}\n示例:#翻译你好 - 自动翻译\n#日语翻译你好 - 指定翻译为语种\n#中文-日语翻译你好 - 指定原语言翻译为指定语言`
|
||||
// 翻译结果为空的提示
|
||||
const RESULT_ERROR = '找不到翻译结果'
|
||||
// API 请求错误提示
|
||||
const qs = (obj) => {
|
||||
let res = ''
|
||||
for (const [k, v] of Object.entries(obj)) { res += `${k}=${encodeURIComponent(v)}&` }
|
||||
return res.slice(0, res.length - 1)
|
||||
}
|
||||
const appVersion = '5.0 (Windows NT 10.0; Win64; x64) Chrome/98.0.4750.0'
|
||||
const payload = {
|
||||
from,
|
||||
to,
|
||||
bv: md5(appVersion),
|
||||
client: 'fanyideskweb',
|
||||
doctype: 'json',
|
||||
version: '2.1',
|
||||
keyfrom: 'fanyi.web',
|
||||
action: 'FY_BY_DEFAULT',
|
||||
smartresult: 'dict'
|
||||
}
|
||||
const headers = {
|
||||
'Host': 'fanyi.youdao.com',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/98.0.4758.102',
|
||||
'Referer': 'https://fanyi.youdao.com/',
|
||||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||
'Cookie': 'OUTFOX_SEARCH_USER_ID_NCOO=133190305.98519628; OUTFOX_SEARCH_USER_ID="2081065877@10.169.0.102";'
|
||||
}
|
||||
const api = 'https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
|
||||
const key = 'Ygy_4c=r#e#4EX^NUGUc5'
|
||||
|
||||
const i = msg // 翻译的内容
|
||||
const lts = '' + new Date().getTime()
|
||||
const salt = lts + parseInt(String(10 * Math.random()), 10)
|
||||
const sign = md5(payload.client + i + salt + key)
|
||||
const postData = qs(Object.assign({ i, lts, sign, salt }, payload))
|
||||
try {
|
||||
let { errorCode, translateResult } = await fetch(api, {
|
||||
method: 'POST',
|
||||
body: postData,
|
||||
headers
|
||||
}).then(res => res.json()).catch(err => console.error(err))
|
||||
if (errorCode != 0) return API_ERROR
|
||||
translateResult = _.flattenDeep(translateResult)?.map(item => item.tgt).join('\n')
|
||||
if (!translateResult) return RESULT_ERROR
|
||||
return translateResult
|
||||
} catch (err) {
|
||||
logger.error(err)
|
||||
return API_ERROR
|
||||
}
|
||||
}
|
||||
|
||||
/** 随机唱歌/唱鸭 */
|
||||
async randomSinging () {
|
||||
try {
|
||||
const api = 'https://m.api.singduck.cn/user-piece/SoQJ9cKu61FJ1Vwc7'
|
||||
let res = await fetch(api).then(res => res.text())
|
||||
let JSONdara = JSON.parse(res.match(/<script id="__NEXT_DATA__" type="application\/json" crossorigin="anonymous">(.*?)<\/script>/)[1])
|
||||
if (!JSONdara) return { error: API_ERROR }
|
||||
let piece = _.sample(JSONdara.props.pageProps.pieces)
|
||||
let { songName, lyric, audioUrl } = piece
|
||||
if (!audioUrl) return { error: '找不到歌曲文件' }
|
||||
return {
|
||||
lyrics: `《${songName}》\n${lyric}`,
|
||||
audioUrl: decodeURIComponent(audioUrl)
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(error)
|
||||
return { error: API_ERROR }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 黑丝屋
|
||||
* @param {data.heisiType} type 类型
|
||||
* @param {Number} page 页数
|
||||
* @return {*}
|
||||
*/
|
||||
async heisiwu (type, page) {
|
||||
await this._importDependency()
|
||||
const url = `http://hs.heisiwu.com/${type}/page/${_.random(1, page)}`
|
||||
const home = await request.get(url).then(res => res.text())
|
||||
const href = _.sample(_.map(cheerio.load(home)('article > a'), (item) => item.attribs.href))
|
||||
if (_.isEmpty(href)) throw Error('获取页面失败')
|
||||
const details = await request.get(href).then(res => res.text())
|
||||
const $ = cheerio.load(details)
|
||||
const imgs = _.map($('.alignnone'), (item) => item.attribs.src)
|
||||
if (_.isEmpty(imgs)) throw Error('获取图片失败')
|
||||
const title = $('.article-content > p:nth-child(1)').text()
|
||||
const msg = imgs.map(item => segment.image(item, undefined, undefined,
|
||||
{
|
||||
'Referer': 'http://hs.heisiwu.com',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.46'
|
||||
})
|
||||
)
|
||||
return [title, ..._.take(msg, 30)]
|
||||
}
|
||||
|
||||
async pandadiu (type = 'cos', keywords = '') {
|
||||
await this._importDependency()
|
||||
let domain = 'https://www.pandadiu.com'
|
||||
const { id, page } = pandadiuType[type]
|
||||
let homeUrl = `${domain}/list-${id}-${_.random(1, page)}.html`
|
||||
if (keywords) {
|
||||
homeUrl = `${domain}/index.php?m=search&c=index&a=init&typeid=1&siteid=1&q=${keywords}`
|
||||
}
|
||||
logger.debug('[Yenai-Plugin][acg]作品索引页:' + homeUrl)
|
||||
const home = await request.get(homeUrl).then(res => res.text())
|
||||
const href = _.sample(_.map(cheerio.load(home)('div.cos-list.clearfix > ul > a, div.cover.mod_imgLight > a'), item => item.attribs.href))
|
||||
if (!href) throw Error('未找到结果')
|
||||
logger.debug('[Yenai-Plugin][acg]图片详情页:' + domain + href)
|
||||
const details = await request.get(domain + href).then(res => res.text())
|
||||
const $ = cheerio.load(details)
|
||||
const imgs = _.map($('div.con > p > img'), item =>
|
||||
segment.image(item.attribs.src.includes('http')
|
||||
? item.attribs.src
|
||||
: domain + item.attribs.src
|
||||
))
|
||||
const title = $('div.title > h1').text()
|
||||
return [
|
||||
title,
|
||||
..._.take(imgs, 30)
|
||||
]
|
||||
}
|
||||
|
||||
async mengdui (keywords, isSearch) {
|
||||
await this._importDependency()
|
||||
const domain = 'https://b6u8.com'
|
||||
let href = ''
|
||||
if (isSearch) {
|
||||
const mengduipage = JSON.parse(await redis.get('yenai:mengduipage')) || {}
|
||||
const randomPage = _.random(1, mengduipage[keywords] || 1)
|
||||
const url = `${domain}/search.php?mdact=community&q=${keywords}&page=${randomPage}`
|
||||
const home = await request.get(url).then(res => res.text())
|
||||
const $ = cheerio.load(home)
|
||||
href = _.sample(_.map($('div.md-wide > ul > li > a'), item => item.attribs.href))
|
||||
if (!href) throw Error($('div.no-tips > p:nth-of-type(1)').text().trim())
|
||||
const maxPage = $('div.pagebar.md-flex-wc.mb20 > a:not(:last-child)').length
|
||||
mengduipage[keywords] = maxPage
|
||||
await redis.set('yenai:mengduipage', JSON.stringify(mengduipage))
|
||||
} else {
|
||||
let random = keywords
|
||||
if (!random) {
|
||||
do {
|
||||
random = _.random(1, 11687)
|
||||
} while (
|
||||
_.inRange(random, 7886, 10136)
|
||||
)
|
||||
}
|
||||
href = `${domain}/post/${random}.html`
|
||||
}
|
||||
const details = await request.get(href).then(res => res.text())
|
||||
const $ = cheerio.load(details)
|
||||
const imgs = _.map($('div.md-text.mb20.f-16 > p > img'), item => segment.image(item.attribs.src))
|
||||
const title = $('h1').text().trim()
|
||||
const number = `序号:${href.match(/(\d+).html/)[1]}`
|
||||
return [title, number, ..._.take(imgs, 30)]
|
||||
}
|
||||
|
||||
async xiuren (type) {
|
||||
await this._importDependency()
|
||||
// 可扩展
|
||||
let handleType = this.xiurenTypeId[type]
|
||||
let homeUrl = `https://www.lisiku1.com/forum-${handleType.id}-${_.random(1, handleType.maxPage)}.html`
|
||||
let html = await request.get(homeUrl).then(res => res.text())
|
||||
let $ = cheerio.load(html)
|
||||
let href = _.sample(
|
||||
_.map(
|
||||
$('#moderate > div > div.kind_show > div > div:nth-child(1) > a'),
|
||||
(item) => item.attribs.href
|
||||
)
|
||||
)
|
||||
let imgPageUrl = 'https://www.lisiku1.com/' + href
|
||||
let imgPage = await request.get(imgPageUrl).then((res) =>
|
||||
res.text()
|
||||
)
|
||||
let $1 = cheerio.load(imgPage)
|
||||
let imgList = _.map(
|
||||
$1(
|
||||
'td > img'
|
||||
), item => segment.image('https://www.lisiku1.com/' + item.attribs.src)
|
||||
)
|
||||
return imgList
|
||||
}
|
||||
|
||||
async bgg (keyword) {
|
||||
await this._importDependency()
|
||||
let url = 'https://www.gstonegames.com/game/?hot_sort=1&keyword=' + encodeURIComponent(keyword)
|
||||
const home = await request.get(url).then((res) => res.text())
|
||||
const $ = cheerio.load(home)
|
||||
|
||||
// 获取集石第一个搜索结果的地址
|
||||
const firstGameLink = $('.goods-list.fl').first().find('a').attr('href')
|
||||
// 如果搜不到
|
||||
if (!firstGameLink) {
|
||||
const screenshot = await puppeteer.Webpage({ url })
|
||||
return [
|
||||
'集石搜索不到该游戏:',
|
||||
`搜索地址:${url}`,
|
||||
'\n以下是搜索页面的截图:',
|
||||
screenshot
|
||||
]
|
||||
}
|
||||
// 拼出集石详情网址并访问
|
||||
let href = `https://www.gstonegames.com${firstGameLink}`
|
||||
logger.info(`集石详情网址:${href}`)
|
||||
|
||||
const detailshtml = await request.get(href).then((res) => res.text())
|
||||
|
||||
const details$ = cheerio.load(detailshtml)
|
||||
|
||||
// 获取游戏类型
|
||||
const gametype = details$(
|
||||
'.published:contains("分类信息") .part-left-title + ul li:nth-child(1) a'
|
||||
)
|
||||
.text()
|
||||
.trim()
|
||||
const gamemode = details$(
|
||||
'.published:contains("分类信息") .part-left-title + ul li:nth-child(2) a'
|
||||
)
|
||||
.text()
|
||||
.trim()
|
||||
// const gamemove =details$('.published:contains("分类信息") .part-left-title + ul li:nth-child(3) a').text().trim();
|
||||
|
||||
// 获取BGG网址
|
||||
const bgglink = details$('.published.who.matop15.mabot50')
|
||||
.eq(2)
|
||||
.find('a')
|
||||
.attr('href')
|
||||
// 如果搜不到
|
||||
if (!bgglink) {
|
||||
let url = href
|
||||
const screenshot = await puppeteer.Webpage({ url })
|
||||
return [
|
||||
'集石该游戏页面无BGG信息:',
|
||||
`搜索地址:${url}`,
|
||||
'\n以下是该游戏集石页面的截图:',
|
||||
screenshot
|
||||
]
|
||||
}
|
||||
// 如果搜到了
|
||||
logger.info(bgglink)
|
||||
// 扒集石的数据
|
||||
const gameName2 = details$('.details-title h2 a').text().trim()
|
||||
logger.info(`游戏中文名字:${gameName2}`)
|
||||
|
||||
// 访问bgg
|
||||
const bgghtml = await request.get(bgglink).then((res) => res.text())
|
||||
|
||||
const bgg$ = cheerio.load(bgghtml)
|
||||
|
||||
// 开扒
|
||||
let scriptdataA = bgg$('script').eq(2).text()
|
||||
let scriptdata = JSON.parse(
|
||||
scriptdataA.substring(
|
||||
scriptdataA.indexOf('GEEK.geekitemPreload = ') + 22,
|
||||
scriptdataA.indexOf('GEEK.geekitemSettings = ') - 3
|
||||
)
|
||||
)
|
||||
let {
|
||||
minplayers,
|
||||
maxplayers,
|
||||
minplaytime,
|
||||
maxplaytime,
|
||||
minage
|
||||
} = scriptdata.item
|
||||
let avgweight = scriptdata.item.stats.avgweight.substring(0, 4)
|
||||
let OverallRank = scriptdata.item.rankinfo[0].rank
|
||||
|
||||
|
||||
// 获取游戏英文名字
|
||||
const gameName1 = bgg$(`meta[property='og:title']`).attr('content');
|
||||
|
||||
// 获取游戏图片URL
|
||||
const gameimgLink = bgg$(`link[rel='preload'][as='image']:eq(1)`).attr('href');
|
||||
|
||||
// 游戏图片URL可能有多条,这里取第一条
|
||||
const gameimg = gameimgLink ? gameimgLink : null;
|
||||
|
||||
logger.info(`游戏英文名字:${gameName1}`)
|
||||
|
||||
// 回复
|
||||
return [
|
||||
`游戏中文名:${gameName2}\n`,
|
||||
`游戏英文名:${gameName1}\n`,
|
||||
`游戏类型:${gametype}\n`,
|
||||
`游戏模式:${gamemode}\n`,
|
||||
`BGG地址:${bgglink}\n`,
|
||||
`集石地址:${href}\n`,
|
||||
`BGG当前总排名:${OverallRank}\n`,
|
||||
`支持游玩人数:${minplayers}-${maxplayers}\n`,
|
||||
`大概游玩时间:${minplaytime}-${maxplaytime}分钟\n`,
|
||||
`推荐年龄:${minage}+\n`,
|
||||
`游戏重度:${avgweight}/5\n`,
|
||||
segment.image(gameimg)
|
||||
]
|
||||
}
|
||||
|
||||
async coser () {
|
||||
await this._importDependency()
|
||||
const domain = 'https://t2cy.com'
|
||||
const homeUrl = `${domain}/acg/cos/index_${_.random(1, 30)}.html`
|
||||
logger.debug('[Yenai-Plugin][coser]作品索引页:' + homeUrl)
|
||||
const home = await request.get(homeUrl).then(res => res.text())
|
||||
const $ = cheerio.load(home)
|
||||
const href = _.sample(
|
||||
_.map(
|
||||
$('body > div > div.content.hidden > ul.cy2-coslist.clr > li > div.showImg > a'),
|
||||
(item) => item.attribs.href
|
||||
)
|
||||
)
|
||||
if (!href) throw Error('未知错误')
|
||||
logger.debug('[Yenai-Plugin][coser]图片详情页:' + domain + href)
|
||||
const imgPage = await request.get(domain + href).then(res => res.text())
|
||||
const $1 = cheerio.load(imgPage)
|
||||
const imgList = _.map(
|
||||
$1(
|
||||
'body > div > div.content.pb20.clr > div.cy_cosCon > div.w.maxImg.tc > p > img'
|
||||
), item => segment.image(_.includes(item.attribs.src, 'http') ? item.attribs.src : domain + (item.attribs['data-loadsrc'] || item.attribs.src))
|
||||
)
|
||||
const title = $1('h1').text().trim()
|
||||
return [title, ..._.take(imgList, 20)]
|
||||
}
|
||||
}()
|
||||
import bgg from './funApi/bgg.js'
|
||||
import youdao from './funApi/youdao.js'
|
||||
import * as pageCrawling from './funApi/pageCrawling.js'
|
||||
import randomSinging from './funApi/randomSinging.js'
|
||||
import thumbUp from './funApi/thumbUp.js'
|
||||
export default {
|
||||
bgg,
|
||||
youdao,
|
||||
thumbUp,
|
||||
randomSinging,
|
||||
...pageCrawling
|
||||
}
|
||||
|
||||
115
model/api/funApi/bgg.js
Normal file
115
model/api/funApi/bgg.js
Normal file
@@ -0,0 +1,115 @@
|
||||
import { _importDependency } from './utils.js'
|
||||
import request from '../../../lib/request/request.js'
|
||||
import { puppeteer } from '../../index.js'
|
||||
|
||||
export default async function bgg (keyword) {
|
||||
let cheerio = await _importDependency()
|
||||
let url = 'https://www.gstonegames.com/game/?hot_sort=1&keyword=' + encodeURIComponent(keyword)
|
||||
const home = await request.get(url).then((res) => res.text())
|
||||
const $ = cheerio.load(home)
|
||||
|
||||
// 获取集石第一个搜索结果的地址
|
||||
const firstGameLink = $('.goods-list.fl').first().find('a').attr('href')
|
||||
// 如果搜不到
|
||||
if (!firstGameLink) {
|
||||
const screenshot = await puppeteer.Webpage({ url })
|
||||
return [
|
||||
'集石搜索不到该游戏:',
|
||||
`搜索地址:${url}`,
|
||||
'\n以下是搜索页面的截图:',
|
||||
screenshot
|
||||
]
|
||||
}
|
||||
// 拼出集石详情网址并访问
|
||||
let href = `https://www.gstonegames.com${firstGameLink}`
|
||||
logger.info(`集石详情网址:${href}`)
|
||||
|
||||
const detailshtml = await request.get(href).then((res) => res.text())
|
||||
|
||||
const details$ = cheerio.load(detailshtml)
|
||||
|
||||
// 获取游戏类型
|
||||
const gametype = details$(
|
||||
'.published:contains("分类信息") .part-left-title + ul li:nth-child(1) a'
|
||||
)
|
||||
.text()
|
||||
.trim()
|
||||
const gamemode = details$(
|
||||
'.published:contains("分类信息") .part-left-title + ul li:nth-child(2) a'
|
||||
)
|
||||
.text()
|
||||
.trim()
|
||||
// const gamemove =details$('.published:contains("分类信息") .part-left-title + ul li:nth-child(3) a').text().trim();
|
||||
|
||||
// 获取BGG网址
|
||||
const bgglink = details$('.published.who.matop15.mabot50')
|
||||
.eq(2)
|
||||
.find('a')
|
||||
.attr('href')
|
||||
// 如果搜不到
|
||||
if (!bgglink) {
|
||||
let url = href
|
||||
const screenshot = await puppeteer.Webpage({ url })
|
||||
return [
|
||||
'集石该游戏页面无BGG信息:',
|
||||
`搜索地址:${url}`,
|
||||
'\n以下是该游戏集石页面的截图:',
|
||||
screenshot
|
||||
]
|
||||
}
|
||||
// 如果搜到了
|
||||
logger.info(bgglink)
|
||||
// 扒集石的数据
|
||||
const gameName2 = details$('.details-title h2 a').text().trim()
|
||||
logger.info(`游戏中文名字:${gameName2}`)
|
||||
|
||||
// 访问bgg
|
||||
const bgghtml = await request.get(bgglink).then((res) => res.text())
|
||||
|
||||
const bgg$ = cheerio.load(bgghtml)
|
||||
|
||||
// 开扒
|
||||
let scriptdataA = bgg$('script').eq(2).text()
|
||||
let scriptdata = JSON.parse(
|
||||
scriptdataA.substring(
|
||||
scriptdataA.indexOf('GEEK.geekitemPreload = ') + 22,
|
||||
scriptdataA.indexOf('GEEK.geekitemSettings = ') - 3
|
||||
)
|
||||
)
|
||||
let {
|
||||
minplayers,
|
||||
maxplayers,
|
||||
minplaytime,
|
||||
maxplaytime,
|
||||
minage
|
||||
} = scriptdata.item
|
||||
let avgweight = scriptdata.item.stats.avgweight.substring(0, 4)
|
||||
let OverallRank = scriptdata.item.rankinfo[0].rank
|
||||
|
||||
// 获取游戏英文名字
|
||||
const gameName1 = bgg$('meta[property=\'og:title\']').attr('content')
|
||||
|
||||
// 获取游戏图片URL
|
||||
const gameimgLink = bgg$('link[rel=\'preload\'][as=\'image\']:eq(1)').attr('href')
|
||||
|
||||
// 游戏图片URL可能有多条,这里取第一条
|
||||
const gameimg = gameimgLink || null
|
||||
|
||||
logger.info(`游戏英文名字:${gameName1}`)
|
||||
|
||||
// 回复
|
||||
return [
|
||||
`游戏中文名:${gameName2}\n`,
|
||||
`游戏英文名:${gameName1}\n`,
|
||||
`游戏类型:${gametype}\n`,
|
||||
`游戏模式:${gamemode}\n`,
|
||||
`BGG地址:${bgglink}\n`,
|
||||
`集石地址:${href}\n`,
|
||||
`BGG当前总排名:${OverallRank}\n`,
|
||||
`支持游玩人数:${minplayers}-${maxplayers}\n`,
|
||||
`大概游玩时间:${minplaytime}-${maxplaytime}分钟\n`,
|
||||
`推荐年龄:${minage}+\n`,
|
||||
`游戏重度:${avgweight}/5\n`,
|
||||
segment.image(gameimg)
|
||||
]
|
||||
}
|
||||
116
model/api/funApi/pageCrawling.js
Normal file
116
model/api/funApi/pageCrawling.js
Normal file
@@ -0,0 +1,116 @@
|
||||
import { pandadiuType, xiurenTypeId } from '../../../constants/fun.js'
|
||||
import _ from 'lodash'
|
||||
import { _importDependency } from './utils.js'
|
||||
import request from '../../../lib/request/request.js'
|
||||
|
||||
export async function pandadiu (type = 'cos', keywords = '') {
|
||||
let cheerio = await _importDependency()
|
||||
let domain = 'https://www.pandadiu.com'
|
||||
const { id, page } = pandadiuType[type]
|
||||
let homeUrl = `${domain}/list-${id}-${_.random(1, page)}.html`
|
||||
if (keywords) {
|
||||
homeUrl = `${domain}/index.php?m=search&c=index&a=init&typeid=1&siteid=1&q=${keywords}`
|
||||
}
|
||||
logger.debug('[Yenai-Plugin][acg]作品索引页:' + homeUrl)
|
||||
const home = await request.get(homeUrl).then(res => res.text())
|
||||
const href = _.sample(_.map(cheerio.load(home)('div.cos-list.clearfix > ul > a, div.cover.mod_imgLight > a'), item => item.attribs.href))
|
||||
if (!href) throw Error('未找到结果')
|
||||
logger.debug('[Yenai-Plugin][acg]图片详情页:' + domain + href)
|
||||
const details = await request.get(domain + href).then(res => res.text())
|
||||
const $ = cheerio.load(details)
|
||||
const imgs = _.map($('div.con > p > img'), item =>
|
||||
segment.image(item.attribs.src.includes('http')
|
||||
? item.attribs.src
|
||||
: domain + item.attribs.src
|
||||
))
|
||||
const title = $('div.title > h1').text()
|
||||
return [
|
||||
title,
|
||||
..._.take(imgs, 30)
|
||||
]
|
||||
}
|
||||
export async function mengdui (keywords, isSearch) {
|
||||
let cheerio = await _importDependency()
|
||||
const domain = 'https://b6u8.com'
|
||||
let href = ''
|
||||
if (isSearch) {
|
||||
const mengduipage = JSON.parse(await redis.get('yenai:mengduipage')) || {}
|
||||
const randomPage = _.random(1, mengduipage[keywords] || 1)
|
||||
const url = `${domain}/search.php?mdact=community&q=${keywords}&page=${randomPage}`
|
||||
const home = await request.get(url).then(res => res.text())
|
||||
const $ = cheerio.load(home)
|
||||
href = _.sample(_.map($('div.md-wide > ul > li > a'), item => item.attribs.href))
|
||||
if (!href) throw Error($('div.no-tips > p:nth-of-type(1)').text().trim())
|
||||
const maxPage = $('div.pagebar.md-flex-wc.mb20 > a:not(:last-child)').length
|
||||
mengduipage[keywords] = maxPage
|
||||
await redis.set('yenai:mengduipage', JSON.stringify(mengduipage))
|
||||
} else {
|
||||
let random = keywords
|
||||
if (!random) {
|
||||
do {
|
||||
random = _.random(1, 11687)
|
||||
} while (
|
||||
_.inRange(random, 7886, 10136)
|
||||
)
|
||||
}
|
||||
href = `${domain}/post/${random}.html`
|
||||
}
|
||||
const details = await request.get(href).then(res => res.text())
|
||||
const $ = cheerio.load(details)
|
||||
const imgs = _.map($('div.md-text.mb20.f-16 > p > img'), item => segment.image(item.attribs.src))
|
||||
const title = $('h1').text().trim()
|
||||
const number = `序号:${href.match(/(\d+).html/)[1]}`
|
||||
return [title, number, ..._.take(imgs, 30)]
|
||||
}
|
||||
|
||||
export async function xiuren (type) {
|
||||
let cheerio = await _importDependency()
|
||||
// 可扩展
|
||||
let handleType = xiurenTypeId[type]
|
||||
let homeUrl = `https://www.lisiku1.com/forum-${handleType.id}-${_.random(1, handleType.maxPage)}.html`
|
||||
let html = await request.get(homeUrl).then(res => res.text())
|
||||
let $ = cheerio.load(html)
|
||||
let href = _.sample(
|
||||
_.map(
|
||||
$('#moderate > div > div.kind_show > div > div:nth-child(1) > a'),
|
||||
(item) => item.attribs.href
|
||||
)
|
||||
)
|
||||
let imgPageUrl = 'https://www.lisiku1.com/' + href
|
||||
let imgPage = await request.get(imgPageUrl).then((res) =>
|
||||
res.text()
|
||||
)
|
||||
let $1 = cheerio.load(imgPage)
|
||||
let imgList = _.map(
|
||||
$1(
|
||||
'td > img'
|
||||
), item => segment.image('https://www.lisiku1.com/' + item.attribs.src)
|
||||
)
|
||||
return imgList
|
||||
}
|
||||
|
||||
export async function coser () {
|
||||
let cheerio = await _importDependency()
|
||||
const domain = 'https://t2cy.com'
|
||||
const homeUrl = `${domain}/acg/cos/index_${_.random(1, 30)}.html`
|
||||
logger.debug('[Yenai-Plugin][coser]作品索引页:' + homeUrl)
|
||||
const home = await request.get(homeUrl).then(res => res.text())
|
||||
const $ = cheerio.load(home)
|
||||
const href = _.sample(
|
||||
_.map(
|
||||
$('body > div > div.content.hidden > ul.cy2-coslist.clr > li > div.showImg > a'),
|
||||
(item) => item.attribs.href
|
||||
)
|
||||
)
|
||||
if (!href) throw Error('未知错误')
|
||||
logger.debug('[Yenai-Plugin][coser]图片详情页:' + domain + href)
|
||||
const imgPage = await request.get(domain + href).then(res => res.text())
|
||||
const $1 = cheerio.load(imgPage)
|
||||
const imgList = _.map(
|
||||
$1(
|
||||
'body > div > div.content.pb20.clr > div.cy_cosCon > div.w.maxImg.tc > p > img'
|
||||
), item => segment.image(_.includes(item.attribs.src, 'http') ? item.attribs.src : domain + (item.attribs['data-loadsrc'] || item.attribs.src))
|
||||
)
|
||||
const title = $1('h1').text().trim()
|
||||
return [title, ..._.take(imgList, 20)]
|
||||
}
|
||||
22
model/api/funApi/randomSinging.js
Normal file
22
model/api/funApi/randomSinging.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import { API_ERROR } from './utils.js'
|
||||
import _ from 'lodash'
|
||||
|
||||
/** 随机唱歌/唱鸭 */
|
||||
export default async function randomSinging () {
|
||||
try {
|
||||
const api = 'https://m.api.singduck.cn/user-piece/SoQJ9cKu61FJ1Vwc7'
|
||||
let res = await fetch(api).then(res => res.text())
|
||||
let JSONdara = JSON.parse(res.match(/<script id="__NEXT_DATA__" type="application\/json" crossorigin="anonymous">(.*?)<\/script>/)[1])
|
||||
if (!JSONdara) return { error: API_ERROR }
|
||||
let piece = _.sample(JSONdara.props.pageProps.pieces)
|
||||
let { songName, lyric, audioUrl } = piece
|
||||
if (!audioUrl) return { error: '找不到歌曲文件' }
|
||||
return {
|
||||
lyrics: `《${songName}》\n${lyric}`,
|
||||
audioUrl: decodeURIComponent(audioUrl)
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(error)
|
||||
return { error: API_ERROR }
|
||||
}
|
||||
}
|
||||
116
model/api/funApi/thumbUp.js
Normal file
116
model/api/funApi/thumbUp.js
Normal file
@@ -0,0 +1,116 @@
|
||||
import _ from 'lodash'
|
||||
import { QQApi, memes, common } from '../../index.js'
|
||||
import { Config } from '../../../components/index.js'
|
||||
import { successImgs, faildsImgs } from '../../../constants/fun.js'
|
||||
|
||||
export default async function thumbUp (e) {
|
||||
let _do = '赞'
|
||||
if (e.msg.includes('超', '操', '草', '抄', '吵', '炒')) {
|
||||
_do = '超'
|
||||
}
|
||||
/** 判断是赞自己还是赞别人 */
|
||||
if (e.at && e.msg.includes('他', '她', '它', 'TA', 'ta', 'Ta')) {
|
||||
/** 判断是否为好友 */
|
||||
let isFriend = await (e.bot ?? Bot).fl.get(e.at)
|
||||
let allowLikeByStrangers = Config.whole.Strangers_love
|
||||
if (!isFriend && !allowLikeByStrangers) return e.reply(`不加好友不${_do}🙄`, true)
|
||||
/** 执行点赞 */
|
||||
let n = 0
|
||||
let failsMsg = `今天已经${_do}过了,还搁这讨${_do}呢!!!`
|
||||
for (let i = 0; i < 10; i++) {
|
||||
let res = null
|
||||
try {
|
||||
res = await new QQApi(e).thumbUp(e.at, 10)
|
||||
} catch (error) {
|
||||
logger.error(error)
|
||||
return common.handleException(e, error)
|
||||
}
|
||||
logger.debug(`${e.logFnc}给${e.at}点赞`, res)
|
||||
if (res.code) {
|
||||
if (res.code == 1) {
|
||||
failsMsg = `${_do}失败,请检查是否开启陌生人点赞或添加好友`
|
||||
} else {
|
||||
if (_do == '超') {
|
||||
failsMsg = res.msg.replace(/点赞/g, '超').replace('给', '超').replace('点', '').replace('个赞', '下')
|
||||
} else {
|
||||
failsMsg = res.msg
|
||||
}
|
||||
}
|
||||
break
|
||||
} else {
|
||||
n += 10
|
||||
}
|
||||
}
|
||||
let successMsg = `给${e.at}${_do}了${n}下哦,记得回我~ ${isFriend ? '' : `(如${_do}失败请添加好友)`}`
|
||||
const avatar = `https://q1.qlogo.cn/g?b=qq&s=100&nk=${e.at}`
|
||||
const successFn = _.sample(['ganyu', 'zan'])
|
||||
|
||||
/** 判断点赞是否成功 */
|
||||
let msg = n > 0
|
||||
? [
|
||||
`\n${successMsg}`,
|
||||
segment.image((await memes[successFn](avatar)) ||
|
||||
_.sample(successImgs) + e.user_id)
|
||||
]
|
||||
: [
|
||||
`\n${failsMsg}`,
|
||||
segment.image((await memes.crawl(avatar)) ||
|
||||
_.sample(faildsImgs) + e.user_id)
|
||||
]
|
||||
|
||||
/** 回复 */
|
||||
e.reply(msg, true, { at: e.at })
|
||||
} else if (!e.msg.includes('他', '她', '它', 'TA', 'ta', 'Ta')) {
|
||||
/** 判断是否为好友 */
|
||||
let isFriend = await (e.bot ?? Bot).fl.get(e.user_id)
|
||||
let allowLikeByStrangers = Config.whole.Strangers_love
|
||||
if (!isFriend && !allowLikeByStrangers) return e.reply(`不加好友不${_do}🙄`, true)
|
||||
|
||||
/** 执行点赞 */
|
||||
let n = 0
|
||||
let failsMsg = `今天已经${_do}过了,还搁这讨${_do}呢!!!`
|
||||
for (let i = 0; i < 10; i++) {
|
||||
let res = null
|
||||
try {
|
||||
res = await new QQApi(e).thumbUp(e.user_id, 10)
|
||||
} catch (error) {
|
||||
logger.error(error)
|
||||
return common.handleException(e, error)
|
||||
}
|
||||
logger.debug(`${e.logFnc}给${e.user_id}点赞`, res)
|
||||
if (res.code) {
|
||||
if (res.code == 1) {
|
||||
failsMsg = `${_do}失败,请检查是否开启陌生人点赞或添加好友`
|
||||
} else {
|
||||
if (_do == '超') {
|
||||
failsMsg = res.msg.replace(/点赞/g, '超').replace('给', '超').replace('点', '').replace('个赞', '下')
|
||||
} else {
|
||||
failsMsg = res.msg
|
||||
}
|
||||
}
|
||||
break
|
||||
} else {
|
||||
n += 10
|
||||
}
|
||||
}
|
||||
let successMsg = `给你${_do}了${n}下哦,记得回我~ ${isFriend ? '' : `(如${_do}失败请添加好友)`}`
|
||||
const avatar = `https://q1.qlogo.cn/g?b=qq&s=100&nk=${e.user_id}`
|
||||
const successFn = _.sample(['ganyu', 'zan'])
|
||||
|
||||
/** 判断点赞是否成功 */
|
||||
let msg = n > 0
|
||||
? [
|
||||
`\n${successMsg}`,
|
||||
segment.image((await memes[successFn](avatar)) ||
|
||||
_.sample(successImgs) + e.user_id)
|
||||
]
|
||||
: [
|
||||
`\n${failsMsg}`,
|
||||
segment.image((await memes.crawl(avatar)) ||
|
||||
_.sample(faildsImgs) + e.user_id)
|
||||
]
|
||||
|
||||
/** 回复 */
|
||||
e.reply(msg, true, { at: true })
|
||||
}
|
||||
}
|
||||
12
model/api/funApi/utils.js
Normal file
12
model/api/funApi/utils.js
Normal file
@@ -0,0 +1,12 @@
|
||||
export const API_ERROR = '出了点小问题,待会再试试吧'
|
||||
|
||||
let cheerio = null
|
||||
|
||||
export async function _importDependency () {
|
||||
if (cheerio) return cheerio
|
||||
cheerio = await import('cheerio')
|
||||
.catch(() => {
|
||||
throw Error('未检测到依赖cheerio,请安装后再使用该功能,安装命令:pnpm add cheerio -w 或 pnpm install -P')
|
||||
})
|
||||
return cheerio
|
||||
}
|
||||
60
model/api/funApi/youdao.js
Normal file
60
model/api/funApi/youdao.js
Normal file
@@ -0,0 +1,60 @@
|
||||
import { youDaoLangType } from '../../../constants/fun.js'
|
||||
import md5 from 'md5'
|
||||
import { API_ERROR } from './utils.js'
|
||||
import _ from 'lodash'
|
||||
|
||||
/** 有道翻译 */
|
||||
export default async function youdao (msg, to = 'auto', from = 'auto') {
|
||||
if (to != 'auto') to = youDaoLangType.find(item => item.label == to)?.code
|
||||
if (from != 'auto') from = youDaoLangType.find(item => item.label == from)?.code
|
||||
if (!to || !from) return `未找到翻译的语种,支持的语言为:\n${youDaoLangType.map(item => item.label).join(',')}\n示例:#翻译你好 - 自动翻译\n#日语翻译你好 - 指定翻译为语种\n#中文-日语翻译你好 - 指定原语言翻译为指定语言`
|
||||
// 翻译结果为空的提示
|
||||
const RESULT_ERROR = '找不到翻译结果'
|
||||
// API 请求错误提示
|
||||
const qs = (obj) => {
|
||||
let res = ''
|
||||
for (const [k, v] of Object.entries(obj)) { res += `${k}=${encodeURIComponent(v)}&` }
|
||||
return res.slice(0, res.length - 1)
|
||||
}
|
||||
const appVersion = '5.0 (Windows NT 10.0; Win64; x64) Chrome/98.0.4750.0'
|
||||
const payload = {
|
||||
from,
|
||||
to,
|
||||
bv: md5(appVersion),
|
||||
client: 'fanyideskweb',
|
||||
doctype: 'json',
|
||||
version: '2.1',
|
||||
keyfrom: 'fanyi.web',
|
||||
action: 'FY_BY_DEFAULT',
|
||||
smartresult: 'dict'
|
||||
}
|
||||
const headers = {
|
||||
'Host': 'fanyi.youdao.com',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/98.0.4758.102',
|
||||
'Referer': 'https://fanyi.youdao.com/',
|
||||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||
'Cookie': 'OUTFOX_SEARCH_USER_ID_NCOO=133190305.98519628; OUTFOX_SEARCH_USER_ID="2081065877@10.169.0.102";'
|
||||
}
|
||||
const api = 'https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
|
||||
const key = 'Ygy_4c=r#e#4EX^NUGUc5'
|
||||
|
||||
const i = msg // 翻译的内容
|
||||
const lts = '' + new Date().getTime()
|
||||
const salt = lts + parseInt(String(10 * Math.random()), 10)
|
||||
const sign = md5(payload.client + i + salt + key)
|
||||
const postData = qs(Object.assign({ i, lts, sign, salt }, payload))
|
||||
try {
|
||||
let { errorCode, translateResult } = await fetch(api, {
|
||||
method: 'POST',
|
||||
body: postData,
|
||||
headers
|
||||
}).then(res => res.json()).catch(err => console.error(err))
|
||||
if (errorCode != 0) return API_ERROR
|
||||
translateResult = _.flattenDeep(translateResult)?.map(item => item.tgt).join('\n')
|
||||
if (!translateResult) return RESULT_ERROR
|
||||
return translateResult
|
||||
} catch (err) {
|
||||
logger.error(err)
|
||||
return API_ERROR
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user