mirror of
https://github.com/ikechan8370/chatgpt-plugin.git
synced 2025-12-17 13:57:10 +00:00
fix: 修复一些功能易用性
This commit is contained in:
parent
be7ceafb4b
commit
599f37e627
8 changed files with 249 additions and 61 deletions
17
apps/chat.js
17
apps/chat.js
|
|
@ -51,6 +51,9 @@ import { KickOutTool } from '../utils/tools/KickOutTool.js'
|
||||||
import { SendAvatarTool } from '../utils/tools/SendAvatarTool.js'
|
import { SendAvatarTool } from '../utils/tools/SendAvatarTool.js'
|
||||||
import { SendDiceTool } from '../utils/tools/SendDiceTool.js'
|
import { SendDiceTool } from '../utils/tools/SendDiceTool.js'
|
||||||
import { EditCardTool } from '../utils/tools/EditCardTool.js'
|
import { EditCardTool } from '../utils/tools/EditCardTool.js'
|
||||||
|
import {SearchVideoTool} from "../utils/tools/SearchBilibiliTool.js";
|
||||||
|
import {SearchMusicTool} from "../utils/tools/SearchMusicTool.js";
|
||||||
|
import {QueryStarRailTool} from "../utils/tools/QueryStarRailTool.js";
|
||||||
try {
|
try {
|
||||||
await import('emoji-strip')
|
await import('emoji-strip')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
@ -1809,7 +1812,7 @@ export class chatgpt extends plugin {
|
||||||
let promptPrefix = `You are ${Config.assistantLabel} ${useCast?.api || Config.promptPrefixOverride || defaultPropmtPrefix}
|
let promptPrefix = `You are ${Config.assistantLabel} ${useCast?.api || Config.promptPrefixOverride || defaultPropmtPrefix}
|
||||||
Knowledge cutoff: 2021-09. Current date: ${currentDate}`
|
Knowledge cutoff: 2021-09. Current date: ${currentDate}`
|
||||||
let maxModelTokens = getMaxModelTokens(completionParams.model)
|
let maxModelTokens = getMaxModelTokens(completionParams.model)
|
||||||
let system = Config.promptPrefixOverride
|
let system = promptPrefix
|
||||||
if (maxModelTokens >= 16000 && Config.enableGroupContext) {
|
if (maxModelTokens >= 16000 && Config.enableGroupContext) {
|
||||||
try {
|
try {
|
||||||
let opt = {}
|
let opt = {}
|
||||||
|
|
@ -1917,22 +1920,22 @@ export class chatgpt extends plugin {
|
||||||
timeoutMs: 120000
|
timeoutMs: 120000
|
||||||
// systemMessage: promptPrefix
|
// systemMessage: promptPrefix
|
||||||
}
|
}
|
||||||
if (Math.floor(Math.random() * 100) < 5) {
|
option.systemMessage = system
|
||||||
// 小概率再次发送系统消息
|
|
||||||
option.systemMessage = promptPrefix
|
|
||||||
}
|
|
||||||
if (conversation) {
|
if (conversation) {
|
||||||
option = Object.assign(option, conversation)
|
option = Object.assign(option, conversation)
|
||||||
}
|
}
|
||||||
let tools = [
|
let tools = [
|
||||||
new JinyanTool(),
|
new JinyanTool(),
|
||||||
|
new SearchVideoTool(),
|
||||||
new SendVideoTool(),
|
new SendVideoTool(),
|
||||||
|
new SearchMusicTool(),
|
||||||
new SendMusicTool(),
|
new SendMusicTool(),
|
||||||
new KickOutTool(),
|
new KickOutTool(),
|
||||||
new SendAvatarTool(),
|
new SendAvatarTool(),
|
||||||
new SendDiceTool(),
|
// new SendDiceTool(),
|
||||||
new KickOutTool(),
|
new KickOutTool(),
|
||||||
new EditCardTool()
|
new EditCardTool(),
|
||||||
|
new QueryStarRailTool()
|
||||||
]
|
]
|
||||||
let funcMap = {}
|
let funcMap = {}
|
||||||
tools.forEach(tool => {
|
tools.forEach(tool => {
|
||||||
|
|
|
||||||
|
|
@ -23,17 +23,22 @@ export class JinyanTool extends AbstractTool {
|
||||||
|
|
||||||
func = async function (opts) {
|
func = async function (opts) {
|
||||||
let { qq, groupId, time = '600' } = opts
|
let { qq, groupId, time = '600' } = opts
|
||||||
|
let group = await Bot.pickGroup(groupId)
|
||||||
|
time = parseInt(time.trim())
|
||||||
if (time < 60) {
|
if (time < 60) {
|
||||||
time = 60
|
time = 60
|
||||||
}
|
}
|
||||||
if (time > 86400 * 30) {
|
if (time > 86400 * 30) {
|
||||||
time = 86400 * 30
|
time = 86400 * 30
|
||||||
}
|
}
|
||||||
let group = await Bot.pickGroup(groupId)
|
|
||||||
time = parseInt(time.trim())
|
|
||||||
if (qq.trim() === 'all') {
|
if (qq.trim() === 'all') {
|
||||||
await group.sendMsg('[日志]试图开启全员禁言')
|
if (time > 0) {
|
||||||
// await group.muteAll(time > 0)
|
await group.sendMsg('[日志]试图开启全员禁言,但被系统阻止了')
|
||||||
|
return 'error: you are not allowed to mute all in this group'
|
||||||
|
} else {
|
||||||
|
await group.muteAll(false)
|
||||||
|
return '该群的全体禁言已经被解除'
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
qq = parseInt(qq.trim())
|
qq = parseInt(qq.trim())
|
||||||
await group.muteMember(qq, time)
|
await group.muteMember(qq, time)
|
||||||
|
|
@ -41,5 +46,5 @@ export class JinyanTool extends AbstractTool {
|
||||||
return `the user ${qq} has been muted for ${time} seconds`
|
return `the user ${qq} has been muted for ${time} seconds`
|
||||||
}
|
}
|
||||||
|
|
||||||
description = 'Useful when you want to ban someone. The input to this tool should be the group number, the qq number of the one who should be banned and the mute duration in seconds(at least 60, at most 180, the number should be an integer multiple of 60), these three number should be concated with a space. If you want to mute all, just replace the qq number with \'all\''
|
description = 'Useful when you want to ban someone. If you want to mute all, just replace the qq number with \'all\''
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import {AbstractTool} from "./AbstractTool.js";
|
import { AbstractTool } from './AbstractTool.js'
|
||||||
|
|
||||||
export class KickOutTool extends AbstractTool {
|
export class KickOutTool extends AbstractTool {
|
||||||
name = 'kickOut'
|
name = 'kickOut'
|
||||||
|
|
|
||||||
76
utils/tools/QueryStarRailTool.js
Normal file
76
utils/tools/QueryStarRailTool.js
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
import { AbstractTool } from './AbstractTool.js'
|
||||||
|
|
||||||
|
export class QueryStarRailTool extends AbstractTool {
|
||||||
|
name = 'queryStarRail'
|
||||||
|
|
||||||
|
parameters = {
|
||||||
|
properties: {
|
||||||
|
qq: {
|
||||||
|
type: 'string',
|
||||||
|
description: '要查询的用户的qq号,将使用该qq号绑定的uid进行查询'
|
||||||
|
},
|
||||||
|
groupId: {
|
||||||
|
type: 'string',
|
||||||
|
description: '群号'
|
||||||
|
},
|
||||||
|
uid: {
|
||||||
|
type: 'string',
|
||||||
|
description: '游戏的uid,如果用户提供了则传入并优先使用'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
required: ['qq', 'groupId']
|
||||||
|
}
|
||||||
|
|
||||||
|
func = async function (opts) {
|
||||||
|
let { qq, groupId, uid } = opts
|
||||||
|
if (!uid) {
|
||||||
|
try {
|
||||||
|
let { Panel } = await import('../../../StarRail-plugin/apps/panel.js')
|
||||||
|
uid = await redis.get(`STAR_RAILWAY:UID:${qq}`)
|
||||||
|
if (!uid) {
|
||||||
|
return '用户没有绑定uid,无法查询。可以让用户主动提供uid进行查询'
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
return '未安装StarRail-Plugin,无法查询'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
let uidRes = await fetch('https://avocado.wiki/v1/info/' + uid)
|
||||||
|
uidRes = await uidRes.json()
|
||||||
|
let { assistAvatar, displayAvatars } = uidRes.playerDetailInfo
|
||||||
|
function dealAvatar (avatar) {
|
||||||
|
delete avatar.position
|
||||||
|
delete avatar.vo_tag
|
||||||
|
delete avatar.desc
|
||||||
|
delete avatar.promption
|
||||||
|
delete avatar.relics
|
||||||
|
delete avatar.behaviorList
|
||||||
|
delete avatar.images
|
||||||
|
delete avatar.ranks
|
||||||
|
if (avatar.equipment) {
|
||||||
|
avatar.equipment = {
|
||||||
|
level: avatar.equipment.level,
|
||||||
|
rank: avatar.equipment.rank,
|
||||||
|
name: avatar.equipment.name,
|
||||||
|
skill_desc: avatar.equipment.skill_desc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dealAvatar(assistAvatar)
|
||||||
|
if (displayAvatars) {
|
||||||
|
displayAvatars.forEach(avatar => {
|
||||||
|
dealAvatar(avatar)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
uidRes.playerDetailInfo.assistAvatar = assistAvatar
|
||||||
|
uidRes.playerDetailInfo.displayAvatars = displayAvatars
|
||||||
|
delete uidRes.repository
|
||||||
|
delete uidRes.version
|
||||||
|
return `the player info in json format is: \n${JSON.stringify(uidRes)}`
|
||||||
|
} catch (err) {
|
||||||
|
return `failed to query, error: ${err.toString()}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
description = 'Useful when you want to query player information of Honkai Star Rail(崩坏:星穹铁道). '
|
||||||
|
}
|
||||||
76
utils/tools/SearchBilibiliTool.js
Normal file
76
utils/tools/SearchBilibiliTool.js
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
import fetch from 'node-fetch'
|
||||||
|
|
||||||
|
import { formatDate, mkdirs } from '../common.js'
|
||||||
|
import fs from 'fs'
|
||||||
|
import { AbstractTool } from './AbstractTool.js'
|
||||||
|
export class SearchVideoTool extends AbstractTool {
|
||||||
|
name = 'searchVideo'
|
||||||
|
|
||||||
|
parameters = {
|
||||||
|
properties: {
|
||||||
|
keyword: {
|
||||||
|
type: 'string',
|
||||||
|
description: '要搜索的视频的标题或关键词'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
required: ['keyword']
|
||||||
|
}
|
||||||
|
|
||||||
|
func = async function (opts) {
|
||||||
|
let { keyword } = opts
|
||||||
|
try {
|
||||||
|
return await searchBilibili(keyword)
|
||||||
|
} catch (err) {
|
||||||
|
logger.error(err)
|
||||||
|
return `fail to search video, error: ${err.toString()}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
description = 'Useful when you want to search a video by keywords. you should remember the id of the video if you want to share it'
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function searchBilibili (name) {
|
||||||
|
let biliRes = await fetch('https://www.bilibili.com',
|
||||||
|
{
|
||||||
|
// headers: {
|
||||||
|
// accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
|
||||||
|
// Accept: '*/*',
|
||||||
|
// 'Accept-Encoding': 'gzip, deflate, br',
|
||||||
|
// 'accept-language': 'en-US,en;q=0.9',
|
||||||
|
// Connection: 'keep-alive',
|
||||||
|
// 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36'
|
||||||
|
// }
|
||||||
|
})
|
||||||
|
const headers = biliRes.headers.raw()
|
||||||
|
const setCookieHeaders = headers['set-cookie']
|
||||||
|
if (setCookieHeaders) {
|
||||||
|
const cookies = []
|
||||||
|
setCookieHeaders.forEach(header => {
|
||||||
|
const cookie = header.split(';')[0]
|
||||||
|
cookies.push(cookie)
|
||||||
|
})
|
||||||
|
const cookieHeader = cookies.join('; ')
|
||||||
|
let headers = {
|
||||||
|
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
|
||||||
|
'accept-language': 'en-US,en;q=0.9',
|
||||||
|
Referer: 'https://www.bilibili.com',
|
||||||
|
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36',
|
||||||
|
cookie: cookieHeader
|
||||||
|
}
|
||||||
|
let response = await fetch(`https://api.bilibili.com/x/web-interface/search/type?keyword=${name}&search_type=video`,
|
||||||
|
{
|
||||||
|
headers
|
||||||
|
})
|
||||||
|
let json = await response.json()
|
||||||
|
if (json.data?.numResults > 0) {
|
||||||
|
let result = json.data.result.map(r => {
|
||||||
|
return `id: ${r.bvid},标题:${r.title},作者:${r.author},播放量:${r.play},发布日期:${formatDate(new Date(r.pubdate * 1000))}`
|
||||||
|
}).slice(0, Math.min(json.data?.numResults, 5)).join('\n')
|
||||||
|
return `这些是关键词“${name}”的搜索结果:\n${result}`
|
||||||
|
} else {
|
||||||
|
return `没有找到关键词“${name}”的搜索结果`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {}
|
||||||
|
}
|
||||||
39
utils/tools/SearchMusicTool.js
Normal file
39
utils/tools/SearchMusicTool.js
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
import fetch from 'node-fetch'
|
||||||
|
import { AbstractTool } from './AbstractTool.js'
|
||||||
|
|
||||||
|
export class SearchMusicTool extends AbstractTool {
|
||||||
|
name = 'searchMusic'
|
||||||
|
|
||||||
|
parameters = {
|
||||||
|
properties: {
|
||||||
|
keyword: {
|
||||||
|
type: 'string',
|
||||||
|
description: '音乐的标题或关键词'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
required: ['keyword']
|
||||||
|
}
|
||||||
|
|
||||||
|
func = async function (opts) {
|
||||||
|
let { keyword } = opts
|
||||||
|
try {
|
||||||
|
let result = await searchMusic163(keyword)
|
||||||
|
return `search result: ${result}`
|
||||||
|
} catch (e) {
|
||||||
|
return `music search failed: ${e}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
description = 'Useful when you want to search music by keyword.'
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function searchMusic163 (name) {
|
||||||
|
let response = await fetch(`http://music.163.com/api/search/get/web?s=${name}&type=1&offset=0&total=true&limit=6`)
|
||||||
|
let json = await response.json()
|
||||||
|
if (json.result?.songCount > 0) {
|
||||||
|
return json.result.songs.map(song => {
|
||||||
|
return `id: ${song.id}, name: ${song.name}, artists: ${song.artists.map(a => a.name).join('&')}, alias: ${song.alias || 'none'}`
|
||||||
|
}).join('\n')
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
@ -8,31 +8,33 @@ export class SendVideoTool extends AbstractTool {
|
||||||
|
|
||||||
parameters = {
|
parameters = {
|
||||||
properties: {
|
properties: {
|
||||||
keyword: {
|
id: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: '要发的视频的标题或关键词,用于搜索'
|
description: '要发的视频的id'
|
||||||
},
|
},
|
||||||
groupId: {
|
groupId: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: '群号或qq号,发送目标'
|
description: '群号或qq号,发送目标'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
required: ['keyword', 'groupId']
|
required: ['id', 'groupId']
|
||||||
}
|
}
|
||||||
|
|
||||||
func = async function (opts) {
|
func = async function (opts) {
|
||||||
let { keyword, groupId } = opts
|
let { id, groupId } = opts
|
||||||
groupId = parseInt(groupId.trim())
|
groupId = parseInt(groupId.trim())
|
||||||
let msg = []
|
let msg = []
|
||||||
try {
|
try {
|
||||||
let { arcurl, title, pic, description, videoUrl, headers, bvid, author, play, pubdate, like } = await searchBilibili(keyword)
|
let { arcurl, title, pic, description, videoUrl, headers, bvid, author, play, pubdate, like, honor } = await getBilibili(id)
|
||||||
let group = await Bot.pickGroup(groupId)
|
let group = await Bot.pickGroup(groupId)
|
||||||
console.log({ arcurl, title, pic, description, videoUrl })
|
|
||||||
msg.push(title.replace(/(<([^>]+)>)/ig, '') + '\n')
|
msg.push(title.replace(/(<([^>]+)>)/ig, '') + '\n')
|
||||||
msg.push(`UP主:${author} 发布日期:${formatDate(new Date(pubdate * 1000))} 播放量:${play} 点赞:${like}\n`)
|
msg.push(`UP主:${author} 发布日期:${formatDate(new Date(pubdate * 1000))} 播放量:${play} 点赞:${like}\n`)
|
||||||
msg.push(arcurl + '\n')
|
msg.push(arcurl + '\n')
|
||||||
msg.push(segment.image('https:' + pic))
|
msg.push(segment.image('https:' + pic))
|
||||||
msg.push('\n' + description)
|
msg.push('\n' + description)
|
||||||
|
if (honor) {
|
||||||
|
msg.push(`本视频曾获得过${honor}称号`)
|
||||||
|
}
|
||||||
msg.push('\n视频在路上啦!')
|
msg.push('\n视频在路上啦!')
|
||||||
await group.sendMsg(msg)
|
await group.sendMsg(msg)
|
||||||
const videoResponse = await fetch(videoUrl, { headers })
|
const videoResponse = await fetch(videoUrl, { headers })
|
||||||
|
|
@ -45,7 +47,7 @@ export class SendVideoTool extends AbstractTool {
|
||||||
await fs.writeFileSync(fileLoc, buffer)
|
await fs.writeFileSync(fileLoc, buffer)
|
||||||
await group.sendMsg(segment.video(fileLoc))
|
await group.sendMsg(segment.video(fileLoc))
|
||||||
})
|
})
|
||||||
return `the video ${title.replace(/(<([^>]+)>)/ig, '')} will be shared to ${groupId} after a while, please wait`
|
return `the video ${title.replace(/(<([^>]+)>)/ig, '')} was shared to ${groupId}. the video information: ${msg}`
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(err)
|
logger.error(err)
|
||||||
if (msg.length > 0) {
|
if (msg.length > 0) {
|
||||||
|
|
@ -56,10 +58,10 @@ export class SendVideoTool extends AbstractTool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
description = 'Useful when you want to share a video. The input should be the group number and the keywords that can find the video, connected with a space. If you want to send a specific video, you can give more detailed keywords'
|
description = 'Useful when you want to share a video. You must use searchVideo to get search result and choose one video and get its id'
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function searchBilibili (name) {
|
export async function getBilibili (bvid) {
|
||||||
let biliRes = await fetch('https://www.bilibili.com',
|
let biliRes = await fetch('https://www.bilibili.com',
|
||||||
{
|
{
|
||||||
// headers: {
|
// headers: {
|
||||||
|
|
@ -87,28 +89,28 @@ export async function searchBilibili (name) {
|
||||||
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36',
|
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36',
|
||||||
cookie: cookieHeader
|
cookie: cookieHeader
|
||||||
}
|
}
|
||||||
let response = await fetch(`https://api.bilibili.com/x/web-interface/search/type?keyword=${name}&search_type=video`,
|
let videoInfo = await fetch(`https://api.bilibili.com/x/web-interface/view?bvid=${bvid}`, {
|
||||||
{
|
headers
|
||||||
headers
|
})
|
||||||
})
|
videoInfo = await videoInfo.json()
|
||||||
let json = await response.json()
|
let cid = videoInfo.data.cid
|
||||||
if (json.data?.numResults > 0) {
|
let arcurl = `http://www.bilibili.com/video/av${videoInfo.data.aid}`
|
||||||
let index = randomIndex()
|
let title = videoInfo.data.title
|
||||||
let { arcurl, title, pic, description, bvid, author, play, pubdate, like } = json.data.result[Math.min(index, json.data.numResults)]
|
let pic = videoInfo.data.pic
|
||||||
let videoInfo = await fetch(`https://api.bilibili.com/x/web-interface/view?bvid=${bvid}`, {
|
let description = videoInfo.data.desc
|
||||||
headers
|
let author = videoInfo.data.owner.name
|
||||||
})
|
let play = videoInfo.data.stat.view
|
||||||
videoInfo = await videoInfo.json()
|
let pubdate = videoInfo.data.pubdate
|
||||||
let cid = videoInfo.data.cid
|
let like = videoInfo.data.stat.like
|
||||||
let downloadInfo = await fetch(`https://api.bilibili.com/x/player/playurl?bvid=${bvid}&cid=${cid}`, { headers })
|
let honor = videoInfo.data.honor_reply?.honor?.map(h => h.desc)?.join('、')
|
||||||
let videoUrl = (await downloadInfo.json()).data.durl[0].url
|
let downloadInfo = await fetch(`https://api.bilibili.com/x/player/playurl?bvid=${bvid}&cid=${cid}`, {headers})
|
||||||
return {
|
let videoUrl = (await downloadInfo.json()).data.durl[0].url
|
||||||
arcurl, title, pic, description, videoUrl, headers, bvid, author, play, pubdate, like
|
return {
|
||||||
}
|
arcurl, title, pic, description, videoUrl, headers, bvid, author, play, pubdate, like, honor
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return {}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function randomIndex () {
|
function randomIndex () {
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
import fetch from 'node-fetch'
|
import { AbstractTool } from './AbstractTool.js'
|
||||||
import {AbstractTool} from "./AbstractTool.js";
|
|
||||||
|
|
||||||
export class SendMusicTool extends AbstractTool {
|
export class SendMusicTool extends AbstractTool {
|
||||||
name = 'sendMusic'
|
name = 'sendMusic'
|
||||||
|
|
||||||
parameters = {
|
parameters = {
|
||||||
properties: {
|
properties: {
|
||||||
keyword: {
|
id: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: '音乐的标题或关键词'
|
description: '音乐的id'
|
||||||
},
|
},
|
||||||
groupId: {
|
groupId: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
|
@ -19,28 +18,16 @@ export class SendMusicTool extends AbstractTool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func = async function (opts) {
|
func = async function (opts) {
|
||||||
let { keyword, groupId } = opts
|
let { id, groupId } = opts
|
||||||
groupId = parseInt(groupId.trim())
|
groupId = parseInt(groupId.trim())
|
||||||
try {
|
try {
|
||||||
let { id, name } = await searchMusic163(keyword)
|
|
||||||
let group = await Bot.pickGroup(groupId)
|
let group = await Bot.pickGroup(groupId)
|
||||||
await group.shareMusic('163', id)
|
await group.shareMusic('163', id)
|
||||||
return `the music ${name} has been shared to ${groupId}`
|
return `the music has been shared to ${groupId}`
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return `music share failed: ${e}`
|
return `music share failed: ${e}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
description = 'Useful when you want to share music. The input should be the group number and the name of the music to be sent or the keywords that can find the music, connected with a space'
|
description = 'Useful when you want to share music. You must use searchMusic first to get the music id'
|
||||||
}
|
|
||||||
|
|
||||||
export async function searchMusic163 (name) {
|
|
||||||
let response = await fetch(`http://music.163.com/api/search/get/web?s=${name}&type=1&offset=0&total=true&limit=20`)
|
|
||||||
let json = await response.json()
|
|
||||||
if (json.result?.songCount > 0) {
|
|
||||||
let id = json.result.songs[0].id
|
|
||||||
let name = json.result.songs[0].name
|
|
||||||
return { id, name }
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue