我正在使用heroku通过discord.js库在Discord上启动音乐机器人 所有软件包都已安装,并且该应用程序运行正常 但是当我想在我的机器人上播放歌曲时 它发送正在播放的消息 但是,它什么也没玩,甚至没有加入语音室
我认为这是“ Opus Engine”问题,因为当我想部署应用程序时 即使我将其安装在package.json上,它也不会安装opus引擎
我需要帮助 谢谢。
答案 0 :(得分:0)
const botSettings = require("./config.json");
const Discord = require("discord.js");
const RichEmbed = require("discord.js");
const { Client, Util } = require('discord.js');
const client = new Discord.Client();
const axios = require("axios");
const yt = require("ytdl-core");
const YouTube = require("simple-youtube-api");
const fs = require("fs");
const getYTID = require("get-youtube-id");
const fetchVideoInfo = require("youtube-info");
const child_process = require("child_process");//
const prefix = botSettings.prefix;
const ytApiKey = botSettings.ytApiKey;
const youtube = new YouTube(ytApiKey);
const express = require('express');
const app = express();
const http = require('http');
app.get("/", (request, response) => { //
response.sendStatus(200);
});
app.listen(process.env.PORT);
setInterval(() => {
http.get(`http://z-music2.glitch.me/`);
}, 280000);
const bot = new Discord.Client({
disableEveryone: true
});
client.on('ready', () => {
console.log(`Logged in as * [ " ${client.user.username} " ] servers! [ " ${client.guilds.size} " ]`);
console.log(`Logged in as * [ " ${client.user.username} " ] Users! [ " ${client.users.size} " ]`);
console.log(`Logged in as * [ " ${client.user.username} " ] channels! [ " ${client.channels.size} " ]`);
});
client.on('ready', async () => {
console.log('I am ready!');
});
/* MUSIC VARIABLES */
let queue = []; // Songs queue
let songsQueue = []; // Song names stored for queue command
let isPlaying = false; // Is music playing
let dispatcher = null;
let voiceChannel = null;
let skipRequest = 0; // Stores the number of skip requests
let skippers = []; // Usernames of people who voted to skip the song
let ytResultList = []; // Video names results from yt command
let ytResultAdd = []; // For storing !add command choice
/* MUSIC VARIABLES END */
let re = /^(?:[1-5]|0[1-5]|10)$/; // RegEx for allowing only 1-5 while selecting song from yt results
let regVol = /^(?:([1][0-9][0-9])|200|([1-9][0-9])|([0-9]))$/; // RegEx for volume control
let youtubeSearched = false; // If youtube has been searched (for !add command)
let selectUser; // Selecting user from guild
bot.on("ready", async () => {
console.log(`Bot is ready! ${bot.user.username}`);
/*try {
let link = await bot.generateInvite(["ADMINISTRATOR"]);
console.log(link);
} catch (e) {
console.log(e.stack);
}*/
});
bot.on("message", async message => {
if (message.author.bot) return;
if (message.channel.type === "dm") return;
let messageContent = message.content.split(" ");
let command = messageContent[0];
let args = messageContent.slice(1);
if (!command.startsWith(prefix)) return;
switch (command.slice(1).toLowerCase()) {
case "userinfo":
if (args.length == 0) { // Displays the message author info if args are empty
let embed = new Discord.RichEmbed()
.setThumbnail(message.author.avatarURL)
.setColor("#8A2BE2")
.setDescription(`User info for: **${message.author.username}**`)
.addField("Avatar:", `[Link](${message.author.avatarURL})`, true)
.addField("Status:", message.author.presence.status, true)
.addField("Bot: ", message.author.bot, true)
.addField("In game: ", message.author.presence.game ? message.author.presence.game : "Not in game", true)
.addField("Tag: ", message.author.tag, true)
.addField("Discriminator:", message.author.discriminator, true)
.addBlankField()
.setFooter(`Profile created at: ${message.author.createdAt}`);
message.channel.send(embed);
} else { // Else displays info of user from args
if (message.guild.available) {
let selectUser = message.guild.member(message.mentions.users.first() || message.guild.members.get(args[0]));
let embed = new Discord.RichEmbed()
.setThumbnail(selectUser.user.displayAvatarURL)
.setColor("#8A2BE2")
.setDescription(`User info for: **${selectUser.user.username}**`)
.addField("Avatar:", `[Link](${selectUser.user.displayAvatarURL})`, true)
.addField("Status:", selectUser.user.presence.status, true)
.addField("Bot: ", selectUser.user.bot, true)
.addField("In game: ", selectUser.user.presence.game ? selectUser.user.presence.game : "Not in game", true)
.addField("Tag: ", selectUser.user.tag, true)
.addField("Discriminator:", selectUser.user.discriminator, true)
.addBlankField()
.setFooter(`Profile created at: ${selectUser.user.createdAt}`);
message.channel.send(embed);
}
}
break;
case "play":
if (args.length == 0 && queue.length > 0) {
if (!message.member.voiceChannel) {
message.reply("**You Need To Be in a Voice Channel To Play Music. Please, Join One And Try Again.**");
} else {
isPlaying = true;
playMusic(queue[0], message);
message.reply(`Now Playing **${songsQueue[0]}**:musical_note: `);
}
} else if (args.length == 0 && queue.length == 0) {
message.reply(`**Queue is Empty Now, type ${prefix}play [song name] or ${prefix}yt [song name] to play/search new songs!**`);
} else if (queue.length > 0 || isPlaying) {
getID(args).then(id => {
if (id) {
queue.push(id);
getYouTubeResultsId(args, 1).then(ytResults => {
message.reply(`added To Queue **${ytResults[0]}**:notes:`);
songsQueue.push(ytResults[0]);
}).catch(error => console.log(error));
} else {
message.reply("Sorry, Couldn't find The Song.");
}
}).catch(error => console.log(error));
} else {
isPlaying = true;
getID(args).then(id => {
if (id) {
queue.push(id);
playMusic(id, message);
getYouTubeResultsId(args, 1).then(ytResults => {
message.reply(`Now Playing **${ytResults[0]}**:musical_note:`);
songsQueue.push(ytResults[0]);
}).catch(error => console.log(error));
} else {
message.reply("Sorry, Couldn't Find The Song.");
}
}).catch(error => console.log(error));
}
break;
case "skip":
console.log(queue);
if (queue.length === 1) {
message.reply(`**queue is empty now, type ${prefix}play [song name] or ${prefix}yt [song name] to play/search new songs!**`);
dispatcher.end();
setTimeout(() => voiceChannel.leave(), 1000);
} else {
if (skippers.indexOf(message.author.id) === -1) {
skippers.push(message.author.id);
skipRequest++;
if (skipRequest >= Math.ceil((voiceChannel.members.size - 1) / 2)) {
skipSong(message);
message.reply("**Your Skip has Been Added To The List. Skipping!**");
} else {
message.reply(`Your Skip has Been Added to the list. You need **${Math.ceil((voiceChannel.members.size - 1) / 2) - skipRequest}** more to skip current song!`);
}
} else {
message.reply("**You Already Voted To Skip!**");
}
}
break;
case "queue":
if (queue.length === 0) { // if there are no songs in the queue, send message that queue is empty
message.reply(`**Queue is empty, type ${prefix}play or ${prefix}yt to play/search new songs!**`);
} else if (args.length > 0 && args[0] == 'remove') { // if arguments are provided and first one is remove
if (args.length == 2 && args[1] <= queue.length) { // check if there are no more than 2 arguments and that second one is in range of songs number in queue
// then remove selected song from the queue
message.reply(`**${songsQueue[args[1] - 1]}** has been removed from the queue. Type !queue to see the current queue.`);
queue.splice(args[1] - 1, 1);
songsQueue.splice(args[1] - 1, 1);
} else { // if there are more than 2 arguments and the second one is not in the range of songs number in queue, send message
message.reply(`**You Need To Enter Valid Queued Song number **(1-${queue.length}).`);
}
} else if (args.length > 0 && args[0] == 'clear') { // same as remove, only clears queue if clear is first argument
if (args.length == 1) {
// reseting queue and songsQueue, but leaving current song
message.reply(`all upcoming songs have been removed from the queue. type ${prefix}play or ${prefix}yt to play/search new songs!`);
queue.splice(1);
songsQueue.splice(1);
} else {
message.reply("**You need to type !queue clear without following arguments.**");
}
} else if (args.length > 0 && args[0] == 'shuffle') {
let tempA = [songsQueue[0]];
let tempB = songsQueue.slice(1);
songsQueue = tempA.concat(shuffle(tempB));
message.channel.send("Queue has been shuffled. Type !queue to see the new queue!");
} else { // if there are songs in the queue and queue commands is without arguments display current queue
let format = "```"
for (const songName in songsQueue) {
if (songsQueue.hasOwnProperty(songName)) {
let temp = `${parseInt(songName) + 1}: ${songsQueue[songName]} ${songName == 0 ? "**(Current Song)**" : ""}\n`;
if ((format + temp).length <= 2000 - 3) {
format += temp;
} else {
format += "```";
message.channel.send(format);
format = "```";
}
}
}
format += "```";
message.channel.send(format);
}
break;
case "repeat":
if (isPlaying) {
queue.splice(1, 0, queue[0]);
songsQueue.splice(1, 0, songsQueue[0]);
message.reply(`**${songsQueue[0]}** Will be played again.`);
}
break;
case "stop":
dispatcher.end();
setTimeout(() => voiceChannel.leave(), 1000);
break;
case "vol":
if (args.length == 0 && dispatcher) {
message.reply(`current volume is ${dispatcher.volume}. Type !vol [percentage - 0 to 200] to set music volume.`);
} else if (args.length > 0 && regVol.test(args) == true && dispatcher) {
dispatcher.setVolume(args * 0.01);
message.reply(`music volume has been set to ${args}%.`);
console.log(dispatcher.volume);
} else if (!regVol.test(args) && dispatcher) {
message.reply("you need to enter a number in 0-200 range.");
} else {
message.reply("you can only set music volume if music is playing.");
}
break;
}
});
/*--------------------------------*/
/* MUSIC CONTROL FUNCTIONS START */
/*------------------------------*/
function playMusic(id, message) {
voiceChannel = message.member.voiceChannel;
voiceChannel.join()
.then(connection => {
console.log("Connected...");
stream = yt(`https://www.youtube.com/watch?v=${id}`, {
filter: 'audioonly'
})
skipRequest = 0;
skippers = [];
dispatcher = connection.playStream(stream);
dispatcher.setVolume(0.25);
dispatcher.on('end', () => {
skipRequest = 0;
skippers = [];
queue.shift();
songsQueue.shift();
if (queue.length === 0) {
console.log("Disconnected...");
voiceChannel.leave()
queue = [];
songsQueue = [];
isPlaying = false;
} else {
setTimeout(() => playMusic(queue[0], message), 500);
}
});
})
.catch(error => console.log(error));
}
async function getID(str) {
if (str.indexOf("youtube.com") > -1) {
return getYTID(str);
} else {
let body = await axios(`https://www.googleapis.com/youtube/v3/search?part=id&type=video&q=${encodeURIComponent(str)}&key=${ytApiKey}`);
if (body.data.items[0] === undefined) {
return null;
} else {
return body.data.items[0].id.videoId;
}
}
}
function addToQueue(strID) {
if (strID.indexOf("youtube.com")) {
queue.push(getYTID(strID));
} else {
queue.push(strID);
songsQueue.push(strID);
}
}
function skipSong(message) {
dispatcher.end();
}
/*------------------------------*/
/* MUSIC CONTROL FUNCTIONS END */
/*----------------------------*/
/*----------------------------------*/
/* YOUTUBE CONTROL FUNCTIONS START */
/*--------------------------------*/
async function searchYouTube(str) {
let search = await axios(`https://www.googleapis.com/youtube/v3/search?part=id&type=video&q=${encodeURIComponent(str)}&key=${ytApiKey}`);
if (search.data.items[0] === undefined) {
return null;
} else {
return search.data.items;
}
}
async function getYouTubeResultsId(ytResult, numOfResults) {
let resultsID = [];
await youtube.searchVideos(ytResult, numOfResults)
.then(results => {
for (const resultId of results) {
resultsID.push(resultId.title);
}
})
.catch(err => console.log(err));
return resultsID;
}
/*--------------------------------*/
/* YOUTUBE CONTROL FUNCTIONS END */
/*------------------------------*/
/*-----------------------*/
/* MISC FUNCTIONS START */
/*---------------------*/
function shuffle(queue) {
for (let i = queue.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[queue[i], queue[j]] = [queue[j], queue[i]];
}
return queue;
}
/*---------------------*/
/* MISC FUNCTIONS END */
/*-------------------*/
const devs = ["523836549390139392"]
const adminprefix = "..";
client.on('message', message => {
var argresult = message.content.split(` `).slice(1).join(' ');
if (!devs.includes(message.author.id)) return;
if (message.content.startsWith(adminprefix + 'ply')) {
client.user.setGame(argresult);
message.channel.sendMessage(`**:white_check_mark: ${argresult}**`)
} else
if (message.content === (adminprefix + "Percie")) {
message.guild.leave();
} else
if (message.content.startsWith(adminprefix + 'wt')) {
client.user.setActivity(argresult, {type:'WATCHING'});
message.channel.sendMessage(`**:white_check_mark: ${argresult}**`)
} else
if (message.content.startsWith(adminprefix + 'ls')) {
client.user.setActivity(argresult , {type:'LISTENING'});
message.channel.sendMessage(`**:white_check_mark: ${argresult}**`)
} else
if (message.content.startsWith(adminprefix + 'setname')) {
client.user.setUsername(argresult).then
message.channel.sendMessage(`**${argresult}** : Done :>`)
return message.reply("**You Can't Change Your Name ,Only After Two Hours :>**");
} else
if (message.content.startsWith(adminprefix + 'setavatar')) {
client.user.setAvatar(argresult);
message.channel.sendMessage(`**${argresult}** : تم تغير صورة البوت`);
} else
if (message.content.startsWith(adminprefix + 'st')) {
client.user.setGame(argresult, "https://www.twitch.tv/idk");
message.channel.sendMessage(`**:white_check_mark: ${argresult}**`)
}
if(message.content === adminprefix + "restart") {
if (!devs.includes(message.author.id)) return;
message.channel.send(`:warning:️ **Bot restarting by ${message.author.username}**`);
console.log("\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
console.log(`⚠️ Bot restarting... ⚠️`);
console.log("===============================================\n\n");
client.destroy();
child_process.fork(__dirname + "/bot.js");
console.log(`Bot Successfully Restarted`);
}
});
bot.login(process.env.BOT_TOKEN); // nevermind this line