Skip to content

Instantly share code, notes, and snippets.

@Quaggie
Last active May 6, 2017 21:16
Show Gist options
  • Select an option

  • Save Quaggie/d9c2f2cc2d2701d03595e6fe0eb6b842 to your computer and use it in GitHub Desktop.

Select an option

Save Quaggie/d9c2f2cc2d2701d03595e6fe0eb6b842 to your computer and use it in GitHub Desktop.
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