summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
author8cy <[email protected]>2020-04-13 05:32:35 -0700
committer8cy <[email protected]>2020-04-13 05:32:35 -0700
commit9dff52f7d047c905326bc2f476ede5463e00f2a0 (patch)
tree1fec8563b3b72fde9b2ab7ad9e56a97398798685 /src
parenttypescript (diff)
downloads5nical-9dff52f7d047c905326bc2f476ede5463e00f2a0.tar.xz
s5nical-9dff52f7d047c905326bc2f476ede5463e00f2a0.zip
typescript final
Diffstat (limited to 'src')
-rw-r--r--src/Cache/DiscordEmoji.json1
-rw-r--r--src/app.js6
-rw-r--r--src/assets/audio/farts/1.mp3bin0 -> 1201502 bytes
-rw-r--r--src/assets/audio/farts/2.mp3bin0 -> 975523 bytes
-rw-r--r--src/assets/audio/farts/3.mp3bin0 -> 1396550 bytes
-rw-r--r--src/assets/audio/farts/4.mp3bin0 -> 928142 bytes
-rw-r--r--src/assets/audio/farts/5.mp3bin0 -> 10123976 bytes
-rw-r--r--src/assets/audio/farts/6.mp3bin0 -> 754181 bytes
-rw-r--r--src/assets/audio/farts/7.mp3bin0 -> 32409192 bytes
-rw-r--r--src/assets/audio/farts/8.mp3bin0 -> 2992326 bytes
-rw-r--r--src/assets/audio/longest_fart_ever.mp3bin0 -> 1041482 bytes
-rw-r--r--src/assets/audio/squeak.wavbin0 -> 194146 bytes
-rw-r--r--src/assets/audio/uhhhh.wavbin0 -> 133344 bytes
-rw-r--r--src/assets/audio/wahoo.mp3bin0 -> 1726068 bytes
-rw-r--r--src/bot.ts71
-rw-r--r--src/commands/fun/8ball.js30
-rw-r--r--src/commands/fun/dm.js51
-rw-r--r--src/commands/fun/emoji.js22
-rw-r--r--src/commands/fun/gay.js32
-rw-r--r--src/commands/fun/quote.js38
-rw-r--r--src/commands/fun/respect.js21
-rw-r--r--src/commands/fun/say.js29
-rw-r--r--src/commands/utility/botstatus.js124
-rw-r--r--src/commands/utility/btc.js33
-rw-r--r--src/commands/utility/btcchange.js45
-rw-r--r--src/commands/utility/clear.js70
-rw-r--r--src/commands/utility/membercount.js28
-rw-r--r--src/commands/utility/server.js52
-rw-r--r--src/commands/utility/uptime.js28
-rw-r--r--src/commands/voice/abee.js197
-rw-r--r--src/commands/voice/fart.js209
-rw-r--r--src/commands/voice/itemshop.js211
-rw-r--r--src/commands/voice/join.js29
-rw-r--r--src/commands/voice/leave.js32
-rw-r--r--src/commands/voice/loop.js32
-rw-r--r--src/commands/voice/moan.js30
-rw-r--r--src/commands/voice/pause.js30
-rw-r--r--src/commands/voice/play.js290
-rw-r--r--src/commands/voice/psycho.js196
-rw-r--r--src/commands/voice/queue.js49
-rw-r--r--src/commands/voice/remove.js39
-rw-r--r--src/commands/voice/resume.js30
-rw-r--r--src/commands/voice/shuffle.js51
-rw-r--r--src/commands/voice/skip.js27
-rw-r--r--src/commands/voice/skipall.js42
-rw-r--r--src/commands/voice/skipto.js41
-rw-r--r--src/commands/voice/squeak.js29
-rw-r--r--src/commands/voice/volume.js43
-rw-r--r--src/commands/voice/wahoo.js30
-rw-r--r--src/config.json4
50 files changed, 2322 insertions, 0 deletions
diff --git a/src/Cache/DiscordEmoji.json b/src/Cache/DiscordEmoji.json
new file mode 100644
index 0000000..4046fd2
--- /dev/null
+++ b/src/Cache/DiscordEmoji.json
@@ -0,0 +1 @@
+{"Categories":"{\"1\":\"Original Style\",\"18\":\"Recolors\",\"2\":\"TV \\/ Movie\",\"10\":\"Gaming\",\"3\":\"Meme\",\"4\":\"Anime\",\"13\":\"Pepe\",\"5\":\"Celebrity\",\"6\":\"Blobs\",\"7\":\"Thinking\",\"17\":\"Animals\",\"15\":\"Cute\",\"11\":\"Letters\",\"14\":\"Logos\",\"16\":\"Utility\",\"12\":\"Other\",\"8\":\"Animated\",\"9\":\"NSFW\"}"} \ No newline at end of file
diff --git a/src/app.js b/src/app.js
new file mode 100644
index 0000000..843db70
--- /dev/null
+++ b/src/app.js
@@ -0,0 +1,6 @@
+const { ShardingManager } = require('discord.js');
+const config = require('./config.json');
+const manager = new ShardingManager('./bot.js', { token: config['secret'] });
+
+manager.spawn();
+manager.on('shardCreate', shard => console.log(`Launched shard: ${shard.id}`)); \ No newline at end of file
diff --git a/src/assets/audio/farts/1.mp3 b/src/assets/audio/farts/1.mp3
new file mode 100644
index 0000000..39c85c7
--- /dev/null
+++ b/src/assets/audio/farts/1.mp3
Binary files differ
diff --git a/src/assets/audio/farts/2.mp3 b/src/assets/audio/farts/2.mp3
new file mode 100644
index 0000000..ee702d8
--- /dev/null
+++ b/src/assets/audio/farts/2.mp3
Binary files differ
diff --git a/src/assets/audio/farts/3.mp3 b/src/assets/audio/farts/3.mp3
new file mode 100644
index 0000000..f9179ad
--- /dev/null
+++ b/src/assets/audio/farts/3.mp3
Binary files differ
diff --git a/src/assets/audio/farts/4.mp3 b/src/assets/audio/farts/4.mp3
new file mode 100644
index 0000000..2a88503
--- /dev/null
+++ b/src/assets/audio/farts/4.mp3
Binary files differ
diff --git a/src/assets/audio/farts/5.mp3 b/src/assets/audio/farts/5.mp3
new file mode 100644
index 0000000..b4ccf9d
--- /dev/null
+++ b/src/assets/audio/farts/5.mp3
Binary files differ
diff --git a/src/assets/audio/farts/6.mp3 b/src/assets/audio/farts/6.mp3
new file mode 100644
index 0000000..f57c501
--- /dev/null
+++ b/src/assets/audio/farts/6.mp3
Binary files differ
diff --git a/src/assets/audio/farts/7.mp3 b/src/assets/audio/farts/7.mp3
new file mode 100644
index 0000000..5ea9d51
--- /dev/null
+++ b/src/assets/audio/farts/7.mp3
Binary files differ
diff --git a/src/assets/audio/farts/8.mp3 b/src/assets/audio/farts/8.mp3
new file mode 100644
index 0000000..d135519
--- /dev/null
+++ b/src/assets/audio/farts/8.mp3
Binary files differ
diff --git a/src/assets/audio/longest_fart_ever.mp3 b/src/assets/audio/longest_fart_ever.mp3
new file mode 100644
index 0000000..82b11e1
--- /dev/null
+++ b/src/assets/audio/longest_fart_ever.mp3
Binary files differ
diff --git a/src/assets/audio/squeak.wav b/src/assets/audio/squeak.wav
new file mode 100644
index 0000000..fea330b
--- /dev/null
+++ b/src/assets/audio/squeak.wav
Binary files differ
diff --git a/src/assets/audio/uhhhh.wav b/src/assets/audio/uhhhh.wav
new file mode 100644
index 0000000..f8dfb24
--- /dev/null
+++ b/src/assets/audio/uhhhh.wav
Binary files differ
diff --git a/src/assets/audio/wahoo.mp3 b/src/assets/audio/wahoo.mp3
new file mode 100644
index 0000000..b507034
--- /dev/null
+++ b/src/assets/audio/wahoo.mp3
Binary files differ
diff --git a/src/bot.ts b/src/bot.ts
new file mode 100644
index 0000000..dd06d56
--- /dev/null
+++ b/src/bot.ts
@@ -0,0 +1,71 @@
+import config from './config.json';
+import { CommandoClient } from 'discord.js-commando';
+import path from 'path';
+import { Structures } from 'discord.js';
+Structures.extend('Guild', Guild => {
+ class MusicGuild extends Guild {
+ musicData: { queue: never[]; isPlaying: boolean; volume: number; songDispatcher: null; };
+ constructor(client, data) {
+ super(client, data);
+ this.musicData = {
+ queue: [],
+ isPlaying: false,
+ volume: 1,
+ songDispatcher: null
+ };
+ }
+ }
+ return MusicGuild;
+});
+
+const client = new CommandoClient({
+ commandPrefix: 's5n!',
+ owner: '217348698294714370'
+});
+
+client.registry
+ .registerDefaultTypes()
+ .registerGroups([
+ ['fun', 'fun command group'],
+ ['moderation', 'moderation command group'],
+ ['utility', 'utility command group'],
+ ['voice', 'voice command group']
+ ])
+ .registerDefaultGroups()
+ .registerDefaultCommands({
+ help: true
+ })
+ .registerCommandsIn(path.join(__dirname, 'commands'));
+
+client.once('ready', () => {
+ console.log(`Started bot: ${client.user.tag} (ID: ${client.user.id})\nCurrently running on ${client.guilds.cache.size} server(s).`);
+ client.user.setActivity('psycho~ uwu', {
+ type: 'LISTENING'
+ });
+ //client.channels.cache.get('600773421525237781').send('bot started up');
+});
+
+client.on('error', console.error);
+client.on('debug', console.debug);
+
+client.on('message', async msg => {
+ var msgContent = msg.content.toLowerCase();
+ function prefixCheck() {
+ if (msgContent.startsWith('s5n!')) {
+ return true;
+ }
+ }
+ if (prefixCheck()) {
+ if (msg.channel.type == 'dm') {
+ console.log(msg.author.tag, 'says', msgContent, 'in a DM');
+ } else {
+ console.log(msg.member.user.tag, 'says', msgContent, 'in #' + msg.channel.name);
+ }
+ }
+
+ if (msg.mentions.everyone) {
+ msg.react(':ArisaPing:695887537390223402');
+ }
+});
+
+client.login(config['secret']); \ No newline at end of file
diff --git a/src/commands/fun/8ball.js b/src/commands/fun/8ball.js
new file mode 100644
index 0000000..e4cb3a2
--- /dev/null
+++ b/src/commands/fun/8ball.js
@@ -0,0 +1,30 @@
+const { Command } = require('discord.js-commando');
+const { MessageEmbed } = require('discord.js');
+
+module.exports = class EightBallFun extends Command {
+ constructor(client) {
+ super(client, {
+ name: '8ball',
+ aliases: ['8b'],
+ group: 'fun',
+ memberName: '8ball',
+ description: 'shake the 8ball 4 a fortune',
+ throttling: {
+ usages: 5,
+ duration: 30
+ },
+ examples: ['s5n!8ball', 's5n!8b']
+ });
+ }
+ run(msg) {
+ var r = ['yes~ uwu', 'no.', 'yes!', 'no!', 'what, no.', 'yes.', 'maybe.', 'perhaps.', 'try again.', 'i\'m not sure.'];
+ var s = r[Math.floor(Math.random() * r.length)];
+
+ let embed = new MessageEmbed()
+
+ .setAuthor('the 8-ball says', 'https://upload.wikimedia.org/wikipedia/commons/thumb/f/fd/8-Ball_Pool.svg/500px-8-Ball_Pool.svg.png')
+ .setDescription('`' + s + '`');
+
+ msg.channel.send(embed);
+ }
+}; \ No newline at end of file
diff --git a/src/commands/fun/dm.js b/src/commands/fun/dm.js
new file mode 100644
index 0000000..fc10f28
--- /dev/null
+++ b/src/commands/fun/dm.js
@@ -0,0 +1,51 @@
+const { Command } = require('discord.js-commando');
+const { RichEmbed } = require('discord.js');
+
+module.exports = class DMFun extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'dm',
+ aliases: [
+ 'directmessage',
+ 'directmsg',
+ 'direct-message',
+ 'direct-msg'
+ ],
+ group: 'fun',
+ memberName: 'dm',
+ description: 'dm someone',
+ guildOnly: true,
+ args: [
+ {
+ key: 'msgContent',
+ prompt: 'what would u like to send',
+ type: 'string'
+ }
+ ],
+ examples: [
+ 's5n!dm @sin#1337 hi',
+ 's5n!directmessage @sin#1337 hey',
+ 's5n!directmsg @sin#1337 hello',
+ 's5n!direct-message @sin#1337 yo',
+ 's5n!direct-msg @sin#1337 aye',
+ ]
+ });
+ }
+ run(msg, { msgContent }) {
+ if (msg.author) {
+ if (!msg.mentions.users.first() && msgContent) {
+ msg.reply('you haven\'t specified anyone to send to.');
+ } else {
+ var sendTo = msg.mentions.users.first().id;
+ var d = new Date(msg.createdTimestamp);
+
+ msg.guild.members.fetch(sendTo, false).then(messageUser => {
+ messageUser.send(msgContent);
+ msg.reply('sent :D');
+ });
+ }
+ } else {
+ msg.reply('insufficent perms bruh');
+ }
+ }
+}; \ No newline at end of file
diff --git a/src/commands/fun/emoji.js b/src/commands/fun/emoji.js
new file mode 100644
index 0000000..027cd55
--- /dev/null
+++ b/src/commands/fun/emoji.js
@@ -0,0 +1,22 @@
+const emoji = require('emoji-random');
+const { Command } = require('discord.js-commando');
+
+module.exports = class EmojiFun extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'emoji',
+ aliases: ['moji'],
+ group: 'fun',
+ memberName: 'emoji',
+ description: 'gives u a random emoji',
+ throttling: {
+ usages: 5,
+ duration: 30
+ },
+ examples: ['s5n!emoji', 's5n!moji']
+ });
+ }
+ run(msg) {
+ msg.reply(emoji.random());
+ }
+}; \ No newline at end of file
diff --git a/src/commands/fun/gay.js b/src/commands/fun/gay.js
new file mode 100644
index 0000000..1a45374
--- /dev/null
+++ b/src/commands/fun/gay.js
@@ -0,0 +1,32 @@
+const { Command } = require('discord.js-commando');
+
+module.exports = class GayFun extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'gay',
+ aliases: [
+ 'gayamount',
+ 'gayrange',
+ 'gayrate'
+ ],
+ group: 'fun',
+ memberName: 'gay',
+ description: 'tells you your gay-ness amount',
+ examples: [
+ 's5n!gay',
+ 's5n!gayamount',
+ 's5n!gayrange',
+ 's5n!gayrate'
+ ]
+ });
+ }
+ run(msg) {
+ var gayAmount = Math.floor((Math.random() * 100) + 1);
+ var gayAmountDecimal = Math.floor((Math.random() * 100) + 1);
+
+ msg.reply('scanning..').then(scanningMsg => {
+ scanningMsg.delete()
+ msg.reply('your gay-ness amount is **' + gayAmount + '.' + gayAmountDecimal + '%** 🏳️‍🌈');
+ });
+ }
+}; \ No newline at end of file
diff --git a/src/commands/fun/quote.js b/src/commands/fun/quote.js
new file mode 100644
index 0000000..2e0d2c9
--- /dev/null
+++ b/src/commands/fun/quote.js
@@ -0,0 +1,38 @@
+const atquotes = require('at-quotes');
+const { Command } = require('discord.js-commando');
+const emoji = require('emoji-random');
+
+module.exports = class QuoteFun extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'quote',
+ aliases: ['quotes'],
+ group: 'fun',
+ memberName: 'quote',
+ description: 'gives you a random quote from adventure time',
+ throttling: {
+ usages: 5,
+ duration: 30
+ },
+ examples: ['s5n!quote', 's5n!quote finn'],
+ args: [
+ {
+ key: 'atCharacter',
+ prompt: 'would u like a specific character? (finn, jake, ice king, no)',
+ type: 'string'
+ }
+ ]
+ });
+ }
+ run(msg, { atCharacter }) {
+ if (!atCharacter || atCharacter == 'no' || atCharacter == 'n') {
+ msg.reply(atquotes.getQuote() + ' ' + emoji.random());
+ } else if (atCharacter == 'finn' || atCharacter == 'f') {
+ msg.reply(atquotes.getFinnQuote() + ' ' + emoji.random());
+ } else if (atCharacter == 'jake' || atCharacter == 'j') {
+ msg.reply(atquotes.getJakeQuote() + ' ' + emoji.random());
+ } else if (atCharacter == 'ice king' || atCharacter == 'ik') {
+ msg.reply(atquotes.getIceKingQuote() + ' ' + emoji.random());
+ }
+ }
+}; \ No newline at end of file
diff --git a/src/commands/fun/respect.js b/src/commands/fun/respect.js
new file mode 100644
index 0000000..863c9b0
--- /dev/null
+++ b/src/commands/fun/respect.js
@@ -0,0 +1,21 @@
+const { Command } = require('discord.js-commando');
+
+module.exports = class RespectFun extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'respect',
+ aliases: ['f'],
+ group: 'fun',
+ memberName: 'respect',
+ description: 'press f to pay respects',
+ examples: ['s5n!respect', 's5n!f'],
+ guildOnly: true
+ });
+ }
+ run(msg) {
+ msg.channel.send('press f to pay respects').then(m => {
+ m.react('🇫');
+ msg.delete();
+ });
+ }
+}; \ No newline at end of file
diff --git a/src/commands/fun/say.js b/src/commands/fun/say.js
new file mode 100644
index 0000000..07c6dba
--- /dev/null
+++ b/src/commands/fun/say.js
@@ -0,0 +1,29 @@
+const { Command } = require('discord.js-commando');
+
+module.exports = class SayFun extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'say',
+ group: 'fun',
+ memberName: 'say',
+ description: 'speak as the bot',
+ guildOnly: true,
+ args: [
+ {
+ key: 'say',
+ prompt: 'u cant send an empty msg lol',
+ type: 'string'
+ }
+ ],
+ examples: ['s5n!say hi']
+ });
+ }
+ run(msg, { say }) {
+ if (msg.member.hasPermission('KICK_MEMBERS')) {
+ msg.channel.send(say);
+ msg.delete();
+ } else {
+ msg.reply('insufficent perms homie ' + emoji.random());
+ }
+ }
+}; \ No newline at end of file
diff --git a/src/commands/utility/botstatus.js b/src/commands/utility/botstatus.js
new file mode 100644
index 0000000..65825bb
--- /dev/null
+++ b/src/commands/utility/botstatus.js
@@ -0,0 +1,124 @@
+const { Command } = require('discord.js-commando');
+const emoji = require('discord.js');
+
+module.exports = class BotStatusUtility extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'botstatus',
+ aliases: ['status', 'bs'],
+ group: 'utility',
+ memberName: 'botstatus',
+ description: 'lets you change the bots status',
+ args: [
+ {
+ key: 'userChangeType',
+ prompt: 'would you like to change the status message or type?',
+ type: 'string'
+ },
+ {
+ key: 'userActivityName',
+ prompt: 'what would u like the message 2 be?',
+ type: 'string'
+ },
+ {
+ key: 'userActivityType',
+ prompt: 'what would u like the status type to be?',
+ type: 'string'
+ }
+ ],
+ guildOnly: true,
+ examples: [
+ 's5n!botstatus type watching',
+ 's5n!status t w',
+ 's5n!status message youtube',
+ 's5n!bs m lol'
+ ]
+ });
+ }
+ run(msg, { userActivityName, userActivityType }) {
+ if (msg.member.hasPermission('KICK_MEMBERS')) {
+ var activityType = this.client.user.presence.activities[0].type;
+ var activityName = this.client.user.presence.activities[0].name;
+
+ function activityTypeToWords() {
+ if (activityName == '0') {
+ var activityName = 'PLAYING';
+ } else if (activityName == '1') {
+ var activityName = 'STREAMING';
+ } else if (activityName == '2') {
+ var activityName = 'LISTENING';
+ } else if (activityName == '3') {
+ var activityName = 'WATCHING';
+ }
+ }
+
+ if (userChangeType == 'reset' || userChangeType == 'r') {
+ this.client.user.setActivity('psycho ~uwu', {
+ type: 'LISTENING'
+ });
+ msg.reply('status has been reset lol ' + emoji.random());
+ } else if (userChangeType == 'format' || userChangeType == 'f') {
+ // Print full, proper format for the Discord.js setActivity() function
+ msg.reply('\n`' + this.client.user.setActivity.toString() + '`');
+ } else if (userChangeType == 'message' || userChangeType == 'msg' || userChangeType == 'm') {
+ // This took way to long to complete lol, 2020/04/08, 00:12, my birthday lol
+ if (userChangeType == 'message') {
+ var m = userChangeType.join(' ');
+ var mf = m.slice(8, 22);
+ } else if (userChangeType == 'msg') {
+ var m = userChangeType.join(' ');
+ var mf = m.slice(4, 22);
+ } else if (userChangeType == 'm') {
+ var m = userChangeType.join(' ');
+ var mf = m.slice(2, 22);
+ }
+
+ if (mf == 'reset' || mf == 'r') {
+ this.client.user.setActivity('psycho ~uwu', {
+ type: activityType
+ });
+
+ msg.reply('status message has been reset lol');
+ } else {
+ this.client.user.setActivity(mf, {
+ type: activityType
+ });
+ }
+ } else if (userChangeType == 'userChangeType' || args == 't') {
+ var m = userChangeType;
+ userChangeType.toLowerCase();
+ if (userChangeType == 'playing' || userChangeType == 'p') {
+ var m = 'playing';
+
+ this.client.user.setActivity(activityName, {
+ type: 'playing'
+ });
+ } else if (userChangeType == 'listening' || userChangeType == 'l') {
+ var m = 'LISTENING';
+
+ this.client.user.setActivity(activityName, {
+ type: m
+ });
+ } else if (userChangeType == 'watching' || userChangeType == 'w') {
+ var m = 'WATCHING';
+
+ this.client.user.setActivity(activityName, {
+ type: m
+ });
+ } else if (userChangeType == 'custom' || userChangeType == 'c') {
+ msg.reply('custom status is disabled due to discord api policies about self-botting :(');
+ } else if (userChangeType == 'reset' || userChangeType == 'r') {
+ this.client.user.setActivity(activityName, {
+ type: 'LISTENING'
+ });
+
+ msg.reply('status type has been reset lol');
+ }
+ } else if (!args) {
+ msg.reply('no arguments specified');
+ }
+ } else {
+ msg.reply('insufficent perms bruh');
+ }
+ }
+}; \ No newline at end of file
diff --git a/src/commands/utility/btc.js b/src/commands/utility/btc.js
new file mode 100644
index 0000000..3971fa9
--- /dev/null
+++ b/src/commands/utility/btc.js
@@ -0,0 +1,33 @@
+const { Command } = require('discord.js-commando');
+const btc = require('btc-value');
+btc.setApiKey('a43419ce-fc59-4951-8af9-20c5e36ef73f');
+
+module.exports = class BTCUtility extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'btc',
+ aliases: ['bitcoin', 'crypto'],
+ group: 'utility',
+ memberName: 'btc',
+ description: 'allows you to check current bitcoin prices',
+ args: [
+ {
+ key: 'currencyName',
+ prompt: 'what currency u wanna see it in? (usd, aud, cad)',
+ type: 'string'
+ }
+ ],
+ examples: [
+ 's5n!bitcoin aud',
+ 's5n!crypto cad',
+ 's5n!btc usd'
+ ]
+ });
+ }
+ run(msg, { currencyName }) {
+ currencyName = currencyName.toUpperCase();
+ btc({ isDecimal: true, currencyCode: currencyName }).then(value => {
+ msg.reply('the current *bitcoin* price in **' + currencyName + '** is **' + value + '** ' + emoji.random());
+ });
+ }
+}; \ No newline at end of file
diff --git a/src/commands/utility/btcchange.js b/src/commands/utility/btcchange.js
new file mode 100644
index 0000000..eb7a204
--- /dev/null
+++ b/src/commands/utility/btcchange.js
@@ -0,0 +1,45 @@
+const { Command } = require('discord.js-commando');
+const btc = require('btc-value');
+btc.setApiKey('a43419ce-fc59-4951-8af9-20c5e36ef73f');
+
+module.exports = class BTCChangeUtility extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'btcchange',
+ aliases: ['bitcoinchange', 'cryptochange', 'btcc'],
+ group: 'utility',
+ memberName: 'btcchange',
+ description: 'allows you to check the fluctuation in bitcoin prices in a specified amount of time',
+ args: [
+ {
+ key: 'timeAmount',
+ prompt: 'what time range do you want to check the fluction amount in? (day, hour, week)',
+ type: 'string'
+ }
+ ],
+ examples: [
+ 's5n!btcchange day',
+ 's5n!bitcoinchange hour',
+ 's5n!cryptochange week',
+ 's5n!btcc day'
+ ]
+ });
+ }
+ run(msg, { timeAmount }) {
+ if (timeAmount == 'day') {
+ btc.getPercentageChangeLastDay().then(percentage => {
+ msg.reply('the fluction amount of *bitcoin* in the last **' + timeAmount + '** is **' + percentage + '%** ' + emoji.random());
+ });
+ } else if (timeAmount == 'hour') {
+ btc.getPercentageChangeLastHour().then(percentage => {
+ msg.reply('the fluction amount of *bitcoin* in the last **' + timeAmount + '** is **' + percentage + '%** ' + emoji.random());
+ });
+ } else if (timeAmount == 'week') {
+ btc.getPercentageChangeLastWeek().then(percentage => {
+ msg.reply('the fluction amount of *bitcoin* in the last **' + timeAmount + '** is **' + percentage + '%** ' + emoji.random());
+ });
+ } else {
+ msg.reply('*' + timeAmount + '* is not a valid range lol ' + emoji.random());
+ }
+ }
+}; \ No newline at end of file
diff --git a/src/commands/utility/clear.js b/src/commands/utility/clear.js
new file mode 100644
index 0000000..d563501
--- /dev/null
+++ b/src/commands/utility/clear.js
@@ -0,0 +1,70 @@
+const { Command } = require('discord.js-commando');
+const emoji = require('emoji-random');
+
+module.exports = class ClearUtility extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'clear',
+ aliases: ['delete', 'del', 'c', 'd'],
+ group: 'utility',
+ memberName: 'clear',
+ description: 'clear an ammount of messages',
+ guildOnly: true,
+ args: [
+ {
+ key: 'deleteAmount',
+ prompt: 'how many messages would u like to delete?',
+ type: 'integer'
+ }
+ ],
+ examples: [
+ 's5n!clear 23',
+ 's5n!delete 75',
+ 's5n!del 32',
+ 's5n!c 45',
+ 's5n!d 84'
+ ]
+ });
+ }
+ async run(msg, { deleteAmount }) {
+ if (msg.member.hasPermission('MANAGE_MESSAGES')) {
+ if (!deleteAmount) {
+ msg.reply('you haven\'t specified an amount of messages which should be deleted. ' + emoji.random()).then(deleteNotificationMessage => {
+ deleteNotificationMessage.delete({ timeout: 1000 });
+ });
+ } else if (isNaN(deleteAmount)) {
+ msg.reply('the amount parameter isn\'t a number. ' + emoji.random()).then(deleteNotificationMessage => {
+ deleteNotificationMessage.delete({ timeout: 1000 });
+ });
+ } else if (deleteAmount > 100) {
+ msg.reply('you can\'t delete more than 100 messages at once. ' + emoji.random()).then(deleteNotificationMessage => {
+ deleteNotificationMessage.delete({ timeout: 1000 });
+ });
+ } else if (deleteAmount < 1) {
+ msg.reply('you have to delete at least 1 message. ' + emoji.random()).then(deleteNotificationMessage => {
+ deleteNotificationMessage.delete({ timeout: 1000 });
+ });
+ }
+ /*else if (msg.createdTimestamp > 1209600) {
+ msg.reply('due to discord rules, bots can only bulk delete messages that are under 14 days old :(')
+ } */
+ else {
+ var clearAmount = deleteAmount + 1;
+ // It took me so long to figure out why this was not really working. It would delete but an insane amount at a time.
+ // I realized that because it was getting parsed as a string, it would just add 1 to it so if I tried to delete 1
+ // message, it would delete 11 lol. Fixed by parsing as integer THEN adding one. 02:30 2020/04/03/2020
+
+ await msg.channel.messages.fetch({
+ limit: clearAmount
+ }).then(messages => { // I am on v11 discord.js
+ msg.channel.bulkDelete(messages);
+ });
+ msg.reply('it\'s been deleted ~uwu ' + emoji.random()).then(deleteNotificationMessage => {
+ deleteNotificationMessage.delete({ timeout: 1000 });
+ });
+ }
+ } else {
+ msg.reply('insufficent perms bruh ' + emoji.random());
+ }
+ }
+}; \ No newline at end of file
diff --git a/src/commands/utility/membercount.js b/src/commands/utility/membercount.js
new file mode 100644
index 0000000..d799c68
--- /dev/null
+++ b/src/commands/utility/membercount.js
@@ -0,0 +1,28 @@
+const { Command } = require('discord.js-commando');
+const emoji = require('emoji-random');
+
+module.exports = class MemberCountUtility extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'membercount',
+ aliases: ['memberc', 'mcount', 'mc'],
+ group: 'utility',
+ memberName: 'membercount',
+ description: 'says how many members there are in the server',
+ throttling: {
+ usages: 5,
+ duration: 30
+ },
+ guildOnly: true,
+ examples: [
+ 's5n!membercount',
+ 's5n!memberc',
+ 's5n!mcount',
+ 's5n!mc'
+ ]
+ });
+ }
+ run(msg) {
+ msg.reply(`there are **${msg.guild.memberCount}** members in **${msg.guild.name}** ` + emoji.random());
+ }
+}; \ No newline at end of file
diff --git a/src/commands/utility/server.js b/src/commands/utility/server.js
new file mode 100644
index 0000000..5f395fd
--- /dev/null
+++ b/src/commands/utility/server.js
@@ -0,0 +1,52 @@
+const { Command } = require('discord.js-commando');
+const { MessageEmbed } = require('discord.js');
+
+module.exports = class ServerUtility extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'server',
+ aliases: [
+ 'serverinfo',
+ 'si',
+ 'server-info',
+ 'serverstats',
+ 'server-stats'
+ ],
+ group: 'utility',
+ memberName: 'server',
+ description: 'gives u info about the server',
+ throttling: {
+ usages: 2,
+ duration: 60
+ },
+ guildOnly: true,
+ examples: [
+ 's5n!server',
+ 's5n!serverinfo',
+ 's5n!server-info',
+ 's5n!serverstats',
+ 's5n!server-stats',
+ 's5n!si'
+ ]
+ });
+ }
+ run(msg) {
+ var o = msg.guild.members.cache.filter(m => m.presence.status === 'online').size;
+
+ let embed = new MessageEmbed()
+
+ .setAuthor(`${msg.guild.name} - ${msg.guild.id}`, `${msg.guild.iconURL()}`, `https://discordapp.com/channels/${msg.guild.id}/${msg.guild.id}`)
+ .setDescription(`here\'s all the information on \`${msg.guild.name}\``)
+ .setThumbnail(`${msg.guild.iconURL()}`)
+ .addField('owner', `${msg.guild.owner}`, false)
+ .addField(`members [${msg.guild.memberCount}]`, `${o} members are online.`, true)
+ .addField('region', `${msg.guild.region}`, true)
+ .addField('text channels', `${msg.guild.channels.filter(c => c.type === 'text').size}`, true)
+ .addField('voice channels', `${msg.guild.channels.filter(c => c.type === 'voice').size}`, true)
+ .addField('guild created', `${msg.guild.createdAt}`, false)
+ .addField('s5nical joined', `${msg.guild.members.get('695107550403756192').joinedAt}`)
+ .setColor(0xF97DAE);
+
+ msg.channel.send(embed);
+ }
+}; \ No newline at end of file
diff --git a/src/commands/utility/uptime.js b/src/commands/utility/uptime.js
new file mode 100644
index 0000000..0c76754
--- /dev/null
+++ b/src/commands/utility/uptime.js
@@ -0,0 +1,28 @@
+const { Command } = require('discord.js-commando');
+const upTime = require('moment');
+require('moment-duration-format');
+const emoji = require('emoji-random');
+
+module.exports = class UptimeUtility extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'uptime',
+ aliases: ['ut'],
+ group: 'utility',
+ memberName: 'uptime',
+ description: 'tells you how long the bot has been online',
+ throttling: {
+ usages: 5,
+ duration: 30
+ },
+ examples: [
+ 's5n!uptime',
+ 's5n!ut'
+ ]
+ });
+ }
+ run(msg) {
+ const duration = upTime.duration(this.client.uptime).format(" D [days], H [hrs], m [mins], s [secs]");
+ msg.reply(duration + ' ' + emoji.random());
+ }
+}; \ No newline at end of file
diff --git a/src/commands/voice/abee.js b/src/commands/voice/abee.js
new file mode 100644
index 0000000..9dfda85
--- /dev/null
+++ b/src/commands/voice/abee.js
@@ -0,0 +1,197 @@
+const ytdl = require('ytdl-core');
+const { Command } = require('discord.js-commando');
+const { MessageEmbed } = require('discord.js');
+const Youtube = require('simple-youtube-api');
+//const { youtubeAPI } = require('../../config.json');
+const youtube = new Youtube('AIzaSyB9xJENORzZt-GmOGx4WsNCPgKSIxhJcds');
+const emoji = require('emoji-random');
+
+module.exports = class ABeeVoice extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'abee',
+ aliases: ['a-bee'],
+ group: 'voice',
+ memberName: 'abee',
+ description: 'a bee :D 🐝',
+ guildOnly: true,
+ clientPermissions: ['SPEAK', 'CONNECT'],
+ examples: ['s5n!abee', 's5n!a-bee']
+ });
+ }
+ async run(msg) {
+ const voiceChannel = msg.member.voice.channel;
+ if (!voiceChannel) return msg.say('join a channel and try again ' + emoji.random());
+
+ const id = 'lvdnhWhQBdo';
+ const video = await youtube.getVideoByID(id).catch(function () {
+ return msg.say(
+ 'there was a problem getting the video you provided ' + emoji.random()
+ );
+ });
+ // // can be uncommented if you don't want the bot to play live streams
+ // if (video.raw.snippet.liveBroadcastContent === 'live') {
+ // return msg.say("I don't support live streams!");
+ // }
+ // // can be uncommented if you don't want the bot to play videos longer than 1 hour
+ // if (video.duration.hours !== 0) {
+ // return msg.say('I cannot play videos longer than 1 hour');
+ // }
+ // // can be uncommented if you want to limit the queue
+ // if (msg.guild.musicData.queue.length > 10) {
+ // return msg.say(
+ // 'There are too many songs in the queue already, skip or wait a bit'
+ // );
+ // }
+ msg.guild.musicData.queue.push(
+ this.constructSongObj(video, voiceChannel)
+ );
+ if (
+ msg.guild.musicData.isPlaying == false ||
+ typeof msg.guild.musicData.isPlaying == 'undefined'
+ ) {
+ msg.guild.musicData.isPlaying = true;
+ return this.playSong(msg.guild.musicData.queue, msg);
+ } else if (msg.guild.musicData.isPlaying == true) {
+ return msg.say(`${video.title} added to queue ` + emoji.random());
+ }
+
+ var that = this;
+ msg.channel
+ .awaitMessages(
+ function (msg) {
+ return (msg.content > 0 && msg.content < 6) || msg.content === 'exit';
+ }, {
+ max: 1,
+ time: 60000,
+ errors: ['time']
+ }
+ )
+ .then(function (response) {
+ const videoIndex = parseInt(response.first().content);
+ if (response.first().content === 'exit') return songEmbed.delete();
+ youtube
+ .getVideoByID(videos[videoIndex - 1].id)
+ .then(function (video) {
+ // // can be uncommented if you don't want the bot to play live streams
+ // if (video.raw.snippet.liveBroadcastContent === 'live') {
+ // songEmbed.delete();
+ // return msg.say("I don't support live streams!");
+ // }
+
+ // // can be uncommented if you don't want the bot to play videos longer than 1 hour
+ // if (video.duration.hours !== 0) {
+ // songEmbed.delete();
+ // return msg.say('I cannot play videos longer than 1 hour');
+ // }
+
+ // // can be uncommented if you don't want to limit the queue
+ // if (msg.guild.musicData.queue.length > 10) {
+ // songEmbed.delete();
+ // return msg.say(
+ // 'There are too many songs in the queue already, skip or wait a bit'
+ // );
+ // }
+ msg.guild.musicData.queue.push(
+ that.constructSongObj(video, voiceChannel)
+ );
+ if (msg.guild.musicData.isPlaying == false) {
+ msg.guild.musicData.isPlaying = true;
+ if (songEmbed) {
+ songEmbed.delete();
+ }
+ that.playSong(msg.guild.musicData.queue, msg);
+ } else if (msg.guild.musicData.isPlaying == true) {
+ if (songEmbed) {
+ songEmbed.delete();
+ }
+ return msg.say(`${video.title} added to queue ` + emoji.random());
+ }
+ })
+ .catch(function () {
+ if (songEmbed) {
+ songEmbed.delete();
+ }
+ return msg.say(
+ 'an error has occured when trying to get the video id from youtube ' + emoji.random()
+ );
+ });
+ });
+ }
+ playSong(queue, msg) {
+ const classThis = this; // use classThis instead of 'this' because of lexical scope below
+ queue[0].voiceChannel
+ .join()
+ .then(function (connection) {
+ const dispatcher = connection
+ .play(
+ ytdl(queue[0].url, {
+ quality: 'highestaudio',
+ highWaterMark: 1024 * 1024 * 10
+ })
+ )
+ .on('start', function () {
+ msg.guild.musicData.songDispatcher = dispatcher;
+ const volume = 10 / 100;
+ msg.guild.musicData.volume = volume;
+ dispatcher.setVolume(msg.guild.musicData.volume);
+ const videoEmbed = new MessageEmbed()
+ .setThumbnail(queue[0].thumbnail)
+ .setColor(0xF97DAE)
+ .addField('now playing:', queue[0].title)
+ .addField('duration:', queue[0].duration);
+ if (queue[1]) videoEmbed.addField('next song:', queue[1].title);
+ msg.say(videoEmbed);
+ msg.guild.musicData.nowPlaying = queue[0];
+ return queue.shift();
+ })
+ .on('finish', function () {
+ if (queue.length >= 1) {
+ return classThis.playSong(queue, msg);
+ } else {
+ msg.guild.musicData.isPlaying = false;
+ msg.guild.musicData.nowPlaying = null;
+ msg.guild.musicData.songDispatcher = null;
+ return msg.guild.me.voice.channel.leave();
+ }
+ })
+ .on('error', function (e) {
+ msg.say('can\'t play song ' + emoji.random());
+ console.error(e);
+ msg.guild.musicData.queue.length = 0;
+ msg.guild.musicData.isPlaying = false;
+ msg.guild.musicData.nowPlaying = null;
+ msg.guild.musicData.songDispatcher = null;
+ return msg.guild.me.voice.channel.leave();
+ });
+ })
+ .catch(function (e) {
+ console.error(e);
+ return msg.guild.me.voice.channel.leave();
+ });
+ }
+ constructSongObj(video, voiceChannel) {
+ let duration = this.formatDuration(video.duration);
+ if (duration == '00:00') duration = 'live stream';
+ return {
+ url: `https://www.youtube.com/watch?v=${video.raw.id}`,
+ title: video.title,
+ duration,
+ thumbnail: video.thumbnails.high.url,
+ voiceChannel
+ };
+ }
+ // prettier-ignore
+ formatDuration(durationObj) {
+ const duration = `${durationObj.hours ? (durationObj.hours + ':') : ''}${
+ durationObj.minutes ? durationObj.minutes : '00'
+ }:${
+ (durationObj.seconds < 10)
+ ? ('0' + durationObj.seconds)
+ : (durationObj.seconds
+ ? durationObj.seconds
+ : '00')
+ }`;
+ return duration;
+ }
+}; \ No newline at end of file
diff --git a/src/commands/voice/fart.js b/src/commands/voice/fart.js
new file mode 100644
index 0000000..394a2d5
--- /dev/null
+++ b/src/commands/voice/fart.js
@@ -0,0 +1,209 @@
+// TODO: shits broken bc i cant get variables from different scopes
+/*
+const ytdl = require('ytdl-core');
+const { Command } = require('discord.js-commando');
+const { MessageEmbed } = require('discord.js');
+const Youtube = require('simple-youtube-api');
+//const { youtubeAPI } = require('../../config.json');
+const youtube = new Youtube('AIzaSyB9xJENORzZt-GmOGx4WsNCPgKSIxhJcds');
+const emoji = require('emoji-random');
+
+module.exports = class FartVoice extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'fart',
+ group: 'voice',
+ memberName: 'fart',
+ description: 'gives you a random fart',
+ guildOnly: true,
+ clientPermissions: ['SPEAK', 'CONNECT'],
+ examples: ['s5n!fart']
+ });
+ }
+ async run(msg) {
+ var fartNum = Math.floor((Math.random() * 8) + 1);
+ if (fartNum == 1) {
+ var fartMsg = 'you got fart 1, courtesy of sin ' + emoji.random();
+ var fartTitle = 'fart 1';
+ var fartAudio = '../../assets/audio/farts/1.mp3';
+ } else if (fartNum == 2) {
+ var fartMsg = 'you got fart 2, courtesy of sin ' + emoji.random();
+ var fartTitle = 'fart 2';
+ var fartAudio = '../../assets/audio/farts/2.mp3';
+ } else if (fartNum == 3) {
+ var fartMsg = 'you got fart 3, courtesy of sin ' + emoji.random();
+ var fartTitle = 'fart 3';
+ var fartAudio = '../../assets/audio/farts/3.mp3';
+ } else if (fartNum == 4) {
+ var fartMsg = 'you got fart 4, courtesy of sin ' + emoji.random();
+ var fartTitle = 'fart 4';
+ var fartAudio = '../../assets/audio/farts/4.mp3';
+ } else if (fartNum == 5) {
+ var fartMsg = 'you got fart 5, courtesy of sin ' + emoji.random();
+ var fartTitle = 'fart 5';
+ var fartAudio = '../../assets/audio/farts/5.mp3';
+ } else if (fartNum == 6) {
+ var fartMsg = 'you got fart 6, courtesy of nick ' + emoji.random();
+ var fartTitle = 'fart 6';
+ var fartAudio = '../../assets/audio/farts/6.mp3';
+ } else if (fartNum == 7) {
+ var fartMsg = 'you got fart 7, courtesy of nick ' + emoji.random();
+ var fartTitle = 'fart 7';
+ var fartAudio = '../../assets/audio/farts/7.mp3';
+ } else if (fartNum == 8) {
+ var fartMsg = 'you got fart 8, courtesy of nick ' + emoji.random();
+ var fartTitle = 'fart 8';
+ var fartAudio = '../../assets/audio/farts/8.mp3';
+ }
+
+ const voiceChannel = msg.member.voice.channel;
+ if (!voiceChannel) return msg.say('join a channel and try again ' + emoji.random());
+
+ const video = await fartAudio;
+ // // can be uncommented if you don't want the bot to play live streams
+ // if (video.raw.snippet.liveBroadcastContent === 'live') {
+ // return msg.say("I don't support live streams!");
+ // }
+ // // can be uncommented if you don't want the bot to play videos longer than 1 hour
+ // if (video.duration.hours !== 0) {
+ // return msg.say('I cannot play videos longer than 1 hour');
+ // }
+ // // can be uncommented if you want to limit the queue
+ // if (msg.guild.musicData.queue.length > 10) {
+ // return msg.say(
+ // 'There are too many songs in the queue already, skip or wait a bit'
+ // );
+ // }
+ msg.guild.musicData.queue.push(
+ this.constructSongObj(video, voiceChannel)
+ );
+ if (
+ msg.guild.musicData.isPlaying == false ||
+ typeof msg.guild.musicData.isPlaying == 'undefined'
+ ) {
+ msg.guild.musicData.isPlaying = true;
+ return this.playSong(msg.guild.musicData.queue, msg);
+ } else if (msg.guild.musicData.isPlaying == true) {
+ msg.reply(fartMsg);
+ msg.say(fartTitle, 'added to queue ' + emoji.random());
+ return
+ }
+
+ var that = this;
+ msg.channel
+ .awaitMessages(
+ function (msg) {
+ return (msg.content > 0 && msg.content < 6) || msg.content === 'exit';
+ }, {
+ max: 1,
+ time: 60000,
+ errors: ['time']
+ }
+ )
+ .then(function (response) {
+ const videoIndex = parseInt(response.first().content);
+ if (response.first().content === 'exit') return songEmbed.delete();
+ youtube
+ .then(function (video) {
+ // // can be uncommented if you don't want the bot to play live streams
+ // if (video.raw.snippet.liveBroadcastContent === 'live') {
+ // songEmbed.delete();
+ // return msg.say("I don't support live streams!");
+ // }
+
+ // // can be uncommented if you don't want the bot to play videos longer than 1 hour
+ // if (video.duration.hours !== 0) {
+ // songEmbed.delete();
+ // return msg.say('I cannot play videos longer than 1 hour');
+ // }
+
+ // // can be uncommented if you don't want to limit the queue
+ // if (msg.guild.musicData.queue.length > 10) {
+ // songEmbed.delete();
+ // return msg.say(
+ // 'There are too many songs in the queue already, skip or wait a bit'
+ // );
+ // }
+ msg.guild.musicData.queue.push(
+ that.constructSongObj(video, voiceChannel)
+ );
+ if (msg.guild.musicData.isPlaying == false) {
+ msg.guild.musicData.isPlaying = true;
+ if (songEmbed) {
+ songEmbed.delete();
+ }
+ that.playSong(msg.guild.musicData.queue, msg);
+ } else if (msg.guild.musicData.isPlaying == true) {
+ if (songEmbed) {
+ songEmbed.delete();
+ }
+ return msg.say(fartTitle, 'added to queue ' + emoji.random());
+ }
+ })
+ .catch(function () {
+ if (songEmbed) {
+ songEmbed.delete();
+ }
+ return msg.say(
+ 'an error has occured when trying to get the video file ' + emoji.random()
+ );
+ });
+ });
+ }
+ playSong(queue, msg) {
+ const classThis = this; // use classThis instead of 'this' because of lexical scope below
+ queue[0].voiceChannel
+ .join()
+ .then(function (connection) {
+ const dispatcher = connection
+ .play(
+ fartAudio // TODO: broken here
+ )
+ .on('start', function () {
+ msg.guild.musicData.songDispatcher = dispatcher;
+ const volume = 100 / 100;
+ msg.guild.musicData.volume = volume;
+ dispatcher.setVolume(msg.guild.musicData.volume);
+ const videoEmbed = new MessageEmbed()
+ .setThumbnail(queue[0].thumbnail)
+ .setColor(0xF97DAE)
+ .addField('now playing:', queue[0].title)
+ .addField('duration:', queue[0].duration);
+ if (queue[1]) videoEmbed.addField('next song:', queue[1].title);
+ msg.say(videoEmbed);
+ msg.guild.musicData.nowPlaying = queue[0];
+ return queue.shift();
+ })
+ .on('finish', function () {
+ if (queue.length >= 1) {
+ return classThis.playSong(queue, msg);
+ } else {
+ msg.guild.musicData.isPlaying = false;
+ msg.guild.musicData.nowPlaying = null;
+ msg.guild.musicData.songDispatcher = null;
+ return msg.guild.me.voice.channel.leave();
+ }
+ })
+ .on('error', function (e) {
+ msg.say('can\'t play song ' + emoji.random());
+ console.error(e);
+ msg.guild.musicData.queue.length = 0;
+ msg.guild.musicData.isPlaying = false;
+ msg.guild.musicData.nowPlaying = null;
+ msg.guild.musicData.songDispatcher = null;
+ return msg.guild.me.voice.channel.leave();
+ });
+ })
+ .catch(function (e) {
+ console.error(e);
+ return msg.guild.me.voice.channel.leave();
+ });
+ }
+ constructSongObj(video, voiceChannel) {
+ return { // TODO: and broken here
+ url: 'fart',
+ title: 'fart 1',
+ voiceChannel
+ };
+ }
+}; \ No newline at end of file
diff --git a/src/commands/voice/itemshop.js b/src/commands/voice/itemshop.js
new file mode 100644
index 0000000..730ce83
--- /dev/null
+++ b/src/commands/voice/itemshop.js
@@ -0,0 +1,211 @@
+const ytdl = require('ytdl-core');
+const { Command } = require('discord.js-commando');
+const { MessageEmbed } = require('discord.js');
+const Youtube = require('simple-youtube-api');
+//const { youtubeAPI } = require('../../config.json');
+const youtube = new Youtube('AIzaSyB9xJENORzZt-GmOGx4WsNCPgKSIxhJcds');
+const emoji = require('emoji-random');
+
+module.exports = class ABeeVoice extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'itemshop',
+ aliases: ['item-shop'],
+ group: 'voice',
+ memberName: 'itemshop',
+ description: 'use code frozen in the itemshop',
+ guildOnly: true,
+ clientPermissions: ['SPEAK', 'CONNECT'],
+ examples: ['s5n!itemshop', 's5n!item-shop']
+ });
+ }
+ async run(msg) {
+ const voiceChannel = msg.member.voice.channel;
+ if (!voiceChannel) return msg.say('join a channel and try again ' + emoji.random());
+
+ const id = 'pBiI1hTwU7E';
+ const video = await youtube.getVideoByID(id).catch(function () {
+ return msg.say(
+ 'there was a problem getting the video you provided ' + emoji.random()
+ );
+ });
+ // // can be uncommented if you don't want the bot to play live streams
+ // if (video.raw.snippet.liveBroadcastContent === 'live') {
+ // return msg.say("I don't support live streams!");
+ // }
+ // // can be uncommented if you don't want the bot to play videos longer than 1 hour
+ // if (video.duration.hours !== 0) {
+ // return msg.say('I cannot play videos longer than 1 hour');
+ // }
+ // // can be uncommented if you want to limit the queue
+ // if (msg.guild.musicData.queue.length > 10) {
+ // return msg.say(
+ // 'There are too many songs in the queue already, skip or wait a bit'
+ // );
+ // }
+ msg.guild.musicData.queue.push(
+ this.constructSongObj(video, voiceChannel)
+ );
+ if (
+ msg.guild.musicData.isPlaying == false ||
+ typeof msg.guild.musicData.isPlaying == 'undefined'
+ ) {
+ msg.guild.musicData.isPlaying = true;
+ return this.playSong(msg.guild.musicData.queue, msg);
+ } else if (msg.guild.musicData.isPlaying == true) {
+ msg.reply('USE CODE FROZEN IN THE FORTNITE ITEM SHOP!!! ' + emoji.random());
+ msg.say(`${video.title} added to queue ` + emoji.random());
+ return;
+ }
+
+ var that = this;
+ msg.channel
+ .awaitMessages(
+ function (msg) {
+ return (msg.content > 0 && msg.content < 6) || msg.content === 'exit';
+ }, {
+ max: 1,
+ time: 60000,
+ errors: ['time']
+ }
+ )
+ .then(function (response) {
+ const videoIndex = parseInt(response.first().content);
+ if (response.first().content === 'exit') return songEmbed.delete();
+ youtube
+ .getVideoByID(videos[videoIndex - 1].id)
+ .then(function (video) {
+ // // can be uncommented if you don't want the bot to play live streams
+ // if (video.raw.snippet.liveBroadcastContent === 'live') {
+ // songEmbed.delete();
+ // return msg.say("I don't support live streams!");
+ // }
+
+ // // can be uncommented if you don't want the bot to play videos longer than 1 hour
+ // if (video.duration.hours !== 0) {
+ // songEmbed.delete();
+ // return msg.say('I cannot play videos longer than 1 hour');
+ // }
+
+ // // can be uncommented if you don't want to limit the queue
+ // if (msg.guild.musicData.queue.length > 10) {
+ // songEmbed.delete();
+ // return msg.say(
+ // 'There are too many songs in the queue already, skip or wait a bit'
+ // );
+ // }
+ msg.guild.musicData.queue.push(
+ that.constructSongObj(video, voiceChannel)
+ );
+ if (msg.guild.musicData.isPlaying == false) {
+ msg.guild.musicData.isPlaying = true;
+ if (songEmbed) {
+ songEmbed.delete();
+ }
+ that.playSong(msg.guild.musicData.queue, msg);
+ } else if (msg.guild.musicData.isPlaying == true) {
+ if (songEmbed) {
+ songEmbed.delete();
+ }
+ msg.reply('USE CODE FROZEN IN THE FORTNITE ITEM SHOP!!! ' + emoji.random());
+ msg.say(`${video.title} added to queue`);
+ return;
+ }
+ })
+ .catch(function () {
+ if (songEmbed) {
+ songEmbed.delete();
+ }
+ return msg.say(
+ 'an error has occured when trying to get the video id from youtube'
+ );
+ });
+ });
+ }
+ playSong(queue, msg) {
+ const classThis = this; // use classThis instead of 'this' because of lexical scope below
+ queue[0].voiceChannel
+ .join()
+ .then(function (connection) {
+ const dispatcher = connection
+ .play(
+ ytdl(queue[0].url, {
+ quality: 'highestaudio',
+ highWaterMark: 1024 * 1024 * 10
+ })
+
+ )
+ .on('start', function () {
+ msg.guild.musicData.songDispatcher = dispatcher;
+ const volume = 10 / 100;
+ msg.guild.musicData.volume = volume;
+ dispatcher.setVolume(msg.guild.musicData.volume);
+ const videoEmbed = new MessageEmbed()
+ .setThumbnail(queue[0].thumbnail)
+ .setColor(0xF97DAE)
+ .addField('now playing:', queue[0].title)
+ .addField('duration:', queue[0].duration);
+ if (queue[1]) videoEmbed.addField('next song:', queue[1].title);
+ msg.say(videoEmbed);
+ msg.reply('use code frozen in the itemshop : 3 ' + emoji.random());
+ msg.guild.musicData.nowPlaying = queue[0];
+ return queue.shift();
+ })
+ .on('finish', function () {
+ if (queue.length >= 1) {
+ return classThis.playSong(queue, msg);
+ } else {
+ msg.guild.musicData.isPlaying = false;
+ msg.guild.musicData.nowPlaying = null;
+ msg.guild.musicData.songDispatcher = null;
+ return msg.guild.me.voice.channel.leave();
+ }
+ })
+ .on('error', function (e) {
+ msg.say('can\'t play song');
+ console.error(e);
+ msg.guild.musicData.queue.length = 0;
+ msg.guild.musicData.isPlaying = false;
+ msg.guild.musicData.nowPlaying = null;
+ msg.guild.musicData.songDispatcher = null;
+ return msg.guild.me.voice.channel.leave();
+ });
+ function timeCheck() {
+ if (dispatcher.streamTime >= 6000) {
+ msg.guild.musicData.isPlaying = false;
+ msg.guild.musicData.nowPlaying = null;
+ msg.guild.musicData.songDispatcher = null;
+ }
+ }
+ setInterval(timeCheck, 500);
+ })
+ .catch(function (e) {
+ console.error(e);
+ return msg.guild.me.voice.channel.leave();
+ });
+ }
+ constructSongObj(video, voiceChannel) {
+ let duration = this.formatDuration(video.duration);
+ if (duration == '00:00') duration = 'live stream';
+ return {
+ url: `https://www.youtube.com/watch?v=${video.raw.id}`,
+ title: video.title,
+ duration,
+ thumbnail: video.thumbnails.high.url,
+ voiceChannel
+ };
+ }
+ // prettier-ignore
+ formatDuration(durationObj) {
+ const duration = `${durationObj.hours ? (durationObj.hours + ':') : ''}${
+ durationObj.minutes ? durationObj.minutes : '00'
+ }:${
+ (durationObj.seconds < 10)
+ ? ('0' + durationObj.seconds)
+ : (durationObj.seconds
+ ? durationObj.seconds
+ : '00')
+ }`;
+ return duration;
+ }
+}; \ No newline at end of file
diff --git a/src/commands/voice/join.js b/src/commands/voice/join.js
new file mode 100644
index 0000000..fda2516
--- /dev/null
+++ b/src/commands/voice/join.js
@@ -0,0 +1,29 @@
+const { Command } = require('discord.js-commando');
+const emoji = require('emoji-random');
+
+module.exports = class JoinVoice extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'join',
+ group: 'voice',
+ memberName: 'join',
+ description: 'joins your voice channel',
+ throttling: {
+ usages: 2,
+ duration: 5
+ },
+ guildOnly: true,
+ examples: ['s5n!join']
+ });
+ }
+ run(msg) {
+ if (msg.guild.musicData.isPlaying == false && msg.member.voice.channel) {
+ msg.member.voice.channel.join();
+ msg.reply('succesfully joined voice channel ' + emoji.random());
+ } else if (msg.guild.musicData.isPlaying == false) {
+ msg.reply('i\'m already in voice channel ' + emoji.random());
+ } else if (!msg.member.voice.channel) {
+ msg.reply('you\'re not in a voice channel ' + emoji.random());
+ }
+ }
+}; \ No newline at end of file
diff --git a/src/commands/voice/leave.js b/src/commands/voice/leave.js
new file mode 100644
index 0000000..51456a6
--- /dev/null
+++ b/src/commands/voice/leave.js
@@ -0,0 +1,32 @@
+const { Command } = require('discord.js-commando');
+const emoji = require('emoji-random');
+
+module.exports = class LeaveVoice extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'leave',
+ aliases: ['end', 'stop'],
+ group: 'voice',
+ memberName: 'leave',
+ description: 'stops voice channel if any playing',
+ guildOnly: true,
+ examples: ['s5n!leave', 's5n!end', 's5n!stop']
+ });
+ }
+ run(msg) {
+ var voiceChannel = msg.member.voice.channel;
+ if (!voiceChannel) return msg.reply('join a channel and try again ' + emoji.random());
+
+ if (
+ typeof msg.guild.musicData.songDispatcher == 'undefined' ||
+ msg.guild.musicData.songDispatcher == null
+ ) {
+ return msg.reply('there isn\'t a song playing right now lol ' + emoji.random());
+ }
+ if (!msg.guild.musicData.queue)
+ return msg.say('there are no songs in queue rn lol ' + emoji.random());
+ msg.guild.musicData.songDispatcher.end();
+ msg.guild.musicData.queue.length = 0;
+ return;
+ }
+}; \ No newline at end of file
diff --git a/src/commands/voice/loop.js b/src/commands/voice/loop.js
new file mode 100644
index 0000000..3679b4f
--- /dev/null
+++ b/src/commands/voice/loop.js
@@ -0,0 +1,32 @@
+const { Command } = require('discord.js-commando');
+const emoji = require('emoji-random');
+
+module.exports = class LoopVoice extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'loop',
+ aliases: ['repeat'],
+ group: 'voice',
+ memberName: 'loop',
+ description: 'loops currently playing audio',
+ guildOnly: true,
+ examples: ['s5n!loop', 's5n!repeat']
+ });
+ }
+ run(msg) {
+ var voiceChannel = msg.member.voice.channel;
+ if (!voiceChannel) return msg.reply('join a channel and try again ' + emoji.random());
+
+ if (
+ typeof msg.guild.musicData.songDispatcher == 'undefined' ||
+ msg.guild.musicData.songDispatcher == null
+ ) {
+ return msg.reply('there isn\'t a song playing right now lol ' + emoji.random());
+ }
+ msg.channel.send(
+ `${msg.guild.musicData.nowPlaying.title} added to queue ` + emoji.random()
+ );
+ msg.guild.musicData.queue.unshift(msg.guild.musicData.nowPlaying);
+ return;
+ }
+}; \ No newline at end of file
diff --git a/src/commands/voice/moan.js b/src/commands/voice/moan.js
new file mode 100644
index 0000000..03824e3
--- /dev/null
+++ b/src/commands/voice/moan.js
@@ -0,0 +1,30 @@
+const { Command } = require('discord.js-commando');
+const emoji = require('emoji-random');
+
+module.exports = class MoanVoice extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'moan',
+ aliases: ['uhhhh'],
+ group: 'voice',
+ memberName: 'moan',
+ description: 'uhhhh',
+ guildOnly: true,
+ examples: ['s5n!moan', 's5n!uhhhh']
+ });
+ }
+ async run(msg) {
+ if (msg.member.voice.channel && !msg.guild.voice) {
+ const connection = await msg.member.voice.channel.join();
+ const dispatcher = connection.play('./assets/audio/uhhhh.wav');
+
+ dispatcher.on('finish', () => {
+ connection.disconnect();
+ });
+ } else if (msg.guild.voice) {
+ msg.reply('i\'m already playing that lol ' + emoji.random());
+ } else {
+ msg.reply('you need to join a voice channel first silly ' + emoji.random());
+ }
+ }
+}; \ No newline at end of file
diff --git a/src/commands/voice/pause.js b/src/commands/voice/pause.js
new file mode 100644
index 0000000..f24d1ef
--- /dev/null
+++ b/src/commands/voice/pause.js
@@ -0,0 +1,30 @@
+const { Command } = require('discord.js-commando');
+const emoji = require('emoji-random');
+
+module.exports = class PauseVoice extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'pause',
+ group: 'voice',
+ memberName: 'pause',
+ description: 'pauses music if there is any playing',
+ guildOnly: true,
+ examples: ['s5n!pause']
+ });
+ }
+ run(msg) {
+ var voiceChannel = msg.member.voice.channel;
+ if (!voiceChannel) return msg.reply('join a channel and try again ' + emoji.random());
+
+ if (
+ typeof msg.guild.musicData.songDispatcher == 'undefined' ||
+ msg.guild.musicData.songDispatcher == null
+ ) {
+ return msg.reply('there isn\'t a song playing right now lol ' + emoji.random());
+ }
+
+ msg.say('song paused :pause_button:');
+
+ msg.guild.musicData.songDispatcher.pause();
+ }
+}; \ No newline at end of file
diff --git a/src/commands/voice/play.js b/src/commands/voice/play.js
new file mode 100644
index 0000000..bf59268
--- /dev/null
+++ b/src/commands/voice/play.js
@@ -0,0 +1,290 @@
+const ytdl = require('ytdl-core');
+const { Command } = require('discord.js-commando');
+const { MessageEmbed } = require('discord.js');
+const Youtube = require('simple-youtube-api');
+const { youtubeAPI } = require('../../config.json');
+const youtube = new Youtube('AIzaSyB9xJENORzZt-GmOGx4WsNCPgKSIxhJcds');
+const emoji = require('emoji-random');
+
+module.exports = class PlayVoice extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'play',
+ group: 'voice',
+ memberName: 'play',
+ description: 'play a youtube video',
+ guildOnly: true,
+ clientPermissions: ['SPEAK', 'CONNECT'],
+ args: [
+ {
+ key: 'query',
+ prompt: 'what song u wanna hear?',
+ type: 'string',
+ validate: function (query) {
+ return query.length > 0 && query.length < 200;
+ }
+ }
+ ],
+ examples: [
+ 's5n!play https://www.youtube.com/watch?v=dQw4w9WgXcQ',
+ 's5n!play despacito'
+ ]
+ });
+ }
+ async run(msg, { query }) {
+ const voiceChannel = msg.member.voice.channel;
+ if (!voiceChannel) return msg.say('join a channel and try again ' + emoji.random());
+
+ if (
+ // if the user entered yt playlist url
+ query.match(
+ /^(?!.*\?.*\bv=)https:\/\/www\.youtube\.com\/.*\?.*\blist=.*$/
+ )
+ ) {
+ const playlist = await youtube.getPlaylist(query).catch(function () {
+ return msg.say('playlist is either private or it does not exist ' + emoji.random());
+ });
+ // remove the 10 if you removed the queue limit conditions below
+ const videosObj = await playlist.getVideos(10).catch(function () {
+ return msg.say(
+ 'there was a problem getting one of the videos in the playlist ' + emoji.random()
+ );
+ });
+ for (let i = 0; i < videosObj.length; i++) {
+ const video = await videosObj[i].fetch();
+ // this can be uncommented if you choose to limit the queue
+ // if (msg.guild.musicData.queue.length < 10) {
+ //
+ msg.guild.musicData.queue.push(
+ this.constructSongObj(video, voiceChannel)
+ );
+ // } else {
+ // return msg.say(
+ // `I can't play the full playlist because there will be more than 10 songs in queue`
+ // );
+ // }
+ }
+ if (msg.guild.musicData.isPlaying == false) {
+ msg.guild.musicData.isPlaying = true;
+ return this.playSong(msg.guild.musicData.queue, msg);
+ } else if (msg.guild.musicData.isPlaying == true) {
+ return msg.say(
+ `playlist - :musical_note: ${playlist.title} :musical_note: has been added to queue ` + emoji.random()
+ );
+ }
+ }
+
+ // This if statement checks if the user entered a youtube url, it can be any kind of youtube url
+ if (query.match(/^(http(s)?:\/\/)?((w){3}.)?youtu(be|.be)?(\.com)?\/.+/)) {
+ query = query
+ .replace(/(>|<)/gi, '')
+ .split(/(vi\/|v=|\/v\/|youtu\.be\/|\/embed\/)/);
+ const id = query[2].split(/[^0-9a-z_\-]/i)[0];
+ const video = await youtube.getVideoByID(id).catch(function () {
+ return msg.say(
+ 'there was a problem getting the video you provided ' + emoji.random()
+ );
+ });
+ // // can be uncommented if you don't want the bot to play live streams
+ // if (video.raw.snippet.liveBroadcastContent === 'live') {
+ // return msg.say("I don't support live streams!");
+ // }
+ // // can be uncommented if you don't want the bot to play videos longer than 1 hour
+ // if (video.duration.hours !== 0) {
+ // return msg.say('I cannot play videos longer than 1 hour');
+ // }
+ // // can be uncommented if you want to limit the queue
+ // if (msg.guild.musicData.queue.length > 10) {
+ // return msg.say(
+ // 'There are too many songs in the queue already, skip or wait a bit'
+ // );
+ // }
+ msg.guild.musicData.queue.push(
+ this.constructSongObj(video, voiceChannel)
+ );
+ if (
+ msg.guild.musicData.isPlaying == false ||
+ typeof msg.guild.musicData.isPlaying == 'undefined'
+ ) {
+ msg.guild.musicData.isPlaying = true;
+ return this.playSong(msg.guild.musicData.queue, msg);
+ } else if (msg.guild.musicData.isPlaying == true) {
+ return msg.say(`${video.title} added to queue ` + emoji.random());
+ }
+ }
+
+ // if user provided a song/video name
+ const videos = await youtube.searchVideos(query, 5).catch(function () {
+ return msg.say(
+ 'there was a problem searching the video you requested :( ' + emoji.random()
+ );
+ });
+ if (videos.length < 5) {
+ return msg.say(
+ `i had some trouble finding what you were looking for, please try again or be more specific lol ` + emoji.random()
+ );
+ }
+ const vidNameArr = [];
+ for (let i = 0; i < videos.length; i++) {
+ vidNameArr.push(`${i + 1}: ${videos[i].title}`);
+ }
+ vidNameArr.push('exit');
+ const embed = new MessageEmbed()
+ .setColor(0xF97DAE)
+ .setTitle('choose a song by msging a number between 1 and 5 ' + emoji.random())
+ .addField(`‎`, '**song #**' + vidNameArr[0])
+ .addField(`‎`, '**song #**' + vidNameArr[1])
+ .addField(`‎`, '**song #**' + vidNameArr[2])
+ .addField(`‎`, '**song #**' + vidNameArr[3])
+ .addField(`‎`, '**song #**' + vidNameArr[4])
+ .addField(`‎`, '**exit selection**: ' + 'exit');
+ var songEmbed = await msg.channel.send({
+ embed
+ });
+ var that = this;
+ msg.channel
+ .awaitMessages(
+ function (msg) {
+ return (msg.content > 0 && msg.content < 6) || msg.content === 'exit';
+ }, {
+ max: 1,
+ time: 60000,
+ errors: ['time']
+ }
+ )
+ .then(function (response) {
+ const videoIndex = parseInt(response.first().content);
+ if (response.first().content === 'exit') return songEmbed.delete();
+ youtube
+ .getVideoByID(videos[videoIndex - 1].id)
+ .then(function (video) {
+ // // can be uncommented if you don't want the bot to play live streams
+ // if (video.raw.snippet.liveBroadcastContent === 'live') {
+ // songEmbed.delete();
+ // return msg.say("I don't support live streams!");
+ // }
+
+ // // can be uncommented if you don't want the bot to play videos longer than 1 hour
+ // if (video.duration.hours !== 0) {
+ // songEmbed.delete();
+ // return msg.say('I cannot play videos longer than 1 hour');
+ // }
+
+ // // can be uncommented if you don't want to limit the queue
+ // if (msg.guild.musicData.queue.length > 10) {
+ // songEmbed.delete();
+ // return msg.say(
+ // 'There are too many songs in the queue already, skip or wait a bit'
+ // );
+ // }
+ msg.guild.musicData.queue.push(
+ that.constructSongObj(video, voiceChannel)
+ );
+ if (msg.guild.musicData.isPlaying == false) {
+ msg.guild.musicData.isPlaying = true;
+ if (songEmbed) {
+ songEmbed.delete();
+ }
+ that.playSong(msg.guild.musicData.queue, msg);
+ } else if (msg.guild.musicData.isPlaying == true) {
+ if (songEmbed) {
+ songEmbed.delete();
+ }
+ return msg.say(`${video.title} added to queue ` + emoji.random());
+ }
+ })
+ .catch(function () {
+ if (songEmbed) {
+ songEmbed.delete();
+ }
+ return msg.say(
+ 'an error has occured when trying to get the video id from youtube ' + emoji.random()
+ );
+ });
+ })
+ .catch(function () {
+ if (songEmbed) {
+ songEmbed.delete();
+ }
+ return msg.say(
+ 'try again and enter a number between 1 and 5 or exit ' + emoji.random()
+ );
+ });
+ }
+ playSong(queue, msg) {
+ const classThis = this; // use classThis instead of 'this' because of lexical scope below
+ queue[0].voiceChannel
+ .join()
+ .then(function (connection) {
+ const dispatcher = connection
+ .play(
+ ytdl(queue[0].url, {
+ quality: 'highestaudio',
+ highWaterMark: 1024 * 1024 * 10
+ })
+ )
+ .on('start', function () {
+ msg.guild.musicData.songDispatcher = dispatcher;
+ const volume = 10 / 100;
+ msg.guild.musicData.volume = volume;
+ dispatcher.setVolume(msg.guild.musicData.volume);
+ const videoEmbed = new MessageEmbed()
+ .setThumbnail(queue[0].thumbnail)
+ .setColor(0xF97DAE)
+ .addField('now playing:', queue[0].title)
+ .addField('duration:', queue[0].duration);
+ if (queue[1]) videoEmbed.addField('next song:', queue[1].title);
+ msg.say(videoEmbed);
+ msg.guild.musicData.nowPlaying = queue[0];
+ return queue.shift();
+ })
+ .on('finish', function () {
+ if (queue.length >= 1) {
+ return classThis.playSong(queue, msg);
+ } else {
+ msg.guild.musicData.isPlaying = false;
+ msg.guild.musicData.nowPlaying = null;
+ msg.guild.musicData.songDispatcher = null;
+ return msg.guild.me.voice.channel.leave();
+ }
+ })
+ .on('error', function (e) {
+ msg.say('can\'t play song ' + emoji.random());
+ console.error(e);
+ msg.guild.musicData.queue.length = 0;
+ msg.guild.musicData.isPlaying = false;
+ msg.guild.musicData.nowPlaying = null;
+ msg.guild.musicData.songDispatcher = null;
+ return msg.guild.me.voice.channel.leave();
+ });
+ })
+ .catch(function (e) {
+ console.error(e);
+ return msg.guild.me.voice.channel.leave();
+ });
+ }
+ constructSongObj(video, voiceChannel) {
+ let duration = this.formatDuration(video.duration);
+ if (duration == '00:00') duration = 'live stream';
+ return {
+ url: `https://www.youtube.com/watch?v=${video.raw.id}`,
+ title: video.title,
+ duration,
+ thumbnail: video.thumbnails.high.url,
+ voiceChannel
+ };
+ }
+ // prettier-ignore
+ formatDuration(durationObj) {
+ const duration = `${durationObj.hours ? (durationObj.hours + ':') : ''}${
+ durationObj.minutes ? durationObj.minutes : '00'
+ }:${
+ (durationObj.seconds < 10)
+ ? ('0' + durationObj.seconds)
+ : (durationObj.seconds
+ ? durationObj.seconds
+ : '00')
+ }`;
+ return duration;
+ }
+}; \ No newline at end of file
diff --git a/src/commands/voice/psycho.js b/src/commands/voice/psycho.js
new file mode 100644
index 0000000..ba45254
--- /dev/null
+++ b/src/commands/voice/psycho.js
@@ -0,0 +1,196 @@
+const ytdl = require('ytdl-core');
+const { Command } = require('discord.js-commando');
+const { MessageEmbed } = require('discord.js');
+const Youtube = require('simple-youtube-api');
+const { youtubeAPI } = require('../../config.json');
+const youtube = new Youtube('AIzaSyB9xJENORzZt-GmOGx4WsNCPgKSIxhJcds');
+const emoji = require('emoji-random');
+
+module.exports = class PsychoVoice extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'psycho',
+ group: 'voice',
+ memberName: 'psycho',
+ description: 'plays the psycho by mase',
+ guildOnly: true,
+ clientPermissions: ['SPEAK', 'CONNECT'],
+ examples: ['s5n!psycho']
+ });
+ }
+ async run(msg, { query }) {
+ const voiceChannel = msg.member.voice.channel;
+ if (!voiceChannel) return msg.say('join a channel and try again ' + emoji.random());
+
+ const id = 'fnd_HSmAODs';
+ const video = await youtube.getVideoByID(id).catch(function () {
+ return msg.say(
+ 'there was a problem getting the video you provided ' + emoji.random()
+ );
+ });
+ // // can be uncommented if you don't want the bot to play live streams
+ // if (video.raw.snippet.liveBroadcastContent === 'live') {
+ // return msg.say("I don't support live streams!");
+ // }
+ // // can be uncommented if you don't want the bot to play videos longer than 1 hour
+ // if (video.duration.hours !== 0) {
+ // return msg.say('I cannot play videos longer than 1 hour');
+ // }
+ // // can be uncommented if you want to limit the queue
+ // if (msg.guild.musicData.queue.length > 10) {
+ // return msg.say(
+ // 'There are too many songs in the queue already, skip or wait a bit'
+ // );
+ // }
+ msg.guild.musicData.queue.push(
+ this.constructSongObj(video, voiceChannel)
+ );
+ if (
+ msg.guild.musicData.isPlaying == false ||
+ typeof msg.guild.musicData.isPlaying == 'undefined'
+ ) {
+ msg.guild.musicData.isPlaying = true;
+ return this.playSong(msg.guild.musicData.queue, msg);
+ } else if (msg.guild.musicData.isPlaying == true) {
+ return msg.say(`${video.title} added to queue ` + emoji.random());
+ }
+
+ var that = this;
+ msg.channel
+ .awaitMessages(
+ function (msg) {
+ return (msg.content > 0 && msg.content < 6) || msg.content === 'exit';
+ }, {
+ max: 1,
+ time: 60000,
+ errors: ['time']
+ }
+ )
+ .then(function (response) {
+ const videoIndex = parseInt(response.first().content);
+ if (response.first().content === 'exit') return songEmbed.delete();
+ youtube
+ .getVideoByID(videos[videoIndex - 1].id)
+ .then(function (video) {
+ // // can be uncommented if you don't want the bot to play live streams
+ // if (video.raw.snippet.liveBroadcastContent === 'live') {
+ // songEmbed.delete();
+ // return msg.say("I don't support live streams!");
+ // }
+
+ // // can be uncommented if you don't want the bot to play videos longer than 1 hour
+ // if (video.duration.hours !== 0) {
+ // songEmbed.delete();
+ // return msg.say('I cannot play videos longer than 1 hour');
+ // }
+
+ // // can be uncommented if you don't want to limit the queue
+ // if (msg.guild.musicData.queue.length > 10) {
+ // songEmbed.delete();
+ // return msg.say(
+ // 'There are too many songs in the queue already, skip or wait a bit'
+ // );
+ // }
+ msg.guild.musicData.queue.push(
+ that.constructSongObj(video, voiceChannel)
+ );
+ if (msg.guild.musicData.isPlaying == false) {
+ msg.guild.musicData.isPlaying = true;
+ if (songEmbed) {
+ songEmbed.delete();
+ }
+ that.playSong(msg.guild.musicData.queue, msg);
+ } else if (msg.guild.musicData.isPlaying == true) {
+ if (songEmbed) {
+ songEmbed.delete();
+ }
+ return msg.say(`${video.title} added to queue ` + emoji.random());
+ }
+ })
+ .catch(function () {
+ if (songEmbed) {
+ songEmbed.delete();
+ }
+ return msg.say(
+ 'an error has occured when trying to get the video id from youtube ' + emoji.random()
+ );
+ });
+ });
+ }
+ playSong(queue, msg) {
+ const classThis = this; // use classThis instead of 'this' because of lexical scope below
+ queue[0].voiceChannel
+ .join()
+ .then(function (connection) {
+ const dispatcher = connection
+ .play(
+ ytdl(queue[0].url, {
+ quality: 'highestaudio',
+ highWaterMark: 1024 * 1024 * 10
+ })
+ )
+ .on('start', function () {
+ msg.guild.musicData.songDispatcher = dispatcher;
+ const volume = 10 / 100;
+ msg.guild.musicData.volume = volume;
+ dispatcher.setVolume(msg.guild.musicData.volume);
+ const videoEmbed = new MessageEmbed()
+ .setThumbnail(queue[0].thumbnail)
+ .setColor(0xF97DAE)
+ .addField('now playing:', queue[0].title)
+ .addField('duration:', queue[0].duration);
+ if (queue[1]) videoEmbed.addField('next song:', queue[1].title);
+ msg.say(videoEmbed);
+ msg.guild.musicData.nowPlaying = queue[0];
+ return queue.shift();
+ })
+ .on('finish', function () {
+ if (queue.length >= 1) {
+ return classThis.playSong(queue, msg);
+ } else {
+ msg.guild.musicData.isPlaying = false;
+ msg.guild.musicData.nowPlaying = null;
+ msg.guild.musicData.songDispatcher = null;
+ return msg.guild.me.voice.channel.leave();
+ }
+ })
+ .on('error', function (e) {
+ msg.say('can\'t play song ' + emoji.random());
+ console.error(e);
+ msg.guild.musicData.queue.length = 0;
+ msg.guild.musicData.isPlaying = false;
+ msg.guild.musicData.nowPlaying = null;
+ msg.guild.musicData.songDispatcher = null;
+ return msg.guild.me.voice.channel.leave();
+ });
+ })
+ .catch(function (e) {
+ console.error(e);
+ return msg.guild.me.voice.channel.leave();
+ });
+ }
+ constructSongObj(video, voiceChannel) {
+ let duration = this.formatDuration(video.duration);
+ if (duration == '00:00') duration = 'live stream';
+ return {
+ url: `https://www.youtube.com/watch?v=${video.raw.id}`,
+ title: video.title,
+ duration,
+ thumbnail: video.thumbnails.high.url,
+ voiceChannel
+ };
+ }
+ // prettier-ignore
+ formatDuration(durationObj) {
+ const duration = `${durationObj.hours ? (durationObj.hours + ':') : ''}${
+ durationObj.minutes ? durationObj.minutes : '00'
+ }:${
+ (durationObj.seconds < 10)
+ ? ('0' + durationObj.seconds)
+ : (durationObj.seconds
+ ? durationObj.seconds
+ : '00')
+ }`;
+ return duration;
+ }
+}; \ No newline at end of file
diff --git a/src/commands/voice/queue.js b/src/commands/voice/queue.js
new file mode 100644
index 0000000..d93de8b
--- /dev/null
+++ b/src/commands/voice/queue.js
@@ -0,0 +1,49 @@
+const { Command } = require('discord.js-commando');
+const { MessageEmbed } = require('discord.js');
+const emoji = require('emoji-random');
+
+module.exports = class QueueVoice extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'queue',
+ aliases: [
+ 'q',
+ 'song-list',
+ 'next-songs',
+ 'songlist',
+ 'nextsongs',
+ 'nextsong',
+ 'next-song'
+ ],
+ group: 'voice',
+ memberName: 'queue',
+ description: 'display song queue',
+ guildOnly: true,
+ examples: [
+ 's5n!queue',
+ 's5n!q',
+ 's5n!songlist',
+ 's5n!song-list',
+ 's5n!nextsong',
+ 's5n!next-song',
+ 's5n!nextsongs',
+ 's5n!next-songs'
+ ]
+ });
+ }
+ run(msg) {
+ if (msg.guild.musicData.queue.length == 0)
+ return msg.say('there are no songs in the queue lol ' + emoji.random());
+ const titleArray = [];
+ msg.guild.musicData.queue.map(obj => {
+ titleArray.push(obj.title);
+ });
+ let queueEmbed = new MessageEmbed()
+ .setColor(0xF97DAE)
+ .setTitle('music queue ' + emoji.random());
+ for (let i = 0; i < titleArray.length; i++) {
+ queueEmbed.addField(`‎`, `**${i + 1}**: ` + `${titleArray[i]}`);
+ }
+ return msg.say(queueEmbed);
+ }
+}; \ No newline at end of file
diff --git a/src/commands/voice/remove.js b/src/commands/voice/remove.js
new file mode 100644
index 0000000..a336ae4
--- /dev/null
+++ b/src/commands/voice/remove.js
@@ -0,0 +1,39 @@
+const { Command } = require('discord.js-commando');
+const emoji = require('emoji-random');
+
+module.exports = class RemoveVoice extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'remove',
+ group: 'voice',
+ memberName: 'remove',
+ description: 'removes a song from the queue',
+ guildOnly: true,
+ args: [
+ {
+ key: 'songNumber',
+ prompt: 'what song u want to remove from q?',
+ type: 'integer'
+ }
+ ],
+ examples: ['s5n!remove 2']
+ });
+ }
+ run(msg, { songNumber }) {
+ if (songNumber < 1 && songNumber >= msg.guild.musicData.queue.length) {
+ return msg.reply('enter a valid song number lol ' + emoji.random());
+ }
+ var voiceChannel = msg.member.voice.channel;
+ if (!voiceChannel) return msg.reply('join a channel and try again lol ' + emoji.random());
+
+ if (
+ typeof msg.guild.musicData.songDispatcher == 'undefined' ||
+ msg.guild.musicData.songDispatcher == null
+ ) {
+ return msg.reply('no songs playing right now lol ' + emoji.random());
+ }
+
+ msg.guild.musicData.queue.splice(songNumber - 1, 1);
+ return msg.say(`removed song **#${songNumber}** from queue ` + emoji.random());
+ }
+}; \ No newline at end of file
diff --git a/src/commands/voice/resume.js b/src/commands/voice/resume.js
new file mode 100644
index 0000000..dfd69f8
--- /dev/null
+++ b/src/commands/voice/resume.js
@@ -0,0 +1,30 @@
+const { Command } = require('discord.js-commando');
+const emoji = require('emoji-random');
+
+module.exports = class ResumeVoice extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'resume',
+ group: 'voice',
+ memberName: 'resume',
+ description: 'resumes music if there is any stopped',
+ guildOnly: true,
+ examples: ['s5n!resume']
+ });
+ }
+ run(msg) {
+ var voiceChannel = msg.member.voice.channel;
+ if (!voiceChannel) return msg.reply('join a channel and try again ') + emoji.random();
+
+ if (
+ typeof msg.guild.musicData.songDispatcher == 'undefined' ||
+ msg.guild.musicData.songDispatcher == null
+ ) {
+ return msg.reply('there isn\'t a song playing right now lol ' + emoji.random());
+ }
+
+ msg.say('song resumed :play_pause:');
+
+ msg.guild.musicData.songDispatcher.resume();
+ }
+}; \ No newline at end of file
diff --git a/src/commands/voice/shuffle.js b/src/commands/voice/shuffle.js
new file mode 100644
index 0000000..3771f16
--- /dev/null
+++ b/src/commands/voice/shuffle.js
@@ -0,0 +1,51 @@
+const { Command } = require('discord.js-commando');
+const { MessageEmbed } = require('discord.js');
+const emoji = require('emoji-random');
+
+module.exports = class ShuffleVoice extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'shuffle',
+ group: 'voice',
+ memberName: 'shuffle',
+ description: 'shuffle the queue',
+ guildOnly: true,
+ examples: ['s5n!shuffle']
+ });
+ }
+ run(msg) {
+ var voiceChannel = msg.member.voice.channel;
+ if (!voiceChannel) return msg.reply('join channel and try again k ' + emoji.random());
+
+ if (
+ typeof msg.guild.musicData.songDispatcher == 'undefined' ||
+ msg.guild.musicData.songDispatcher == null
+ ) {
+ return msg.reply('there is no song playing right now ' + emoji.random());
+ }
+
+ if (msg.guild.musicData.queue.length < 1)
+ return msg.say('There are no songs in queue ' + emoji.random());
+
+ shuffleQueue(msg.guild.musicData.queue);
+
+ const titleArray = [];
+ msg.guild.musicData.queue.map(obj => {
+ titleArray.push(obj.title);
+ });
+ var queueEmbed = new MessageEmbed()
+ .setColor(0xF97DAE)
+ .setTitle('new music q ' + emoji.random());
+ for (let i = 0; i < titleArray.length; i++) {
+ queueEmbed.addField(`${i + 1}:`, `${titleArray[i]}`);
+ }
+ return msg.say(queueEmbed);
+ }
+};
+
+function shuffleQueue(queue) {
+ for (let i = queue.length - 1; i > 0; i--) {
+ const j = Math.floor(Math.random() * (i + 1));
+ [queue[i], queue[j]] = [queue[j], queue[i]];
+ }
+} \ No newline at end of file
diff --git a/src/commands/voice/skip.js b/src/commands/voice/skip.js
new file mode 100644
index 0000000..1bd70cd
--- /dev/null
+++ b/src/commands/voice/skip.js
@@ -0,0 +1,27 @@
+const { Command } = require('discord.js-commando');
+const emoji = require('emoji-random');
+
+module.exports = class SkipVoice extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'skip',
+ group: 'voice',
+ memberName: 'skip',
+ description: 'skip 1 song ahead in the queue',
+ guildOnly: true,
+ examples: ['s5n!skip']
+ });
+ }
+ run(msg) {
+ const voiceChannel = msg.member.voice.channel;
+ if (!voiceChannel) return msg.reply('join a channel and try again ' + emoji.random());
+
+ if (
+ typeof msg.guild.musicData.songDispatcher == 'undefined' ||
+ msg.guild.musicData.songDispatcher == null
+ ) {
+ return msg.reply('no songs playing right now bruh ' + emoji.random());
+ }
+ msg.guild.musicData.songDispatcher.end();
+ }
+}; \ No newline at end of file
diff --git a/src/commands/voice/skipall.js b/src/commands/voice/skipall.js
new file mode 100644
index 0000000..ad4f15e
--- /dev/null
+++ b/src/commands/voice/skipall.js
@@ -0,0 +1,42 @@
+const { Command } = require('discord.js-commando');
+const emoji = require('emoji-random');
+
+module.exports = class SkipAllVoice extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'skipall',
+ aliases: [
+ 'endqueue',
+ 'endq',
+ 'skipqueue',
+ 'skipq'
+ ],
+ group: 'voice',
+ memberName: 'skipall',
+ description: 'skip all songs in the queue',
+ guildOnly: true,
+ examples: [
+ 's5n!endqueue',
+ 's5n!endq',
+ 's5n!skipqueue',
+ 's5n!skipq'
+ ]
+ });
+ }
+ run(msg) {
+ var voiceChannel = msg.member.voice.channel;
+ if (!voiceChannel) return msg.reply('join a channel and try again ' + emoji.random());
+
+ if (
+ typeof msg.guild.musicData.songDispatcher == 'undefined' ||
+ msg.guild.musicData.songDispatcher == null
+ ) {
+ return msg.reply('there is no song playing right now ' + emoji.random());
+ }
+ if (!msg.guild.musicData.queue)
+ return msg.say('there are no songs in queue now >:) ' + emoji.random());
+ msg.guild.musicData.songDispatcher.end();
+ msg.guild.musicData.queue.length = 0; // clear queue
+ return;
+ }
+}; \ No newline at end of file
diff --git a/src/commands/voice/skipto.js b/src/commands/voice/skipto.js
new file mode 100644
index 0000000..65febfd
--- /dev/null
+++ b/src/commands/voice/skipto.js
@@ -0,0 +1,41 @@
+const { Command } = require('discord.js-commando');
+const emoji = require('emoji-random');
+
+module.exports = class SkipToVoice extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'skipto',
+ group: 'voice',
+ memberName: 'skipto',
+ description: 'skip to a certain song in da q >_<',
+ guildOnly: true,
+ args: [{
+ key: 'songNumber',
+ prompt: 'what song u want to skip 2 in da q ???',
+ type: 'integer'
+ }],
+ examples: ['s5n!skipto 5']
+ });
+ }
+ run(msg, { songNumber }) {
+ if (songNumber < 1 && songNumber >= msg.guild.musicData.queue.length) {
+ return msg.reply('enter a valid song number dumb ' + emoji.random());
+ }
+ var voiceChannel = msg.member.voice.channel;
+ if (!voiceChannel) return msg.reply('join channel and try again for cool ' + emoji.random());
+
+ if (
+ typeof msg.guild.musicData.songDispatcher == 'undefined' ||
+ msg.guild.musicData.songDispatcher == null
+ ) {
+ return msg.reply('there is no song playing right now dumby ' + emoji.random());
+ }
+
+ if (msg.guild.musicData.queue < 1)
+ return msg.reply('there are no songs in queue rn ' + emoji.random());
+
+ msg.guild.musicData.queue.splice(0, songNumber - 1);
+ msg.guild.musicData.songDispatcher.end();
+ return;
+ }
+}; \ No newline at end of file
diff --git a/src/commands/voice/squeak.js b/src/commands/voice/squeak.js
new file mode 100644
index 0000000..9d2b6a3
--- /dev/null
+++ b/src/commands/voice/squeak.js
@@ -0,0 +1,29 @@
+const { Command } = require('discord.js-commando');
+const emoji = require('emoji-random');
+
+module.exports = class SqueakVoice extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'squeak',
+ group: 'voice',
+ memberName: 'squeak',
+ description: 'squeak',
+ guildOnly: true,
+ examples: ['s5n!queak']
+ });
+ }
+ async run(msg) {
+ if (msg.member.voice.channel && !msg.guild.voice) {
+ const connection = await msg.member.voice.channel.join();
+ const dispatcher = connection.play('./assets/audio/squeak.wav');
+
+ dispatcher.on('finish', () => {
+ connection.disconnect();
+ });
+ } else if (msg.guild.voice) {
+ msg.reply('i\'m already playing that lol ' + emoji.random());
+ } else {
+ msg.reply('you need to join a voice channel first silly ' + emoji.random());
+ }
+ }
+}; \ No newline at end of file
diff --git a/src/commands/voice/volume.js b/src/commands/voice/volume.js
new file mode 100644
index 0000000..bd5f0b0
--- /dev/null
+++ b/src/commands/voice/volume.js
@@ -0,0 +1,43 @@
+const { Command } = require('discord.js-commando');
+const emoji = require('emoji-random');
+
+module.exports = class VolumeVoice extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'volume',
+ aliases: ['vol'],
+ group: 'voice',
+ memberName: 'volume',
+ description: 'changes volume of audio if playing',
+ guildOnly: true,
+ args: [
+ {
+ key: 'wantedVol',
+ prompt: 'what volume u want, from 1 to 200',
+ type: 'integer',
+ validate: wantedVol => wantedVol >= 1 && wantedVol <= 200
+ }
+ ],
+ examples: [
+ 's5n!volume 20',
+ 's5n!vol 50'
+ ]
+ });
+ }
+ run(msg, { wantedVol }) {
+ var voiceChannel = msg.member.voice.channel;
+ if (!voiceChannel) return msg.reply('join a channel and try again ' + emoji.random());
+
+ if (
+ typeof msg.guild.musicData.songDispatcher == 'undefined' ||
+ msg.guild.musicData.songDispatcher == null
+ ) {
+ return msg.reply('there isn\'t a song playing right now lol ' + emoji.random());
+ }
+
+ const volume = wantedVol / 100;
+ msg.guild.musicData.volume = volume;
+ msg.guild.musicData.songDispatcher.setVolume(volume);
+ msg.reply(`volume is now: **${wantedVol}%** ` + emoji.random());
+ }
+}; \ No newline at end of file
diff --git a/src/commands/voice/wahoo.js b/src/commands/voice/wahoo.js
new file mode 100644
index 0000000..a791795
--- /dev/null
+++ b/src/commands/voice/wahoo.js
@@ -0,0 +1,30 @@
+const { Command } = require('discord.js-commando');
+const emoji = require('emoji-random');
+
+module.exports = class WahooVoice extends Command {
+ constructor(client) {
+ super(client, {
+ name: 'wahoo',
+ aliases: ['mario'],
+ group: 'voice',
+ memberName: 'wahoo',
+ description: 'wahoo',
+ guildOnly: true,
+ examples: ['s5n!wahoo', 's5n!mario']
+ });
+ }
+ async run(msg) {
+ if (msg.member.voice.channel && !msg.guild.voice) {
+ const connection = await msg.member.voice.channel.join();
+ const dispatcher = connection.play('../../assets/audio/wahoo.mp3');
+
+ dispatcher.on('finish', () => {
+ connection.disconnect();
+ });
+ } else if (msg.guild.voice) {
+ msg.reply('i\'m already playing that lol ' + emoji.random());
+ } else {
+ msg.reply('you need to join a voice channel first silly ' + emoji.random());
+ }
+ }
+}; \ No newline at end of file
diff --git a/src/config.json b/src/config.json
new file mode 100644
index 0000000..529615c
--- /dev/null
+++ b/src/config.json
@@ -0,0 +1,4 @@
+{
+ "secret":"Njk1MTA3NTUwNDAzNzU2MTky.XoVXcQ.JqQAhfqtYW-fz5nYCHvo13BjXAM",
+ "yt-api-key":"AIzaSyB9xJENORzZt-GmOGx4WsNCPgKSIxhJcds"
+} \ No newline at end of file