round-api.js
Version:
Uma blibioteca para iniciantes no discord, que precisam de um bot de música mas não sabe como fazer...
365 lines (331 loc) • 15.1 kB
JavaScript
const { Util, MessageEmbed } = require("discord.js");
const fetch = require("node-fetch");
const ytdl = require("ytdl-core");
const ytdlDiscord = require("ytdl-core-discord");
const yts = require("yt-search");
const fs = require('fs');
const sendError = require("./utils")
const round = function (key, client) {
if (!key) return console.error("[ROUND] Error: key não foi providenciada!");
if (!isNaN(key)) return console.error("[ROUND] Error: key inválida!");
if (key.length != 19) return console.error("[ROUND] Error: key inválida!")
if (typeof key != "string") return console.error("[ROUND] Error: key inválida!");
if (!client) return console.error("[ROUND] Error: client não foi providenciado!");
if (typeof client != "object") return console.error("[ROUND] Error: client não suportado ou inválido!");
if (!client.queue || client.queue == undefined) client.queue = new Map();
const data = {
client: {
id: client.user.id,
key: key
}
};
fetch('https://dashboard.roundbot.tk/api/verify', {
method: 'POST',
body: JSON.stringify(data),
headers: { 'Content-Type': 'application/json' }
}).then(response => response.json()).then(res => {
if (res.message == 'recused'){
this.isConnected = false;
return console.error("[ROUND] Error: key inválida!");
} else {
this.isConnected = true;
console.log("[ROUND] Sucess: api conectada!");
};
});
return {
play: async (message, args, callback) => {
let channel = message.member.voice.channel;
if (!channel) return sendError("[ROUND] Error: você precisa estar em um canal de voz", message.channel);
const permissions = channel.permissionsFor(message.client.user);
if (!permissions.has("CONNECT")) return sendError("[ROUND] Error: eu não tenho permissões para conectar!", message.channel);
if (!permissions.has("SPEAK")) return sendError("[ROUND] Error: eu não tenho permissões para falar!", message.channel);
var searchString = args.join(" ");
if (!searchString) return sendError("[ROUND] Error: você não disse qual musica tocar!", message.channel);
const url = args[0] ? args[0].replace(/<(.+)>/g, "$1") : "";
var serverQueue = message.client.queue.get(message.guild.id);
let songInfo = null;
let song = null;
if (url.match(/^(https?:\/\/)?(www\.)?(m\.)?(youtube\.com|youtu\.?be)\/.+$/gi)) {
try {
songInfo = await ytdl.getInfo(url);
if(!songInfo) return sendError("[ROUND] Error: eu não encontrei essa musica no youtube!", message.channel);
song = {
id: songInfo.videoDetails.videoId,
title: songInfo.videoDetails.title,
url: songInfo.videoDetails.video_url,
img: songInfo.player_response.videoDetails.thumbnail.thumbnails[0].url,
duration: songInfo.videoDetails.lengthSeconds,
ago: songInfo.videoDetails.publishDate,
views: String(songInfo.videoDetails.viewCount).padStart(10, ' '),
req: message.author
};
} catch (error) {
console.error(error);
return message.reply(error.message).catch(console.error);
}
} else {
try {
var searched = await yts.search(searchString);
if(searched.videos.length === 0) return sendError("[ROUND] Error: eu não encontrei essa musica no youtube!", message.channel)
songInfo = searched.videos[0]
song = {
id: songInfo.videoId,
title: Util.escapeMarkdown(songInfo.title),
views: String(songInfo.views).padStart(10, ' '),
url: songInfo.url,
ago: songInfo.ago,
duration: songInfo.duration.toString(),
img: songInfo.image,
req: message.author
};
} catch (error) {
console.error(error);
return message.reply(error.message).catch(console.error);
}
}
if (serverQueue) {
serverQueue.songs.push(song);
return callback(song);
}
const queueConstruct = {
textChannel: message.channel,
voiceChannel: channel,
connection: null,
songs: [],
volume: 80,
playing: true,
loop: false
};
message.client.queue.set(message.guild.id, queueConstruct);
queueConstruct.songs.push(song);
const play = async (song) => {
const queue = message.client.queue.get(message.guild.id);
let stream = null;
if (song.url.includes("youtube.com")) {
stream = await ytdl(song.url);
stream.on('error', function(er) {
if (er) {
if (queue) {
queue.songs.shift();
play(queue.songs[0]);
return sendError(`[ROUND] Error: \`${er}\``, message.channel)
}
}
});
}
queue.connection.on("disconnect", () => message.client.queue.delete(message.guild.id));
const dispatcher = queue.connection
.play(ytdl(song.url, {quality: 'highestaudio', highWaterMark: 1 << 25 ,type: "opus"}))
.on("finish", () => {
const shiffed = queue.songs.shift();
if (queue.loop === true) {
queue.songs.push(shiffed);
};
play(queue.songs[0])
});
dispatcher.setVolumeLogarithmic(queue.volume / 100);
}
try {
const connection = await channel.join();
queueConstruct.connection = connection;
play(queueConstruct.songs[0]);
} catch (error) {
console.error(`[ROUND] Error: eu não pude entrar no canal de voz ${error}`);
message.client.queue.delete(message.guild.id);
await channel.leave();
return sendError(`[ROUND] Error: eu não pude entrar no canal de voz ${error}`, message.channel);
}
callback(song)
},
stop: async (message, callback) => {
const channel = message.member.voice.channel;
if (!channel) return sendError("[ROUND] Error: eu não pude parar á musica!", message.channel);
const serverQueue = message.client.queue.get(message.guild.id);
if (!serverQueue) return sendError("[ROUND] Error: não tem nenhuma musica na fila!", message.channel);
if(!serverQueue.connection) return;
if(!serverQueue.connection.dispatcher) return;
try {
serverQueue.connection.dispatcher.end();
} catch (error) {
message.guild.me.voice.channel.leave();
message.client.queue.delete(message.guild.id);
return sendError(`[ROUND] Error: ${error}`, message.channel);
}
message.client.queue.delete(message.guild.id);
serverQueue.songs = [];
callback(message.channel);
},
skip: async (message, callback) => {
const channel = message.member.voice.channel
if (!channel) return sendError("[ROUND] Error: ocorreu um erro!", message.channel);
const serverQueue = message.client.queue.get(message.guild.id);
if (!serverQueue) return sendError("[ROUND] Error: não á nada tocando no momento!", message.channel);
if(!serverQueue.connection) return;
if(!serverQueue.connection.dispatcher) return;
if (serverQueue && !serverQueue.playing) {
serverQueue.playing = true;
serverQueue.connection.dispatcher.resume();
return callback(message.channel);
};
try{
serverQueue.connection.dispatcher.end()
} catch (error) {
serverQueue.voiceChannel.leave()
message.client.queue.delete(message.guild.id);
return sendError(`[ROUND] Error: ${error}`, message.channel);
};
callback(message.channel);
},
pause: async (message, callback) => {
const serverQueue = message.client.queue.get(message.guild.id);
if (serverQueue && serverQueue.playing) {
serverQueue.playing = false;
try{
serverQueue.connection.dispatcher.pause()
} catch (error) {
message.client.queue.delete(message.guild.id);
return sendError(`[ROUND] Error: ${error}`, message.channel);
}
return callback(message.channel);
}
return sendError("[ROUND] Error: não á nada tocando no momento!", message.channel);
},
resume: async (message, callback) => {
const serverQueue = message.client.queue.get(message.guild.id);
if (serverQueue && !serverQueue.playing) {
serverQueue.playing = true;
serverQueue.connection.dispatcher.resume();
return callback(message.channel);
}
return sendError("[ROUND] Error: não á nada tocando no momento!", message.channel);
},
volume: async (message, args, callback) => {
const channel = message.member.voice.channel;
if (!channel)return sendError("[ROUND] Error: ocorreu um erro!", message.channel);
const serverQueue = message.client.queue.get(message.guild.id);
if (!serverQueue) return sendError("[ROUND] Error: não á nada tocando no momento!", message.channel);
if (!args[0])return message.channel.send(`Volume atual: **${serverQueue.volume}**`);
if(isNaN(args[0])) return message.channel.send(':notes: Apenas numeros!').catch(err => console.log(err));
if(parseInt(args[0]) > 150 ||(args[0]) < 0) return sendError('Escolha um numero entre 0 e 150!',message.channel).catch(err => console.log(err));
serverQueue.volume = args[0];
serverQueue.connection.dispatcher.setVolumeLogarithmic(args[0] / 100);
return callback({ value: args[0]/1 });
},
nowplaying: async (message, callback) => {
const serverQueue = message.client.queue.get(message.guild.id);
if (!serverQueue) return sendError("[ROUND] Error: não á nada tocando no momento!", message.channel);
let song = serverQueue.songs[0]
return callback(song);
},
loop: async (message, callback) => {
const serverQueue = message.client.queue.get(message.guild.id);
if (serverQueue) {
serverQueue.loop = !serverQueue.loop;
return callback({ state: serverQueue.loop === true ? "ativado" : "desativado" });
};
return sendError("[ROUND] Error: não á nada tocando no momento!", message.channel);
},
jump: async (message, args, callback) => {
if (!args.length || isNaN(args[0])) return sendError("[ROUND] Error: posição não providenciada!", message.channel)
const queue = message.client.queue.get(message.guild.id);
if (!queue) return sendError("[ROUND] Error: posição inválida!",message.channel).catch(console.error);
if (args[0] > queue.songs.length) return sendError(`[ROUND] Error: a fila possue apenas ${queue.songs.length} musicas!`,message.channel).catch(console.error);
queue.playing = true;
if (queue.loop) {
for (let i = 0; i < args[0] - 2; i++) {
queue.songs.push(queue.songs.shift());
}
} else {
queue.songs = queue.songs.slice(args[0] - 2);
};
try{
queue.connection.dispatcher.end();
} catch (error) {
queue.voiceChannel.leave()
message.client.queue.delete(message.guild.id);
return sendError(`:notes: The player has stopped and the queue has been cleared.: ${error}`, message.channel);
}
callback({ position: args[0] });
},
queue: async (message, args, callback) => {
const permissions = message.channel.permissionsFor(message.client.user);
if (!permissions.has(["MANAGE_MESSAGES", "ADD_REACTIONS"])) return sendError("[ROUND] Error: o bot não possue as permissões: ``ADD_REACTIONS, MANAGE_MESSAGES``",message.channel);
const queue = message.client.queue.get(message.guild.id);
if (!queue) return sendError("[ROUND] Error: não á nada tocando no momento!",message.channel)
let currentPage = 0;
const embeds = generateQueueEmbed(message, queue.songs);
const queueEmbed = await message.channel.send(
`**\`${currentPage + 1}\`**/**${embeds.length}**`,
embeds[currentPage]
);
try {
await queueEmbed.react("⬅️");
await queueEmbed.react("🛑");
await queueEmbed.react("➡️");
} catch (error) {
console.error(error);
message.channel.send(error.message).catch(console.error);
}
const filter = (reaction, user) => ["⬅️", "🛑", "➡️"].includes(reaction.emoji.name) && message.author.id === user.id;
const collector = queueEmbed.createReactionCollector(filter, { time: 60000 });
collector.on("collect", async (reaction, user) => {
try {
if (reaction.emoji.name === "➡️") {
if (currentPage < embeds.length - 1) {
currentPage++;
queueEmbed.edit(`**\`${currentPage + 1}\`**/**${embeds.length}**`, embeds[currentPage]);
}
} else if (reaction.emoji.name === "⬅️") {
if (currentPage !== 0) {
--currentPage;
queueEmbed.edit(`**\`${currentPage + 1}\`**/**${embeds.length}**`, embeds[currentPage]);
}
} else {
collector.stop();
reaction.message.reactions.removeAll();
}
await reaction.users.remove(message.author.id);
} catch (error) {
console.error(error);
return message.channel.send(error.message).catch(console.error);
}
});
function generateQueueEmbed(message, queue) {
let embeds = [];
let k = 10;
for (let i = 0; i < queue.length; i += 10) {
const current = queue.slice(i, k);
let j = i;
k += 10;
const info = current.map((track) => `**\`${++j}\`** | [\`${track.title}\`](${track.url})`).join("\n");
const serverQueue =message.client.queue.get(message.guild.id);
embeds.push(client.embed);
callback({
description: info,
playing: `[${queue[0].title}](${queue[0].url})`,
volume: serverQueue.volume,
channel: {
text: serverQueue.textChannel,
voice: serverQueue.voiceChannel
}
});
}
return embeds;
};
},
lyrics: async (message, callback) => {
const queue = message.client.queue.get(message.guild.id);
if (!queue) return sendError("[ROUND] Error: nenhuma musica tocando no momento!",message.channel).catch(console.error);
let lyrics = null;
try {
lyrics = await lyricsFinder(queue.songs[0].title, "");
if (!lyrics) lyrics = `Nenhuma letra encontrada para a musica: ${queue.songs[0].title}.`;
} catch (error) {
lyrics = `Nenhuma letra encontrada para a musica: ${queue.songs[0].title}.`;
}
if (lyrics.length >= 2000) return lyrics = `Nenhuma letra encontrada para a musica :(`;
return callback({ lyrics: lyrics, image: queue.songs[0].img, title: queue.songs[0].title });
}
};
};
module.exports = round;