Typeerror: voiceChannel. Join Is Not a Function

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

5

2 Answers

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.

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.

2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

James H. Sterling
Author

James H. Sterling

James Sterling reports on renewable energy developments, climate policy, ecological conservation, and green tech innovations around the globe.