Как решить ошибку типа: класс расширяет неопределенное значение, не является конструктором или нулем (Discord Bot)

#javascript #node.js #discord #bots

#javascript #node.js #Discord #боты

Вопрос:

позвольте мне сказать это, прежде чем объяснять вопрос..Я новичок в области кодирования, так что мне многое известно об этом материале (именно поэтому я спрашиваю об этом).Итак, я разрабатываю Discord Bot (музыкальный бот) и я почти закончил с кодом.(пока только 1 cmd).Я столкнулся с этой ошибкой, указанной в заголовке (TypeError: класс расширяет неопределенное значение, не является конструктором или нулем), когда я использовал ‘ node . ‘ в моем терминале. Я приведу полную информацию, которая появилась в терминале ниже. Я использую Visual Studio Code.

Это то, что появилось в терминале, когда я использовал ‘ node . ‘-

 C:UsersELCOTDesktopDiscord botnodejsindex.js:76
module.exports = class PlayCommand extends Command { 
                                           ^

TypeError: Class extends value undefined is not a constructor or null
    at Object.<anonymous> (C:UsersELCOTDesktopDiscord botnodejsindex.js:76:44)
    at Module._compile (internal/modules/cjs/loader.js:1251:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1272:10)
    at Module.load (internal/modules/cjs/loader.js:1100:32)
    at Function.Module._load (internal/modules/cjs/loader.js:962:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47```
  

Итак, я действительно надеюсь, что кто-нибудь сможет мне помочь с этим, потому что я застрял в своем продвижении из-за этой ошибки.

Это та часть кода, в которой появилась эта ошибка

   constructor(client) {
    super(client, {
      name: 'play',
      aliases: ['play-song', 'add'],
      memberName: 'play',
      group: 'music',
      description: 'Play any song or playlist from youtube',
      guildOnly: true,
      clientPermissions: ['SPEAK', 'CONNECT'],
      throttling: {
        usages: 2,
        duration: 5
      },
  

С нетерпением ждем какой-нибудь помощи! Ty 🙂

Код-

 const Client = new Discord.Client();
const { Structures } = require('discord.js');
const path = require('path');
const { prefix, token, discord_owner_id } = require('./config.json');

Structures.extend('Guild', function(Guild) {
  class MusicGuild extends Guild {
    constructor(client, data) {
      super(client, data);
      this.musicData = {
        queue: [],
        isPlaying: false,
        nowPlaying: null,
        songDispatcher: null,
        volume: 1
      };
      this.triviaData = {
        isTriviaRunning: false,
        wasTriviaEndCalled: false,
        triviaQueue: [],
        triviaScore: new Map()
      };
    }
  }
  return MusicGuild;
});

const client = new Discord.Client({
  commandPrefix: prefix,
  owner: discord_owner_id // value comes from config.json
});

client.once('ready', () => {
  console.log('Ready!');
  client.user.setActivity(`${prefix}play`, {
    type: 'WATCHING',
  
  });
});

client.on('voiceStateUpdate', async (___, newState) => {
  if (
    newState.member.user.bot amp;amp;
    !newState.channelID amp;amp;
    newState.guild.musicData.songDispatcher amp;amp;
    newState.member.user.id == client.user.id
  ) {
    newState.guild.musicData.queue.length = 0;
    newState.guild.musicData.songDispatcher.end();
    return;
  }
  if (
    newState.member.user.bot amp;amp;
    newState.channelID amp;amp;
    newState.member.user.id == client.user.id amp;amp;
    !newState.selfDeaf
  ) {
    newState.setSelfDeaf(true);
  }
});

client.on('guildMemberAdd', member => {
  const channel = member.guild.channels.cache.find(ch => ch.name === 'general'); // change this to the channel name you want to send the greeting to
  if (!channel) return;
  channel.send(`Welcome ${member}!`);
});

const { Command } = require('discord.js');
const { MessageEmbed } = require('discord.js');
const Youtube = require('simple-youtube-api');
const ytdl = require('ytdl-core');
const { youtubeAPI } = require('./config.json');
const youtube = new Youtube(youtubeAPI);

module.exports = class PlayCommand extends Command {
  constructor(client) {
    super(client, {
      name: 'play',
      aliases: ['play-song', 'add'],
      memberName: 'play',
      group: 'music',
      description: 'Play any song or playlist from youtube',
      guildOnly: true,
      clientPermissions: ['SPEAK', 'CONNECT'],
      throttling: {
        usages: 2,
        duration: 5
      },
      args: [
        {
          key: 'query',
          prompt: 'What song or playlist would you like to listen to?',
          type: 'string',
          validate: function(query) {
            return query.length > 0 amp;amp; query.length < 200;
          }
        }
      ]
    });
  }

  async run(message, { query }) {
    const voiceChannel = message.member.voice.channel;
    if (!voiceChannel) {
      message.say('Join a channel and try again');
      return;
    }

    if (message.guild.triviaData.isTriviaRunning == true) {
      message.say('Please try after the trivia has ended');
      return;
    }

    if (
      // if the user entered a youtube playlist url
      query.match(
        /^(?!.*?.*bv=)https://www.youtube.com/.*?.*blist=.*$/
      )
    ) {
      const playlist = await youtube.getPlaylist(query).catch(function() {
        message.say('Playlist is either private or it does not exist!');
        return;
      });
      // add 10 as an argument in getVideos() if you choose to limit the queue
      const videosArr = await playlist.getVideos().catch(function() {
        message.say(
          'There was a problem getting one of the videos in the playlist!'
        );
        return;
      });

      // this for loop can be uncommented if you want to shuffle the playlist

      /*for (let i = videosArr.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i   1));
        [videosArr[i], videosArr[j]] = [videosArr[j], videosArr[i]];
      }
      */

      for (let i = 0; i < videosArr.length; i  ) {
        if (videosArr[i].raw.status.privacyStatus == 'private') {
          continue;
        } else {
          try {
            const video = await videosArr[i].fetch();
            // this can be uncommented if you choose to limit the queue
            // if (message.guild.musicData.queue.length < 10) {
            //
            message.guild.musicData.queue.push(
              PlayCommand.constructSongObj(
                video,
                voiceChannel,
                message.member.user
              )
            );
            // } else {
            //   return message.say(
            //     `I can't play the full playlist because there will be more than 10 songs in queue`
            //   );
            // }
          } catch (err) {
            return console.error(err);
          }
        }
      }
      if (message.guild.musicData.isPlaying == false) {
        message.guild.musicData.isPlaying = true;
        return PlayCommand.playSong(message.guild.musicData.queue, message);
      } else if (message.guild.musicData.isPlaying == true) {
        message.say(
          `Playlist - :musical_note:  ${playlist.title} :musical_note: has been added to queue`
        );
        return;
      }
    }

    // This if statement checks if the user entered a youtube url, it can be any kind of youtube url
    if (query.match(/^(http(s)?://)?((w){3}.)?youtu(be|.be)?(.com)?/. /)) {
      query = query
        .replace(/(>|<)/gi, '')
        .split(/(vi/|v=|/v/|youtu.be/|/embed/)/);
      const id = query[2].split(/[^0-9a-z_-]/i)[0];
      const video = await youtube.getVideoByID(id).catch(function() {
        message.say('There was a problem getting the video you provided!');
        return;
      });
      // // can be uncommented if you don't want the bot to play live streams
      // if (video.raw.snippet.liveBroadcastContent === 'live') {
      //   return message.say("I don't support live streams!");
      // }
      // // can be uncommented if you don't want the bot to play videos longer than 1 hour
      // if (video.duration.hours !== 0) {
      //   return message.say('I cannot play videos longer than 1 hour');
      // }
      // // can be uncommented if you want to limit the queue
      // if (message.guild.musicData.queue.length > 10) {
      //   return message.say(
      //     'There are too many songs in the queue already, skip or wait a bit'
      //   );
      // }
      message.guild.musicData.queue.push(
        PlayCommand.constructSongObj(video, voiceChannel, message.member.user)
      );
      if (
        message.guild.musicData.isPlaying == false ||
        typeof message.guild.musicData.isPlaying == 'undefined'
      ) {
        message.guild.musicData.isPlaying = true;
        return PlayCommand.playSong(message.guild.musicData.queue, message);
      } else if (message.guild.musicData.isPlaying == true) {
        message.say(`${video.title} added to queue`);
        return;
      }
    }

    // if user provided a song/video name
    const videos = await youtube.searchVideos(query, 5).catch(async function() {
      await message.say(
        'There was a problem searching the video you requested :('
      );
      return;
    });
    if (videos.length < 5 || !videos) {
      message.say(
        `I had some trouble finding what you were looking for, please try again or be more specific`
      );
      return;
    }
    const vidNameArr = [];
    for (let i = 0; i < videos.length; i  ) {
      vidNameArr.push(`${i   1}: ${videos[i].title}`);
    }
    vidNameArr.push('exit');
    const embed = new MessageEmbed()
      .setColor('#e9f931')
      .setTitle('Choose a song by commenting a number between 1 and 5')
      .addField('Song 1', vidNameArr[0])
      .addField('Song 2', vidNameArr[1])
      .addField('Song 3', vidNameArr[2])
      .addField('Song 4', vidNameArr[3])
      .addField('Song 5', vidNameArr[4])
      .addField('Exit', 'exit');
    var songEmbed = await message.channel.send({ embed });
    message.channel
      .awaitMessages(
        function(msg) {
          return (msg.content > 0 amp;amp; msg.content < 6) || msg.content === 'exit';
        },
        {
          max: 1,
          time: 60000,
          errors: ['time']
        }
      )
      .then(function(response) {
        const videoIndex = parseInt(response.first().content);
        if (response.first().content === 'exit') {
          songEmbed.delete();
          return;
        }
        youtube
          .getVideoByID(videos[videoIndex - 1].id)
          .then(function(video) {
            // // can be uncommented if you don't want the bot to play live streams
            // if (video.raw.snippet.liveBroadcastContent === 'live') {
            //   songEmbed.delete();
            //   return message.say("I don't support live streams!");
            // }

            // // can be uncommented if you don't want the bot to play videos longer than 1 hour
            // if (video.duration.hours !== 0) {
            //   songEmbed.delete();
            //   return message.say('I cannot play videos longer than 1 hour');
            // }

            // // can be uncommented if you don't want to limit the queue
            // if (message.guild.musicData.queue.length > 10) {
            //   songEmbed.delete();
            //   return message.say(
            //     'There are too many songs in the queue already, skip or wait a bit'
            //   );
            // }
            message.guild.musicData.queue.push(
              PlayCommand.constructSongObj(
                video,
                voiceChannel,
                message.member.user
              )
            );
            if (message.guild.musicData.isPlaying == false) {
              message.guild.musicData.isPlaying = true;
              if (songEmbed) {
                songEmbed.delete();
              }
              PlayCommand.playSong(message.guild.musicData.queue, message);
            } else if (message.guild.musicData.isPlaying == true) {
              if (songEmbed) {
                songEmbed.delete();
              }
              message.say(`${video.title} added to queue`);
              return;
            }
          })
          .catch(function() {
            if (songEmbed) {
              songEmbed.delete();
            }
            message.say(
              'An error has occured when trying to get the video ID from youtube'
            );
            return;
          });
      })
      .catch(function() {
        if (songEmbed) {
          songEmbed.delete();
        }
        message.say(
          'Please try again and enter a number between 1 and 5 or exit'
        );
        return;
      });
  }
  static playSong(queue, message) {
    const classThis = this; // use classThis instead of 'this' because of lexical scope below
    queue[0].voiceChannel
      .join()
      .then(function(connection) {
        const dispatcher = connection
          .play(
            ytdl(queue[0].url, {
              quality: 'highestaudio',
              highWaterMark: 1 << 25
            })
          )
          .on('start', function() {
            message.guild.musicData.songDispatcher = dispatcher;
            dispatcher.setVolume(message.guild.musicData.volume);
            const videoEmbed = new MessageEmbed()
              .setThumbnail(queue[0].thumbnail)
              .setColor('#e9f931')
              .addField('Now Playing:', queue[0].title)
              .addField('Duration:', queue[0].duration)
              .setFooter(
                `Requested by ${queue[0].memberDisplayName}`,
                queue[0].memberAvatar
              );
            if (queue[1]) videoEmbed.addField('Next Song:', queue[1].title);
            message.say(videoEmbed);
            message.guild.musicData.nowPlaying = queue[0];
            queue.shift();
            return;
          })
          .on('finish', function() {
            if (queue.length >= 1) {
              classThis.playSong(queue, message);
              return;
            } else {
              message.guild.musicData.isPlaying = false;
              message.guild.musicData.nowPlaying = null;
              message.guild.musicData.songDispatcher = null;
              if (message.guild.me.voice.channel) {
                message.guild.me.voice.channel.leave();
                return;
              }
            }
          })
          .on('error', function(e) {
            message.say('Cannot play song');
            console.error(e);
            message.guild.musicData.queue.length = 0;
            message.guild.musicData.isPlaying = false;
            message.guild.musicData.nowPlaying = null;
            message.guild.musicData.songDispatcher = null;
            message.guild.me.voice.channel.leave();
            return;
          });
      })
      .catch(function(e) {
        message.guild.musicData.queue.length = 0;
        message.guild.musicData.isPlaying = false;
        message.guild.musicData.nowPlaying = null;
        message.guild.musicData.songDispatcher = null;
        if (message.guild.me.voice.channel) {
          message.guild.me.voice.channel.leave();
        }
        return console.error(e);
      });
  }
  static constructSongObj(video, voiceChannel, user) {
    let duration = this.formatDuration(video.duration);
    if (duration == '00:00') duration = 'Live Stream';
    return {
      url: `https://www.youtube.com/watch?v=${video.raw.id}`,
      title: video.title,
      rawDuration: video.duration,
      duration,
      thumbnail: video.thumbnails.high.url,
      voiceChannel,
      memberDisplayName: user.username,
      memberAvatar: user.avatarURL('webp', false, 16)
    };
  }
  // prettier-ignore
  static formatDuration(durationObj) {
    const duration = `${durationObj.hours ? (durationObj.hours   ':') : ''}${
      durationObj.minutes ? durationObj.minutes : '00'
    }:${
      (durationObj.seconds < 10)
        ? ('0'   durationObj.seconds)
        : (durationObj.seconds
        ? durationObj.seconds
        : '00')
    }`;
    return duration;
  }
};

