Jona
Jona

Reputation: 11

TypeError: voiceChannel.join is not a function

I'm new to coding in general so expect nooby behaviour.

My Discord Bot goes online with the command node . and I try my !ping command and everything works just fine. But when I try the declared command !play to play a video from YT but when I press enter the bot crashes with the log:

const  connection = await voiceChannel.join();
                                               ^

TypeError: voiceChannel.join is not a function
    at Object.execute (D:\Discord Bot\commands\play.js:43:48)
    at Client.<anonymous> (D:\Discord Bot\main.js:33:41)
    at Client.emit (node:events:394:28)
    at MessageCreateAction.handle (D:\Discord Bot\node_modules\discord.js\src\client\actions\MessageCreate.js:31:18)
    at Object.module.exports [as MESSAGE_CREATE] (D:\Discord Bot\node_modules\discord.js\src\client\websocket\handlers\MESSAGE_CREATE.js:4:32)
    at WebSocketManager.handlePacket (D:\Discord Bot\node_modules\discord.js\src\client\websocket\WebSocketManager.js:345:31)
    at WebSocketShard.onPacket (D:\Discord Bot\node_modules\discord.js\src\client\websocket\WebSocketShard.js:443:22)
    at WebSocketShard.onMessage (D:\Discord Bot\node_modules\discord.js\src\client\websocket\WebSocketShard.js:300:10)
    at WebSocket.onMessage (D:\Discord Bot\node_modules\ws\lib\event-target.js:132:16)
    at WebSocket.emit (node:events:394:28)

This is the main code:


const client = new Discord.Client({ intents: ["GUILDS", "GUILD_MESSAGES"] });

const prefix = '!';

const fs = require('fs');
const { join } = require('path');

client.commands = new Discord.Collection();

const commandFiles = fs.readdirSync('./commands/').filter(file => file.endsWith('.js'));
for(const file of commandFiles){
    const command = require(`./commands/${file}`);

    client.commands.set(command.name, command);
}


client.once('ready', () => {
    console.log('Mein Mussig Bot ist nun online!');
});

client.on('message', message =>{
    if(!message.content.startsWith(prefix) || message.author.bot)  return;

    const args = message.content.slice(prefix.length).split(/ +/);
    const command = args.shift().toLowerCase();

    if(command === 'ping'){
        client.commands.get('ping').execute(message,args);
    }   else if (command === 'play'){
            client.commands.get('play').execute(message,args);
    }   else if (command === 'stop'){
            client.commands.get('stop').execute(message,args);
    }
});

client.login('token')

This is the play command code:

const ytdl = require('ytdl-core');
const ytSearch = require('yt-search');


module.exports = {
    name: 'play',
    description: 'Joins and plays a video from youtube',
    async execute(message, args) {
        const voiceChannel = message.member.voice.channel;
 
        if (!voiceChannel) return message.channel.send('You need to be in a channel to execute this command!');
        const permissions = voiceChannel.permissionsFor(message.client.user);
        if (!permissions.has('CONNECT')) return message.channel.send('You dont have the correct permissins');
        if (!permissions.has('SPEAK')) return message.channel.send('You dont have the correct permissins');
        if (!args.length) return message.channel.send('You need to send the second argument!');
 
        const validURL = (str) =>{
            var regex = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/;
            if(!regex.test(str)){
                return false;
            } else {
                return true;
            }
        }
 
        if(validURL(args[0])){
 
            const  connection = await voiceChannel.join()
            .catch(console.error);
            const stream  = ytdl(args[0], {filter: 'audioonly'});
 
            connection.play(stream, {seek: 0, volume: 1})
            .on('finish', () =>{
                voiceChannel.leave();
                message.channel.send('leaving channel');
            });
 
            await message.reply(`:thumbsup: Now Playing ***Your Link!***`)
 
            return
        }
        
        const  connection = await voiceChannel.join();
 
        const videoFinder = async (query) => {
            const videoResult = await ytSearch(query);
 
            return (videoResult.videos.length > 1) ? videoResult.videos[0] : null;
 
        }
 
        const video = await videoFinder(args.join(' '));
 
        if(video){
            const stream  = ytdl(video.url, {filter: 'audioonly'});
            connection.play(stream, {seek: 0, volume: 1})
            .on('finish', () =>{
                voiceChannel.leave();
            });
 
            await message.reply(`:thumbsup: Now Playing ***${video.title}***`)
        } else {
            message.channel.send('No video results found');
        }
    }
}

Pls help

Upvotes: 1

Views: 10504

Answers (2)

Because of the updates and changes from Discord v12 to Discord v13 (see here, you would have to install another package called @discord/voice. You can install it (including the required encryption package) via three different ways:

  • Npm: npm install @discordjs/voice libsodium-wrappers
  • Yarn: yarn add @discordjs/voice libsodium-wrappers
  • Pnpm: pnpm add @discordjs/voice libsodium-wrappers

Please refer to the guide for more information about upgrading from Discord v12 to Discord v13.

Upvotes: 0

UnidentifiedX
UnidentifiedX

Reputation: 199

I know I am like a month late but whoever sees this, after the new update of Discord JS v13, joining a voice channel is now like this:

import { joinVoiceChannel } from "@discordjs/voice";

const connection = joinVoiceChannel(
{
    channelId: message.member.voice.channel,
    guildId: message.guild.id,
    adapterCreator: message.guild.voiceAdapterCreator
});

More info on @discordjs/voice here. Run npm i @discordjs/voice to install.

Upvotes: 9

Related Questions