A v9 Discord.JS music bot in 100 lines or less

This commit is contained in:
bdistin 2016-09-09 22:26:14 -05:00
parent f12722f1cc
commit 221a54406f
6 changed files with 175 additions and 0 deletions

29
.eslintrc.json Normal file
View file

@ -0,0 +1,29 @@
{
"env": {
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"parserOptions": {
"sourceType": "module"
},
"rules": {
"no-console": "off",
"indent": [
"error",
"tab"
],
"linebreak-style": [
"error",
"windows"
],
"quotes": [
"warn",
"single"
],
"semi": [
"warn",
"always"
]
}
}

6
.gitignore vendored
View file

@ -45,3 +45,9 @@ $RECYCLE.BIN/
Network Trash Folder Network Trash Folder
Temporary Items Temporary Items
.apdisk .apdisk
# Ignores
node_modules/*
start.bat
tokens.json

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 BDISTIN
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

16
package.json Normal file
View file

@ -0,0 +1,16 @@
{
"name": "ohgodmusicbot",
"version": "1.0.0",
"description": "A v9 Discord.JS music bot in 100 lines or less",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js"
},
"dependencies": {
"discord.js" : "github:hydrabolt/discord.js#indev",
"ytdl-core" : "github:fent/node-ytdl-core#master",
},
"author": "BDISTIN",
"license": "MIT"
}

100
server.js Normal file
View file

@ -0,0 +1,100 @@
const Discord = require('discord.js');
const yt = require('ytdl-core');
const tokens = require('./tokens.json');
const client = new Discord.Client();
let queue = {};
client.on('message', msg => {
if (msg.content.startsWith(tokens.prefix + 'play')) {
if (queue[msg.guild.id].playing) return msg.channel.sendMessage('Already Playing');
if (queue[msg.guild.id] === undefined) return msg.channel.sendMessage('Add some songs to the queue first with ++add');
if (!client.voiceConnections.exists('channel', msg.member.voiceChannel)) return msg.channel.sendMessage('Join me to a voice channel with ++join first');
let myVoiceConnection = client.voiceConnections.find('channel', msg.member.voiceChannel);
let dispatcher;
console.log(queue);
(function play(song) {
queue[msg.guild.id].playing = true;
console.log(song);
if (song === undefined) {
msg.channel.sendMessage('Queue is empty');
queue[msg.guild.id].playing = false;
msg.member.voiceChannel.leave();
return;
}
msg.channel.sendMessage(`Playing: **${song.title}**`);
dispatcher = myVoiceConnection.playStream(yt(song.url, { audioonly: true }));
let collector = msg.channel.createCollector(m => m);
collector.on('message', m => {
if (m.content.startsWith(tokens.prefix + 'pause')) {
dispatcher.pause();
msg.channel.sendMessage('paused');
} else if (m.content.startsWith(tokens.prefix + 'resume')){
dispatcher.resume();
msg.channel.sendMessage('resumed');
} else if (m.content.startsWith(tokens.prefix + 'skip')){
dispatcher.end();
msg.channel.sendMessage('skipped');
} else if (m.content.startsWith('volume+')){
if (Math.round(dispatcher.volume*100) >= 100) return msg.channel.sendMessage(`Volume: ${Math.round(dispatcher.volume*100)}%`);
const amount = m.content.split('+').length-1;
dispatcher.setVolume(Math.max((dispatcher.volume*100 + 4*amount)/100,1));
msg.channel.sendMessage(`Volume: ${Math.round(dispatcher.volume*50)}%`);
} else if (m.content.startsWith('volume-')){
if (Math.round(dispatcher.volume*100) <= 0) return msg.channel.sendMessage(`Volume: ${Math.round(dispatcher.volume*100)}%`);
const amount = m.content.split('-').length-1;
dispatcher.setVolume(Math.min((dispatcher.volume*100 - 4*amount)/100,0));
msg.channel.sendMessage(`Volume: ${Math.round(dispatcher.volume*50)}%`);
}
});
dispatcher.on('end', () => {
setTimeout(()=>{
collector.stop();
queue[msg.guild.id].songs.shift();
play(queue[msg.guild.id].songs[0]);
}, 1000);
});
dispatcher.on('error', (err) => {
collector.stop();
queue[msg.guild.id].songs.shift();
queue[msg.guild.id].playing = false;
msg.channel.sendMessage('error: ' + err);
msg.member.voiceChannel.leave();
return;
});
})(queue[msg.guild.id].songs[0]);
} else if (msg.content.startsWith(tokens.prefix + 'join')) {
const voiceChannel = msg.member.voiceChannel;
if (!voiceChannel || voiceChannel.type !== 'voice') return msg.reply('I couldn\'t connect to your voice channel...');
voiceChannel.join();
} else if (msg.content.startsWith(tokens.prefix + 'add')) {
let url = msg.content.slice(6);
yt.getInfo(url, (err, info) => {
if(err) return msg.channel.sendMessage('Invalid YouTube Link: ' + err);
if (!queue.hasOwnProperty(msg.guild.id)) {
queue[msg.guild.id] = {};
queue[msg.guild.id].playing = false;
queue[msg.guild.id].songs = [];
}
queue[msg.guild.id].songs.push({url: url, title: info.title});
msg.channel.sendMessage(`added **${info.title}** to the queue`);
});
} else if (msg.content.startsWith(tokens.prefix + 'help')) {
let tosend = ['```xl',
'++join : "Join Voice channel of msg sender"',
'++add : "Add a valid youtube link to the queue"',
'++play : "Play the music queue if already joined to a voice channel',
'++pause : "pauses the music, only available while play command is running."',
'++resume : "resumes the music, only available while play command is running."',
'++skip : "skips the playing song, only available while play command is running."',
'volume+(+++) : "increases volume by 2%/+, only available while play command is running."',
'volume+(---) : "decreases volume by 2%/-, only available while play command is running."',
'notes : "commands are case sensitive, because I want to be a lazy ass on this bot."',
'```'];
msg.channel.sendMessage(tosend.join('\n'));
} else if (msg.content.startsWith(tokens.prefix + 'reboot')) {
if (msg.author.id == tokens.adminID) process.exit();
}
});
client.login(tokens.d_token);
client.on('ready', () => {
console.log('ready!');
});

3
tokens.json.example Normal file
View file

@ -0,0 +1,3 @@
{
"d_token" : "YOUR DISCORD APP TOKEN",
}