client.login(token);```

I did not know how to make this like a spoiler, so forgive me if it was done in the wrong way/ too long.
  

Комментарии:

1. Вы убедились в импорте Command ? Это класс?

2. Я думаю, что это вопрос отсутствия инструкции import . Вы также могли бы предоставить определенную часть вашего кода, так называемый «Минимально воспроизводимый пример», чтобы люди могли ознакомиться с ним.

3. Как я уже сказал, сэр, я студент и мне многое об этом известно.. Я создал все это, потратив несколько дней на просмотр видео на YouTube и поиск в Google определенного материала. (tbh idk, что вы имеете в виду под этим, но это класс.) Пожалуйста, помогите мне с учетом того, что я действительно новичок в этих вещах. ty

4. @DaneBrouwer Должен ли я публиковать подобные вопросы здесь, на этом сайте? Я совершенно новичок в кодировании, а также на этом сайте, но я не знаю, где можно попросить помощи.

5. @AsadS Привет! Этого достаточно? module.exports = class PlayCommand расширяет команду { constructor(client) { super(client, { name: ‘play’, псевдонимы: [‘play-song’, ‘add’], MemberName: ‘play’, group: ‘music’, description: ‘Воспроизвести любую песню или плейлист с YouTube’, guildOnly: true, clientPermissions: [‘SPEAK’, ‘CONNECT’], регулирование: { usages : 2, длительность: 5 }, аргументы: [ { клавиша: ‘query’, подсказка: ‘Какую песню или плейлист вы хотели бы прослушать?’, тип: ‘string’,