我正在编写自己的 discord bot,我有一个函数应该返回一个 youtubelink,但是每次我都没有定义。这是机器人的代码,它写在 discord.js/node.js
例如,我在我的不和谐谈话中,我写了“!播放艾伦贝克尔褪色”我只在嵌入消息中得到一个未定义,我也尝试控制台.记录返回的字符串,但它的套索未定义{{3 }}
const Discord = require('discord.js')
const fs = require('fs')
const ytdl = require('ytdl-core')
const ffmpeg = require('ffmpeg')
const { debug, Console } = require('console')
const config = JSON.parse(fs.readFileSync('config.json', 'utf8'))
const ytapi3 = config.GoogleApiYT3
const search = require('youtube-search')
var client = new Discord.Client()
//setting status
client.on('ready', () => {
console.log("Logged in as", client.user.username, "...")
client.user.setPresence({
status: config.status,
activity: {
name: config.activity,
type: 'STREAMING',
url: config.streamingURL
}
})
})
//musicbot
client.on('message', async message => {
if(message.author.bot) return // test if bot has written this message
if(!message.channel.id == config.botcommandsChannelID) return //test if message is in botcommands channel
if(!message.content.startsWith(config.prefix)) return // test if prefix is used
const args = message.content.substring(config.prefix.length).split(" ") // split arguments into args[]-list and cut the prefix out
const voiceChannel = message.member.voice.channel
//test if user has permissions to use command
if(config.UseDJRole == "true") {
if(message.member.roles.cache.has(config.DJroleID) || message.member.roles.cache.has(config.ModeratorRoleID) || message.member.user.id == config.owner){
}else{
return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoPermissionsToUseThisCommand)
}
}
if(!voiceChannel) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_404) //testing if user is in voiceChannel
if(message.content.startsWith(config.prefix + config.PlayCommand)){ //Play-case
const permission = voiceChannel.permissionsFor(message.client.user)
if(!permission.has('CONNECT')) sendEmbed(message.channel, config.ErrorColor, "Error", config.NoPermissionsToJoinVC)
if(!permission.has('SPEAK')) sendEmbed(message.channel, config.ErrorColor, "Error", config.NoPermissionsToSpeakInVC)
var vidURL = new String("nothing");
//get link "vidURL"
if(args.length >= 2){
if(ytdl.validateURL(args[1])){
vidURL = args[1]
} else{
args.shift()
const vidSearchLink = args.join(' ')
try{
vidURL = searchOnYT(vidSearchLink, message.channel, args)
}catch(error){
return console.log(error)
}
}
}else {
return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoArgs)
}
if(client.connection == null){
voiceChannel.join()
//play
sendEmbed(message.channel, config.MusicEmbedColorHEX, "Playing", vidURL)
} else{
if(voiceChannel.id != client.connection.voice.channel.id){
sendEmbed(message.channel, config.ErrorColor, "Error", config.AllreadyUsed + client.connection.voice.channel.name)
} else{
//play
sendEmbed(message.channel, config.MusicEmbedColorHEX, "Playing", vidURL)
}
}
}else if(message.content.startsWith(config.prefix + config.StopCommand) || message.content.startsWith(config.prefix + config.LeaveCommand)){
if(voiceChannel == client.voice.channel) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400) //test if you are in one voice channel with the bot
voiceChannel.leave()
if(message.member.voice.connection) message.guild.voice.disconnect()
}else if(message.content.startsWith(config.prefix + config.PauseCommand)){
if(voiceChannel == client.voice.channel) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400) //test if you are in one voice channel with the bot
//pause music
}else if(message.content.startsWith(config.prefix + config.ResumeCommand)){
if(voiceChannel == client.voice.channel) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400) //test if you are in one voice channel with the bot
//resume music
}else if(message.content.startsWith(config.prefix + config.SkipCommand)){
if(voiceChannel == client.voice.channel) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400) //test if you are in one voice channel with the bot
//skip
}else if(message.content.startsWith(config.prefix + config.QueueCommand)){
if(voiceChannel == client.voice.channel) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400)//test if you are in one voice channel with the bot
//show queue
}
})
function sendEmbed(_channel, _Color, _Title, _Description, _URL){
const embedMessage = new Discord.MessageEmbed()
.setColor(_Color)
.setTitle(_Title)
.setDescription(_Description)
.setURL(_URL);
_channel.send(embedMessage)
}
function searchOnYT(searchstring, _channel){
var opts = {
maxResults: 1,
key: config.GoogleApiYT3,
type: 'video'
}
search(searchstring, opts, function(err, results) {
if(err) return console.log(err);
if(results){
const r = results[0]
return new String(r.link)
}else{
return sendEmbed(_channel, config.ErrorColor, "Error", NoResultsFound, searchstring)
}
})
}
client.login(config.token)
答案 0 :(得分:1)
正如您在评论中提到的,您的 searchOnYT()
函数应该只在获得结果后返回一个值。否则,vidURL
将始终未定义。您可以将 Promise
与 async/await
结合使用来实现此目的。这是一个示例,仅在代码中需要更改以执行此操作的部分。
在您的消息处理程序中:
try{
vidURL = await searchOnYT(vidSearchLink, message.channel, args);
} catch(error){
return console.log(error)
}
在您的 searchOnYT()
函数中:
function searchOnYT(searchstring, _channel){
var opts = {
maxResults: 1,
key: config.GoogleApiYT3,
type: 'video'
}
return new Promise((resolve, reject) => {
search(searchstring, opts, function(err, results) {
if(err) reject(err);
if(results) {
const r = results[0]
resolve(new String(r.link))
}
else {
sendEmbed(_channel, config.ErrorColor, "Error", NoResultsFound, searchstring);
reject("No results found");
}
})
});
}
既然 searchOnYT()
返回一个 Promise
,这就确保了该函数只会在 search()
执行完毕后才返回一个值。使用回调也可以实现这一点,但 Promise 是一种在返回值之前等待的更简洁的方式(并且 Promise 与 async/await
一起工作得非常好,幸运的是您的消息处理程序已经使用了 async
) .