#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’,