函数 returns 未定义 discord.js
function returns undefined discord.js
我正在编写我自己的 discord 机器人,我有一个应该 return YouTube 链接的功能,但每次我都未定义。这是机器人的代码,它是用 discord.js/node.js
写的
例如,我在不和谐的谈话中写了“!play allan becker faded”,我只在嵌入消息中得到一个未定义的,我也尝试 console.log returned字符串,但它的 laso undefinedEmbed message
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)
正如您在评论中提到的,您的 searchOnYT()
函数在获得结果后应该只 return 一个值。否则,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()
return 是 Promise
,这确保了一旦 search()
完成执行,该函数只会 return 一个值。使用回调也可以实现这一点,但 promise 是在 returning 一个值之前等待的一种更简洁的方法(并且 promises 与 async/await
一起工作得很好,幸运的是你的消息处理程序已经使用 async
).
我正在编写我自己的 discord 机器人,我有一个应该 return YouTube 链接的功能,但每次我都未定义。这是机器人的代码,它是用 discord.js/node.js
写的例如,我在不和谐的谈话中写了“!play allan becker faded”,我只在嵌入消息中得到一个未定义的,我也尝试 console.log returned字符串,但它的 laso undefinedEmbed message
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)
正如您在评论中提到的,您的 searchOnYT()
函数在获得结果后应该只 return 一个值。否则,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()
return 是 Promise
,这确保了一旦 search()
完成执行,该函数只会 return 一个值。使用回调也可以实现这一点,但 promise 是在 returning 一个值之前等待的一种更简洁的方法(并且 promises 与 async/await
一起工作得很好,幸运的是你的消息处理程序已经使用 async
).