Last active
May 6, 2017 21:16
-
-
Save Quaggie/d9c2f2cc2d2701d03595e6fe0eb6b842 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const Discord = require('discord.js') | |
| const client = new Discord.Client() | |
| const fetch = require('node-fetch') | |
| const ytdl = require('ytdl-core') | |
| const streamOptions = { seek: 0, volume: 1 } | |
| let dispatcher = null; | |
| const YOUTUBE_API_URL = 'https://www.googleapis.com/youtube/v3/search' | |
| const CARLOS_BOT_TOKEN = process.env.CARLOS_BOT_TOKEN | |
| const CARLOS_YOUTUBE_API_KEY = process.env.CARLOS_YOUTUBE_API_KEY | |
| const CARLOS = 'carlos'; | |
| const COMMANDS = { | |
| CARLOS_VOICE: 'carlos voice', | |
| CARLOS_LEAVE: 'carlos leave', | |
| CARLOS_PLAY: 'carlos play', | |
| CARLOS_PAUSE: 'carlos pause', | |
| CARLOS_RESUME: 'carlos resume', | |
| CARLOS_SKIP: 'carlos skip' | |
| } | |
| const PEDRO_URL = 'https://www.youtube.com/watch?v=C7pMKBeYe4Y' | |
| let videoRequests = [] | |
| /* | |
| *** Bot url -> https://discordapp.com/oauth2/authorize?client_id=310276220359147522&scope=bot | |
| > $ sudo npm install --global ffmpeg-binaries | |
| > $ sudo npm install | |
| > $ npm run start | |
| TODO: | |
| - Add volume control | |
| - Add gepona emojis | |
| - Add server to heroku or some shit | |
| */ | |
| client.login(CARLOS_BOT_TOKEN) | |
| client.on('ready', () => { | |
| console.log('Carlos na ativa!') | |
| }); | |
| client.on('message', message => { | |
| const content = message.content | |
| const member = message.member | |
| const voiceChannel = member.voiceChannel | |
| // Don't let the bot go through an infinite loop | |
| if (client.user.id === member.id) return | |
| // Carlos request --------------------- | |
| if (content.includes(CARLOS)) { | |
| const request = getContentFromKeyword(CARLOS, content) | |
| console.log('----------------------------[REQUEST]----------------------------') | |
| console.log(request); | |
| console.log('----------------------------[END-REQUEST]----------------------------') | |
| if (content.toLowerCase().trim() === COMMANDS.CARLOS_VOICE) { | |
| if (!isInVoiceChannel(message)) { | |
| voiceChannel.join() | |
| } else { | |
| message.reply("Já estou to no voice, caralho") | |
| .then( msg => { | |
| (function (msg) { | |
| setTimeout(() => { | |
| msg.delete() | |
| }, 2000) | |
| })(msg) | |
| }) | |
| } | |
| return; | |
| } // voice | |
| if (content.toLowerCase().trim() === COMMANDS.CARLOS_LEAVE) { | |
| if (isInVoiceChannel(message)) { | |
| voiceChannel.leave() | |
| } else { | |
| message.reply("Eu não estou em nenhum voice...") | |
| .then( msg => { | |
| (function (msg) { | |
| setTimeout(() => { | |
| msg.delete() | |
| }, 2000) | |
| })(msg) | |
| }) | |
| } | |
| return; | |
| } // voice | |
| if (content.toLowerCase().trim() === COMMANDS.CARLOS_PAUSE) { | |
| if (!dispatcher) { | |
| message.reply("Eu não estou tocando nada... #NoFap") | |
| .then( msg => { | |
| (function (msg) { | |
| setTimeout(() => { | |
| msg.delete() | |
| }, 2000) | |
| })(msg) | |
| }) | |
| } else { | |
| dispatcher.pause() | |
| } | |
| return; | |
| } | |
| if (content.toLowerCase().trim() === COMMANDS.CARLOS_RESUME) { | |
| if (!dispatcher) { | |
| message.reply("Eu não estou em tocando nada... #NoFap") | |
| .then( msg => { | |
| (function (msg) { | |
| setTimeout(() => { | |
| msg.delete() | |
| }, 2000) | |
| })(msg) | |
| }) | |
| } else { | |
| dispatcher.resume() | |
| } | |
| return; | |
| } | |
| if (content.toLowerCase().trim() === COMMANDS.CARLOS_SKIP) { | |
| if (!videoRequests.length) { | |
| message.reply('Valeu troxas...') | |
| .then( msg => { | |
| (function (msg) { | |
| setTimeout(() => { | |
| msg.delete() | |
| }, 2000) | |
| })(msg) | |
| }) | |
| disconnectCommand() | |
| } else { | |
| if (videoRequests.length > 1) { | |
| message.reply('Indo para próximo video') | |
| .then( msg => { | |
| (function (msg) { | |
| setTimeout(() => { | |
| msg.delete() | |
| }, 2000) | |
| })(msg) | |
| }) | |
| } | |
| playNextStreamInQueue() | |
| } | |
| } | |
| // Voice channel --------- | |
| if (content.toLowerCase().trim().includes(COMMANDS.CARLOS_PLAY)) { | |
| if (!isInVoiceChannel(message)) { | |
| message.reply('Me bota em um canal de voz, porra!') | |
| .then( msg => { | |
| (function (msg) { | |
| setTimeout(() => { | |
| msg.delete() | |
| }, 2000) | |
| })(msg) | |
| }) | |
| } else { | |
| voiceChannel.join() | |
| .then( connection => { | |
| const query = getContentFromKeyword(COMMANDS.CARLOS_PLAY, content) | |
| if (query === '') { | |
| const stream = ytdl(PEDRO_URL, { filter : 'audioonly' }); | |
| playStream(stream) | |
| } else { | |
| return fetchYoutube(query) | |
| .then( json => { | |
| console.log('----------------------------[YOUTUBE FETCH]----------------------------') | |
| console.log(json) | |
| console.log('----------------------------[END YOUTUBE FETCH]----------------------------') | |
| if (json && json.pageInfo && json.pageInfo.totalResults && json.pageInfo.totalResults > 0 && json.items && json.items.length) { | |
| const videoId = json.items[0].id.videoId; | |
| const title = json.items[0].snippet.title | |
| if (videoRequests.length) { | |
| console.log(`Adicionando video ${title} na fila`) | |
| message.reply(`Adicionando *${title}* na fila`) | |
| .then( msg => { | |
| (function (msg) { | |
| setTimeout(() => { | |
| msg.delete() | |
| }, 2000) | |
| })(msg) | |
| }) | |
| } else { | |
| console.log(`Adicionando video *${title}* de soundtrack`) | |
| message.reply(`Tocando *${title}* no ${voiceChannel.name}`) | |
| .then( msg => { | |
| (function (msg) { | |
| setTimeout(() => { | |
| msg.delete() | |
| }, 2000) | |
| })(msg) | |
| }) | |
| playStream(getStream(videoId)); | |
| } | |
| videoRequests.push(videoId) | |
| } else { | |
| message.reply(`Nenhum video encontrado com a busca ${query}`) | |
| .then( msg => { | |
| (function (msg) { | |
| setTimeout(() => { | |
| msg.delete() | |
| }, 2000) | |
| })(msg) | |
| }) | |
| } | |
| }).catch(err => { | |
| console.log('----------------------------[YOUTUBE ERROR]----------------------------') | |
| console.log(err) | |
| console.log('----------------------------[END YOUTUBE ERROR]----------------------------') | |
| }) | |
| } | |
| }) | |
| .catch( err => console.log(err)) | |
| } // voiceChannel | |
| } | |
| return; | |
| } // carlos | |
| // GEPONA ------- | |
| if (content.toLowerCase().includes('gepona')) { | |
| const curses = ['otário', 'merda', 'cuzão', '171', 'fdp', 'viadão', 'dá cú', 'palhaço', 'arrombado'] | |
| message.reply(`Você quis dizer o ${getRandomItem(curses)} do Luis?`) | |
| return; | |
| } | |
| // PEDRO -------- | |
| if (content.toLowerCase().includes('pedro')) { | |
| message.reply(PEDRO_URL) | |
| return; | |
| } | |
| }); | |
| // Create an event listener for new guild members | |
| client.on('guildMemberAdd', member => { | |
| // Send the message to the guilds default channel (usually #general), mentioning the member | |
| const defaultChannel = member.guild.defaultChannel | |
| defaultChannel.send(`Bem vindo ao Carlos, teu merda(${member})!`); | |
| }); | |
| // --------------- CLOSURES ------------ | |
| function helpCommand (message) { | |
| message.reply('carlos voice - CarlosBot conecta ao canal de voz que você está') | |
| message.reply('carlos play <Nome do video | Id do video> - CarlosBot procura pelo video especificado no Youtube e faz um soundtrack gostoso') | |
| message.reply('carlos leave - CarlosBot sai do seu canal de voz') | |
| message.reply('carlos pause - CarlosBot dá um pause no soundtrack') | |
| message.reply('carlos resume - CarlosBot resume o soundtrack') | |
| message.reply('carlos volume <0 a 100> - CarlosBot controla o volume do soundtrack') | |
| } | |
| function joinCommand(channelName) { | |
| const voiceChannel = getChannel(channelName) | |
| if (voiceChannel) { | |
| voiceChannel.join() | |
| console.log("Joined " + voiceChannel.name) | |
| } | |
| return voiceChannel; | |
| } | |
| function getChannel(channelName) { | |
| return client.channels.find( ({name}) => name === channelName) | |
| } | |
| function playStream(stream) { | |
| if (!dispatcher) { | |
| const connection = client.voiceConnections.first(); | |
| if (connection) { | |
| console.log('Now playing!') | |
| dispatcher = connection.playStream(stream, streamOptions); | |
| dispatcher.on('end', () => { | |
| playNextStreamInQueue(); | |
| }); | |
| dispatcher.on('error', (err) => { | |
| console.log('Parece que houve um erro!!!! -> ') | |
| console.log(err); | |
| disconnectCommand(connection) | |
| }); | |
| } | |
| } else { | |
| dispatcher = client.voiceConnections.first().playStream(stream, streamOptions); | |
| } | |
| } | |
| function playNextStreamInQueue() { | |
| const connection = client.voiceConnections.first() | |
| if (connection) { | |
| if (videoRequests.length) { | |
| const videoId = videoRequests.shift() | |
| console.log(`Lista atualizada ->`) | |
| console.log(videoRequests) | |
| console.log(`Carlos is playing the next video -> ${getYoutubeUrl(videoId)}`) | |
| playStream(getStream(videoId)) | |
| } else { | |
| console.log('Carlos leaving voice channel because the video just ended') | |
| disconnectCommand(connection) | |
| } | |
| } | |
| } | |
| function disconnectCommand(connection) { | |
| if (dispatcher) { | |
| dispatcher.destroy() | |
| } | |
| if (connection) connection.disconnect() | |
| else client.voiceConnections.first().disconnect() | |
| } | |
| function deleteMsg(msg, time) { | |
| (function (msg) { | |
| setTimeout(() => { | |
| msg.delete() | |
| }, 2000) | |
| })(msg) | |
| } | |
| // -------------------- HELPERS ---------------- | |
| function getRandomItem(array) { | |
| return array[Math.floor(Math.random() * array.length)]; | |
| } | |
| function getContentFromKeyword(keyword, content) { | |
| return content.substring(keyword.length, content.length).trim() | |
| } | |
| function isInVoiceChannel (message) { | |
| const content = message.content | |
| const member = message.member | |
| const voiceChannel = member.voiceChannel | |
| return voiceChannel && voiceChannel.connection && !voiceChannel.connection.status | |
| } | |
| function fetchYoutube(q) { | |
| return fetch(`${YOUTUBE_API_URL}?key=${CARLOS_YOUTUBE_API_KEY}&type=video&part=id,snippet&q=${q}`) | |
| .then(res => res.json()); | |
| } | |
| function getYoutubeUrl (videoId) { | |
| return `https://www.youtube.com/watch?v=${videoId}` | |
| } | |
| function getStream(videoId) { | |
| return ytdl(getYoutubeUrl(videoId), { filter : 'audioonly' }); | |
| } | |
| function getCorrectVolume(value) { | |
| const number = Number(value) | |
| if (!number) return null; | |
| if (number.isNaN()) return null; | |
| if (typeof number !== 'number') return null; | |
| return parseInt(number) / 100; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment