├── Procfile ├── .gitignore ├── src ├── commands │ ├── hello.js │ ├── pause.js │ ├── resume.js │ ├── stop.js │ ├── help.js │ ├── skip.js │ ├── volume.js │ ├── embed.js │ ├── test.js │ ├── play.js │ └── role.js └── index.js ├── README.md └── package.json /Procfile: -------------------------------------------------------------------------------- 1 | worker: npm start -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .vscode 3 | .env 4 | *.log -------------------------------------------------------------------------------- /src/commands/hello.js: -------------------------------------------------------------------------------- 1 | const execute = (bot, msg, args) => { 2 | return msg.reply("Hello"); 3 | }; 4 | 5 | module.exports = { 6 | name: "hello", 7 | help: "Hello, world!", 8 | execute, 9 | }; 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bot criando usando Discord.js 2 | 3 | Este bot foi desenvolvido em uma série de vídeo-aulas no Youtube, que podem ser encontradas [aqui](https://www.youtube.com/playlist?list=PLekCEh3NxQrJeaV4Wka-tX0vs3Jrm5XQK) -------------------------------------------------------------------------------- /src/commands/pause.js: -------------------------------------------------------------------------------- 1 | const execute = (bot, msg, args) => { 2 | const queue = bot.queues.get(msg.guild.id); 3 | if (!queue) { 4 | return msg.reply("não existe nenhuma música sendo reproduzida"); 5 | } 6 | queue.dispatcher.pause(); 7 | }; 8 | 9 | module.exports = { 10 | name: "pause", 11 | help: "Pausa a reprodução de música atual", 12 | execute, 13 | }; 14 | -------------------------------------------------------------------------------- /src/commands/resume.js: -------------------------------------------------------------------------------- 1 | const execute = (bot, msg, args) => { 2 | const queue = bot.queues.get(msg.guild.id); 3 | if (!queue) { 4 | return msg.reply("não existe nenhuma música sendo reproduzida"); 5 | } 6 | queue.dispatcher.resume(); 7 | }; 8 | 9 | module.exports = { 10 | name: "resume", 11 | help: "Continua a reprodução de música atual", 12 | execute, 13 | }; 14 | -------------------------------------------------------------------------------- /src/commands/stop.js: -------------------------------------------------------------------------------- 1 | const execute = (bot, msg, args) => { 2 | const queue = bot.queues.get(msg.guild.id); 3 | if (!queue) { 4 | return msg.reply("não existe nenhuma música sendo reproduzida"); 5 | } 6 | queue.songs = []; 7 | bot.queues.set(msg.guild.id, queue); 8 | queue.dispatcher.end(); 9 | }; 10 | 11 | module.exports = { 12 | name: "stop", 13 | help: "Para a reprodução de músicas no servidor", 14 | execute, 15 | }; 16 | -------------------------------------------------------------------------------- /src/commands/help.js: -------------------------------------------------------------------------------- 1 | const execute = (bot, msg, args) => { 2 | let string = "**===== AJUDA =====**\n\n"; 3 | bot.commands.forEach((command) => { 4 | if (command.help) { 5 | string += `**${process.env.PREFIX}${command.name}**: ${command.help}\n`; 6 | } 7 | }); 8 | return msg.channel.send(string); 9 | }; 10 | 11 | module.exports = { 12 | name: "help", 13 | help: "Exibe a ajuda de todos os comandos", 14 | execute, 15 | }; 16 | -------------------------------------------------------------------------------- /src/commands/skip.js: -------------------------------------------------------------------------------- 1 | const playSong = require("./play").playSong; 2 | 3 | const execute = (bot, msg, args) => { 4 | const queue = bot.queues.get(msg.guild.id); 5 | if (!queue) { 6 | return msg.reply("não existe nenhuma música sendo reproduzida"); 7 | } 8 | queue.songs.shift(); 9 | bot.queues.set(msg.guild.id, queue); 10 | playSong(bot, msg, queue.songs[0]); 11 | }; 12 | 13 | module.exports = { 14 | name: "skip", 15 | help: "Pula para a próxima música", 16 | execute, 17 | }; 18 | -------------------------------------------------------------------------------- /src/commands/volume.js: -------------------------------------------------------------------------------- 1 | const execute = (bot, msg, args) => { 2 | const queue = bot.queues.get(msg.guild.id); 3 | if (!queue) { 4 | return msg.reply("não existe nenhuma música sendo reproduzida"); 5 | } 6 | const volume = Number(args.join(" ")); 7 | if (isNaN(volume) || volume < 0 || volume > 10) { 8 | return msg.reply("o volume deve ser um valor entre 0 e 10"); 9 | } 10 | queue.dispatcher.setVolume(volume / 10); 11 | queue.volume = volume; 12 | bot.queues.set(msg.guild.id, queue); 13 | }; 14 | 15 | module.exports = { 16 | name: "vol", 17 | help: "Ajusta o volume numa escala de 0 a 10", 18 | execute, 19 | }; 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bot-aula", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "nodemon src/index.js --watch src/*", 8 | "start": "node src/index.js" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "@discordjs/opus": "^0.2.1", 15 | "discord.js": "12.1.1", 16 | "dotenv": "^8.2.0", 17 | "ffmpeg": "^0.0.4", 18 | "fluent-ffmpeg": "^2.1.2", 19 | "yt-search": "^2.0.1", 20 | "ytdl-core-discord": "^1.2.1" 21 | }, 22 | "devDependencies": { 23 | "nodemon": "^2.0.2" 24 | }, 25 | "engines": { 26 | "node": "14.2.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | const Discord = require("discord.js"); 2 | const dotenv = require("dotenv"); 3 | const fs = require("fs"); 4 | const path = require("path"); 5 | 6 | dotenv.config(); 7 | 8 | const bot = new Discord.Client(); 9 | bot.commands = new Discord.Collection(); 10 | bot.queues = new Map(); 11 | 12 | const commandFiles = fs 13 | .readdirSync(path.join(__dirname, "/commands")) 14 | .filter((filename) => filename.endsWith(".js")); 15 | 16 | for (var filename of commandFiles) { 17 | const command = require(`./commands/${filename}`); 18 | bot.commands.set(command.name, command); 19 | } 20 | 21 | bot.login(process.env.TOKEN); 22 | 23 | bot.on("ready", function () { 24 | console.log(`Estou conectado como ${bot.user.username}`); 25 | }); 26 | 27 | bot.on("message", (msg) => { 28 | if (!msg.content.startsWith(process.env.PREFIX) || msg.author.bot) return; 29 | 30 | const args = msg.content.slice(process.env.PREFIX.length).split(" "); 31 | const command = args.shift(); 32 | 33 | try { 34 | bot.commands.get(command).execute(bot, msg, args); 35 | } catch (e) { 36 | console.error(e); 37 | return msg.reply("Ops! Eu ainda não conheço esse comando!"); 38 | } 39 | }); 40 | -------------------------------------------------------------------------------- /src/commands/embed.js: -------------------------------------------------------------------------------- 1 | const MessageEmbed = require("discord.js").MessageEmbed; 2 | 3 | const execute = (bot, msg, args) => { 4 | const embed = new MessageEmbed() 5 | .setColor("#0099ff") 6 | .setTitle( 7 | `Seja bem-vindo, ${msg.author.username}#${msg.author.discriminator}!` 8 | ) 9 | .setDescription("Esta é uma descrição de teste") 10 | .setThumbnail( 11 | msg.author.avatar 12 | ? `https://cdn.discordapp.com/avatars/${msg.author.id}/${msg.author.avatar}.png` 13 | : `https://cdn.discordapp.com/embed/avatars/${ 14 | msg.author.discriminator % 5 15 | }.png` 16 | ) 17 | .setURL("https://twitch.tv/reisdev") 18 | .setAuthor( 19 | "ReisDev", 20 | `https://cdn.discordapp.com/icons/${msg.guild.id}/${msg.guild.icon}.png`, 21 | "https://reisdev.github.io" 22 | ) 23 | .addFields([ 24 | { 25 | name: "Você é membro nº", 26 | value: msg.guild.memberCount, 27 | inline: true, 28 | }, 29 | { 30 | name: "Este é um teste", 31 | value: "teste", 32 | inline: true, 33 | }, 34 | ]) 35 | .setTimestamp() 36 | .setFooter( 37 | "ReisDev 2020. Todos os direitos reservados", 38 | `https://cdn.discordapp.com/icons/${msg.guild.id}/${msg.guild.icon}.png` 39 | ); 40 | msg.channel.send({ embed }); 41 | }; 42 | 43 | module.exports = { 44 | name: "embed", 45 | help: "Retorna uma MessageEmbed", 46 | execute, 47 | }; 48 | -------------------------------------------------------------------------------- /src/commands/test.js: -------------------------------------------------------------------------------- 1 | const search = require("yt-search"); 2 | const ytdl = require("ytdl-core-discord"); 3 | exports.run = async (bot, msg, args) => { 4 | const s = args.join(" "); 5 | try { 6 | search(s, (err, result) => { 7 | if (err) { 8 | throw err; 9 | } else if (result && result.videos.length > 0) { 10 | const song = result.videos[0]; 11 | playSong(bot, msg, song); 12 | } else { 13 | return msg.reply("Desculpe nao encontrei o que voce deseja ouvir!"); 14 | } 15 | }); 16 | } catch (e) { 17 | console.log(e); 18 | } 19 | }; 20 | 21 | const playSong = async (bot, msg, song) => { 22 | if (!song) { 23 | return; 24 | } 25 | if (!msg.member.voice.channel) { 26 | return msg.channel.send( 27 | "Voce precisa estar em um canal de voz para ouvir musica!" 28 | ); 29 | } 30 | 31 | let queue = bot.queues.get(msg.member.guild.id); 32 | if (!queue) { 33 | const conn = await msg.member.voice.channel.join(); 34 | queue = { 35 | volume: 10, 36 | connection: conn, 37 | dispatcher: null, 38 | songs: [song], 39 | }; 40 | queue.dispatcher = queue.connection.play(await ytdl(song.url), { 41 | type: "opus", 42 | }); 43 | queue.dispatcher.on("finish", () => { 44 | queue.songs.shift(); 45 | playSong(bot, msg, queue, songs[0]); 46 | }); 47 | bot.queues.set(msg.member.guild.id, queue); 48 | } else { 49 | queue.songs.push(song); 50 | bot.queues.set(msg.member.guild.id); 51 | } 52 | }; 53 | 54 | module.exports.config = { 55 | name: "play", 56 | description: "Tocar uma musica", 57 | usage: "n!play link", 58 | accessableby: "Membros", 59 | aliases: ["p"], 60 | }; 61 | -------------------------------------------------------------------------------- /src/commands/play.js: -------------------------------------------------------------------------------- 1 | const search = require("yt-search"); 2 | const ytdl = require("ytdl-core-discord"); 3 | 4 | const execute = (bot, msg, args) => { 5 | const s = args.join(" "); 6 | try { 7 | search(s, (err, result) => { 8 | if (err) { 9 | throw err; 10 | } else if (result && result.videos.length > 0) { 11 | const song = result.videos[0]; 12 | const queue = bot.queues.get(msg.guild.id); 13 | if (queue) { 14 | queue.songs.push(song); 15 | bot.queues.set(msg.guild.id, queue); 16 | } else playSong(bot, msg, song); 17 | } else { 18 | return msg.reply("desculpe, não encontrei o que você desejava!"); 19 | } 20 | }); 21 | } catch (e) { 22 | console.error(e); 23 | } 24 | }; 25 | 26 | const playSong = async (bot, msg, song) => { 27 | let queue = bot.queues.get(msg.member.guild.id); 28 | if (!song) { 29 | if (queue) { 30 | queue.connection.disconnect(); 31 | return bot.queues.delete(msg.member.guild.id); 32 | } 33 | } 34 | if (!msg.member.voice.channel) { 35 | return msg.reply( 36 | "você precisa estar em um canal de voz para reproduzir uma música!" 37 | ); 38 | } 39 | if (!queue) { 40 | const conn = await msg.member.voice.channel.join(); 41 | queue = { 42 | volume: 10, 43 | connection: conn, 44 | dispatcher: null, 45 | songs: [song], 46 | }; 47 | } 48 | queue.dispatcher = await queue.connection.play( 49 | await ytdl(song.url, { highWaterMark: 1 << 25, filter: "audioonly" }), 50 | { 51 | type: "opus", 52 | } 53 | ); 54 | queue.dispatcher.on("finish", () => { 55 | queue.songs.shift(); 56 | playSong(bot, msg, queue.songs[0]); 57 | }); 58 | bot.queues.set(msg.member.guild.id, queue); 59 | }; 60 | 61 | module.exports = { 62 | name: "p", 63 | help: "Reproduz a música desejada no canal atual do usuário", 64 | execute, 65 | playSong, 66 | }; 67 | -------------------------------------------------------------------------------- /src/commands/role.js: -------------------------------------------------------------------------------- 1 | const MessageEmbed = require("discord.js").MessageEmbed; 2 | 3 | const execute = (bot, msg, args) => { 4 | if (args.length === 0) { 5 | const embed = new MessageEmbed(); 6 | embed.setTitle("Escolha suas área de interesse"); 7 | embed.setDescription( 8 | "Para escolher uma área de interesse, reaja à essa mensagem com os emojis que desejar. Cada uma das áreas possui um emoji, representados abaixo:" 9 | ); 10 | embed.setAuthor( 11 | "ReisDev", 12 | `https://cdn.discordapp.com/icons/${msg.guild.id}/${msg.guild.icon}.png`, 13 | "https://reisdev.github.io" 14 | ); 15 | embed.addFields([ 16 | { name: "DEV", value: "💻", inline: true }, 17 | { name: "CS:GO", value: "💣", inline: true }, 18 | { name: "VALORANT", value: "🔫", inline: true }, 19 | { name: "Rainbow 6: Siege", value: "6️⃣", inline: true }, 20 | { name: "COD: Warzone", value: "✈️", inline: true }, 21 | ]); 22 | msg.member.send({ embed }).then(async (embed) => { 23 | try { 24 | await embed.react("💻"); 25 | await embed.react("💣"); 26 | await embed.react("🔫"); 27 | await embed.react("6️⃣"); 28 | await embed.react("✈️"); 29 | const collector = embed.createReactionCollector( 30 | (reaction, user) => 31 | ["💻", "💣", "🔫", "6️⃣", "✈️"].includes(reaction.emoji.name) && 32 | !user.bot, 33 | { 34 | time: 1000, 35 | } 36 | ); 37 | collector.on("collect", (reaction, user) => { 38 | let role; 39 | switch (reaction.emoji.name) { 40 | case "💻": 41 | role = msg.guild.roles.cache.find((r) => r.name === "dev"); 42 | if (role) msg.member.roles.add(role); 43 | else console.error("Cargo não encontrado"); 44 | break; 45 | case "💣": 46 | role = msg.guild.roles.cache.find((r) => r.name === "CS:GO"); 47 | if (role) msg.member.roles.add(role); 48 | else console.error("Cargo não encontrado"); 49 | break; 50 | case "🔫": 51 | role = msg.guild.roles.cache.find((r) => r.name === "VALORANT"); 52 | if (role) msg.member.roles.add(role); 53 | else console.error("Cargo não encontrado"); 54 | break; 55 | case "6️⃣": 56 | role = msg.guild.roles.cache.find((r) => r.name === "R6"); 57 | if (role) msg.member.roles.add(role); 58 | else console.error("Cargo não encontrado"); 59 | break; 60 | case "✈️": 61 | role = msg.guild.roles.cache.find((r) => r.name === "COD:WZ"); 62 | if (role) msg.member.roles.add(role); 63 | else console.error("Cargo não encontrado"); 64 | break; 65 | } 66 | }); 67 | } catch (e) { 68 | console.error(e); 69 | } 70 | }); 71 | } else { 72 | if (!msg.member.hasPermission("MANAGE_ROLES")) 73 | return msg.reply("Desculpa, você não pode executar essa ação"); 74 | const [mention, roleArg] = args; 75 | const member = msg.mentions.members.first(); 76 | if (!member) 77 | return msg.reply("você precisa mencionar a quem deseja dar o cargo."); 78 | if (!roleArg) return msg.reply("você precisa escolher um cargo"); 79 | const role = msg.guild.roles.cache.find((r) => r.name === roleArg); 80 | if (!role) return msg.reply(`não encontrei o cargo \`${roleArg}\``); 81 | member.roles.add(role); 82 | } 83 | }; 84 | 85 | module.exports = { 86 | name: "role", 87 | help: "Atribui cargos a um usuário", 88 | execute, 89 | }; 90 | --------------------------------------------------------------------------------