函数返回未定义的 discord.js

时间:2020-12-23 12:07:55

标签: node.js return discord.js undefined

我正在编写自己的 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)

1 个答案:

答案 0 :(得分:1)

正如您在评论中提到的,您的 searchOnYT() 函数应该只在获得结果后返回一个值。否则,vidURL 将始终未定义。您可以将 Promiseasync/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) .