├── .eslintrc.json ├── .gitignore ├── LICENSE.md ├── Procfile ├── README.md ├── Shard.js ├── XiaoBot.js ├── assets ├── fonts │ └── OpenSans.ttf ├── images │ ├── 3000-years.png │ ├── beautiful.png │ ├── bob-ross.png │ ├── card.png │ ├── challenger.png │ ├── dexter.png │ ├── rip.png │ ├── simba.png │ ├── spam.png │ ├── steam-card.png │ ├── triggered.png │ ├── wanted.png │ ├── xiao1.png │ ├── xiao10.png │ ├── xiao2.png │ ├── xiao3.png │ ├── xiao4.png │ ├── xiao5.png │ ├── xiao6.png │ ├── xiao7.png │ ├── xiao8.png │ └── xiao9.png ├── json │ ├── 8-ball.json │ ├── clear-setting.json │ ├── compliment.json │ ├── currency.json │ ├── easter-egg.json │ ├── fact-core.json │ ├── fortune.json │ ├── horoscope.json │ ├── magic-conch.json │ ├── math-game.json │ ├── meme.json │ ├── morse.json │ ├── name.json │ ├── pirate.json │ ├── roast.json │ ├── soundboard.json │ ├── temmie.json │ ├── translate.json │ ├── typing-game.json │ ├── upside-down.json │ └── vocaloid.json └── sounds │ ├── airhorn.mp3 │ ├── cat.mp3 │ ├── dun-dun-dun.mp3 │ ├── pikachu.mp3 │ └── space.mp3 ├── commands ├── avataredit │ ├── 3000-years.js │ ├── beautiful.js │ ├── bob-ross.js │ ├── card.js │ ├── challenger.js │ ├── dexter.js │ ├── greyscale.js │ ├── invert.js │ ├── rip.js │ ├── simba.js │ ├── steam-card.js │ ├── triggered.js │ └── wanted.js ├── games │ ├── battle.js │ ├── lottery.js │ ├── math-game.js │ ├── quiz.js │ ├── rock-paper-scissors.js │ ├── slots.js │ └── typing-game.js ├── guildinfo │ ├── emoji.js │ └── server-info.js ├── moderation │ ├── ban.js │ ├── kick.js │ ├── lockdown.js │ ├── prune.js │ ├── softban.js │ ├── unban.js │ └── warn.js ├── numedit │ ├── currency.js │ ├── math.js │ └── temperature.js ├── random │ ├── cleverbot.js │ ├── easter-egg.js │ ├── give-flower.js │ ├── horoscope.js │ ├── lenny.js │ ├── meme.js │ ├── nitro.js │ ├── pokemon-fusion.js │ ├── soundboard.js │ ├── spam.js │ ├── star.js │ ├── strawpoll.js │ ├── today.js │ └── would-you-rather.js ├── randomimg │ ├── cat.js │ ├── dog.js │ ├── vocaloid.js │ └── xiao.js ├── response │ ├── 8-ball.js │ ├── choose.js │ ├── coin.js │ ├── compliment.js │ ├── fact-core.js │ ├── fishy.js │ ├── fortune.js │ ├── magic-conch.js │ ├── name.js │ ├── offspring.js │ ├── quantum-coin.js │ ├── rate-waifu.js │ ├── roast.js │ ├── roll.js │ ├── roulette.js │ └── ship.js ├── roleplay │ ├── cuddle.js │ ├── divorce.js │ ├── eat.js │ ├── falcon-punch.js │ ├── fist-bump.js │ ├── high-five.js │ ├── hit-with-shovel.js │ ├── hug.js │ ├── inhale.js │ ├── kill.js │ ├── kiss.js │ ├── marry.js │ ├── pat.js │ ├── poke.js │ ├── punch.js │ └── slap.js ├── search │ ├── anime.js │ ├── bot-info.js │ ├── bulbapedia.js │ ├── danbooru.js │ ├── define.js │ ├── discrim.js │ ├── forecast.js │ ├── gelbooru.js │ ├── giphy.js │ ├── github.js │ ├── google.js │ ├── konachan.js │ ├── lmgtfy.js │ ├── manga.js │ ├── map.js │ ├── neopet.js │ ├── osu.js │ ├── rule34.js │ ├── soundcloud.js │ ├── urban.js │ ├── wattpad.js │ ├── weather.js │ ├── wikipedia.js │ ├── xkcd.js │ ├── youtube.js │ └── yu-gi-oh.js ├── settings │ ├── clear-setting.js │ ├── invite-guard.js │ ├── join-role.js │ ├── member-channel.js │ ├── member-message.js │ ├── mod-channel.js │ ├── setting-list.js │ ├── single-role.js │ └── starboard.js ├── textedit │ ├── binary.js │ ├── cow-say.js │ ├── embed.js │ ├── mocking.js │ ├── morse.js │ ├── pirate.js │ ├── repeat.js │ ├── reverse.js │ ├── say.js │ ├── temmie.js │ ├── translate.js │ ├── upside-down.js │ ├── webhook.js │ └── zalgo.js ├── userinfo │ ├── avatar.js │ └── user-info.js └── util │ ├── help.js │ ├── info.js │ ├── invite.js │ ├── ping.js │ ├── shard-info.js │ └── uptime.js ├── html ├── carbondesc.html ├── carbonfeat.html ├── carbonuse.html └── discordbots.html ├── package.json ├── providers └── Sequelize.js ├── structures ├── Command.js ├── CommandoClient.js ├── PostgreSQL.js └── Stats.js └── util └── Util.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Compiled binary addons (http://nodejs.org/api/addons.html) 7 | build/Release 8 | 9 | # Dependency directory 10 | # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git 11 | node_modules 12 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Internet Systems Consortium license 2 | =================================== 3 | 4 | Copyright (c) 2017, dragonfire535 5 | 6 | Permission to use, copy, modify, and/or distribute this software for any purpose 7 | with or without fee is hereby granted, provided that the above copyright notice 8 | and this permission notice appear in all copies. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 11 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 12 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 13 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 14 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 16 | THIS SOFTWARE. 17 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | worker: node Shard.js 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # XiaoBot 2 | [![Discord](https://discordapp.com/api/guilds/252317073814978561/embed.png)](https://discord.gg/fqQF8mc) 3 | [![Codacy](https://api.codacy.com/project/badge/Grade/2be44c0fadf64597b4e07f95d0f6a8ef)](https://www.codacy.com/app/dragonfire535/xiaobot) 4 | 5 | Public Source Code for the Discord Bot XiaoBot, a Discord bot coded in 6 | JavaScript with [discord.js](https://github.com/hydrabolt/discord.js) using the 7 | [Commando](https://github.com/Gawdl3y/discord.js-commando) command framework. 8 | 9 | ## Adding it to Your Server 10 | Visit XiaoBot's page on the Discord Bots list, which is quite fancy, with 11 | [this link](https://bots.discord.pw/bots/278305350804045834). 12 | 13 | ## Home Server 14 | You can join the home server with [this link](https://discord.gg/fqQF8mc). 15 | 16 | ## Licensing 17 | The bot is licensed under an [ISC License](https://opensource.org/licenses/ISC). 18 | See the file `LICENSE.md` for more information. 19 | -------------------------------------------------------------------------------- /Shard.js: -------------------------------------------------------------------------------- 1 | const { ShardingManager } = require('discord.js'); 2 | const { TOKEN } = process.env; 3 | const Manager = new ShardingManager('./XiaoBot.js', { token: TOKEN }); 4 | Manager.spawn(); 5 | -------------------------------------------------------------------------------- /assets/fonts/OpenSans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/fonts/OpenSans.ttf -------------------------------------------------------------------------------- /assets/images/3000-years.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/3000-years.png -------------------------------------------------------------------------------- /assets/images/beautiful.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/beautiful.png -------------------------------------------------------------------------------- /assets/images/bob-ross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/bob-ross.png -------------------------------------------------------------------------------- /assets/images/card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/card.png -------------------------------------------------------------------------------- /assets/images/challenger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/challenger.png -------------------------------------------------------------------------------- /assets/images/dexter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/dexter.png -------------------------------------------------------------------------------- /assets/images/rip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/rip.png -------------------------------------------------------------------------------- /assets/images/simba.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/simba.png -------------------------------------------------------------------------------- /assets/images/spam.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/spam.png -------------------------------------------------------------------------------- /assets/images/steam-card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/steam-card.png -------------------------------------------------------------------------------- /assets/images/triggered.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/triggered.png -------------------------------------------------------------------------------- /assets/images/wanted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/wanted.png -------------------------------------------------------------------------------- /assets/images/xiao1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/xiao1.png -------------------------------------------------------------------------------- /assets/images/xiao10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/xiao10.png -------------------------------------------------------------------------------- /assets/images/xiao2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/xiao2.png -------------------------------------------------------------------------------- /assets/images/xiao3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/xiao3.png -------------------------------------------------------------------------------- /assets/images/xiao4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/xiao4.png -------------------------------------------------------------------------------- /assets/images/xiao5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/xiao5.png -------------------------------------------------------------------------------- /assets/images/xiao6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/xiao6.png -------------------------------------------------------------------------------- /assets/images/xiao7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/xiao7.png -------------------------------------------------------------------------------- /assets/images/xiao8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/xiao8.png -------------------------------------------------------------------------------- /assets/images/xiao9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/images/xiao9.png -------------------------------------------------------------------------------- /assets/json/8-ball.json: -------------------------------------------------------------------------------- 1 | [ 2 | "It is certain", 3 | "It is decidedly so", 4 | "Without a doubt", 5 | "Yes definitely", 6 | "You may rely on it", 7 | "As I see it, yes", 8 | "Most likely", 9 | "Outlook good", 10 | "Yes", 11 | "Signs point to yes", 12 | "Reply hazy try again", 13 | "Ask again later", 14 | "Better not tell you now", 15 | "Cannot predict now", 16 | "Concentrate and ask again", 17 | "Don't count on it", 18 | "My reply is no", 19 | "My sources say no", 20 | "Outlook not so good", 21 | "Very doubtful" 22 | ] 23 | -------------------------------------------------------------------------------- /assets/json/clear-setting.json: -------------------------------------------------------------------------------- 1 | [ 2 | "inviteGuard", 3 | "modLog", 4 | "memberLog", 5 | "joinMsg", 6 | "leaveMsg", 7 | "singleRole", 8 | "joinRole", 9 | "starboard" 10 | ] 11 | -------------------------------------------------------------------------------- /assets/json/currency.json: -------------------------------------------------------------------------------- 1 | [ 2 | "AUD", 3 | "USD", 4 | "BGN", 5 | "BRL", 6 | "CAD", 7 | "CHF", 8 | "CNY", 9 | "CZK", 10 | "DKK", 11 | "GBP", 12 | "HKD", 13 | "HRK", 14 | "HUF", 15 | "IDR", 16 | "ILS", 17 | "INR", 18 | "JPY", 19 | "KRW", 20 | "MXN", 21 | "MYR", 22 | "NOK", 23 | "NZD", 24 | "PHP", 25 | "PLN", 26 | "RON", 27 | "RUB", 28 | "SEK", 29 | "SGD", 30 | "THB", 31 | "TRY", 32 | "ZAR", 33 | "EUR" 34 | ] 35 | -------------------------------------------------------------------------------- /assets/json/easter-egg.json: -------------------------------------------------------------------------------- 1 | { 2 | "if900hp": "All cars unlocked!", 3 | "i'm an easter egg": "You're also an example.", 4 | "not a valid tag": "No, it's not valid at all.", 5 | "tag": "This command is *easter egg*, not *tag* :yum:", 6 | "easter egg": ":egg:", 7 | "snek": "*Blame :snake:*", 8 | "snekfetch": "superagent is better.", 9 | "xiaobot": "That's my name.", 10 | "dragonfire535": "http://dragonfire535.tk", 11 | "heroes of dreamland": "https://www.wattpad.com/story/8712240-heroes-of-dreamland-book-1-kirby-and-the-monstrous", 12 | "neopets": "I got robbed by the pant devil.", 13 | "koneko-chan": "https://i.ytimg.com/vi/YStwTmG4Ex0/hqdefault.jpg", 14 | "shrug": "¯\\_(ツ)_/¯", 15 | "vulcan": ":vulcan:", 16 | "soundboard": "Rest in Peace...", 17 | "me": "You.", 18 | "no u": "no u", 19 | "eat pant": "https://i.redd.it/226fiufo2slx.jpg", 20 | "i never asked for this": "https://cdn.discordapp.com/attachments/252317073814978561/304811008457834516/image.jpg", 21 | "egg": "You're an egg.", 22 | "beta": "https://cdn.discordapp.com/attachments/252317073814978561/304812045851688963/image.jpg", 23 | "pathetic": "https://cdn.discordapp.com/attachments/252317073814978561/304812045851688963/image.jpg", 24 | "swagolor": "https://cdn.discordapp.com/attachments/252317073814978561/306110096491151363/Swagolor.png", 25 | "canyounot": "Can YOU not?", 26 | "slowclap": "*slow clap*", 27 | "just do it": "https://www.youtube.com/watch?v=ZXsQAXx_ao0", 28 | "april": "https://i.imgur.com/c60iG3E.png", 29 | "captain karen": "https://i.imgur.com/8TFq5If.jpg", 30 | "karen": "https://i.imgur.com/a4ZbCiO.png", 31 | "rules": "https://i.imgur.com/PYeFBU5.png", 32 | "book1": "Book.", 33 | "new": "Nope, not quite yet.", 34 | "adam": "Adam pls.", 35 | "token": "[READACTED]", 36 | "nom": "https://cdn.discordapp.com/attachments/256055608279695360/308434352377954304/tumblr_ojzfs3jjoJ1qz64n4o1_540.gif", 37 | "good vs evil": "https://cdn.discordapp.com/attachments/256055608279695360/308404323392684033/837631b64ef351ddabe8c2200c2feca54d81af62_hq.jpg", 38 | "ebearskittychan": "The best :heart:", 39 | "i am your father": "NOOOOOOOOOOOOOO!", 40 | "waifu": "I'm your waifu, right?", 41 | "no": "yes", 42 | "miki": "Pure Evil.", 43 | "pokemon": "Gotta catch 'em all.", 44 | "angery": "https://cdn.discordapp.com/attachments/256055608279695360/308701431165091840/angerey.png", 45 | "banana": "https://cdn.discordapp.com/attachments/256055608279695360/308771979010244618/vfy6JExK7Ryhi.gif", 46 | "yuno gasai": "https://cdn.discordapp.com/attachments/256055608279695360/308658394766508033/ff79c3c19cf7e6fdc00c1c26c204c3f6.jpg" 47 | } 48 | -------------------------------------------------------------------------------- /assets/json/fortune.json: -------------------------------------------------------------------------------- 1 | [ 2 | "Do not seek so much to find the answer as much as to understand the question better.", 3 | "You will soon be honored by someone you respect.", 4 | "Happiness comes from a good life.", 5 | "You are contemplating some action which will bring credit upon you.", 6 | "Be prepared for extra energy.", 7 | "You are admired for your adventurous ways.", 8 | "The love of your life is sitting across from you.", 9 | "Beauty is simply beauty. Originality is magical.", 10 | "Never quit!", 11 | "Today is an ideal time to water your personal garden.", 12 | "Questions provide the key to unlocking our unlimited potential.", 13 | "Expect great things and great things will come.", 14 | "The Greatest War Sometimes Isn't On The Battlefield But Against Oneself.", 15 | "Become who you are.", 16 | "In case of fire, keep calm, pay bill and run.", 17 | "Anyone who dares to be, can never be weak.", 18 | "You broke my cookie!", 19 | "Dream lofty dreams, and as you dream, so shall you become.", 20 | "You've got what it takes, but it will take everything you've got!", 21 | "Trust your intuition.", 22 | "The wise are aware of their treasure, while fools follow their vanity.", 23 | "You will always have good luck in your personal affairs.", 24 | "You don't need talent to gain experience.", 25 | "All the preparation you've done will finally be paying off!", 26 | "Determination is the wake-up call to the human will.", 27 | "The most useless energy is trying to change what and who God so carefully created.", 28 | "You cannot become rich except by enriching others.", 29 | "Your happiness is intertwined with your outlook on life.", 30 | "Sing and rejoice, fortune is smiling on you.", 31 | "Well-arranged time is the surest sign of a well-arranged mind." 32 | ] 33 | -------------------------------------------------------------------------------- /assets/json/horoscope.json: -------------------------------------------------------------------------------- 1 | [ 2 | "capricorn", 3 | "aquarius", 4 | "pisces", 5 | "aries", 6 | "taurus", 7 | "gemini", 8 | "cancer", 9 | "leo", 10 | "virgo", 11 | "libra", 12 | "scorpio", 13 | "sagittarius" 14 | ] 15 | -------------------------------------------------------------------------------- /assets/json/magic-conch.json: -------------------------------------------------------------------------------- 1 | [ 2 | "Maybe someday", 3 | "Nothing", 4 | "Neither", 5 | "I don't think so", 6 | "Yes", 7 | "Try asking again" 8 | ] 9 | -------------------------------------------------------------------------------- /assets/json/math-game.json: -------------------------------------------------------------------------------- 1 | { 2 | "operations": [ 3 | "+", 4 | "-", 5 | "*" 6 | ], 7 | "difficulties": [ 8 | "easy", 9 | "medium", 10 | "hard", 11 | "extreme", 12 | "impossible" 13 | ], 14 | "maxValues": { 15 | "easy": 10, 16 | "medium": 50, 17 | "hard": 100, 18 | "extreme": 1000, 19 | "impossible": 10000 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /assets/json/meme.json: -------------------------------------------------------------------------------- 1 | [ 2 | "tenguy", 3 | "afraid", 4 | "older", 5 | "aag", 6 | "tried", 7 | "biw", 8 | "blb", 9 | "kermit", 10 | "bd", 11 | "ch", 12 | "cbg", 13 | "wonka", 14 | "cb", 15 | "keanu", 16 | "dsm", 17 | "live", 18 | "ants", 19 | "doge", 20 | "alwaysonbeat", 21 | "ermg", 22 | "facepalm", 23 | "fwp", 24 | "fa", 25 | "fbf", 26 | "fry", 27 | "hipster", 28 | "icanhas", 29 | "crazypills", 30 | "mw", 31 | "noidea", 32 | "regret", 33 | "boat", 34 | "hagrid", 35 | "sohappy", 36 | "captain", 37 | "inigo", 38 | "iw", 39 | "ackbar", 40 | "happening", 41 | "joker", 42 | "ive", 43 | "ll", 44 | "morpheus", 45 | "mb", 46 | "badchoice", 47 | "mmm", 48 | "jetpack", 49 | "red", 50 | "mordor", 51 | "oprah", 52 | "oag", 53 | "remembers", 54 | "philosoraptor", 55 | "jw", 56 | "patrick", 57 | "rollsafe", 58 | "sad-obama", 59 | "sad-clinton", 60 | "sadfrog", 61 | "sad-bush", 62 | "sad-biden", 63 | "sad-boehner", 64 | "saltbae", 65 | "sarcasticbear", 66 | "dwight", 67 | "sb", 68 | "ss", 69 | "sf", 70 | "dodgson", 71 | "money", 72 | "sohot", 73 | "nice", 74 | "awesome-awkward", 75 | "awesome", 76 | "awkward-awesome", 77 | "awkward", 78 | "fetch", 79 | "success", 80 | "scc", 81 | "ski", 82 | "officespace", 83 | "interesting", 84 | "toohigh", 85 | "bs", 86 | "center", 87 | "both", 88 | "winter", 89 | "xy", 90 | "buzz", 91 | "yodawg", 92 | "uno", 93 | "yallgot", 94 | "bad", 95 | "elf", 96 | "chosen" 97 | ] 98 | -------------------------------------------------------------------------------- /assets/json/morse.json: -------------------------------------------------------------------------------- 1 | { 2 | "a": ".-", 3 | "b": "-...", 4 | "c": "-.-.", 5 | "d": "-..", 6 | "e": ".", 7 | "f": "..-.", 8 | "g": "--.", 9 | "h": "....", 10 | "i": "..", 11 | "j": ".---", 12 | "k": "-.-", 13 | "l": ".-..", 14 | "m": "--", 15 | "n": "-.", 16 | "o": "---", 17 | "p": ".--.", 18 | "q": "--.-", 19 | "r": ".-.", 20 | "s": "...", 21 | "t": "-", 22 | "u": "..-", 23 | "v": "...-", 24 | "w": ".--", 25 | "x": "-..-", 26 | "y": "-.--", 27 | "z": "--..", 28 | "0": "-----", 29 | "1": ".----", 30 | "2": "..---", 31 | "3": "...--", 32 | "4": "....-", 33 | "5": ".....", 34 | "6": "-....", 35 | "7": "--...", 36 | "8": "---..", 37 | "9": "----.", 38 | ".": ".-.-.-", 39 | "?": "..--..", 40 | ",": "--..--", 41 | "'": ".----." 42 | } 43 | -------------------------------------------------------------------------------- /assets/json/roast.json: -------------------------------------------------------------------------------- 1 | [ 2 | "*puts you in the oven*", 3 | "You're so stupid.", 4 | "Sorry, I can't hear you over how annoying you are.", 5 | "I've got better things to do.", 6 | "You're as dumb as Cleverbot.", 7 | "Your IQ is lower than the Mariana Trench.", 8 | "You're so annoying even the flies stay away from your stench.", 9 | "Go away, please.", 10 | "I'd give you a nasty look but you've already got one.", 11 | "It looks like your face caught fire and someone tried to put it out with a hammer.", 12 | "Your family tree must be a cactus because everyone on it is a prick.", 13 | "Someday you will go far, and I hope you stay there.", 14 | "The zoo called. They're wondering how you got out of your cage.", 15 | "I was hoping for a battle of wits, but you appear to be unarmed.", 16 | "You are proof that evolution can go in reverse.", 17 | "Brains aren't everything, in your case, they're nothing.", 18 | "Sorry I didn't get that, I don't speak idiot.", 19 | "Why is it acceptable for you to be an idiot, but not for me to point it out?", 20 | "We all sprang from apes, but you did not spring far enough.", 21 | "You're an unknown command.", 22 | "If you could go anywhere I chose, I'd choose dead.", 23 | "Even monkeys can go to space, so clearly you lack some potential.", 24 | "It's brains over brawn, yet you have neither.", 25 | "You look like a monkey, and you smell like one too.", 26 | "Even among idiots you're lacking.", 27 | "You fail even when you're doing absolutely nothing.", 28 | "If there was a vote for 'least likely to succeed' you'd win first prize.", 29 | "I'm surrounded by idiots... Or, wait, that's just you.", 30 | "I wanna go home. Well, really I just want to get away from the awful aroma you've got going there.", 31 | "Every time you touch me I have to go home and wash all my clothes nine times just to get a normal smell back.", 32 | "If I had a dollar for every brain you don't have, I'd have one dollar.", 33 | "I'd help you succeed but you're incapable.", 34 | "Your hairline is built like a graph chart, positive and negative forces attract but the clippers and your hair repel", 35 | "I know a good joke! You!" 36 | ] 37 | -------------------------------------------------------------------------------- /assets/json/soundboard.json: -------------------------------------------------------------------------------- 1 | { 2 | "names": [ 3 | "airhorn", 4 | "cat", 5 | "dun dun dun", 6 | "pikachu", 7 | "space" 8 | ], 9 | "paths": { 10 | "airhorn": "airhorn.mp3", 11 | "cat": "cat.mp3", 12 | "dun dun dun": "dun-dun-dun.mp3", 13 | "pikachu": "pikachu.mp3", 14 | "space": "space.mp3" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /assets/json/translate.json: -------------------------------------------------------------------------------- 1 | { 2 | "az": "Azerbaijan", 3 | "sq": "Albanian", 4 | "am": "Amharic", 5 | "en": "English", 6 | "ar": "Arabic", 7 | "hy": "Armenian", 8 | "af": "Afrikaans", 9 | "eu": "Basque", 10 | "ba": "Bashkir", 11 | "be": "Belarusian", 12 | "bn": "Bengali", 13 | "my": "Burmese", 14 | "bg": "Bulgarian", 15 | "bs": "Bosnian", 16 | "cy": "Welsh", 17 | "hu": "Hungarian", 18 | "vi": "Vietnamese", 19 | "ht": "Haitian (Creole)", 20 | "gl": "Galician", 21 | "nl": "Dutch", 22 | "mrj": "Hill Mari", 23 | "el": "Greek", 24 | "ka": "Georgian", 25 | "gu": "Gujarati", 26 | "da": "Danish", 27 | "he": "Hebrew", 28 | "yi": "Yiddish", 29 | "id": "Indonesian", 30 | "ga": "Irish", 31 | "it": "Italian", 32 | "is": "Icelandic", 33 | "es": "Spanish", 34 | "kk": "Kazakh", 35 | "kn": "Kannada", 36 | "ca": "Catalan", 37 | "ky": "Kyrgyz", 38 | "zh": "Chinese", 39 | "ko": "Korean", 40 | "xh": "Xhosa", 41 | "km": "Khmer", 42 | "lo": "Laotian", 43 | "la": "Latin", 44 | "lv": "Latvian", 45 | "lt": "Lithuanian", 46 | "lb": "Luxembourgish", 47 | "mg": "Malagasy", 48 | "ms": "Malay", 49 | "ml": "Malayalam", 50 | "mt": "Maltese", 51 | "mk": "Macedonian", 52 | "mi": "Maori", 53 | "mr": "Marathi", 54 | "mhr": "Mari", 55 | "mn": "Mongolian", 56 | "de": "German", 57 | "ne": "Nepali", 58 | "no": "Norwegian", 59 | "pa": "Punjabi", 60 | "pap": "Papiamento", 61 | "fa": "Persian", 62 | "pl": "Polish", 63 | "pt": "Portuguese", 64 | "ro": "Romanian", 65 | "ru": "Russian", 66 | "ceb": "Cebuano", 67 | "sr": "Serbian", 68 | "si": "Sinhala", 69 | "sk": "Slovakian", 70 | "sl": "Slovenian", 71 | "sw": "Swahili", 72 | "su": "Sundanese", 73 | "tg": "Tajik", 74 | "th": "Thai", 75 | "tl": "Tagalog", 76 | "ta": "Tamil", 77 | "tt": "Tatar", 78 | "te": "Telugu", 79 | "tr": "Turkish", 80 | "udm": "Udmurt", 81 | "uz": "Uzbek", 82 | "uk": "Ukranian", 83 | "ur": "Urdu", 84 | "fi": "Finnish", 85 | "fr": "French", 86 | "hi": "Hindi", 87 | "hr": "Croatian", 88 | "cs": "Czech", 89 | "sv": "Swedish", 90 | "gd": "Scottish", 91 | "et": "Estonian", 92 | "eo": "Esperanto", 93 | "jv": "Javanese", 94 | "ja": "Japanese" 95 | } 96 | -------------------------------------------------------------------------------- /assets/json/upside-down.json: -------------------------------------------------------------------------------- 1 | { 2 | "a": "ɐ", 3 | "b": "q", 4 | "c": "ɔ", 5 | "d": "p", 6 | "e": "ǝ", 7 | "f": "ɟ", 8 | "g": "ƃ", 9 | "h": "ɥ", 10 | "i": "ᴉ", 11 | "j": "ɾ", 12 | "k": "ʞ", 13 | "m": "ɯ", 14 | "n": "u", 15 | "p": "d", 16 | "q": "b", 17 | "r": "ɹ", 18 | "t": "ʇ", 19 | "u": "n", 20 | "v": "ʌ", 21 | "w": "ʍ", 22 | "y": "ʎ", 23 | "A": "∀", 24 | "C": "Ɔ", 25 | "E": "Ǝ", 26 | "F": "Ⅎ", 27 | "G": "פ", 28 | "J": "ſ", 29 | "L": "˥", 30 | "M": "W", 31 | "P": "Ԁ", 32 | "T": "┴", 33 | "U": "∩", 34 | "V": "Λ", 35 | "W": "M", 36 | "Y": "⅄", 37 | "1": "Ɩ", 38 | "2": "ᄅ", 39 | "3": "Ɛ", 40 | "4": "ㄣ", 41 | "5": "ϛ", 42 | "6": "9", 43 | "7": "ㄥ", 44 | "9": "6", 45 | ",": "'", 46 | ".": "˙", 47 | "'": ",", 48 | "\"": ",,", 49 | "_": "‾", 50 | "&": "⅋", 51 | "!": "¡", 52 | "?": "¿", 53 | "`": "," 54 | } 55 | -------------------------------------------------------------------------------- /assets/json/vocaloid.json: -------------------------------------------------------------------------------- 1 | [ 2 | "https://www.youtube.com/watch?v=ebAKoRcYFTA", 3 | "https://www.youtube.com/watch?v=Mqps4anhz0Q", 4 | "https://www.youtube.com/watch?v=AUEiHQOCQ2M", 5 | "https://www.youtube.com/watch?v=oyteTOBxRm8", 6 | "https://www.youtube.com/watch?v=uwwU55zBYlQ", 7 | "https://www.youtube.com/watch?v=sSYoz0JmnZo", 8 | "https://www.youtube.com/watch?v=NpU4dsXW6EI", 9 | "https://www.youtube.com/watch?v=MzyXD8bNbvk", 10 | "https://www.youtube.com/watch?v=hyV4qGAPKac", 11 | "https://www.youtube.com/watch?v=pywNi6gD1FA", 12 | "https://www.youtube.com/watch?v=17FEtaiWdVg", 13 | "https://www.youtube.com/watch?v=fmrA-gxJxgQ", 14 | "https://www.youtube.com/watch?v=yOBWgSPrYVA", 15 | "https://www.youtube.com/watch?v=nCaqf9WhqOY", 16 | "https://www.youtube.com/watch?v=cQKGUgOfD8U", 17 | "https://www.youtube.com/watch?v=sK92X82T3Sk", 18 | "https://www.youtube.com/watch?v=AH5_sKwDw1E", 19 | "https://www.youtube.com/watch?v=dw-KJNqcK-Q", 20 | "https://www.youtube.com/watch?v=X47JmmqbMvc", 21 | "https://www.youtube.com/watch?v=ojQPpYVQt7U", 22 | "https://www.amazon.com/Gogatsu-Yamai-feat-Kagamine-Len/dp/B00P1BG27S", 23 | "https://www.youtube.com/watch?v=N1-Z8uslIsI", 24 | "https://www.youtube.com/watch?v=EAgk-t2zzqw", 25 | "https://www.youtube.com/watch?v=uLBC2kWYFo8", 26 | "https://www.youtube.com/watch?v=OXHYIlkZLUU", 27 | "https://www.youtube.com/watch?v=ObIa9wXbyMQ", 28 | "https://www.youtube.com/watch?v=dGNoCICGmo0", 29 | "https://www.youtube.com/watch?v=LcoyEZkTKfY", 30 | "https://www.youtube.com/watch?v=mKHaW0qd5Mw", 31 | "https://www.youtube.com/watch?v=GG627DYk_E4", 32 | "https://www.youtube.com/watch?v=jTm6Q5Pj_Jo", 33 | "https://www.youtube.com/watch?v=TVeIDmk3rBo", 34 | "https://www.youtube.com/watch?v=1K3in6w9tt4", 35 | "https://www.youtube.com/watch?v=07r67gGbtLQ", 36 | "https://www.youtube.com/watch?v=243vPl8HdVk", 37 | "https://www.youtube.com/watch?v=zweVJrnE1uY", 38 | "https://www.youtube.com/watch?v=RKtoreimcQ8", 39 | "https://www.youtube.com/watch?v=Je6dCVfHvkU", 40 | "https://www.youtube.com/watch?v=UxFv12y_evM", 41 | "https://www.youtube.com/watch?v=2HegQtmJeto", 42 | "https://www.youtube.com/watch?v=8-Epnpruww0" 43 | ] 44 | -------------------------------------------------------------------------------- /assets/sounds/airhorn.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/sounds/airhorn.mp3 -------------------------------------------------------------------------------- /assets/sounds/cat.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/sounds/cat.mp3 -------------------------------------------------------------------------------- /assets/sounds/dun-dun-dun.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/sounds/dun-dun-dun.mp3 -------------------------------------------------------------------------------- /assets/sounds/pikachu.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/sounds/pikachu.mp3 -------------------------------------------------------------------------------- /assets/sounds/space.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fuseteam/xiaobot/6ed703b51ff162fea8eb8eca7e2ef0f1bfa0fd6d/assets/sounds/space.mp3 -------------------------------------------------------------------------------- /commands/avataredit/3000-years.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const Canvas = require('canvas'); 3 | const snekfetch = require('snekfetch'); 4 | const { promisifyAll } = require('tsubaki'); 5 | const fs = promisifyAll(require('fs')); 6 | const path = require('path'); 7 | 8 | module.exports = class YearsCommand extends Command { 9 | constructor(client) { 10 | super(client, { 11 | name: '3000-years', 12 | aliases: ['az'], 13 | group: 'avataredit', 14 | memberName: '3000-years', 15 | description: 'It\'s been 3000 years...', 16 | throttling: { 17 | usages: 1, 18 | duration: 15 19 | }, 20 | clientPermissions: ['ATTACH_FILES'], 21 | args: [ 22 | { 23 | key: 'user', 24 | prompt: 'Which user would you like to edit the avatar of?', 25 | type: 'user', 26 | default: '' 27 | } 28 | ] 29 | }); 30 | } 31 | 32 | async run(msg, args) { 33 | const user = args.user || msg.author; 34 | const avatarURL = user.avatarURL('png', 256); 35 | if (!avatarURL) return msg.say('The User Provided has No Avatar.'); 36 | const Image = Canvas.Image; 37 | const canvas = new Canvas(856, 569); 38 | const ctx = canvas.getContext('2d'); 39 | const base = new Image(); 40 | const avatar = new Image(); 41 | const generate = () => { 42 | ctx.drawImage(base, 0, 0); 43 | ctx.drawImage(avatar, 461, 127, 200, 200); 44 | }; 45 | base.src = await fs.readFileAsync(path.join(__dirname, '..', '..', 'assets', 'images', '3000-years.png')); 46 | const { body } = await snekfetch.get(avatarURL); 47 | avatar.src = body; 48 | generate(); 49 | return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'az.png' }] }); 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /commands/avataredit/beautiful.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const Canvas = require('canvas'); 3 | const snekfetch = require('snekfetch'); 4 | const { promisifyAll } = require('tsubaki'); 5 | const fs = promisifyAll(require('fs')); 6 | const path = require('path'); 7 | 8 | module.exports = class BeautifulCommand extends Command { 9 | constructor(client) { 10 | super(client, { 11 | name: 'beautiful', 12 | aliases: ['grunkle-stan'], 13 | group: 'avataredit', 14 | memberName: 'beautiful', 15 | description: 'Oh, this? This is beautiful.', 16 | throttling: { 17 | usages: 1, 18 | duration: 15 19 | }, 20 | clientPermissions: ['ATTACH_FILES'], 21 | args: [ 22 | { 23 | key: 'user', 24 | prompt: 'Which user would you like to edit the avatar of?', 25 | type: 'user', 26 | default: '' 27 | } 28 | ] 29 | }); 30 | } 31 | 32 | async run(msg, args) { 33 | const user = args.user || msg.author; 34 | const avatarURL = user.avatarURL('png', 256); 35 | if (!avatarURL) return msg.say('The User Provided has No Avatar.'); 36 | const Image = Canvas.Image; 37 | const canvas = new Canvas(500, 532); 38 | const ctx = canvas.getContext('2d'); 39 | const base = new Image(); 40 | const avatar = new Image(); 41 | const generate = () => { 42 | ctx.drawImage(base, 0, 0); 43 | ctx.drawImage(avatar, 341, 35, 117, 135); 44 | ctx.drawImage(avatar, 343, 301, 117, 135); 45 | }; 46 | base.src = await fs.readFileAsync(path.join(__dirname, '..', '..', 'assets', 'images', 'beautiful.png')); 47 | const { body } = await snekfetch.get(avatarURL); 48 | avatar.src = body; 49 | generate(); 50 | return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'grunkle.png' }] }); 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /commands/avataredit/bob-ross.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const Canvas = require('canvas'); 3 | const snekfetch = require('snekfetch'); 4 | const { promisifyAll } = require('tsubaki'); 5 | const fs = promisifyAll(require('fs')); 6 | const path = require('path'); 7 | 8 | module.exports = class BobRossCommand extends Command { 9 | constructor(client) { 10 | super(client, { 11 | name: 'bob-ross', 12 | aliases: ['ross'], 13 | group: 'avataredit', 14 | memberName: 'bob-ross', 15 | description: 'Make Bob Ross draw an avatar.', 16 | throttling: { 17 | usages: 1, 18 | duration: 15 19 | }, 20 | clientPermissions: ['ATTACH_FILES'], 21 | args: [ 22 | { 23 | key: 'user', 24 | prompt: 'Which user would you like to edit the avatar of?', 25 | type: 'user', 26 | default: '' 27 | } 28 | ] 29 | }); 30 | } 31 | 32 | async run(msg, args) { 33 | const user = args.user || msg.author; 34 | const avatarURL = user.avatarURL('png', 256); 35 | if (!avatarURL) return msg.say('The User Provided has No Avatar.'); 36 | const Image = Canvas.Image; 37 | const canvas = new Canvas(600, 775); 38 | const ctx = canvas.getContext('2d'); 39 | const base = new Image(); 40 | const avatar = new Image(); 41 | const generate = () => { 42 | ctx.fillStyle = 'white'; 43 | ctx.fillRect(0, 0, 600, 775); 44 | ctx.rotate(3 * Math.PI / 180); 45 | ctx.drawImage(avatar, 69, 102, 256, 256); 46 | ctx.rotate(-3 * Math.PI / 180); 47 | ctx.drawImage(base, 0, 0); 48 | }; 49 | base.src = await fs.readFileAsync(path.join(__dirname, '..', '..', 'assets', 'images', 'bob-ross.png')); 50 | const { body } = await snekfetch.get(avatarURL); 51 | avatar.src = body; 52 | generate(); 53 | return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'ross.png' }] }); 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /commands/avataredit/challenger.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const Canvas = require('canvas'); 3 | const snekfetch = require('snekfetch'); 4 | const { promisifyAll } = require('tsubaki'); 5 | const fs = promisifyAll(require('fs')); 6 | const path = require('path'); 7 | 8 | module.exports = class ChallengerCommand extends Command { 9 | constructor(client) { 10 | super(client, { 11 | name: 'challenger', 12 | group: 'avataredit', 13 | memberName: 'challenger', 14 | description: 'A new foe has appeared.', 15 | throttling: { 16 | usages: 1, 17 | duration: 15 18 | }, 19 | clientPermissions: ['ATTACH_FILES'], 20 | args: [ 21 | { 22 | key: 'user', 23 | prompt: 'Which user would you like to edit the avatar of?', 24 | type: 'user', 25 | default: '' 26 | } 27 | ] 28 | }); 29 | } 30 | 31 | async run(msg, args) { 32 | const user = args.user || msg.author; 33 | const avatarURL = user.avatarURL('png', 256); 34 | if (!avatarURL) return msg.say('The User Provided has No Avatar.'); 35 | const Image = Canvas.Image; 36 | const canvas = new Canvas(500, 500); 37 | const ctx = canvas.getContext('2d'); 38 | const base = new Image(); 39 | const avatar = new Image(); 40 | const generate = () => { 41 | ctx.fillStyle = '#ff0028'; 42 | ctx.fillRect(0, 0, 500, 500); 43 | ctx.drawImage(avatar, 226, 155, 200, 200); 44 | ctx.drawImage(base, 0, 0); 45 | }; 46 | base.src = await fs.readFileAsync(path.join(__dirname, '..', '..', 'assets', 'images', 'challenger.png')); 47 | const { body } = await snekfetch.get(avatarURL); 48 | avatar.src = body; 49 | generate(); 50 | return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'challenger.png' }] }); 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /commands/avataredit/dexter.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const Canvas = require('canvas'); 3 | const snekfetch = require('snekfetch'); 4 | const { promisifyAll } = require('tsubaki'); 5 | const fs = promisifyAll(require('fs')); 6 | const path = require('path'); 7 | 8 | module.exports = class DexterCommand extends Command { 9 | constructor(client) { 10 | super(client, { 11 | name: 'dexter', 12 | group: 'avataredit', 13 | memberName: 'dexter', 14 | description: 'Who\'s that pokemon?', 15 | throttling: { 16 | usages: 1, 17 | duration: 15 18 | }, 19 | clientPermissions: ['ATTACH_FILES'], 20 | args: [ 21 | { 22 | key: 'user', 23 | prompt: 'Which user would you like to edit the avatar of?', 24 | type: 'user', 25 | default: '' 26 | } 27 | ] 28 | }); 29 | } 30 | 31 | async run(msg, args) { 32 | const user = args.user || msg.author; 33 | const avatarURL = user.avatarURL('png', 256); 34 | if (!avatarURL) return msg.say('The User Provided has No Avatar.'); 35 | const Image = Canvas.Image; 36 | const canvas = new Canvas(744, 554); 37 | const ctx = canvas.getContext('2d'); 38 | const base = new Image(); 39 | const avatar = new Image(); 40 | const generate = () => { 41 | ctx.drawImage(base, 0, 0); 42 | ctx.rotate(-11 * Math.PI / 180); 43 | ctx.drawImage(avatar, 234, 274, 225, 225); 44 | ctx.rotate(11 * Math.PI / 180); 45 | }; 46 | base.src = await fs.readFileAsync(path.join(__dirname, '..', '..', 'assets', 'images', 'dexter.png')); 47 | const { body } = await snekfetch.get(avatarURL); 48 | avatar.src = body; 49 | generate(); 50 | return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'dexter.png' }] }); 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /commands/avataredit/greyscale.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const Canvas = require('canvas'); 3 | const snekfetch = require('snekfetch'); 4 | 5 | module.exports = class GreyscaleCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'greyscale', 9 | aliases: ['grayscale'], 10 | group: 'avataredit', 11 | memberName: 'greyscale', 12 | description: 'Greyscale a user\'s avatar colors.', 13 | throttling: { 14 | usages: 1, 15 | duration: 15 16 | }, 17 | clientPermissions: ['ATTACH_FILES'], 18 | args: [ 19 | { 20 | key: 'user', 21 | prompt: 'Which user would you like to edit the avatar of?', 22 | type: 'user', 23 | default: '' 24 | } 25 | ] 26 | }); 27 | } 28 | 29 | async run(msg, args) { 30 | const user = args.user || msg.author; 31 | const avatarURL = user.avatarURL('png', 256); 32 | if (!avatarURL) return msg.say('The User Provided has No Avatar.'); 33 | const Image = Canvas.Image; 34 | const canvas = new Canvas(256, 256); 35 | const ctx = canvas.getContext('2d'); 36 | const avatar = new Image(); 37 | const generate = () => { 38 | ctx.drawImage(avatar, 0, 0, 256, 256); 39 | const imgData = ctx.getImageData(0, 0, 256, 256); 40 | const { data } = imgData; 41 | for (let i = 0; i < data.length; i += 4) { 42 | const brightness = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2]; 43 | data[i] = brightness; 44 | data[i + 1] = brightness; 45 | data[i + 2] = brightness; 46 | } 47 | ctx.putImageData(imgData, 0, 0); 48 | }; 49 | const { body } = await snekfetch.get(avatarURL); 50 | avatar.src = body; 51 | generate(); 52 | return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'greyscale.png' }] }); 53 | } 54 | }; 55 | -------------------------------------------------------------------------------- /commands/avataredit/invert.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const Canvas = require('canvas'); 3 | const snekfetch = require('snekfetch'); 4 | 5 | module.exports = class InvertCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'invert', 9 | group: 'avataredit', 10 | memberName: 'invert', 11 | description: 'Invert a user\'s avatar colors.', 12 | throttling: { 13 | usages: 1, 14 | duration: 15 15 | }, 16 | clientPermissions: ['ATTACH_FILES'], 17 | args: [ 18 | { 19 | key: 'user', 20 | prompt: 'Which user would you like to edit the avatar of?', 21 | type: 'user', 22 | default: '' 23 | } 24 | ] 25 | }); 26 | } 27 | 28 | async run(msg, args) { 29 | const user = args.user || msg.author; 30 | const avatarURL = user.avatarURL('png', 256); 31 | if (!avatarURL) return msg.say('The User Provided has No Avatar.'); 32 | const Image = Canvas.Image; 33 | const canvas = new Canvas(256, 256); 34 | const ctx = canvas.getContext('2d'); 35 | const avatar = new Image(); 36 | const generate = () => { 37 | ctx.drawImage(avatar, 0, 0, 256, 256); 38 | const imgData = ctx.getImageData(0, 0, 256, 256); 39 | const { data } = imgData; 40 | for (let i = 0; i < data.length; i += 4) { 41 | data[i] = 255 - data[i]; 42 | data[i + 1] = 255 - data[i + 1]; 43 | data[i + 2] = 255 - data[i + 2]; 44 | } 45 | ctx.putImageData(imgData, 0, 0); 46 | }; 47 | const { body } = await snekfetch.get(avatarURL); 48 | avatar.src = body; 49 | generate(); 50 | return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'invert.png' }] }); 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /commands/avataredit/rip.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const Canvas = require('canvas'); 3 | const snekfetch = require('snekfetch'); 4 | const { promisifyAll } = require('tsubaki'); 5 | const fs = promisifyAll(require('fs')); 6 | const path = require('path'); 7 | 8 | module.exports = class RIPCommand extends Command { 9 | constructor(client) { 10 | super(client, { 11 | name: 'rip', 12 | aliases: ['grave', 'grave-stone'], 13 | group: 'avataredit', 14 | memberName: 'rip', 15 | description: 'Puts a user\'s avatar over a gravestone.', 16 | throttling: { 17 | usages: 1, 18 | duration: 15 19 | }, 20 | clientPermissions: ['ATTACH_FILES'], 21 | args: [ 22 | { 23 | key: 'user', 24 | prompt: 'Which user would you like to edit the avatar of?', 25 | type: 'user', 26 | default: '' 27 | } 28 | ] 29 | }); 30 | } 31 | 32 | async run(msg, args) { 33 | const user = args.user || msg.author; 34 | const avatarURL = user.avatarURL('png', 256); 35 | if (!avatarURL) return msg.say('The User Provided has No Avatar.'); 36 | const Image = Canvas.Image; 37 | const canvas = new Canvas(507, 338); 38 | const ctx = canvas.getContext('2d'); 39 | const base = new Image(); 40 | const avatar = new Image(); 41 | const generate = () => { 42 | ctx.drawImage(base, 0, 0); 43 | ctx.drawImage(avatar, 158, 51, 200, 200); 44 | const imgData = ctx.getImageData(158, 51, 200, 200); 45 | const { data } = imgData; 46 | for (let i = 0; i < data.length; i += 4) { 47 | const brightness = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2]; 48 | data[i] = brightness; 49 | data[i + 1] = brightness; 50 | data[i + 2] = brightness; 51 | } 52 | ctx.putImageData(imgData, 158, 51); 53 | }; 54 | base.src = await fs.readFileAsync(path.join(__dirname, '..', '..', 'assets', 'images', 'rip.png')); 55 | const { body } = await snekfetch.get(avatarURL); 56 | avatar.src = body; 57 | generate(); 58 | return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'rip.png' }] }); 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /commands/avataredit/simba.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const Canvas = require('canvas'); 3 | const snekfetch = require('snekfetch'); 4 | const { promisifyAll } = require('tsubaki'); 5 | const fs = promisifyAll(require('fs')); 6 | const path = require('path'); 7 | 8 | module.exports = class SimbaCommand extends Command { 9 | constructor(client) { 10 | super(client, { 11 | name: 'simba', 12 | group: 'avataredit', 13 | memberName: 'simba', 14 | description: 'Remember who you are...', 15 | throttling: { 16 | usages: 1, 17 | duration: 15 18 | }, 19 | clientPermissions: ['ATTACH_FILES'], 20 | args: [ 21 | { 22 | key: 'user', 23 | prompt: 'Which user would you like to edit the avatar of?', 24 | type: 'user', 25 | default: '' 26 | } 27 | ] 28 | }); 29 | } 30 | 31 | async run(msg, args) { 32 | const user = args.user || msg.author; 33 | const avatarURL = user.avatarURL('png', 256); 34 | if (!avatarURL) return msg.say('The User Provided has No Avatar.'); 35 | const Image = Canvas.Image; 36 | const canvas = new Canvas(500, 281); 37 | const ctx = canvas.getContext('2d'); 38 | const base = new Image(); 39 | const avatar = new Image(); 40 | const generate = () => { 41 | ctx.drawImage(base, 0, 0); 42 | ctx.rotate(-24 * Math.PI / 180); 43 | ctx.drawImage(avatar, 75, 160, 130, 150); 44 | ctx.rotate(24 * Math.PI / 180); 45 | }; 46 | base.src = await fs.readFileAsync(path.join(__dirname, '..', '..', 'assets', 'images', 'simba.png')); 47 | const { body } = await snekfetch.get(avatarURL); 48 | avatar.src = body; 49 | generate(); 50 | return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'simba.png' }] }); 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /commands/avataredit/steam-card.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const Canvas = require('canvas'); 3 | const snekfetch = require('snekfetch'); 4 | const { promisifyAll } = require('tsubaki'); 5 | const fs = promisifyAll(require('fs')); 6 | const path = require('path'); 7 | 8 | module.exports = class SteamCardCommand extends Command { 9 | constructor(client) { 10 | super(client, { 11 | name: 'steam-card', 12 | group: 'avataredit', 13 | memberName: 'steam-card', 14 | description: 'Put an avatar on a Steam Card.', 15 | throttling: { 16 | usages: 1, 17 | duration: 15 18 | }, 19 | clientPermissions: ['ATTACH_FILES'], 20 | args: [ 21 | { 22 | key: 'user', 23 | prompt: 'Which user would you like to edit the avatar of?', 24 | type: 'user', 25 | default: '' 26 | } 27 | ] 28 | }); 29 | } 30 | 31 | async run(msg, args) { 32 | const user = args.user || msg.author; 33 | const avatarURL = user.avatarURL('png', 512); 34 | if (!avatarURL) return msg.say('The User Provided has No Avatar.'); 35 | const Image = Canvas.Image; 36 | Canvas.registerFont(path.join(__dirname, '..', '..', 'assets', 'fonts', 'OpenSans.ttf'), { family: 'Open Sans' }); // eslint-disable-line max-len 37 | const canvas = new Canvas(494, 568); 38 | const ctx = canvas.getContext('2d'); 39 | const base = new Image(); 40 | const avatar = new Image(); 41 | const generate = () => { 42 | ctx.fillStyle = 'white'; 43 | ctx.fillRect(0, 0, 494, 568); 44 | ctx.drawImage(avatar, 25, 25, 450, 450); 45 | ctx.drawImage(base, 0, 0); 46 | ctx.font = '30px Open Sans'; 47 | ctx.fillText(user.username, 35, 48); 48 | }; 49 | base.src = await fs.readFileAsync(path.join(__dirname, '..', '..', 'assets', 'images', 'steam-card.png')); 50 | const { body } = await snekfetch.get(avatarURL); 51 | avatar.src = body; 52 | generate(); 53 | return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'steam.png' }] }); 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /commands/avataredit/triggered.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const Canvas = require('canvas'); 3 | const snekfetch = require('snekfetch'); 4 | const { promisifyAll } = require('tsubaki'); 5 | const fs = promisifyAll(require('fs')); 6 | const path = require('path'); 7 | 8 | module.exports = class TriggeredCommand extends Command { 9 | constructor(client) { 10 | super(client, { 11 | name: 'triggered', 12 | group: 'avataredit', 13 | memberName: 'triggered', 14 | description: 'Put an avatar on a "Triggered" sign.', 15 | throttling: { 16 | usages: 1, 17 | duration: 15 18 | }, 19 | clientPermissions: ['ATTACH_FILES'], 20 | args: [ 21 | { 22 | key: 'user', 23 | prompt: 'Which user would you like to edit the avatar of?', 24 | type: 'user', 25 | default: '' 26 | } 27 | ] 28 | }); 29 | } 30 | 31 | async run(msg, args) { 32 | const user = args.user || msg.author; 33 | const avatarURL = user.avatarURL('png', 512); 34 | if (!avatarURL) return msg.say('The User Provided has No Avatar.'); 35 | const Image = Canvas.Image; 36 | const canvas = new Canvas(320, 371); 37 | const ctx = canvas.getContext('2d'); 38 | const base = new Image(); 39 | const avatar = new Image(); 40 | const generate = () => { 41 | ctx.fillStyle = 'white'; 42 | ctx.fillRect(0, 0, 320, 371); 43 | ctx.drawImage(avatar, 0, 0, 320, 320); 44 | const imgData = ctx.getImageData(0, 0, 320, 320); 45 | const { data } = imgData; 46 | for (let i = 0; i < data.length; i += 4) data[i] = Math.max(255, data[i]); 47 | ctx.putImageData(imgData, 0, 0); 48 | ctx.drawImage(base, 0, 0); 49 | }; 50 | base.src = await fs.readFileAsync(path.join(__dirname, '..', '..', 'assets', 'images', 'triggered.png')); 51 | const { body } = await snekfetch.get(avatarURL); 52 | avatar.src = body; 53 | generate(); 54 | return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'triggered.png' }] }); 55 | } 56 | }; 57 | -------------------------------------------------------------------------------- /commands/avataredit/wanted.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const Canvas = require('canvas'); 3 | const snekfetch = require('snekfetch'); 4 | const { promisifyAll } = require('tsubaki'); 5 | const fs = promisifyAll(require('fs')); 6 | const path = require('path'); 7 | 8 | module.exports = class WantedCommand extends Command { 9 | constructor(client) { 10 | super(client, { 11 | name: 'wanted', 12 | group: 'avataredit', 13 | memberName: 'wanted', 14 | description: 'Puts an avatar on a wanted poster.', 15 | throttling: { 16 | usages: 1, 17 | duration: 15 18 | }, 19 | clientPermissions: ['ATTACH_FILES'], 20 | args: [ 21 | { 22 | key: 'user', 23 | prompt: 'Which user would you like to edit the avatar of?', 24 | type: 'user', 25 | default: '' 26 | } 27 | ] 28 | }); 29 | } 30 | 31 | async run(msg, args) { 32 | const user = args.user || msg.author; 33 | const avatarURL = user.avatarURL('png', 512); 34 | if (!avatarURL) return msg.say('The User Provided has No Avatar.'); 35 | const Image = Canvas.Image; 36 | const canvas = new Canvas(741, 1000); 37 | const ctx = canvas.getContext('2d'); 38 | const base = new Image(); 39 | const avatar = new Image(); 40 | const generate = () => { 41 | ctx.drawImage(base, 0, 0); 42 | ctx.drawImage(avatar, 150, 360, 430, 430); 43 | }; 44 | base.src = await fs.readFileAsync(path.join(__dirname, '..', '..', 'assets', 'images', 'wanted.png')); 45 | const { body } = await snekfetch.get(avatarURL); 46 | avatar.src = body; 47 | generate(); 48 | return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'wanted.png' }] }); 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /commands/games/lottery.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class LotteryCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'lottery', 7 | group: 'games', 8 | memberName: 'lottery', 9 | description: '1 in 100 chance of winning. Winners get... The feeling of winning?' 10 | }); 11 | } 12 | 13 | run(msg) { 14 | const lottery = Math.floor(Math.random() * 100) + 1; 15 | if (lottery === 1) return msg.say(`Wow ${msg.author.username}! You actually won! Great job!`); 16 | else return msg.say(`Nope, sorry ${msg.author.username}, you lost.`); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /commands/games/math-game.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const math = require('mathjs'); 4 | const { operations, difficulties, maxValues } = require('../../assets/json/math-game'); 5 | 6 | module.exports = class MathGameCommand extends Command { 7 | constructor(client) { 8 | super(client, { 9 | name: 'math-game', 10 | group: 'games', 11 | memberName: 'math-game', 12 | description: 'See how fast you can answer a math problem in a given time limit.', 13 | clientPermissions: ['EMBED_LINKS'], 14 | args: [ 15 | { 16 | key: 'difficulty', 17 | prompt: `What should the difficulty of the game be? One of: ${difficulties.join(', ')}`, 18 | type: 'string', 19 | validate: (difficulty) => { 20 | if (difficulties.includes(difficulty.toLowerCase())) return true; 21 | else return `The difficulty must be one of: ${difficulties.join(', ')}`; 22 | }, 23 | parse: (difficulty) => difficulty.toLowerCase() 24 | } 25 | ] 26 | }); 27 | } 28 | 29 | async run(msg, args) { 30 | const { difficulty } = args; 31 | const operation = operations[Math.floor(Math.random() * operations.length)]; 32 | const maxValue = maxValues[difficulty]; 33 | const value1 = Math.floor(Math.random() * maxValue) + 1; 34 | const value2 = Math.floor(Math.random() * maxValue) + 1; 35 | const expression = `${value1} ${operation} ${value2}`; 36 | const answer = math.eval(expression).toString(); 37 | const embed = new RichEmbed() 38 | .setTitle('You have 10 seconds to answer:') 39 | .setDescription(expression); 40 | await msg.embed(embed); 41 | try { 42 | const collected = await msg.channel.awaitMessages((res) => res.author.id === msg.author.id, { 43 | max: 1, 44 | time: 10000, 45 | errors: ['time'] 46 | }); 47 | if (collected.first().content !== answer) return msg.say(`Nope, sorry, it's ${answer}.`); 48 | else return msg.say('Nice job! 10/10! You deserve some cake!'); 49 | } catch (err) { 50 | return msg.say(`Time! It was ${answer}, sorry!`); 51 | } 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /commands/games/quiz.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const { stripIndents } = require('common-tags'); 4 | const snekfetch = require('snekfetch'); 5 | 6 | module.exports = class QuizCommand extends Command { 7 | constructor(client) { 8 | super(client, { 9 | name: 'quiz', 10 | aliases: ['jeopardy'], 11 | group: 'games', 12 | memberName: 'quiz', 13 | description: 'Answer a quiz question.', 14 | clientPermissions: ['EMBED_LINKS'] 15 | }); 16 | } 17 | 18 | async run(msg) { 19 | const { body } = await snekfetch 20 | .get('https://opentdb.com/api.php') 21 | .query({ 22 | amount: 1, 23 | type: 'boolean', 24 | encode: 'url3986' 25 | }); 26 | const answer = body.results[0].correct_answer.toLowerCase(); 27 | const embed = new RichEmbed() 28 | .setTitle('You have 15 seconds to answer this question:') 29 | .setDescription(stripIndents` 30 | **${decodeURIComponent(body.results[0].category)}** 31 | True or False: ${decodeURIComponent(body.results[0].question)} 32 | `); 33 | await msg.embed(embed); 34 | try { 35 | const collected = await msg.channel.awaitMessages((res) => res.author.id === msg.author.id, { 36 | max: 1, 37 | time: 15000, 38 | errors: ['time'] 39 | }); 40 | if (collected.first().content.toLowerCase() !== answer) return msg.say(`Nope, sorry, it's ${answer}.`); 41 | else return msg.say('Nice job! 10/10! You deserve some cake!'); 42 | } catch (err) { 43 | return msg.say(`Time! It was ${answer}, sorry!`); 44 | } 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /commands/games/rock-paper-scissors.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const choices = ['paper', 'rock', 'scissors']; 3 | 4 | module.exports = class RockPaperScissorsCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'rock-paper-scissors', 8 | aliases: ['rps'], 9 | group: 'games', 10 | memberName: 'rock-paper-scissors', 11 | description: 'Play Rock-Paper-Scissors.', 12 | args: [ 13 | { 14 | key: 'choice', 15 | prompt: '`Rock`, `Paper`, or `Scissors`?', 16 | type: 'string', 17 | parse: (choice) => choice.toLowerCase() 18 | } 19 | ] 20 | }); 21 | } 22 | 23 | run(msg, args) { 24 | const { choice } = args; 25 | const response = choices[Math.floor(Math.random() * choices.length)]; 26 | if (choice === 'rock') { 27 | if (response === 'rock') return msg.say('Rock! Aw... A tie...'); 28 | else if (response === 'paper') return msg.say('Paper! Yes! I win!'); 29 | else return msg.say('Scissors! Aw... I lose...'); 30 | } else if (choice === 'paper') { 31 | if (response === 'rock') return msg.say('Rock! Aw... I lose...'); 32 | else if (response === 'paper') return msg.say('Paper! Aw... A tie...'); 33 | else return msg.say('Scissors! Yes! I win!'); 34 | } else if (choice === 'scissors') { 35 | if (response === 'rock') return msg.say('Rock! Yes! I win!'); 36 | else if (response === 'paper') return msg.say('Paper! Aw... I lose...'); 37 | else return msg.say('Scissors! Aw... A tie...'); 38 | } else { 39 | return msg.say('I win by default, you little cheater.'); 40 | } 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /commands/games/slots.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | const slots = [':grapes:', ':tangerine:', ':pear:', ':cherries:']; 4 | 5 | module.exports = class SlotsCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'slots', 9 | group: 'games', 10 | memberName: 'slots', 11 | description: 'Play slots.' 12 | }); 13 | } 14 | 15 | run(msg) { 16 | const slotOne = slots[Math.floor(Math.random() * slots.length)]; 17 | const slotTwo = slots[Math.floor(Math.random() * slots.length)]; 18 | const slotThree = slots[Math.floor(Math.random() * slots.length)]; 19 | if (slotOne === slotTwo && slotOne === slotThree) { 20 | return msg.say(stripIndents` 21 | ${slotOne}|${slotTwo}|${slotThree} 22 | Wow! You won! Great job... er... luck! 23 | `); 24 | } else { 25 | return msg.say(stripIndents` 26 | ${slotOne}|${slotTwo}|${slotThree} 27 | Aww... You lost... Guess it's just bad luck, huh? 28 | `); 29 | } 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /commands/games/typing-game.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const { sentences, difficulties, times } = require('../../assets/json/typing-game'); 4 | 5 | module.exports = class TypingGameCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'typing-game', 9 | group: 'games', 10 | memberName: 'typing-game', 11 | description: 'See how fast you can type a sentence in a given time limit.', 12 | clientPermissions: ['EMBED_LINKS'], 13 | args: [ 14 | { 15 | key: 'difficulty', 16 | prompt: `What should the difficulty of the game be? One of: ${difficulties.join(', ')}`, 17 | type: 'string', 18 | validate: (difficulty) => { 19 | if (difficulties.includes(difficulty.toLowerCase())) return true; 20 | else return `The difficulty must be one of: ${difficulties.join(', ')}`; 21 | }, 22 | parse: (difficulty) => difficulty.toLowerCase() 23 | } 24 | ] 25 | }); 26 | } 27 | 28 | async run(msg, args) { 29 | const { difficulty } = args; 30 | const sentence = sentences[Math.floor(Math.random() * sentences.length)]; 31 | const time = times[difficulty]; 32 | const embed = new RichEmbed() 33 | .setTitle(`You have ${time / 1000} seconds to type:`) 34 | .setDescription(sentence); 35 | await msg.embed(embed); 36 | try { 37 | const collected = await msg.channel.awaitMessages((res) => res.author.id === msg.author.id, { 38 | max: 1, 39 | time: time, 40 | errors: ['time'] 41 | }); 42 | if (collected.first().content !== sentence) return msg.say('Nope, sorry!'); 43 | else return msg.say('Nice job! 10/10! You deserve some cake!'); 44 | } catch (err) { 45 | return msg.say('Time! Sorry!'); 46 | } 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /commands/guildinfo/emoji.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class EmojiCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'emoji', 7 | group: 'guildinfo', 8 | memberName: 'emoji', 9 | description: 'Gives a list of the server\'s custom emoji.', 10 | guildOnly: true 11 | }); 12 | } 13 | 14 | run(msg) { 15 | const emojis = msg.guild.emojis; 16 | if (!emojis.size) return msg.say('You have no Custom Emoji.'); 17 | return msg.say(emojis.map((emoji) => emoji).join('')); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /commands/guildinfo/server-info.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const moment = require('moment'); 4 | const filterLevels = ['Off', 'No Role', 'Everyone']; 5 | 6 | module.exports = class GuildInfoCommand extends Command { 7 | constructor(client) { 8 | super(client, { 9 | name: 'server-info', 10 | aliases: ['guild', 'server', 'guild-info'], 11 | group: 'guildinfo', 12 | memberName: 'server-info', 13 | description: 'Gives some info on the server.', 14 | guildOnly: true, 15 | clientPermissions: ['EMBED_LINKS'] 16 | }); 17 | } 18 | 19 | run(msg) { 20 | const embed = new RichEmbed() 21 | .setColor(0x00AE86) 22 | .setThumbnail(msg.guild.iconURL()) 23 | .addField('❯ Name', 24 | msg.guild.name, true) 25 | .addField('❯ ID', 26 | msg.guild.id, true) 27 | .addField('❯ Creation Date', 28 | moment(msg.guild.createdAt).format('MMMM Do YYYY'), true) 29 | .addField('❯ Default Channel', 30 | msg.guild.defaultChannel, true) 31 | .addField('❯ Region', 32 | msg.guild.region, true) 33 | .addField('❯ Explicit Filter', 34 | filterLevels[msg.guild.explicitContentFilter], true) 35 | .addField('❯ Owner', 36 | msg.guild.owner, true) 37 | .addField('❯ Members', 38 | msg.guild.memberCount, true); 39 | return msg.embed(embed); 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /commands/moderation/lockdown.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | 4 | module.exports = class LockdownCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'lockdown', 8 | group: 'moderation', 9 | memberName: 'lockdown', 10 | description: 'Locks down the current channel or removes a lockdown.', 11 | guildOnly: true, 12 | clientPermissions: ['ADMINISTRATOR'], 13 | userPermissions: ['ADMINISTRATOR'], 14 | args: [ 15 | { 16 | key: 'type', 17 | prompt: 'Please enter either `start` or `stop`.', 18 | type: 'string', 19 | default: 'start', 20 | validate: (type) => { 21 | if (['start', 'stop'].includes(type.toLowerCase())) return true; 22 | else return 'Please enter either `start` or `stop`.'; 23 | }, 24 | parse: (type) => type.toLowerCase() 25 | } 26 | ] 27 | }); 28 | } 29 | 30 | async run(msg, args) { 31 | const { type } = args; 32 | if (type === 'start') { 33 | await msg.channel.overwritePermissions(msg.guild.defaultRole, { SEND_MESSAGES: false }); 34 | return msg.say(stripIndents` 35 | Lockdown Started, users without Administrator can no longer post messages. 36 | Please use \`lockdown stop\` to end the lockdown. 37 | `); 38 | } else { 39 | await msg.channel.overwritePermissions(msg.guild.defaultRole, { SEND_MESSAGES: null }); 40 | return msg.say('Lockdown Ended.'); 41 | } 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /commands/moderation/prune.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class PruneCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'prune', 7 | group: 'moderation', 8 | memberName: 'prune', 9 | description: 'Deletes messages from the current channel, up to 99.', 10 | guildOnly: true, 11 | throttling: { 12 | usages: 1, 13 | duration: 15 14 | }, 15 | clientPermissions: ['READ_MESSAGE_HISTORY', 'MANAGE_MESSAGES'], 16 | userPermissions: ['MANAGE_MESSAGES'], 17 | args: [ 18 | { 19 | key: 'count', 20 | label: 'amount of messages', 21 | prompt: 'How many messages do you want to delete? Limit of up to 99.', 22 | type: 'integer', 23 | validate: (count) => { 24 | if (count < 100 && count > 0) return true; 25 | else return 'Count must be from 1-99.'; 26 | } 27 | } 28 | ] 29 | }); 30 | } 31 | 32 | async run(msg, args) { 33 | const { count } = args; 34 | try { 35 | const messages = await msg.channel.fetchMessages({ limit: count + 1 }); 36 | await msg.channel.bulkDelete(messages, true); 37 | return null; 38 | } catch (err) { 39 | return msg.say('There are no messages younger than two weeks that can be deleted.'); 40 | } 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /commands/numedit/currency.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const snekfetch = require('snekfetch'); 3 | const codes = require('../../assets/json/currency'); 4 | 5 | module.exports = class CurrencyCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'currency', 9 | group: 'numedit', 10 | memberName: 'currency', 11 | description: 'Converts from one currency to another.', 12 | details: `**Codes:** ${codes.join(', ')}`, 13 | args: [ 14 | { 15 | key: 'base', 16 | prompt: 'What currency code do you want to use as the base?', 17 | type: 'string', 18 | validate: (base) => { 19 | if (codes.includes(base.toUpperCase())) return true; 20 | else return 'Invalid Currency Code. Use `help currency` to view a list of currency codes.'; 21 | }, 22 | parse: (base) => base.toUpperCase() 23 | }, 24 | { 25 | key: 'to', 26 | prompt: 'What currency code do you want to convert to?', 27 | type: 'string', 28 | validate: (to) => { 29 | if (codes.includes(to.toUpperCase())) return true; 30 | else return 'Invalid Currency Code. Use `help currency` to view a list of currency codes.'; 31 | }, 32 | parse: (to) => to.toUpperCase() 33 | }, 34 | { 35 | key: 'amount', 36 | prompt: 'How much money should be converted? Do not use symbols.', 37 | type: 'integer' 38 | } 39 | ] 40 | }); 41 | } 42 | 43 | async run(msg, args) { 44 | const { base, to, amount } = args; 45 | if (base === to) return msg.say(`Converting ${base} to ${to} is the same value, dummy.`); 46 | const { body } = await snekfetch 47 | .get('http://api.fixer.io/latest') 48 | .query({ 49 | base, 50 | symbols: to 51 | }); 52 | return msg.say(`${amount} ${base} is ${amount * body.rates[to]} ${to}.`); 53 | } 54 | }; 55 | -------------------------------------------------------------------------------- /commands/numedit/math.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const math = require('mathjs'); 3 | 4 | module.exports = class MathCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'math', 8 | group: 'numedit', 9 | memberName: 'math', 10 | description: 'Does math.', 11 | args: [ 12 | { 13 | key: 'expression', 14 | prompt: 'What do you want to answer?', 15 | type: 'string' 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { expression } = args; 23 | try { 24 | const solved = math.eval(expression).toString(); 25 | return msg.say(solved); 26 | } catch (err) { 27 | return msg.say('Invalid Statement'); 28 | } 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /commands/numedit/temperature.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class TemperatureCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'temperature', 7 | group: 'numedit', 8 | memberName: 'temperature', 9 | description: 'Converts temperatures to/from Celsius, Fahrenheit, or Kelvin.', 10 | args: [ 11 | { 12 | key: 'base', 13 | prompt: 'What temperature unit do you want to use as the base?', 14 | type: 'string', 15 | validate: (base) => { 16 | if (['celsius', 'fahrenheit', 'kelvin'].includes(base.toLowerCase())) return true; 17 | else return 'Please enter either `celsius`, `fahrenheit`, or `kelvin`.'; 18 | }, 19 | parse: (base) => base.toLowerCase() 20 | }, 21 | { 22 | key: 'to', 23 | prompt: 'What temperature unit do you want to convert to?', 24 | type: 'string', 25 | validate: (to) => { 26 | if (['celsius', 'fahrenheit', 'kelvin'].includes(to.toLowerCase())) return true; 27 | else return 'Please enter either `celsius`, `fahrenheit`, or `kelvin`.'; 28 | }, 29 | parse: (to) => to.toLowerCase() 30 | }, 31 | { 32 | key: 'amount', 33 | prompt: 'What temperature should be converted?', 34 | type: 'integer' 35 | } 36 | ] 37 | }); 38 | } 39 | 40 | run(msg, args) { 41 | const { base, to, amount } = args; 42 | if (base === to) return msg.say(`Converting ${base} to ${to} is the same value, dummy.`); 43 | if (base === 'celsius') { 44 | if (to === 'fahrenheit') return msg.say(`${amount}°C is ${(amount * 1.8) + 32}°F.`); 45 | else return msg.say(`${amount}°C is ${amount + 273.15}°K.`); 46 | } else if (base === 'fahrenheit') { 47 | if (to === 'celsius') return msg.say(`${amount}°F is ${(amount - 32) / 1.8}°C.`); 48 | else return msg.say(`${amount}°F is ${(amount + 459.67) * (5 / 9)}°K.`); 49 | } else { 50 | if (to === 'celsius') return msg.say(`${amount}°K is ${amount - 273.15}°C.`); 51 | else return msg.say(`${amount}°K is ${(amount * 1.8) - 459.67}°F.`); 52 | } 53 | } 54 | }; 55 | -------------------------------------------------------------------------------- /commands/random/cleverbot.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const Cleverbot = require('cleverio'); 3 | const { CLEVS_KEY, CLEVS_USER, CLEVS_NICK } = process.env; 4 | 5 | module.exports = class CleverbotCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'cleverbot', 9 | aliases: ['clevs', 'chat'], 10 | group: 'random', 11 | memberName: 'cleverbot', 12 | description: 'Talk to Cleverbot!', 13 | args: [ 14 | { 15 | key: 'text', 16 | prompt: 'What do you want to say to Cleverbot?', 17 | type: 'string' 18 | } 19 | ] 20 | }); 21 | 22 | this.clevs = new Cleverbot.Client({ 23 | key: CLEVS_KEY, 24 | user: CLEVS_USER, 25 | nick: CLEVS_NICK 26 | }); 27 | this.clevs.create(); 28 | } 29 | 30 | async run(msg, args) { 31 | const { text } = args; 32 | const { response } = await this.clevs.ask(text); 33 | return msg.reply(response); 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /commands/random/easter-egg.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const eastereggs = require('../../assets/json/easter-egg'); 3 | 4 | module.exports = class EasterEggCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'easter-egg', 8 | aliases: ['tag'], 9 | group: 'random', 10 | memberName: 'easter-egg', 11 | description: 'Can you discover all the easter eggs?', 12 | args: [ 13 | { 14 | key: 'tag', 15 | prompt: 'What easter egg do you want to view?', 16 | type: 'string', 17 | validate: (tag) => { 18 | if (eastereggs[tag.toLowerCase()]) return true; 19 | else return 'Nope, that\'s not a valid easter egg. Try again!'; 20 | }, 21 | parse: (tag) => tag.toLowerCase() 22 | } 23 | ] 24 | }); 25 | } 26 | 27 | run(msg, args) { 28 | const { tag } = args; 29 | return msg.say(eastereggs[tag]); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /commands/random/give-flower.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class GiveFlowerCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'give-flower', 7 | group: 'random', 8 | memberName: 'give-flower', 9 | description: 'Gives Xiao Pai a flower.' 10 | }); 11 | } 12 | 13 | run(msg) { 14 | return msg.say('Ooh, what a pretty flower. What, I may have it? Thanks! I like flowers, yes? ♪'); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /commands/random/horoscope.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const snekfetch = require('snekfetch'); 4 | const signs = require('../../assets/json/horoscope'); 5 | 6 | module.exports = class HoroscopeCommand extends Command { 7 | constructor(client) { 8 | super(client, { 9 | name: 'horoscope', 10 | group: 'random', 11 | memberName: 'horoscope', 12 | description: 'Gives the horoscope for today for a particular sign.', 13 | details: `**Signs:** ${signs.join(', ')}`, 14 | clientPermissions: ['EMBED_LINKS'], 15 | args: [ 16 | { 17 | key: 'sign', 18 | prompt: 'Which sign would you like to get the horoscope for?', 19 | type: 'string', 20 | validate: (sign) => { 21 | if (signs.includes(sign.toLowerCase())) return true; 22 | else return 'Invalid sign. Use `help horoscope` for a list of signs.'; 23 | }, 24 | parse: (sign) => sign.toLowerCase() 25 | } 26 | ] 27 | }); 28 | } 29 | 30 | async run(msg, args) { 31 | const { sign } = args; 32 | const { text } = await snekfetch 33 | .get(`http://sandipbgt.com/theastrologer/api/horoscope/${sign}/today`); 34 | const body = JSON.parse(text); 35 | const embed = new RichEmbed() 36 | .setColor(0x9797FF) 37 | .setTitle(`Horoscope for ${body.sunsign}...`) 38 | .setTimestamp() 39 | .setDescription(body.horoscope) 40 | .addField('Mood', 41 | body.meta.mood, true) 42 | .addField('Intensity', 43 | body.meta.intensity, true) 44 | .addField('Date', 45 | body.date, true); 46 | return msg.embed(embed); 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /commands/random/lenny.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class LennyCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'lenny', 7 | group: 'random', 8 | memberName: 'lenny', 9 | description: 'Responds with the lenny face.' 10 | }); 11 | } 12 | 13 | run(msg) { 14 | return msg.say('( ͡° ͜ʖ ͡°)'); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /commands/random/meme.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const codes = require('../../assets/json/meme'); 3 | 4 | module.exports = class MemeCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'meme', 8 | group: 'random', 9 | memberName: 'meme', 10 | description: 'Sends a Meme with text of your choice, and a background of your choice.', 11 | details: `**Codes:** ${codes.join(', ')}`, 12 | clientPermissions: ['ATTACH_FILES'], 13 | args: [ 14 | { 15 | key: 'type', 16 | prompt: 'What meme type do you want to use?', 17 | type: 'string', 18 | validate: (type) => { 19 | if (codes.includes(type.toLowerCase())) return true; 20 | else return 'Invalid meme type. Use `help meme` to view a list of meme types.'; 21 | }, 22 | parse: (type) => type.toLowerCase() 23 | }, 24 | { 25 | key: 'top', 26 | prompt: 'What should the top row of the meme to be?', 27 | type: 'string', 28 | parse: (top) => encodeURIComponent(top.replace(/[ ]/g, '-')) 29 | }, 30 | { 31 | key: 'bottom', 32 | prompt: 'What should the bottom row of the meme to be?', 33 | type: 'string', 34 | parse: (bottom) => encodeURIComponent(bottom.replace(/[ ]/g, '-')) 35 | } 36 | ] 37 | }); 38 | } 39 | 40 | run(msg, args) { 41 | const { type, top, bottom } = args; 42 | return msg.say({ files: [`https://memegen.link/${type}/${top}/${bottom}.jpg`] }); 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /commands/random/nitro.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const { stripIndents } = require('common-tags'); 4 | 5 | module.exports = class NitroCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'nitro', 9 | group: 'random', 10 | memberName: 'nitro', 11 | description: 'Sends a "This Message Can Only be viewed by Nitro Members" message.', 12 | clientPermissions: ['EMBED_LINKS'] 13 | }); 14 | } 15 | 16 | run(msg) { 17 | const embed = new RichEmbed() 18 | .setAuthor('Discord Nitro') 19 | .setThumbnail('https://i.imgur.com/wzhMMnl.jpg') 20 | .setColor(0x748BD9) 21 | .setURL('https://discordapp.com/nitro') 22 | .setDescription(stripIndents` 23 | This Message can only be viewed by members with Discord Nitro. 24 | [More Information](https://discordapp.com/nitro) 25 | `); 26 | return msg.embed(embed); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /commands/random/pokemon-fusion.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const pokemon = require('../../assets/json/pokemon-fusion'); 3 | 4 | module.exports = class PokemonFusionCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'pokemon-fusion', 8 | aliases: ['poke-fusion', 'poke-fuse'], 9 | group: 'random', 10 | memberName: 'pokemon-fusion', 11 | description: 'Fuses two Generation 1 Pokémon together.', 12 | args: [ 13 | { 14 | key: 'source1', 15 | prompt: 'What Pokémon should be fused?', 16 | type: 'string', 17 | validate: (source1) => { 18 | if (pokemon[source1.toLowerCase()]) return true; 19 | else return 'Only Pokémon from Generation 1 may be used.'; 20 | }, 21 | parse: (source1) => pokemon[source1.toLowerCase()] 22 | }, 23 | { 24 | key: 'source2', 25 | prompt: 'What Pokémon should be fused?', 26 | type: 'string', 27 | validate: (source2) => { 28 | if (pokemon[source2.toLowerCase()]) return true; 29 | else return 'Only Pokémon from Generation 1 may be used.'; 30 | }, 31 | parse: (source2) => pokemon[source2.toLowerCase()] 32 | } 33 | ] 34 | }); 35 | } 36 | 37 | run(msg, args) { 38 | const { source1, source2 } = args; 39 | return msg.say(`http://images.alexonsager.net/pokemon/fused/${source1}/${source1}.${source2}.png`); 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /commands/random/soundboard.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { names, paths } = require('../../assets/json/soundboard'); 3 | const path = require('path'); 4 | 5 | module.exports = class SoundboardCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'soundboard', 9 | aliases: ['sound'], 10 | group: 'random', 11 | memberName: 'soundboard', 12 | description: 'Plays a sound in your voice channel.', 13 | details: `**Sounds:** ${names.join(', ')}`, 14 | guildOnly: true, 15 | throttling: { 16 | usages: 1, 17 | duration: 15 18 | }, 19 | clientPermissions: ['ADD_REACTIONS'], 20 | args: [ 21 | { 22 | key: 'sound', 23 | prompt: 'What sound would you like to play?', 24 | type: 'string', 25 | validate: (sound) => { 26 | if (names.includes(sound.toLowerCase())) return true; 27 | else return 'Invalid Sound. Use `help soundboard` for a list of sounds.'; 28 | }, 29 | parse: (sound) => sound.toLowerCase() 30 | } 31 | ] 32 | }); 33 | } 34 | 35 | async run(msg, args) { 36 | const voiceChannel = msg.member.voiceChannel; 37 | if (!voiceChannel) return msg.say('Please enter a Voice Channel first.'); 38 | if (!voiceChannel.permissionsFor(this.client.user).has(['CONNECT', 'SPEAK'])) { 39 | return msg.say('Missing the `CONNECT` or `SPEAK` Permission for the Voice Channel.'); 40 | } 41 | if (!voiceChannel.joinable) return msg.say('This Voice Channel is not joinable.'); 42 | if (this.client.voiceConnections.get(voiceChannel.guild.id)) return msg.say('I am already playing a sound.'); 43 | const { sound } = args; 44 | const connection = await voiceChannel.join(); 45 | msg.react('🔊'); 46 | const dispatcher = connection.playFile(path.join(__dirname, '..', '..', 'assets', 'sounds', paths[sound])); 47 | dispatcher.on('end', () => { 48 | voiceChannel.leave(); 49 | msg.react('✅'); 50 | }); 51 | return null; 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /commands/random/spam.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const path = require('path'); 3 | 4 | module.exports = class SpamCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'spam', 8 | group: 'random', 9 | memberName: 'spam', 10 | description: 'Puts a picture of Spam.', 11 | clientPermissions: ['ATTACH_FILES'] 12 | }); 13 | } 14 | 15 | run(msg) { 16 | return msg.say({ files: [path.join(__dirname, '..', '..', 'assets', 'images', 'spam.png')] }); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /commands/random/star.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const { stripIndents } = require('common-tags'); 4 | const moment = require('moment'); 5 | 6 | module.exports = class StarCommand extends Command { 7 | constructor(client) { 8 | super(client, { 9 | name: 'star', 10 | group: 'random', 11 | memberName: 'star', 12 | description: 'Stars a message.', 13 | args: [ 14 | { 15 | key: 'id', 16 | prompt: 'What is the ID of the message you wish to star?', 17 | type: 'string' 18 | } 19 | ] 20 | }); 21 | 22 | this.starred = []; 23 | } 24 | 25 | async run(msg, args, reaction) { 26 | const { id } = args; 27 | const channel = msg.guild.channels.get(msg.guild.settings.get('starboard')); 28 | if (!channel || this.starred.includes(id)) return null; 29 | if (!channel.permissionsFor(this.client.user).has('SEND_MESSAGES')) return null; 30 | const message = await msg.channel.fetchMessage(id); 31 | if (!reaction && msg.author.id === message.author.id) { 32 | return msg.reply('You cannot star your own messages, baka.'); 33 | } 34 | this.starred.push(id); 35 | if (!channel.permissionsFor(this.client.user).has('EMBED_LINKS')) { 36 | return msg.say(stripIndents` 37 | **Author:** ${message.author.tag} 38 | **Content:** ${message.content} 39 | **Date:** ${moment(message.createdTimestamp).format('MMMM Do YYYY h:mm:ss A')} 40 | ${message.attachments.first() ? `**Image:** ${message.attachments.first().url}` : ''} 41 | `); 42 | } else { 43 | const embed = new RichEmbed() 44 | .setColor(0xFFFF00) 45 | .setAuthor(message.author.tag, message.author.displayAvatarURL) 46 | .setDescription(message.content) 47 | .setImage(message.attachments.first() ? message.attachments.first().url : null) 48 | .setFooter(moment(message.createdTimestamp).format('MMMM Do YYYY h:mm:ss A')); 49 | return channel.send({ embed }); 50 | } 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /commands/random/strawpoll.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | const snekfetch = require('snekfetch'); 4 | 5 | module.exports = class StrawpollCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'strawpoll', 9 | group: 'random', 10 | memberName: 'strawpoll', 11 | description: 'Creates a Strawpoll with your options.', 12 | args: [ 13 | { 14 | key: 'title', 15 | prompt: 'What would you like the title of the Strawpoll to be?', 16 | type: 'string', 17 | validate: (title) => { 18 | if (title.length < 200) return true; 19 | else return 'Title must be under 200 characters.'; 20 | } 21 | }, 22 | { 23 | key: 'options', 24 | prompt: 'What options do you want me pick from? Maximum of 31.', 25 | type: 'string', 26 | infinite: true, 27 | validate: (choice) => { 28 | if (choice.length < 160) return true; 29 | else return 'Choices must be under 140 characters each.'; 30 | } 31 | } 32 | ] 33 | }); 34 | } 35 | 36 | async run(msg, args) { 37 | const { title, options } = args; 38 | if (options.length < 2) return msg.say('You provided less than two choices.'); 39 | if (options.length > 31) return msg.say('You provided more than thirty choices.'); 40 | const { body } = await snekfetch 41 | .post('https://strawpoll.me/api/v2/polls') 42 | .send({ title, options }); 43 | return msg.say(stripIndents` 44 | ${body.title} 45 | http://strawpoll.me/${body.id} 46 | `); 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /commands/random/today.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const snekfetch = require('snekfetch'); 4 | 5 | module.exports = class TodayCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'today', 9 | group: 'random', 10 | memberName: 'today', 11 | description: 'Tells you what happened today in history.', 12 | clientPermissions: ['EMBED_LINKS'] 13 | }); 14 | } 15 | 16 | async run(msg) { 17 | const { text } = await snekfetch 18 | .get('http://history.muffinlabs.com/date'); 19 | const body = JSON.parse(text); 20 | const events = body.data.Events; 21 | const event = events[Math.floor(Math.random() * events.length)]; 22 | const embed = new RichEmbed() 23 | .setColor(0x9797FF) 24 | .setURL(body.url) 25 | .setTitle(`On this day (${body.date})...`) 26 | .setTimestamp() 27 | .setDescription(`${event.year}: ${event.text}`); 28 | return msg.embed(embed); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /commands/random/would-you-rather.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const snekfetch = require('snekfetch'); 4 | 5 | module.exports = class WouldYouRatherCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'would-you-rather', 9 | aliases: ['wyrather'], 10 | group: 'random', 11 | memberName: 'would-you-rather', 12 | description: 'Gets a random would you rather question.', 13 | clientPermissions: ['EMBED_LINKS'] 14 | }); 15 | } 16 | 17 | async run(msg) { 18 | const { body } = await snekfetch 19 | .get('http://www.rrrather.com/botapi'); 20 | const embed = new RichEmbed() 21 | .setTitle(`${body.title}...`) 22 | .setURL(body.link) 23 | .setColor(0x9797FF) 24 | .setDescription(`${body.choicea} OR ${body.choiceb}?`); 25 | return msg.embed(embed); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /commands/randomimg/cat.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const snekfetch = require('snekfetch'); 3 | 4 | module.exports = class CatCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'cat', 8 | aliases: ['neko'], 9 | group: 'randomimg', 10 | memberName: 'cat', 11 | description: 'Sends a random cat image.' 12 | }); 13 | } 14 | 15 | async run(msg) { 16 | const { body } = await snekfetch 17 | .get('http://random.cat/meow'); 18 | return msg.say(body.file); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /commands/randomimg/dog.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const snekfetch = require('snekfetch'); 3 | 4 | module.exports = class DogCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'dog', 8 | group: 'randomimg', 9 | memberName: 'dog', 10 | description: 'Sends a random dog image.' 11 | }); 12 | } 13 | 14 | async run(msg) { 15 | const { body } = await snekfetch 16 | .get('https://random.dog/woof.json'); 17 | return msg.say(body.url); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /commands/randomimg/vocaloid.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const songs = require('../../assets/json/vocaloid'); 3 | 4 | module.exports = class VocaloidCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'vocaloid', 8 | group: 'randomimg', 9 | memberName: 'vocaloid', 10 | description: 'Sends a random VOCALOID song.' 11 | }); 12 | } 13 | 14 | run(msg) { 15 | const song = songs[Math.floor(Math.random() * songs.length)]; 16 | return msg.say(song); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /commands/randomimg/xiao.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const path = require('path'); 3 | 4 | module.exports = class XiaoCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'xiao', 8 | aliases: ['xiao-pai'], 9 | group: 'randomimg', 10 | memberName: 'xiao', 11 | description: 'Sends a random image of Xiao Pai.', 12 | clientPermissions: ['ATTACH_FILES'] 13 | }); 14 | } 15 | 16 | run(msg) { 17 | const xiao = Math.floor(Math.random() * 10) + 1; 18 | return msg.say({ files: [path.join(__dirname, '..', '..', 'assets', 'images', `xiao${xiao}.png`)] }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /commands/response/8-ball.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | const answers = require('../../assets/json/8-ball'); 4 | 5 | module.exports = class MagicBallCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: '8-ball', 9 | group: 'response', 10 | memberName: '8-ball', 11 | description: 'Predicts your future.', 12 | args: [ 13 | { 14 | key: 'question', 15 | prompt: 'What do you want to ask the 8 ball?', 16 | type: 'string' 17 | } 18 | ] 19 | }); 20 | } 21 | 22 | run(msg, args) { 23 | const { question } = args; 24 | const answer = answers[Math.floor(Math.random() * answers.length)]; 25 | return msg.say(stripIndents` 26 | Question: ${question} 27 | :8ball: ${answer} :8ball: 28 | `); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /commands/response/choose.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class ChooseCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'choose', 7 | group: 'response', 8 | memberName: 'choose', 9 | description: 'Chooses between things.', 10 | args: [ 11 | { 12 | key: 'choices', 13 | prompt: 'What choices do you want me pick from?', 14 | type: 'string', 15 | infinite: true 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { choices } = args; 23 | const choice = choices[Math.floor(Math.random() * choices.length)]; 24 | return msg.say(`I choose ${choice}!`); 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /commands/response/coin.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const sides = ['heads', 'tails']; 3 | 4 | module.exports = class CoinFlipCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'coin', 8 | aliases: ['coin-flip', 'flip'], 9 | group: 'response', 10 | memberName: 'coin', 11 | description: 'Flips a coin.' 12 | }); 13 | } 14 | 15 | run(msg) { 16 | const side = sides[Math.floor(Math.random() * sides.length)]; 17 | return msg.say(`It landed on ${side}!`); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /commands/response/compliment.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const compliments = require('../../assets/json/compliment'); 3 | 4 | module.exports = class ComplimentCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'compliment', 8 | group: 'response', 9 | memberName: 'compliment', 10 | description: 'Compliments a user.', 11 | args: [ 12 | { 13 | key: 'user', 14 | prompt: 'What user do you want to compliment?', 15 | type: 'user', 16 | default: '' 17 | } 18 | ] 19 | }); 20 | } 21 | 22 | run(msg, args) { 23 | const user = args.user || msg.author; 24 | const compliment = compliments[Math.floor(Math.random() * compliments.length)]; 25 | return msg.say(`${user.username}, ${compliment}`); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /commands/response/fact-core.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const facts = require('../../assets/json/fact-core'); 3 | 4 | module.exports = class FactCoreCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'fact-core', 8 | group: 'response', 9 | memberName: 'fact-core', 10 | description: 'Says a random Fact Core quote.' 11 | }); 12 | } 13 | 14 | run(msg) { 15 | const fact = facts[Math.floor(Math.random() * facts.length)]; 16 | return msg.say(fact); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /commands/response/fishy.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const fishes = [':fish:', ':tropical_fish:', ':blowfish:']; 3 | 4 | module.exports = class FishyCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'fishy', 8 | group: 'response', 9 | memberName: 'fishy', 10 | description: 'Catches a fish.' 11 | }); 12 | } 13 | 14 | run(msg) { 15 | const fish = fishes[Math.floor(Math.random() * fishes.length)]; 16 | return msg.say(`You caught a: ${fish}`); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /commands/response/fortune.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const fortunes = require('../../assets/json/fortune'); 3 | 4 | module.exports = class FortuneCookieCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'fortune', 8 | group: 'response', 9 | memberName: 'fortune', 10 | description: 'Fortune Cookie.' 11 | }); 12 | } 13 | 14 | run(msg) { 15 | const fortune = fortunes[Math.floor(Math.random() * fortunes.length)]; 16 | return msg.say(fortune); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /commands/response/magic-conch.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | const answers = require('../../assets/json/magic-conch'); 4 | 5 | module.exports = class MagicConchCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'magic-conch', 9 | group: 'response', 10 | memberName: 'magic-conch', 11 | description: 'Maybe Someday...', 12 | args: [ 13 | { 14 | key: 'question', 15 | prompt: 'What do you want to ask the magic conch?', 16 | type: 'string' 17 | } 18 | ] 19 | }); 20 | } 21 | 22 | run(msg, args) { 23 | const { question } = args; 24 | const answer = answers[Math.floor(Math.random() * answers.length)]; 25 | return msg.say(stripIndents` 26 | Question: ${question} 27 | :shell: ${answer} :shell: 28 | `); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /commands/response/name.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { lastNames, maleNames, femaleNames } = require('../../assets/json/name'); 3 | 4 | module.exports = class RandomNameCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'name', 8 | group: 'response', 9 | memberName: 'name', 10 | description: 'Generates a random name.', 11 | args: [ 12 | { 13 | key: 'gender', 14 | prompt: 'Which gender do you want to generate a name for?', 15 | type: 'string', 16 | validate: (gender) => { 17 | if (['male', 'female'].includes(gender.toLowerCase())) return true; 18 | else return 'Please enter either `male` or `female`.'; 19 | }, 20 | parse: (gender) => gender.toLowerCase() 21 | } 22 | ] 23 | }); 24 | } 25 | 26 | run(msg, args) { 27 | const { gender } = args; 28 | const lastName = lastNames[Math.floor(Math.random() * lastNames.length)]; 29 | if (gender === 'male') { 30 | const name = maleNames[Math.floor(Math.random() * maleNames.length)]; 31 | return msg.say(`${name} ${lastName}`); 32 | } else { 33 | const name = femaleNames[Math.floor(Math.random() * femaleNames.length)]; 34 | return msg.say(`${name} ${lastName}`); 35 | } 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /commands/response/offspring.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const genders = ['boy', 'girl']; 3 | 4 | module.exports = class OffspringCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'offspring', 8 | group: 'response', 9 | memberName: 'offspring', 10 | description: 'Tells you if your new child is a boy or a girl.' 11 | }); 12 | } 13 | 14 | run(msg) { 15 | const gender = genders[Math.floor(Math.random() * genders.length)]; 16 | return msg.say(`It's a ${gender}!`); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /commands/response/quantum-coin.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const sides = ['on nothing', 'on NaN', 'on 0', 'in the air', 'on null']; 3 | 4 | module.exports = class QuantumCoinCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'quantum-coin', 8 | aliases: ['q-coin'], 9 | group: 'response', 10 | memberName: 'quantum-coin', 11 | description: 'Flips a coin that lands on nothing.' 12 | }); 13 | } 14 | 15 | run(msg) { 16 | const side = sides[Math.floor(Math.random() * sides.length)]; 17 | return msg.say(`It landed ${side}.`); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /commands/response/rate-waifu.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class RateWaifuCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'rate-waifu', 7 | aliases: ['waifu'], 8 | group: 'response', 9 | memberName: 'rate-waifu', 10 | description: 'Rates your Waifu.', 11 | args: [ 12 | { 13 | key: 'waifu', 14 | prompt: 'Who do you want to rate?', 15 | type: 'string' 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { waifu } = args; 23 | const rating = Math.floor(Math.random() * 10) + 1; 24 | return msg.say(`I'd give ${waifu} a ${rating}/10!`); 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /commands/response/roast.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const roasts = require('../../assets/json/roast'); 3 | 4 | module.exports = class RoastCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'roast', 8 | group: 'response', 9 | memberName: 'roast', 10 | description: 'Roasts a user.', 11 | args: [ 12 | { 13 | key: 'user', 14 | prompt: 'What user do you want to roast?', 15 | type: 'user', 16 | default: '' 17 | } 18 | ] 19 | }); 20 | } 21 | 22 | run(msg, args) { 23 | const user = args.user || msg.author; 24 | const roast = roasts[Math.floor(Math.random() * roasts.length)]; 25 | return msg.say(`${user.username}, ${roast}`); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /commands/response/roll.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class RollCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'roll', 7 | aliases: ['dice'], 8 | group: 'response', 9 | memberName: 'roll', 10 | description: 'Rolls a dice with a maximum value you specify.', 11 | args: [ 12 | { 13 | key: 'value', 14 | label: 'maximum number', 15 | prompt: 'What is the maximum number you wish to appear?', 16 | type: 'integer', 17 | default: 6 18 | } 19 | ] 20 | }); 21 | } 22 | 23 | run(msg, args) { 24 | const { value } = args; 25 | const roll = Math.floor(Math.random() * value) + 1; 26 | return msg.say(`You rolled a ${roll}.`); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /commands/response/roulette.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class RouletteCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'roulette', 7 | group: 'response', 8 | memberName: 'roulette', 9 | description: 'Chooses a random member in the server.', 10 | guildOnly: true 11 | }); 12 | } 13 | 14 | run(msg) { 15 | return msg.say(`I choose ${msg.guild.members.random().displayName}!`); 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /commands/response/ship.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class ShipCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'ship', 7 | aliases: ['rate'], 8 | group: 'response', 9 | memberName: 'ship', 10 | description: 'Ships things/people together.', 11 | args: [ 12 | { 13 | key: 'things', 14 | prompt: 'What do you want to ship together?', 15 | type: 'string' 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { things } = args; 23 | const rating = Math.floor(Math.random() * 100) + 1; 24 | return msg.say(`I'd give ${things} a ${rating}%!`); 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /commands/roleplay/cuddle.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | 4 | module.exports = class CuddleCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'cuddle', 8 | group: 'roleplay', 9 | memberName: 'cuddle', 10 | description: 'Cuddles a user.', 11 | args: [ 12 | { 13 | key: 'user', 14 | prompt: 'What user do you want to roleplay with?', 15 | type: 'user' 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { user } = args; 23 | return msg.say(stripIndents` 24 | **${msg.author.username}** *cuddles* **${user.username}** 25 | https://i.imgur.com/0yAIWbg.gif 26 | `); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /commands/roleplay/divorce.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | 4 | module.exports = class DivorceCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'divorce', 8 | group: 'roleplay', 9 | memberName: 'divorce', 10 | description: 'Divorces a user.', 11 | args: [ 12 | { 13 | key: 'user', 14 | prompt: 'What user do you want to roleplay with?', 15 | type: 'user' 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { user } = args; 23 | return msg.say(stripIndents` 24 | **${msg.author.username}** *divorces* **${user.username}** 25 | https://i.imgur.com/IgvLWaa.gif 26 | `); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /commands/roleplay/eat.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | 4 | module.exports = class EatCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'eat', 8 | group: 'roleplay', 9 | memberName: 'eat', 10 | description: 'Eats a user.', 11 | args: [ 12 | { 13 | key: 'user', 14 | prompt: 'What user do you want to roleplay with?', 15 | type: 'user' 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { user } = args; 23 | return msg.say(stripIndents` 24 | **${msg.author.username}** *eats* **${user.username}** 25 | https://i.imgur.com/O7FQ5kz.gif 26 | `); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /commands/roleplay/falcon-punch.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | 4 | module.exports = class FalconPunchCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'falcon-punch', 8 | group: 'roleplay', 9 | memberName: 'falcon-punch', 10 | description: 'Falcon Punches a user.', 11 | args: [ 12 | { 13 | key: 'user', 14 | prompt: 'What user do you want to roleplay with?', 15 | type: 'user' 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { user } = args; 23 | return msg.say(stripIndents` 24 | **${msg.author.username}** *falcon punches* **${user.username}** 25 | https://i.imgur.com/LOuK637.gif 26 | `); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /commands/roleplay/fist-bump.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | 4 | module.exports = class FistBumpCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'fist-bump', 8 | group: 'roleplay', 9 | memberName: 'fist-bump', 10 | description: 'Fistbumps a user.', 11 | args: [ 12 | { 13 | key: 'user', 14 | prompt: 'What user do you want to roleplay with?', 15 | type: 'user' 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { user } = args; 23 | return msg.say(stripIndents` 24 | **${msg.author.username}** *fist-bumps* **${user.username}** 25 | *badalalala* https://i.imgur.com/lO2xZHC.gif 26 | `); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /commands/roleplay/high-five.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | 4 | module.exports = class HighFivesCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'high-five', 8 | group: 'roleplay', 9 | memberName: 'high-five', 10 | description: 'High Fives something/someone.', 11 | args: [ 12 | { 13 | key: 'user', 14 | prompt: 'What user do you want to roleplay with?', 15 | type: 'user' 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { user } = args; 23 | return msg.say(stripIndents` 24 | **${msg.author.username}** *high-fives* **${user.username}** 25 | https://i.imgur.com/7BJ6gfM.gif 26 | `); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /commands/roleplay/hit-with-shovel.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | 4 | module.exports = class HitwithShovelCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'hit-with-shovel', 8 | group: 'roleplay', 9 | memberName: 'hit-with-shovel', 10 | description: 'Hits a user with a shovel.', 11 | args: [ 12 | { 13 | key: 'user', 14 | prompt: 'What user do you want to roleplay with?', 15 | type: 'user' 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { user } = args; 23 | return msg.say(stripIndents` 24 | **${msg.author.username}** *hits* **${user.username}** *with a shovel* 25 | https://i.imgur.com/4yvqw81.gif 26 | `); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /commands/roleplay/hug.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | 4 | module.exports = class HugCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'hug', 8 | group: 'roleplay', 9 | memberName: 'hug', 10 | description: 'Hugs a user.', 11 | args: [ 12 | { 13 | key: 'user', 14 | prompt: 'What user do you want to roleplay with?', 15 | type: 'user' 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { user } = args; 23 | return msg.say(stripIndents` 24 | **${msg.author.username}** *hugs* **${user.username}** 25 | https://i.imgur.com/q9Wkhz4.gif 26 | `); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /commands/roleplay/inhale.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | 4 | module.exports = class InhaleCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'inhale', 8 | group: 'roleplay', 9 | memberName: 'inhale', 10 | description: 'Inhales a user.', 11 | args: [ 12 | { 13 | key: 'user', 14 | prompt: 'What user do you want to roleplay with?', 15 | type: 'user' 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { user } = args; 23 | return msg.say(stripIndents` 24 | **${msg.author.username}** *inhales* **${user.username}** *but gained no ability...* 25 | https://i.imgur.com/b4NeOXj.gif 26 | `); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /commands/roleplay/kill.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | 4 | module.exports = class KillCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'kill', 8 | group: 'roleplay', 9 | memberName: 'kill', 10 | description: 'Kills a user.', 11 | args: [ 12 | { 13 | key: 'user', 14 | prompt: 'What user do you want to roleplay with?', 15 | type: 'user' 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { user } = args; 23 | return msg.say(stripIndents` 24 | **${msg.author.username}** *kills* **${user.username}** 25 | https://i.imgur.com/WxD4XMe.gif 26 | `); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /commands/roleplay/kiss.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | 4 | module.exports = class KissCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'kiss', 8 | group: 'roleplay', 9 | memberName: 'kiss', 10 | description: 'Kisses a user.', 11 | args: [ 12 | { 13 | key: 'user', 14 | prompt: 'What user do you want to roleplay with?', 15 | type: 'user' 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { user } = args; 23 | return msg.say(stripIndents` 24 | **${msg.author.username}** *kisses* **${user.username}** 25 | https://i.imgur.com/S7mwPfE.gif 26 | `); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /commands/roleplay/marry.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | 4 | module.exports = class MarryCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'marry', 8 | group: 'roleplay', 9 | memberName: 'marry', 10 | description: 'Marries a user.', 11 | args: [ 12 | { 13 | key: 'user', 14 | prompt: 'What user do you want to roleplay with?', 15 | type: 'user' 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { user } = args; 23 | return msg.say(stripIndents` 24 | **${msg.author.username}** *marries* **${user.username}** 25 | https://i.imgur.com/u67QLhB.gif 26 | `); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /commands/roleplay/pat.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | 4 | module.exports = class PatCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'pat', 8 | group: 'roleplay', 9 | memberName: 'pat', 10 | description: 'Pats a user.', 11 | args: [ 12 | { 13 | key: 'user', 14 | prompt: 'What user do you want to roleplay with?', 15 | type: 'user' 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { user } = args; 23 | return msg.say(stripIndents` 24 | **${msg.author.username}** *pats* **${user.username}** 25 | https://i.imgur.com/oynHZmT.gif 26 | `); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /commands/roleplay/poke.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | 4 | module.exports = class PokeCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'poke', 8 | group: 'roleplay', 9 | memberName: 'poke', 10 | description: 'Pokes a user.', 11 | args: [ 12 | { 13 | key: 'user', 14 | prompt: 'What user do you want to roleplay with?', 15 | type: 'user' 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { user } = args; 23 | return msg.say(stripIndents` 24 | **${msg.author.username}** *pokes* **${user.username}** 25 | https://i.imgur.com/XMuJ7K8.gif 26 | `); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /commands/roleplay/punch.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | 4 | module.exports = class PunchCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'punch', 8 | group: 'roleplay', 9 | memberName: 'punch', 10 | description: 'Punches a user.', 11 | args: [ 12 | { 13 | key: 'user', 14 | prompt: 'What user do you want to roleplay with?', 15 | type: 'user' 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { user } = args; 23 | return msg.say(stripIndents` 24 | **${msg.author.username}** *punches* **${user.username}** 25 | https://i.imgur.com/R5KBiYV.gif 26 | `); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /commands/roleplay/slap.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | 4 | module.exports = class SlapCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'slap', 8 | group: 'roleplay', 9 | memberName: 'slap', 10 | description: 'Slaps a user.', 11 | args: [ 12 | { 13 | key: 'user', 14 | prompt: 'What user do you want to roleplay with?', 15 | type: 'user' 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { user } = args; 23 | return msg.say(stripIndents` 24 | **${msg.author.username}** *slaps* **${user.username}** 25 | https://i.imgur.com/rfy8z2K.gif 26 | `); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /commands/search/anime.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const snekfetch = require('snekfetch'); 4 | const { cleanXML } = require('../../util/Util'); 5 | const { promisifyAll } = require('tsubaki'); 6 | const xml = promisifyAll(require('xml2js')); 7 | const { ANIMELIST_LOGIN } = process.env; 8 | 9 | module.exports = class AnimeCommand extends Command { 10 | constructor(client) { 11 | super(client, { 12 | name: 'anime', 13 | group: 'search', 14 | memberName: 'anime', 15 | description: 'Searches My Anime List for a specified anime.', 16 | clientPermissions: ['EMBED_LINKS'], 17 | args: [ 18 | { 19 | key: 'query', 20 | prompt: 'What anime would you like to search for?', 21 | type: 'string' 22 | } 23 | ] 24 | }); 25 | } 26 | 27 | async run(msg, args) { 28 | const { query } = args; 29 | try { 30 | const { text } = await snekfetch 31 | .get(`https://${ANIMELIST_LOGIN}@myanimelist.net/api/anime/search.xml`) 32 | .query({ q: query }); 33 | const { anime } = await xml.parseStringAsync(text); 34 | const synopsis = cleanXML(anime.entry[0].synopsis[0].substr(0, 2000)); 35 | const embed = new RichEmbed() 36 | .setColor(0x2D54A2) 37 | .setAuthor('My Anime List', 'https://i.imgur.com/R4bmNFz.png') 38 | .setURL(`https://myanimelist.net/anime/${anime.entry[0].id[0]}`) 39 | .setThumbnail(anime.entry[0].image[0]) 40 | .setTitle(`${anime.entry[0].title[0]} (English: ${anime.entry[0].english[0] || 'N/A'})`) 41 | .setDescription(synopsis) 42 | .addField('❯ Type', 43 | `${anime.entry[0].type[0]} - ${anime.entry[0].status[0]}`, true) 44 | .addField('❯ Episodes', 45 | anime.entry[0].episodes[0], true) 46 | .addField('❯ Start Date', 47 | anime.entry[0].start_date[0], true) 48 | .addField('❯ End Date', 49 | anime.entry[0].end_date[0], true); 50 | return msg.embed(embed); 51 | } catch (err) { 52 | return msg.say('No Results.'); 53 | } 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /commands/search/bot-info.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const snekfetch = require('snekfetch'); 4 | const { DBOTS_KEY } = process.env; 5 | 6 | module.exports = class BotSearchCommand extends Command { 7 | constructor(client) { 8 | super(client, { 9 | name: 'bot-info', 10 | group: 'search', 11 | memberName: 'bot-info', 12 | description: 'Searches Discord Bots for info on a bot.', 13 | clientPermissions: ['EMBED_LINKS'], 14 | args: [ 15 | { 16 | key: 'bot', 17 | prompt: 'Which bot do you want to get information for?', 18 | type: 'user' 19 | } 20 | ] 21 | }); 22 | } 23 | 24 | async run(msg, args) { 25 | const { bot } = args; 26 | try { 27 | const { body } = await snekfetch 28 | .get(`https://bots.discord.pw/api/bots/${bot.id}`) 29 | .set({ Authorization: DBOTS_KEY }); 30 | const embed = new RichEmbed() 31 | .setColor(0x9797FF) 32 | .setAuthor('Discord Bots', 'https://i.imgur.com/lrKYBQi.jpg') 33 | .setTitle(body.name) 34 | .setURL(`https://bots.discord.pw/bots/${bot.id}`) 35 | .setDescription(body.description) 36 | .addField('❯ Library', 37 | body.library, true) 38 | .addField('❯ Invite', 39 | `[Here](${body.invite_url})`, true) 40 | .addField('❯ Prefix', 41 | body.prefix, true); 42 | return msg.embed(embed); 43 | } catch (err) { 44 | return msg.say(err.message); 45 | } 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /commands/search/bulbapedia.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const snekfetch = require('snekfetch'); 4 | 5 | module.exports = class BulbapediaCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'bulbapedia', 9 | aliases: ['bulbagarden'], 10 | group: 'search', 11 | memberName: 'bulbapedia', 12 | description: 'Searches Bulbapedia for something.', 13 | clientPermissions: ['EMBED_LINKS'], 14 | args: [ 15 | { 16 | key: 'query', 17 | prompt: 'What would you like to search for?', 18 | type: 'string' 19 | } 20 | ] 21 | }); 22 | } 23 | 24 | async run(msg, args) { 25 | const { query } = args; 26 | const { body } = await snekfetch 27 | .get('http://bulbapedia.bulbagarden.net/w/api.php') 28 | .query({ 29 | action: 'query', 30 | prop: 'extracts', 31 | format: 'json', 32 | titles: query, 33 | exintro: '', 34 | explaintext: '', 35 | redirects: '', 36 | formatversion: 2 37 | }); 38 | if (body.query.pages[0].missing) return msg.say('No Results.'); 39 | const embed = new RichEmbed() 40 | .setColor(0x3E7614) 41 | .setTitle(body.query.pages[0].title) 42 | .setAuthor('Bulbapedia', 'https://i.imgur.com/09eYo5T.png') 43 | .setDescription(body.query.pages[0].extract.substr(0, 2000).replace(/[\n]/g, '\n\n')); 44 | return msg.embed(embed); 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /commands/search/danbooru.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | const snekfetch = require('snekfetch'); 4 | 5 | module.exports = class DanbooruCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'danbooru', 9 | group: 'search', 10 | memberName: 'danbooru', 11 | description: 'Sends an image from Danbooru, with optional query.', 12 | nsfw: true, 13 | args: [ 14 | { 15 | key: 'query', 16 | prompt: 'What would you like to search for?', 17 | type: 'string', 18 | default: '' 19 | } 20 | ] 21 | }); 22 | } 23 | 24 | async run(msg, args) { 25 | const { query } = args; 26 | const { body } = await snekfetch 27 | .get('https://danbooru.donmai.us/posts.json') 28 | .query({ 29 | tags: `${query ? `${query} ` : ''}order:random`, 30 | limit: 1 31 | }); 32 | if (!body.length || !body[0].file_url) return msg.say('No Results'); 33 | return msg.say(stripIndents` 34 | ${query ? `Result for ${query}:` : 'Random Image:'} 35 | https://danbooru.donmai.us${body[0].file_url} 36 | `); 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /commands/search/define.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const snekfetch = require('snekfetch'); 4 | const { WORDNIK_KEY } = process.env; 5 | 6 | module.exports = class DefineCommand extends Command { 7 | constructor(client) { 8 | super(client, { 9 | name: 'define', 10 | group: 'search', 11 | memberName: 'define', 12 | description: 'Defines a word.', 13 | clientPermissions: ['EMBED_LINKS'], 14 | args: [ 15 | { 16 | key: 'query', 17 | prompt: 'What would you like to define?', 18 | type: 'string', 19 | parse: (query) => encodeURIComponent(query) 20 | } 21 | ] 22 | }); 23 | } 24 | 25 | async run(msg, args) { 26 | const { query } = args; 27 | const { body } = await snekfetch 28 | .get(`http://api.wordnik.com:80/v4/word.json/${query}/definitions`) 29 | .query({ 30 | limit: 1, 31 | includeRelated: false, 32 | useCanonical: false, 33 | api_key: WORDNIK_KEY 34 | }); 35 | if (!body.length) return msg.say('No Results.'); 36 | const embed = new RichEmbed() 37 | .setColor(0x9797FF) 38 | .setTitle(body[0].word) 39 | .setDescription(body[0].text); 40 | return msg.embed(embed); 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /commands/search/discrim.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | 4 | module.exports = class DiscrimCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'discrim', 8 | aliases: ['discriminator', 'search-discrim'], 9 | group: 'search', 10 | memberName: 'discrim', 11 | description: 'Searches for other users with a certain discriminator.', 12 | clientPermissions: ['EMBED_LINKS'], 13 | args: [ 14 | { 15 | key: 'discrim', 16 | prompt: 'Which discriminator would you like to search for?', 17 | type: 'string', 18 | default: '', 19 | validate: (discrim) => { 20 | if (/[0-9]+$/g.test(discrim) && discrim.length === 4) return true; 21 | else return 'Invalid Discriminator.'; 22 | } 23 | } 24 | ] 25 | }); 26 | } 27 | 28 | run(msg, args) { 29 | const discrim = args.discrim || msg.author.discriminator; 30 | const users = this.client.users.filter((user) => user.discriminator === discrim).map((user) => user.username); 31 | const embed = new RichEmbed() 32 | .setTitle(`${users.length} Users with the discriminator: ${discrim}`) 33 | .setDescription(users.join(', ')); 34 | return msg.embed(embed); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /commands/search/gelbooru.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | const snekfetch = require('snekfetch'); 4 | const { promisifyAll } = require('tsubaki'); 5 | const xml = promisifyAll(require('xml2js')); 6 | 7 | module.exports = class GelbooruCommand extends Command { 8 | constructor(client) { 9 | super(client, { 10 | name: 'gelbooru', 11 | group: 'search', 12 | memberName: 'gelbooru', 13 | description: 'Sends an image from Gelbooru, with query.', 14 | nsfw: true, 15 | args: [ 16 | { 17 | key: 'query', 18 | prompt: 'What would you like to search for?', 19 | type: 'string' 20 | } 21 | ] 22 | }); 23 | } 24 | 25 | async run(msg, args) { 26 | const { query } = args; 27 | const { text } = await snekfetch 28 | .get('https://gelbooru.com/index.php') 29 | .query({ 30 | page: 'dapi', 31 | s: 'post', 32 | q: 'index', 33 | tags: query, 34 | limit: 1 35 | }); 36 | const { posts } = await xml.parseStringAsync(text); 37 | if (posts.$.count === '0') return msg.say('No Results.'); 38 | return msg.say(stripIndents` 39 | Result for ${query}: 40 | https:${posts.post[0].$.file_url} 41 | `); 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /commands/search/giphy.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const snekfetch = require('snekfetch'); 3 | const { GIPHY_KEY } = process.env; 4 | 5 | module.exports = class GiphyCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'giphy', 9 | group: 'search', 10 | memberName: 'giphy', 11 | description: 'Searches for GIFs with Giphy.', 12 | args: [ 13 | { 14 | key: 'query', 15 | prompt: 'What would you like to search for?', 16 | type: 'string' 17 | } 18 | ] 19 | }); 20 | } 21 | 22 | async run(msg, args) { 23 | const { query } = args; 24 | const { body } = await snekfetch 25 | .get('http://api.giphy.com/v1/gifs/search') 26 | .query({ 27 | q: query, 28 | api_key: GIPHY_KEY, 29 | rating: msg.channel.nsfw ? 'r' : 'pg' 30 | }); 31 | if (!body.data.length) return msg.say('No Results.'); 32 | const random = Math.floor(Math.random() * body.data.length); 33 | return msg.say(body.data[random].images.original.url); 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /commands/search/github.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const snekfetch = require('snekfetch'); 4 | const moment = require('moment'); 5 | const { GITHUB_LOGIN } = process.env; 6 | 7 | module.exports = class GithubCommand extends Command { 8 | constructor(client) { 9 | super(client, { 10 | name: 'github', 11 | group: 'search', 12 | memberName: 'github', 13 | description: 'Gets repo information from GitHub.', 14 | clientPermissions: ['EMBED_LINKS'], 15 | args: [ 16 | { 17 | key: 'repo', 18 | prompt: 'Which repo do you want to get information for?', 19 | type: 'string' 20 | } 21 | ] 22 | }); 23 | } 24 | 25 | async run(msg, args) { 26 | const { repo } = args; 27 | try { 28 | const { body } = await snekfetch 29 | .get(`https://${GITHUB_LOGIN}@api.github.com/repos/${repo}`); 30 | const embed = new RichEmbed() 31 | .setColor(0xFFFFFF) 32 | .setAuthor('Github', 'https://i.imgur.com/ajcPgJG.png') 33 | .setURL(body.html_url) 34 | .setTitle(body.full_name) 35 | .setDescription(body.description) 36 | .setThumbnail(body.owner.avatar_url) 37 | .addField('❯ Creation Date', 38 | moment(body.created_at).format('MMMM Do YYYY'), true) 39 | .addField('❯ Last Updated On', 40 | moment(body.updated_at).format('MMMM Do YYYY'), true) 41 | .addField('❯ Stargazers', 42 | body.stargazers_count, true) 43 | .addField('❯ Watchers', 44 | body.watchers_count, true) 45 | .addField('❯ Open Issues', 46 | body.open_issues_count, true) 47 | .addField('❯ Language', 48 | body.language, true); 49 | return msg.embed(embed); 50 | } catch (err) { 51 | return msg.say(err.message); 52 | } 53 | } 54 | }; 55 | -------------------------------------------------------------------------------- /commands/search/google.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const snekfetch = require('snekfetch'); 3 | const cheerio = require('cheerio'); 4 | const querystring = require('querystring'); 5 | 6 | module.exports = class GoogleCommand extends Command { 7 | constructor(client) { 8 | super(client, { 9 | name: 'google', 10 | group: 'search', 11 | memberName: 'google', 12 | description: 'Searches Google.', 13 | args: [ 14 | { 15 | key: 'query', 16 | prompt: 'What would you like to search for?', 17 | type: 'string' 18 | } 19 | ] 20 | }); 21 | } 22 | 23 | async run(msg, args) { 24 | const { query } = args; 25 | const message = await msg.say('Searching...'); 26 | const { text } = await snekfetch 27 | .get('https://www.google.com/search') 28 | .query({ q: query }); 29 | const $ = cheerio.load(text); 30 | let href = $('.r').first().find('a').first().attr('href'); 31 | if (!href) return msg.say('No Results.'); 32 | href = querystring.parse(href.replace('/url?', '')); 33 | return message.edit(href.q); 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /commands/search/konachan.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | const snekfetch = require('snekfetch'); 4 | 5 | module.exports = class KonachanCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'konachan', 9 | group: 'search', 10 | memberName: 'konachan', 11 | description: 'Sends an image from Konachan, with optional query.', 12 | nsfw: true, 13 | args: [ 14 | { 15 | key: 'query', 16 | prompt: 'What would you like to search for?', 17 | type: 'string', 18 | default: '' 19 | } 20 | ] 21 | }); 22 | } 23 | 24 | async run(msg, args) { 25 | const { query } = args; 26 | const { body } = await snekfetch 27 | .get('https://konachan.net/post.json') 28 | .query({ 29 | tags: `${query ? `${query} ` : ''}order:random`, 30 | limit: 1 31 | }); 32 | if (!body.length) return msg.say('No Results.'); 33 | return msg.say(stripIndents` 34 | ${query ? `Result for ${query}:` : 'Random Image:'} 35 | https:${body[0].file_url} 36 | `); 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /commands/search/lmgtfy.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class LMGTFYCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'lmgtfy', 7 | group: 'search', 8 | memberName: 'lmgtfy', 9 | description: 'Responds with a LMGTFY link.', 10 | args: [ 11 | { 12 | key: 'query', 13 | prompt: 'What would you like to the link to search for?', 14 | type: 'string', 15 | parse: (query) => encodeURIComponent(query) 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const { query } = args; 23 | return msg.say(`http://lmgtfy.com/?iie=1&q=${query}`); 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /commands/search/manga.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const snekfetch = require('snekfetch'); 4 | const { cleanXML } = require('../../util/Util'); 5 | const { promisifyAll } = require('tsubaki'); 6 | const xml = promisifyAll(require('xml2js')); 7 | const { ANIMELIST_LOGIN } = process.env; 8 | 9 | module.exports = class MangaCommand extends Command { 10 | constructor(client) { 11 | super(client, { 12 | name: 'manga', 13 | group: 'search', 14 | memberName: 'manga', 15 | description: 'Searches My Anime List for a specified manga.', 16 | clientPermissions: ['EMBED_LINKS'], 17 | args: [ 18 | { 19 | key: 'query', 20 | prompt: 'What manga would you like to search for?', 21 | type: 'string' 22 | } 23 | ] 24 | }); 25 | } 26 | 27 | async run(msg, args) { 28 | const { query } = args; 29 | try { 30 | const { text } = await snekfetch 31 | .get(`https://${ANIMELIST_LOGIN}@myanimelist.net/api/manga/search.xml`) 32 | .query({ q: query }); 33 | const { manga } = await xml.parseStringAsync(text); 34 | const synopsis = cleanXML(manga.entry[0].synopsis[0].substr(0, 2000)); 35 | const embed = new RichEmbed() 36 | .setColor(0x2D54A2) 37 | .setAuthor('My Anime List', 'https://i.imgur.com/R4bmNFz.png') 38 | .setURL(`https://myanimelist.net/manga/${manga.entry[0].id[0]}`) 39 | .setThumbnail(manga.entry[0].image[0]) 40 | .setTitle(`${manga.entry[0].title[0]} (English: ${manga.entry[0].english[0] || 'N/A'})`) 41 | .setDescription(synopsis) 42 | .addField('❯ Type', 43 | `${manga.entry[0].type[0]} - ${manga.entry[0].status[0]}`, true) 44 | .addField('❯ Volumes / Chapters', 45 | `${manga.entry[0].volumes[0]} / ${manga.entry[0].chapters[0]}`, true) 46 | .addField('❯ Start Date', 47 | manga.entry[0].start_date[0], true) 48 | .addField('❯ End Date', 49 | manga.entry[0].end_date[0], true); 50 | return msg.embed(embed); 51 | } catch (err) { 52 | return msg.say('No Results.'); 53 | } 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /commands/search/map.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const snekfetch = require('snekfetch'); 3 | const { GOOGLE_KEY } = process.env; 4 | 5 | module.exports = class MapCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'map', 9 | group: 'search', 10 | memberName: 'map', 11 | description: 'Gets a map image for the location you define with the zoom level you define (1-20).', 12 | clientPermissions: ['ATTACH_FILES'], 13 | args: [ 14 | { 15 | key: 'zoom', 16 | label: 'zoom level', 17 | prompt: 'What would you like the zoom level for the map to be? Limit 1-20.', 18 | type: 'integer', 19 | validate: (zoom) => { 20 | if (zoom < 21 && zoom > 0) return true; 21 | else return 'Please enter a zoom value from 1-20'; 22 | } 23 | }, 24 | { 25 | key: 'query', 26 | prompt: 'What location you like to get a map image for?', 27 | type: 'string' 28 | } 29 | ] 30 | }); 31 | } 32 | 33 | async run(msg, args) { 34 | const { zoom, query } = args; 35 | const { body } = await snekfetch 36 | .get('https://maps.googleapis.com/maps/api/staticmap') 37 | .query({ 38 | center: query, 39 | zoom, 40 | size: '500x500', 41 | key: GOOGLE_KEY 42 | }); 43 | return msg.say({ files: [{ attachment: body, name: 'map.png' }] }); 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /commands/search/neopet.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const snekfetch = require('snekfetch'); 3 | const cheerio = require('cheerio'); 4 | 5 | module.exports = class NeopetCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'neopet', 9 | group: 'search', 10 | memberName: 'neopet', 11 | description: 'Gives a Neopet\'s image, searchable by name.', 12 | args: [ 13 | { 14 | key: 'query', 15 | prompt: 'What pet would you like to get the image of?', 16 | type: 'string' 17 | } 18 | ] 19 | }); 20 | } 21 | 22 | async run(msg, args) { 23 | const { query } = args; 24 | const { text } = await snekfetch 25 | .get('http://www.sunnyneo.com/petimagefinder.php') 26 | .query({ 27 | name: query, 28 | size: 5, 29 | mood: 1 30 | }); 31 | const $ = cheerio.load(text); 32 | const link = $('textarea').first().text(); 33 | if (!link.includes('cp')) return msg.say('Invalid Pet Name.'); 34 | return msg.say(link); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /commands/search/osu.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const snekfetch = require('snekfetch'); 4 | const { OSU_KEY } = process.env; 5 | 6 | module.exports = class OsuCommand extends Command { 7 | constructor(client) { 8 | super(client, { 9 | name: 'osu', 10 | group: 'search', 11 | memberName: 'osu', 12 | description: 'Searches Osu! user data.', 13 | clientPermissions: ['EMBED_LINKS'], 14 | args: [ 15 | { 16 | key: 'query', 17 | prompt: 'What osu username would you like to search for?', 18 | type: 'string' 19 | } 20 | ] 21 | }); 22 | } 23 | 24 | async run(msg, args) { 25 | const { query } = args; 26 | const { body } = await snekfetch 27 | .get('https://osu.ppy.sh/api/get_user') 28 | .query({ 29 | k: OSU_KEY, 30 | u: query, 31 | type: 'string' 32 | }); 33 | if (!body.length) return msg.say('No Results.'); 34 | const embed = new RichEmbed() 35 | .setColor(0xFF66AA) 36 | .setAuthor('osu!', 'https://i.imgur.com/EmnUp00.png') 37 | .setURL('https://osu.ppy.sh/') 38 | .addField('❯ Username', 39 | body[0].username, true) 40 | .addField('❯ ID', 41 | body[0].user_id, true) 42 | .addField('❯ Level', 43 | body[0].level, true) 44 | .addField('❯ Accuracy', 45 | body[0].accuracy, true) 46 | .addField('❯ Rank', 47 | body[0].pp_rank, true) 48 | .addField('❯ Play Count', 49 | body[0].playcount, true) 50 | .addField('❯ Country', 51 | body[0].country, true) 52 | .addField('❯ Ranked Score', 53 | body[0].ranked_score, true) 54 | .addField('❯ Total Score', 55 | body[0].total_score, true) 56 | .addField('❯ SS', 57 | body[0].count_rank_ss, true) 58 | .addField('❯ S', 59 | body[0].count_rank_s, true) 60 | .addField('❯ A', 61 | body[0].count_rank_a, true); 62 | return msg.embed(embed); 63 | } 64 | }; 65 | -------------------------------------------------------------------------------- /commands/search/rule34.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | const snekfetch = require('snekfetch'); 4 | const { promisifyAll } = require('tsubaki'); 5 | const xml = promisifyAll(require('xml2js')); 6 | 7 | module.exports = class Rule34Command extends Command { 8 | constructor(client) { 9 | super(client, { 10 | name: 'rule34', 11 | group: 'search', 12 | memberName: 'rule34', 13 | description: 'Sends an image from Rule34, with query.', 14 | nsfw: true, 15 | args: [ 16 | { 17 | key: 'query', 18 | prompt: 'What would you like to search for?', 19 | type: 'string' 20 | } 21 | ] 22 | }); 23 | } 24 | 25 | async run(msg, args) { 26 | const { query } = args; 27 | const { text } = await snekfetch 28 | .get('https://rule34.xxx/index.php') 29 | .query({ 30 | page: 'dapi', 31 | s: 'post', 32 | q: 'index', 33 | tags: query, 34 | limit: 1 35 | }); 36 | const { posts } = await xml.parseStringAsync(text); 37 | if (posts.$.count === '0') return msg.say('No Results.'); 38 | return msg.say(stripIndents` 39 | Result for ${query}: 40 | https:${posts.post[0].$.file_url} 41 | `); 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /commands/search/soundcloud.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const snekfetch = require('snekfetch'); 4 | const { SOUNDCLOUD_KEY } = process.env; 5 | 6 | module.exports = class SoundCloudCommand extends Command { 7 | constructor(client) { 8 | super(client, { 9 | name: 'soundcloud', 10 | group: 'search', 11 | memberName: 'soundcloud', 12 | description: 'Searches SoundCloud for a song.', 13 | clientPermissions: ['EMBED_LINKS'], 14 | args: [ 15 | { 16 | key: 'query', 17 | prompt: 'What do you want to search SoundCloud for?', 18 | type: 'string' 19 | } 20 | ] 21 | }); 22 | } 23 | 24 | async run(msg, args) { 25 | const { query } = args; 26 | const { body } = await snekfetch 27 | .get('https://api.soundcloud.com/tracks') 28 | .query({ 29 | q: query, 30 | client_id: SOUNDCLOUD_KEY 31 | }); 32 | if (!body.length) return msg.say('No Results.'); 33 | const embed = new RichEmbed() 34 | .setColor(0xF15A22) 35 | .setAuthor('SoundCloud', 'https://i.imgur.com/lFIz7RU.png') 36 | .setTitle(body[0].title) 37 | .setURL(body[0].permalink_url) 38 | .setThumbnail(body[0].artwork_url) 39 | .addField('❯ Artist', 40 | body[0].user.username) 41 | .addField('❯ Download Count', 42 | body[0].download_count, true) 43 | .addField('❯ Comment Count', 44 | body[0].comment_count, true) 45 | .addField('❯ Playback Count', 46 | body[0].playback_count, true) 47 | .addField('❯ Favorited Count', 48 | body[0].favoritings_count, true); 49 | return msg.embed(embed); 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /commands/search/urban.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const snekfetch = require('snekfetch'); 4 | 5 | module.exports = class UrbanCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'urban', 9 | group: 'search', 10 | memberName: 'urban', 11 | description: 'Searches Urban Dictionary for a word.', 12 | clientPermissions: ['EMBED_LINKS'], 13 | args: [ 14 | { 15 | key: 'query', 16 | prompt: 'What would you like to define?', 17 | type: 'string' 18 | } 19 | ] 20 | }); 21 | } 22 | 23 | async run(msg, args) { 24 | const { query } = args; 25 | const { body } = await snekfetch 26 | .get('http://api.urbandictionary.com/v0/define') 27 | .query({ term: query }); 28 | if (!body.list.length) return msg.say('No Results.'); 29 | const embed = new RichEmbed() 30 | .setColor(0x32a8f0) 31 | .setAuthor('Urban Dictionary', 'https://i.imgur.com/fzFuuL7.png') 32 | .setURL(body.list[0].permalink) 33 | .setTitle(body.list[0].word) 34 | .setDescription(body.list[0].definition.substr(0, 2000)) 35 | .addField('❯ Example', 36 | body.list[0].example.substr(0, 2000) || 'None'); 37 | return msg.embed(embed); 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /commands/search/wattpad.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const snekfetch = require('snekfetch'); 4 | const moment = require('moment'); 5 | const { WATTPAD_KEY } = process.env; 6 | 7 | module.exports = class WattpadCommand extends Command { 8 | constructor(client) { 9 | super(client, { 10 | name: 'wattpad', 11 | group: 'search', 12 | memberName: 'wattpad', 13 | description: 'Searches Wattpad for a book.', 14 | clientPermissions: ['EMBED_LINKS'], 15 | args: [ 16 | { 17 | key: 'query', 18 | prompt: 'What book would you like to search for?', 19 | type: 'string' 20 | } 21 | ] 22 | }); 23 | } 24 | 25 | async run(msg, args) { 26 | const { query } = args; 27 | const { body } = await snekfetch 28 | .get('https://api.wattpad.com:443/v4/stories') 29 | .query({ 30 | query, 31 | limit: 1 32 | }) 33 | .set({ Authorization: `Basic ${WATTPAD_KEY}` }); 34 | if (!body.stories.length) return msg.say('No Results.'); 35 | const embed = new RichEmbed() 36 | .setColor(0xF89C34) 37 | .setAuthor('Wattpad', 'https://i.imgur.com/Rw9vRQB.png') 38 | .setURL(body.stories[0].url) 39 | .setTitle(body.stories[0].title) 40 | .setDescription(body.stories[0].description.substr(0, 2000)) 41 | .setThumbnail(body.stories[0].cover) 42 | .addField('❯ Created On', 43 | moment(body.stories[0].createDate).format('MMMM Do YYYY'), true) 44 | .addField('❯ Author', 45 | body.stories[0].user, true) 46 | .addField('❯ Parts', 47 | body.stories[0].numParts, true) 48 | .addField('❯ Reads', 49 | body.stories[0].readCount, true) 50 | .addField('❯ Votes', 51 | body.stories[0].voteCount, true) 52 | .addField('❯ Comments', 53 | body.stories[0].commentCount, true); 54 | return msg.embed(embed); 55 | } 56 | }; 57 | -------------------------------------------------------------------------------- /commands/search/wikipedia.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const snekfetch = require('snekfetch'); 4 | 5 | module.exports = class WikipediaCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'wikipedia', 9 | group: 'search', 10 | memberName: 'wikipedia', 11 | description: 'Searches Wikipedia for something.', 12 | clientPermissions: ['EMBED_LINKS'], 13 | args: [ 14 | { 15 | key: 'query', 16 | prompt: 'What would you like to search for?', 17 | type: 'string' 18 | } 19 | ] 20 | }); 21 | } 22 | 23 | async run(msg, args) { 24 | const { query } = args; 25 | const { body } = await snekfetch 26 | .get('https://en.wikipedia.org/w/api.php') 27 | .query({ 28 | action: 'query', 29 | prop: 'extracts', 30 | format: 'json', 31 | titles: query, 32 | exintro: '', 33 | explaintext: '', 34 | redirects: '', 35 | formatversion: 2 36 | }); 37 | if (body.query.pages[0].missing) return msg.say('No Results.'); 38 | const embed = new RichEmbed() 39 | .setColor(0xE7E7E7) 40 | .setTitle(body.query.pages[0].title) 41 | .setAuthor('Wikipedia', 'https://i.imgur.com/a4eeEhh.png') 42 | .setDescription(body.query.pages[0].extract.substr(0, 2000).replace(/[\n]/g, '\n\n')); 43 | return msg.embed(embed); 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /commands/search/xkcd.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const snekfetch = require('snekfetch'); 4 | 5 | module.exports = class XKCDCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'xkcd', 9 | aliases: ['kcd'], 10 | group: 'search', 11 | memberName: 'xkcd', 12 | description: 'Gets an XKCD Comic, optionally opting for today\'s or random.', 13 | clientPermissions: ['EMBED_LINKS'], 14 | args: [ 15 | { 16 | key: 'type', 17 | prompt: 'Please enter either a specific comic number, today, or random.', 18 | type: 'string', 19 | default: 'random', 20 | parse: (type) => type.toLowerCase() 21 | } 22 | ] 23 | }); 24 | } 25 | 26 | async run(msg, args) { 27 | const { type } = args; 28 | const current = await snekfetch 29 | .get('https://xkcd.com/info.0.json'); 30 | if (type === 'today') { 31 | const embed = new RichEmbed() 32 | .setTitle(`${current.body.num} - ${current.body.title}`) 33 | .setURL(`https://xkcd.com/${current.body.num}`) 34 | .setImage(current.body.img) 35 | .setFooter(current.body.alt); 36 | return msg.embed(embed); 37 | } else if (type === 'random') { 38 | const random = Math.floor(Math.random() * current.body.num) + 1; 39 | const { body } = await snekfetch 40 | .get(`https://xkcd.com/${random}/info.0.json`); 41 | const embed = new RichEmbed() 42 | .setTitle(`${body.num} - ${body.title}`) 43 | .setURL(`https://xkcd.com/${body.num}`) 44 | .setImage(body.img) 45 | .setFooter(body.alt); 46 | return msg.embed(embed); 47 | } else { 48 | const choice = parseInt(type, 10); 49 | if (isNaN(choice) || current.body.num < choice || choice < 1) return msg.say('Invalid Number.'); 50 | const { body } = await snekfetch 51 | .get(`https://xkcd.com/${choice}/info.0.json`); 52 | const embed = new RichEmbed() 53 | .setTitle(`${body.num} - ${body.title}`) 54 | .setURL(`https://xkcd.com/${body.num}`) 55 | .setImage(body.img) 56 | .setFooter(body.alt); 57 | return msg.embed(embed); 58 | } 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /commands/search/youtube.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const snekfetch = require('snekfetch'); 4 | const { GOOGLE_KEY } = process.env; 5 | 6 | module.exports = class YouTubeCommand extends Command { 7 | constructor(client) { 8 | super(client, { 9 | name: 'youtube', 10 | group: 'search', 11 | memberName: 'youtube', 12 | description: 'Searches YouTube for a video.', 13 | clientPermissions: ['EMBED_LINKS'], 14 | args: [ 15 | { 16 | key: 'query', 17 | prompt: 'What would you like to search for?', 18 | type: 'string' 19 | } 20 | ] 21 | }); 22 | } 23 | 24 | async run(msg, args) { 25 | const { query } = args; 26 | const { body } = await snekfetch 27 | .get('https://www.googleapis.com/youtube/v3/search') 28 | .query({ 29 | part: 'snippet', 30 | type: 'video', 31 | maxResults: 1, 32 | q: query, 33 | key: GOOGLE_KEY 34 | }); 35 | if (!body.items.length) return msg.say('No Results.'); 36 | const embed = new RichEmbed() 37 | .setColor(0xDD2825) 38 | .setTitle(body.items[0].snippet.title) 39 | .setDescription(body.items[0].snippet.description) 40 | .setAuthor(`YouTube - ${body.items[0].snippet.channelTitle}`, 'https://i.imgur.com/hkUafwu.png') 41 | .setURL(`https://www.youtube.com/watch?v=${body.items[0].id.videoId}`) 42 | .setThumbnail(body.items[0].snippet.thumbnails.default.url); 43 | return msg.embed(embed); 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /commands/search/yu-gi-oh.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const snekfetch = require('snekfetch'); 4 | 5 | module.exports = class YuGiOhCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'yu-gi-oh', 9 | group: 'search', 10 | memberName: 'yu-gi-oh', 11 | description: 'Gets info on a Yu-Gi-Oh! Card.', 12 | clientPermissions: ['EMBED_LINKS'], 13 | args: [ 14 | { 15 | key: 'query', 16 | prompt: 'What card would you like to get data for?', 17 | type: 'string', 18 | parse: (text) => encodeURIComponent(text) 19 | } 20 | ] 21 | }); 22 | } 23 | 24 | async run(msg, args) { 25 | const { query } = args; 26 | const { body } = await snekfetch 27 | .get(`http://yugiohprices.com/api/card_data/${query}`); 28 | if (body.status === 'fail') return msg.say('No Results.'); 29 | const embed = new RichEmbed() 30 | .setColor(0xBE5F1F) 31 | .setTitle(body.data.name) 32 | .setDescription(body.data.text) 33 | .setAuthor('Yu-Gi-Oh!', 'https://i.imgur.com/7gPm9Rr.png') 34 | .addField('❯ Card Type', 35 | body.data.card_type, true); 36 | if (body.data.card_type === 'monster') { 37 | embed 38 | .addField('❯ Type', 39 | body.data.type, true) 40 | .addField('❯ Attribute', 41 | body.data.family, true) 42 | .addField('❯ ATK', 43 | body.data.atk, true) 44 | .addField('❯ DEF', 45 | body.data.def, true) 46 | .addField('❯ Level', 47 | body.data.level, true); 48 | } 49 | return msg.embed(embed); 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /commands/settings/clear-setting.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const settings = require('../../assets/json/clear-setting'); 3 | 4 | module.exports = class ClearSettingCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'clear-setting', 8 | group: 'settings', 9 | memberName: 'clear-setting', 10 | description: 'Removes a custom setting from your server.', 11 | guildOnly: true, 12 | userPermissions: ['ADMINISTRATOR'], 13 | args: [ 14 | { 15 | key: 'setting', 16 | prompt: 'What setting do you want to clear?', 17 | type: 'string', 18 | validate: (setting) => { 19 | if (settings.includes(setting)) return true; 20 | else return `Please enter one of the following: ${settings.join(', ')}.`; 21 | } 22 | } 23 | ] 24 | }); 25 | } 26 | 27 | run(msg, args) { 28 | const { setting } = args; 29 | msg.guild.settings.remove(setting); 30 | return msg.say(`${setting} has been removed from your server settings.`); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /commands/settings/invite-guard.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class InviteGuardCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'invite-guard', 7 | group: 'settings', 8 | memberName: 'invite-guard', 9 | description: 'Configures auto-delete for invites.', 10 | guildOnly: true, 11 | userPermissions: ['ADMINISTRATOR'] 12 | }); 13 | } 14 | 15 | run(msg) { 16 | msg.guild.settings.set('inviteGuard', true); 17 | return msg.say('Invite Guard is now active.'); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /commands/settings/join-role.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class JoinRoleCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'join-role', 7 | group: 'settings', 8 | memberName: 'join-role', 9 | description: 'Sets a role that new members are automatically joined to.', 10 | guildOnly: true, 11 | userPermissions: ['ADMINISTRATOR'], 12 | args: [ 13 | { 14 | key: 'role', 15 | prompt: 'What role should new members be joined to?', 16 | type: 'role' 17 | } 18 | ] 19 | }); 20 | } 21 | 22 | run(msg, args) { 23 | const { role } = args; 24 | msg.guild.settings.set('joinRole', role.id); 25 | return msg.say(`Join Role set to ${role.name}.`); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /commands/settings/member-channel.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class MemberLogCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'member-channel', 7 | group: 'settings', 8 | memberName: 'member-channel', 9 | description: 'Sets the channel for the member logs to be sent.', 10 | guildOnly: true, 11 | userPermissions: ['ADMINISTRATOR'], 12 | args: [ 13 | { 14 | key: 'channel', 15 | prompt: 'What is the channel you want to send logs to?', 16 | type: 'channel' 17 | } 18 | ] 19 | }); 20 | } 21 | 22 | run(msg, args) { 23 | const { channel } = args; 24 | msg.guild.settings.set('memberLog', channel.id); 25 | return msg.say(`Member Log channel set to ${channel.name}.`); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /commands/settings/member-message.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class MemberMsgCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'member-message', 7 | aliases: ['member-msg'], 8 | group: 'settings', 9 | memberName: 'member-message', 10 | description: 'Sets the message for either join/leave logs to use.', 11 | details: '**Placeholders:** : Username, : Server Name, : A Mention of the User', 12 | guildOnly: true, 13 | userPermissions: ['ADMINISTRATOR'], 14 | args: [ 15 | { 16 | key: 'type', 17 | prompt: 'Which message would you like to change? Please enter either `joinMsg` or `leaveMsg`.', 18 | type: 'string', 19 | validate: (type) => { 20 | if (['joinMsg', 'leaveMsg'].includes(type)) return true; 21 | else return 'Please enter either `joinMsg` or `leaveMsg`.'; 22 | } 23 | }, 24 | { 25 | key: 'message', 26 | prompt: 'What should be sent to the channel? Use , , and as placeholders.', 27 | type: 'string', 28 | validate: (message) => { 29 | if (message.length < 150) return true; 30 | else return 'Invalid Message. Message must be under 150 characters.'; 31 | } 32 | } 33 | ] 34 | }); 35 | } 36 | 37 | run(msg, args) { 38 | const { type, message } = args; 39 | if (type === 'joinMsg') { 40 | msg.guild.settings.set('joinMsg', message); 41 | return msg.say(`Join Message set to "${message}".`); 42 | } else { 43 | msg.guild.settings.set('leaveMsg', message); 44 | return msg.say(`Leave Message set to "${message}".`); 45 | } 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /commands/settings/mod-channel.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class ModChannelCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'mod-channel', 7 | group: 'settings', 8 | memberName: 'mod-channel', 9 | description: 'Sets the channel for the mod logs to be sent.', 10 | guildOnly: true, 11 | userPermissions: ['ADMINISTRATOR'], 12 | args: [ 13 | { 14 | key: 'channel', 15 | prompt: 'What is the channel you want to send logs to?', 16 | type: 'channel' 17 | } 18 | ] 19 | }); 20 | } 21 | 22 | run(msg, args) { 23 | const { channel } = args; 24 | msg.guild.settings.set('modLog', channel.id); 25 | return msg.say(`Mod Log channel set to ${channel.name}.`); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /commands/settings/setting-list.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | 4 | module.exports = class SettingListCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'setting-list', 8 | group: 'settings', 9 | memberName: 'setting-list', 10 | description: 'Shows a list of current guild settings.', 11 | guildOnly: true 12 | }); 13 | } 14 | 15 | run(msg) { 16 | const modLog = msg.guild.channels.get(msg.guild.settings.get('modLog')); 17 | const memberLog = msg.guild.channels.get(msg.guild.settings.get('memberLog')); 18 | const singleRole = msg.guild.roles.get(msg.guild.settings.get('singleRole')); 19 | const joinRole = msg.guild.roles.get(msg.guild.settings.get('joinRole')); 20 | const starboard = msg.guild.channels.get(msg.guild.settings.get('starboard')); 21 | return msg.say(stripIndents` 22 | **Prefix:** ${msg.guild.commandPrefix} 23 | **Invite Guard:** ${msg.guild.settings.get('inviteGuard', false)} 24 | **Mod Channel:** ${modLog ? modLog.name : 'None'} 25 | **Starboard:** ${starboard ? starboard.name : 'None'} 26 | **Join Role:** ${joinRole ? joinRole.name : 'None'} 27 | **Member Channel:** ${memberLog ? memberLog.name : 'None'} 28 | **Join Message:** ${msg.guild.settings.get('joinMsg', 'Welcome ! (Default)')} 29 | **Leave Message:** ${msg.guild.settings.get('leaveMsg', 'Bye ... (Default)')} 30 | **Single Role:** ${singleRole ? singleRole.name : 'None'} 31 | `); 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /commands/settings/single-role.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class SingleRoleCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'single-role', 7 | group: 'settings', 8 | memberName: 'single-role', 9 | description: 'Sets a single role that is able to use commands.', 10 | guildOnly: true, 11 | userPermissions: ['ADMINISTRATOR'], 12 | args: [ 13 | { 14 | key: 'role', 15 | prompt: 'What role should be able to use commands?', 16 | type: 'role' 17 | } 18 | ] 19 | }); 20 | } 21 | 22 | run(msg, args) { 23 | const { role } = args; 24 | msg.guild.settings.set('singleRole', role.id); 25 | return msg.say(`Single role mode has been enabled with the role ${role.name}.`); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /commands/settings/starboard.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class StarboardCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'starboard', 7 | group: 'settings', 8 | memberName: 'starboard', 9 | description: 'Sets the channel for the starboard.', 10 | guildOnly: true, 11 | userPermissions: ['ADMINISTRATOR'], 12 | args: [ 13 | { 14 | key: 'channel', 15 | prompt: 'What is the channel you want to set as the starboard?', 16 | type: 'channel' 17 | } 18 | ] 19 | }); 20 | } 21 | 22 | run(msg, args) { 23 | const { channel } = args; 24 | msg.guild.settings.set('starboard', channel.id); 25 | return msg.say(`Starboard set to ${channel.name}.`); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /commands/textedit/binary.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class BinaryCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'binary', 7 | group: 'textedit', 8 | memberName: 'binary', 9 | description: 'Converts text to binary.', 10 | args: [ 11 | { 12 | key: 'text', 13 | prompt: 'What text would you like to convert to binary?', 14 | type: 'string', 15 | validate: (text) => { 16 | if (this.binary(text).length < 2000) return true; 17 | else return 'Your text is too long.'; 18 | } 19 | } 20 | ] 21 | }); 22 | } 23 | 24 | run(msg, args) { 25 | const { text } = args; 26 | const converted = this.binary(text); 27 | return msg.say(converted); 28 | } 29 | 30 | binary(text) { 31 | return unescape(encodeURIComponent(text)).split('').map((str) => { 32 | const converted = str.charCodeAt(0).toString(2); 33 | return `${'00000000'.slice(converted.length)}${converted}`; 34 | }).join(''); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /commands/textedit/cow-say.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndent } = require('common-tags'); 3 | 4 | module.exports = class CowsayCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'cow-say', 8 | group: 'textedit', 9 | memberName: 'cow-say', 10 | description: 'Converts text to cowsay.', 11 | args: [ 12 | { 13 | key: 'text', 14 | prompt: 'What text would you like the cow to say?', 15 | type: 'string', 16 | validate: (text) => { 17 | if (text.length < 1500) return true; 18 | else return 'Invalid Text. Text must be under 1500 characters.'; 19 | } 20 | } 21 | ] 22 | }); 23 | } 24 | 25 | run(msg, args) { 26 | const { text } = args; 27 | return msg.code(null, 28 | stripIndent` 29 | < ${text} > 30 | \\ ^__^ 31 | \\ (oO)\\_______ 32 | (__)\\ )\\/\\ 33 | U ||----w | 34 | || || 35 | ` 36 | ); 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /commands/textedit/embed.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | 4 | module.exports = class EmbedCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'embed', 8 | group: 'textedit', 9 | memberName: 'embed', 10 | description: 'Sends a message in an embed.', 11 | clientPermissions: ['EMBED_LINKS'], 12 | args: [ 13 | { 14 | key: 'text', 15 | prompt: 'What text would you like to embed?', 16 | type: 'string' 17 | } 18 | ] 19 | }); 20 | } 21 | 22 | run(msg, args) { 23 | const { text } = args; 24 | const embed = new RichEmbed() 25 | .setAuthor(msg.author.tag, msg.author.displayAvatarURL) 26 | .setColor(0x00AE86) 27 | .setTimestamp() 28 | .setDescription(text); 29 | return msg.embed(embed); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /commands/textedit/mocking.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class MockingCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'mocking', 7 | aliases: ['mock'], 8 | group: 'textedit', 9 | memberName: 'mocking', 10 | description: 'I aM a caT, I LIkE To DrInK mILK.', 11 | clientPermissions: ['USE_EXTERNAL_EMOJIS'], 12 | args: [ 13 | { 14 | key: 'text', 15 | prompt: 'WHaT tEXt WoUlD yOu LiKE to COnvErt?', 16 | type: 'string', 17 | validate: (text) => { 18 | if (text.length < 1950) return true; 19 | else return 'Invalid Text. Text must be under 1950 characters.'; 20 | }, 21 | parse: (text) => text.split('') 22 | } 23 | ] 24 | }); 25 | } 26 | 27 | run(msg, args) { 28 | const { text } = args; 29 | for (let i = 0; i < text.length; i += Math.floor(Math.random() * 4)) text[i] = text[i].toUpperCase(); 30 | return msg.say(`\u180E${text.join('')} <:sponge:318612443398144000>`); 31 | } 32 | }; 33 | 34 | -------------------------------------------------------------------------------- /commands/textedit/morse.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { letterTrans } = require('custom-translate'); 3 | const dictionary = require('../../assets/json/morse'); 4 | 5 | module.exports = class MorseCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'morse', 9 | group: 'textedit', 10 | memberName: 'morse', 11 | description: 'Translates text to morse code.', 12 | args: [ 13 | { 14 | key: 'text', 15 | prompt: 'What text would you like to convert to morse?', 16 | type: 'string', 17 | validate: (text) => { 18 | if (letterTrans(text, dictionary, ' ').length < 1999) return true; 19 | else return 'Your text is too long.'; 20 | } 21 | } 22 | ] 23 | }); 24 | } 25 | 26 | run(msg, args) { 27 | const { text } = args; 28 | const converted = letterTrans(text.toLowerCase(), dictionary, ' '); 29 | return msg.say(converted); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /commands/textedit/pirate.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { wordTrans } = require('custom-translate'); 3 | const dictionary = require('../../assets/json/pirate'); 4 | 5 | module.exports = class PirateCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'pirate', 9 | group: 'textedit', 10 | memberName: 'pirate', 11 | description: 'Talk like a pirate!', 12 | args: [ 13 | { 14 | key: 'text', 15 | prompt: 'What text would you like to convert to pirate?', 16 | type: 'string', 17 | validate: (text) => { 18 | if (wordTrans(text, dictionary).length < 1999) return true; 19 | else return 'Your text is too long.'; 20 | } 21 | } 22 | ] 23 | }); 24 | } 25 | 26 | run(msg, args) { 27 | const { text } = args; 28 | const converted = wordTrans(text, dictionary); 29 | return msg.say(`\u180E${converted}`); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /commands/textedit/repeat.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class RepeatCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'repeat', 7 | group: 'textedit', 8 | memberName: 'repeat', 9 | description: 'Repeat something over and over and over and over (etc).', 10 | args: [ 11 | { 12 | key: 'text', 13 | prompt: 'What text would you like to repeat over and over and over and over?', 14 | type: 'string' 15 | } 16 | ] 17 | }); 18 | } 19 | 20 | run(msg, args) { 21 | const { text } = args; 22 | const converted = text.repeat(2000).substr(0, 1999); 23 | return msg.say(`\u180E${converted}`); 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /commands/textedit/reverse.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class ReverseCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'reverse', 7 | group: 'textedit', 8 | memberName: 'reverse', 9 | description: 'Reverses text.', 10 | args: [ 11 | { 12 | key: 'text', 13 | prompt: 'What text would you like to reverse?', 14 | type: 'string' 15 | } 16 | ] 17 | }); 18 | } 19 | 20 | run(msg, args) { 21 | const { text } = args; 22 | const converted = text.split('').reverse().join(''); 23 | return msg.say(`\u180E${converted}`); 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /commands/textedit/say.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class SayCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'say', 7 | aliases: ['copy', 'echo'], 8 | group: 'textedit', 9 | memberName: 'say', 10 | description: 'Make XiaoBot say what you wish.', 11 | guildOnly: true, 12 | clientPermissions: ['MANAGE_MESSAGES'], 13 | args: [ 14 | { 15 | key: 'text', 16 | prompt: 'What text would you like XiaoBot to say?', 17 | type: 'string' 18 | } 19 | ] 20 | }); 21 | } 22 | 23 | run(msg, args) { 24 | const { text } = args; 25 | msg.delete(); 26 | return msg.say(`\u180E${text}`); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /commands/textedit/temmie.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { wordTrans } = require('custom-translate'); 3 | const dictionary = require('../../assets/json/temmie'); 4 | 5 | module.exports = class TemmieCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'temmie', 9 | group: 'textedit', 10 | memberName: 'temmie', 11 | description: 'Translate text to Temmie speak.', 12 | args: [ 13 | { 14 | key: 'text', 15 | prompt: 'What text would you like to convert to Temmie speak?', 16 | type: 'string', 17 | validate: (text) => { 18 | if (wordTrans(text, dictionary).length < 1999) return true; 19 | else return 'Your text is too long.'; 20 | } 21 | } 22 | ] 23 | }); 24 | } 25 | 26 | run(msg, args) { 27 | const { text } = args; 28 | const converted = wordTrans(text, dictionary); 29 | return msg.say(`\u180E${converted}`); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /commands/textedit/translate.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const snekfetch = require('snekfetch'); 4 | const codes = require('../../assets/json/translate'); 5 | const { YANDEX_KEY } = process.env; 6 | 7 | module.exports = class TranslateCommand extends Command { 8 | constructor(client) { 9 | super(client, { 10 | name: 'translate', 11 | group: 'textedit', 12 | memberName: 'translate', 13 | description: 'Translates text to a specified language.', 14 | details: '**Codes:** https://tech.yandex.com/translate/doc/dg/concepts/api-overview-docpage/#languages', 15 | clientPermissions: ['EMBED_LINKS'], 16 | args: [ 17 | { 18 | key: 'text', 19 | prompt: 'What text would you like to translate?', 20 | type: 'string' 21 | }, 22 | { 23 | key: 'to', 24 | prompt: 'Which language is being translated to?', 25 | type: 'string', 26 | validate: (to) => { 27 | if (codes[to.toLowerCase()]) return true; 28 | else return 'Invalid Language Code. Use `help translate` for a list of codes.'; 29 | }, 30 | parse: (to) => to.toLowerCase() 31 | }, 32 | { 33 | key: 'from', 34 | prompt: 'Which language is being translated from?', 35 | type: 'string', 36 | default: '', 37 | validate: (from) => { 38 | if (codes[from.toLowerCase()]) return true; 39 | else return 'Invalid Language Code. Use `help translate` for a list of codes.'; 40 | }, 41 | parse: (from) => from.toLowerCase() 42 | } 43 | ] 44 | }); 45 | } 46 | 47 | async run(msg, args) { 48 | const { text, to, from } = args; 49 | const { body } = await snekfetch 50 | .get('https://translate.yandex.net/api/v1.5/tr.json/translate') 51 | .query({ 52 | key: YANDEX_KEY, 53 | text, 54 | lang: from ? `${from}-${to}` : to 55 | }); 56 | const lang = body.lang.split('-'); 57 | const embed = new RichEmbed() 58 | .setColor(0x00AE86) 59 | .addField(`❯ From: ${codes[lang[0]]}`, 60 | text) 61 | .addField(`❯ To: ${codes[lang[1]]}`, 62 | body.text[0]); 63 | return msg.embed(embed); 64 | } 65 | }; 66 | -------------------------------------------------------------------------------- /commands/textedit/upside-down.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { letterTrans } = require('custom-translate'); 3 | const dictionary = require('../../assets/json/upside-down'); 4 | 5 | module.exports = class UpsideDownCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'upside-down', 9 | aliases: ['udown'], 10 | group: 'textedit', 11 | memberName: 'upside-down', 12 | description: 'Flips text upside-down.', 13 | args: [ 14 | { 15 | key: 'text', 16 | prompt: 'What text would you like to flip upside-down?', 17 | type: 'string' 18 | } 19 | ] 20 | }); 21 | } 22 | 23 | run(msg, args) { 24 | const { text } = args; 25 | const converted = letterTrans(text, dictionary); 26 | return msg.say(converted); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /commands/textedit/webhook.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const snekfetch = require('snekfetch'); 3 | const { WEBHOOK_URL } = process.env; 4 | 5 | module.exports = class WebhookCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'webhook', 9 | aliases: ['rin', 'rin-say'], 10 | group: 'textedit', 11 | memberName: 'webhook', 12 | description: 'Posts a message to the webhook defined in your `process.env`.', 13 | guildOnly: true, 14 | ownerOnly: true, 15 | clientPermissions: ['MANAGE_MESSAGES'], 16 | args: [ 17 | { 18 | key: 'content', 19 | prompt: 'What text would you like the webhook to say?', 20 | type: 'string' 21 | } 22 | ] 23 | }); 24 | } 25 | 26 | async run(msg, args) { 27 | const { content } = args; 28 | msg.delete(); 29 | await snekfetch 30 | .post(WEBHOOK_URL) 31 | .send({ content }); 32 | return null; 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /commands/textedit/zalgo.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const zalgo = require('zalgolize'); 3 | 4 | module.exports = class ZalgoCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'zalgo', 8 | group: 'textedit', 9 | memberName: 'zalgo', 10 | description: 'Zalgoizes Text.', 11 | args: [ 12 | { 13 | key: 'text', 14 | prompt: 'What text would you like to convert to zalgo?', 15 | type: 'string', 16 | validate: (text) => { 17 | if (text.length < 500) return true; 18 | else return 'Invalid Text. Text must be under 500 characters.'; 19 | } 20 | } 21 | ] 22 | }); 23 | } 24 | 25 | run(msg, args) { 26 | const { text } = args; 27 | const converted = zalgo(text); 28 | return msg.say(`\u180E${converted}`); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /commands/userinfo/avatar.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | 3 | module.exports = class AvatarCommand extends Command { 4 | constructor(client) { 5 | super(client, { 6 | name: 'avatar', 7 | group: 'userinfo', 8 | memberName: 'avatar', 9 | description: 'Gives a link to a user\'s avatar.', 10 | args: [ 11 | { 12 | key: 'user', 13 | prompt: 'Which user would you like to get the avatar of?', 14 | type: 'user', 15 | default: '' 16 | } 17 | ] 18 | }); 19 | } 20 | 21 | run(msg, args) { 22 | const user = args.user || msg.author; 23 | return msg.say(user.avatarURL('webp', 2048) || user.displayAvatarURL); 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /commands/userinfo/user-info.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const moment = require('moment'); 4 | const statuses = { 5 | online: '<:online:313956277808005120> Online', 6 | idle: '<:away:313956277220802560> Idle', 7 | dnd: '<:dnd:313956276893646850> Do Not Disturb', 8 | offline: '<:offline:313956277237710868> Offline' 9 | }; 10 | const colors = { 11 | online: 0x00AE86, 12 | idle: 0xFFFF00, 13 | dnd: 0xFF0000, 14 | offline: 0x808080 15 | }; 16 | 17 | module.exports = class UserInfoCommand extends Command { 18 | constructor(client) { 19 | super(client, { 20 | name: 'user-info', 21 | aliases: ['user', 'member', 'member-info'], 22 | group: 'userinfo', 23 | memberName: 'user', 24 | description: 'Gives some info on a user.', 25 | guildOnly: true, 26 | clientPermissions: ['EMBED_LINKS'], 27 | args: [ 28 | { 29 | key: 'member', 30 | prompt: 'Which user would you like to get info on?', 31 | type: 'member', 32 | default: '' 33 | } 34 | ] 35 | }); 36 | } 37 | 38 | run(msg, args) { 39 | const member = args.member || msg.member; 40 | const status = member.user.presence.status; 41 | const embed = new RichEmbed() 42 | .setColor(colors[status]) 43 | .setThumbnail(member.user.displayAvatarURL) 44 | .addField('❯ Name', 45 | member.user.tag, true) 46 | .addField('❯ ID', 47 | member.id, true) 48 | .addField('❯ Discord Join Date', 49 | moment(member.user.createdAt).format('MMMM Do YYYY h:mm:ss A')) 50 | .addField('❯ Server Join Date', 51 | moment(member.joinedTimestamp).format('MMMM Do YYYY h:mm:ss A')) 52 | .addField('❯ Status', 53 | statuses[status], true) 54 | .addField('❯ Playing', 55 | member.user.presence.game ? member.user.presence.game.name : 'None', true); 56 | return msg.embed(embed); 57 | } 58 | }; 59 | -------------------------------------------------------------------------------- /commands/util/info.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const { version } = require('../../package'); 4 | const moment = require('moment'); 5 | require('moment-duration-format'); 6 | 7 | module.exports = class InfoCommand extends Command { 8 | constructor(client) { 9 | super(client, { 10 | name: 'info', 11 | aliases: ['information', 'stats'], 12 | group: 'util', 13 | memberName: 'info', 14 | description: 'Gives some bot info.', 15 | guarded: true, 16 | clientPermissions: ['EMBED_LINKS'] 17 | }); 18 | } 19 | 20 | async run(msg) { 21 | const guilds = await this.client.shard.fetchClientValues('guilds.size'); 22 | const memory = await this.client.shard.broadcastEval('process.memoryUsage().heapUsed'); 23 | const embed = new RichEmbed() 24 | .setColor(0x00AE86) 25 | .setFooter('©2017 dragonfire535#8081') 26 | .addField('❯ Servers', 27 | guilds.reduce((prev, val) => prev + val, 0), true) 28 | .addField('❯ Shards', 29 | this.client.options.shardCount, true) 30 | .addField('❯ Commands', 31 | this.client.registry.commands.size, true) 32 | .addField('❯ Source Code', 33 | '[View Here](https://github.com/dragonfire535/xiaobot)', true) 34 | .addField('❯ Memory Usage', 35 | `${Math.round(memory.reduce((prev, val) => prev + val, 0) / 1024 / 1024)}MB`, true) 36 | .addField('❯ Uptime', 37 | moment.duration(this.client.uptime).format('d[d]h[h]m[m]s[s]'), true) 38 | .addField('❯ Version', 39 | `v${version}`, true) 40 | .addField('❯ Node Version', 41 | process.version, true) 42 | .addField('❯ Library', 43 | '[discord.js](https://discord.js.org)[-commando](https://github.com/Gawdl3y/discord.js-commando)', true); // eslint-disable-line max-len 44 | return msg.embed(embed); 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /commands/util/invite.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | 4 | module.exports = class InviteCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'invite', 8 | group: 'util', 9 | memberName: 'invite', 10 | description: 'Sends you an invite for the bot and an invite to my server.', 11 | guarded: true 12 | }); 13 | } 14 | 15 | async run(msg) { 16 | const invite = await this.client.generateInvite('1345846343'); 17 | return msg.say(stripIndents` 18 | Add me to your server with this link: 19 | <${invite}> 20 | Or, come to my server with this link: 21 | ${this.client.options.invite} 22 | `); 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /commands/util/ping.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { stripIndents } = require('common-tags'); 3 | 4 | module.exports = class PingCommand extends Command { 5 | constructor(client) { 6 | super(client, { 7 | name: 'ping', 8 | aliases: ['pong', 'ping-pong'], 9 | group: 'util', 10 | memberName: 'ping', 11 | description: 'Checks the bot\'s ping to the Discord server.', 12 | guarded: true 13 | }); 14 | } 15 | 16 | async run(msg) { 17 | const message = await msg.say('Pinging...'); 18 | return message.edit(stripIndents` 19 | :ping_pong: Pong! \`${Math.round(message.createdTimestamp - msg.createdTimestamp)}ms\` 20 | Heartbeat: \`${Math.round(this.client.ping)}ms\` 21 | `); 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /commands/util/shard-info.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const { RichEmbed } = require('discord.js'); 3 | const moment = require('moment'); 4 | require('moment-duration-format'); 5 | 6 | module.exports = class ShardInfoCommand extends Command { 7 | constructor(client) { 8 | super(client, { 9 | name: 'shard-info', 10 | aliases: ['shard', 'shard-stats'], 11 | group: 'util', 12 | memberName: 'shard-info', 13 | description: 'Gives some bot info for the Shard you specify.', 14 | guarded: true, 15 | clientPermissions: ['EMBED_LINKS'], 16 | args: [ 17 | { 18 | key: 'shard', 19 | prompt: 'Which Shard would you like to get data for?', 20 | type: 'integer', 21 | validate: (shard) => { 22 | if (shard < this.client.options.shardCount && shard > -1) return true; 23 | else return 'Invalid Shard ID'; 24 | } 25 | } 26 | ] 27 | }); 28 | } 29 | 30 | async run(msg, args) { 31 | const { shard } = args; 32 | const memory = await this.client.shard.broadcastEval('process.memoryUsage().heapUsed'); 33 | const uptime = await this.client.shard.fetchClientValues('uptime'); 34 | const guilds = await this.client.shard.fetchClientValues('guilds.size'); 35 | const embed = new RichEmbed() 36 | .setTitle(`Shard ${shard}`) 37 | .setColor(0x00AE86) 38 | .addField('❯ Servers', 39 | guilds[shard], true) 40 | .addField('❯ Memory Usage', 41 | `${Math.round(memory[shard] / 1024 / 1024)}MB`, true) 42 | .addField('❯ Uptime', 43 | moment.duration(uptime[shard]).format('d[d]h[h]m[m]s[s]'), true); 44 | return msg.embed(embed); 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /commands/util/uptime.js: -------------------------------------------------------------------------------- 1 | const Command = require('../../structures/Command'); 2 | const moment = require('moment'); 3 | require('moment-duration-format'); 4 | 5 | module.exports = class UptimeCommand extends Command { 6 | constructor(client) { 7 | super(client, { 8 | name: 'uptime', 9 | group: 'util', 10 | memberName: 'uptime', 11 | description: 'Displays how long the bot has been active on this shard.', 12 | guarded: true 13 | }); 14 | } 15 | 16 | run(msg) { 17 | return msg.say(moment.duration(this.client.uptime).format('d[ days], h[ hours], m[ minutes, and ]s[ seconds]')); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /html/carbondesc.html: -------------------------------------------------------------------------------- 1 |
2 | 14 | 15 | XiaoBot, your personal server companion... 16 | 17 |
18 | Discord Server 19 |
20 |

21 |
22 | Cleverbot, Moderation, Site Searching, Soundboard, Avatar Editing, Meme Generator, Games, and more! 23 |
24 |
25 | -------------------------------------------------------------------------------- /html/carbonuse.html: -------------------------------------------------------------------------------- 1 |
2 | 12 |
13 |

Notes:

14 |
    15 |
  1. Moderation Commands Require a Channel set with x;modchannel to send Ban/Softban/Kick/Unban/Warn Logs
  2. 16 |
  3. To use Member Join/Leave Logging, set a channel with x;memberchannel, a custom message can be set with x;membermsg
  4. 17 |
  5. You can set a special role that is able to use Moderation commands (excluding lockdown) with x;staffrole
  6. 18 |
  7. Use x;help to View a Command List
  8. 19 |
  9. Visit my Home Server for more support, or for updates, or if you just want to hang out.
  10. 20 |
21 |
22 |
23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "xiaobot", 3 | "version": "22.1.4", 4 | "description": "A Discord Bot", 5 | "main": "Shard.js", 6 | "scripts": { 7 | "test": "npm run lint", 8 | "lint": "eslint .", 9 | "start": "node Shard.js" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/dragonfire535/xiaobot.git" 14 | }, 15 | "keywords": [ 16 | "bot", 17 | "commando", 18 | "discord", 19 | "discord-api", 20 | "discord-bot", 21 | "discord-js", 22 | "discord-js-commando", 23 | "postgres", 24 | "postgresql", 25 | "cleverbot" 26 | ], 27 | "author": "dragonfire535 ", 28 | "license": "ISC", 29 | "bugs": { 30 | "url": "https://github.com/dragonfire535/xiaobot/issues" 31 | }, 32 | "homepage": "https://github.com/dragonfire535/xiaobot#readme", 33 | "engines": { 34 | "node": "8.0.0" 35 | }, 36 | "dependencies": { 37 | "bufferutil": "^3.0.1", 38 | "canvas": "automattic/node-canvas", 39 | "cheerio": "^1.0.0-rc.1", 40 | "cleverio": "dragonfire535/cleverio", 41 | "custom-translate": "dragonfire535/custom-translate", 42 | "discord.js": "hydrabolt/discord.js", 43 | "discord.js-commando": "gawdl3y/discord.js-commando", 44 | "erlpack": "hammerandchisel/erlpack", 45 | "mathjs": "^3.13.3", 46 | "moment": "^2.18.1", 47 | "moment-duration-format": "^1.3.0", 48 | "node-opus": "^0.2.6", 49 | "pg": "^6.2.3", 50 | "sequelize": "^3.30.4", 51 | "snekfetch": "^3.1.8", 52 | "tsubaki": "^1.1.1", 53 | "xml2js": "^0.4.17", 54 | "zalgolize": "^1.2.4" 55 | }, 56 | "devDependencies": { 57 | "eslint": "^3.19.0" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /structures/Command.js: -------------------------------------------------------------------------------- 1 | const { Command } = require('discord.js-commando'); 2 | 3 | class XiaoCommand extends Command { 4 | constructor(client, info) { 5 | super(client, info); 6 | 7 | this.ownerOnly = info.ownerOnly; 8 | this.nsfw = info.nsfw; 9 | this.clientPermissions = info.clientPermissions; 10 | this.userPermissions = info.userPermissions; 11 | } 12 | 13 | hasPermission(msg) { 14 | if (this.ownerOnly && !this.client.isOwner(msg.author)) { 15 | return 'This Command can only be used by the bot owner.'; 16 | } 17 | if (this.nsfw && !msg.channel.nsfw) { 18 | return 'This Command can only be used in NSFW Channels.'; 19 | } 20 | if (msg.channel.type !== 'dm') { 21 | if (this.clientPermissions) { 22 | for (const permission of this.clientPermissions) { 23 | if (!msg.channel.permissionsFor(this.client.user).has(permission)) { 24 | return `This Command requires the \`${permission}\` Permission.`; 25 | } 26 | } 27 | } 28 | if (this.userPermissions) { 29 | for (const permission of this.userPermissions) { 30 | if (!msg.channel.permissionsFor(msg.author).has(permission)) { 31 | return `You do not have the \`${permission}\` Permission.`; 32 | } 33 | } 34 | } 35 | } 36 | return true; 37 | } 38 | } 39 | 40 | module.exports = XiaoCommand; 41 | -------------------------------------------------------------------------------- /structures/CommandoClient.js: -------------------------------------------------------------------------------- 1 | const { Client } = require('discord.js-commando'); 2 | const Database = require('./PostgreSQL'); 3 | 4 | class CommandoClient extends Client { 5 | constructor(options) { 6 | super(options); 7 | 8 | this.database = Database.db; 9 | 10 | Database.start(); 11 | } 12 | } 13 | 14 | module.exports = CommandoClient; 15 | -------------------------------------------------------------------------------- /structures/PostgreSQL.js: -------------------------------------------------------------------------------- 1 | const Sequelize = require('sequelize'); 2 | const { DATABASE_URL } = process.env; 3 | const database = new Sequelize(DATABASE_URL, { logging: false }); 4 | 5 | class Database { 6 | static get db() { 7 | return database; 8 | } 9 | 10 | static start() { 11 | database.authenticate() 12 | .then(() => console.log('[DATABASE] Connection has been established successfully.')) 13 | .then(() => console.log('[DATABASE] Synchronizing...')) 14 | .then(() => database.sync() 15 | .then(() => console.log('[DATABASE] Synchronizing complete!')) 16 | .catch((err) => console.error(`[DATABASE] Error synchronizing: ${err}`)) 17 | ) 18 | .then(() => console.log('[DATABASE] Ready!')) 19 | .catch((err) => console.error(`[DATABASE] Unable to connect: ${err}`)); 20 | } 21 | } 22 | 23 | module.exports = Database; 24 | -------------------------------------------------------------------------------- /structures/Stats.js: -------------------------------------------------------------------------------- 1 | const snekfetch = require('snekfetch'); 2 | const { CARBON_KEY, DBOTS_KEY } = process.env; 3 | 4 | class Stats { 5 | static dBots(count, id) { 6 | snekfetch 7 | .post(`https://bots.discord.pw/api/bots/${id}/stats`) 8 | .set({ Authorization: DBOTS_KEY }) 9 | .send({ server_count: count }) 10 | .then(() => console.log('[CARBON] Successfully posted to Carbon.')) 11 | .catch((err) => console.error(`[CARBON] Failed to post to Carbon. ${err}`)); 12 | } 13 | 14 | static carbon(count) { 15 | snekfetch 16 | .post('https://www.carbonitex.net/discord/data/botdata.php') 17 | .send({ 18 | key: CARBON_KEY, 19 | servercount: count 20 | }) 21 | .then(() => console.log('[DBOTS] Successfully posted to Discord Bots.')) 22 | .catch((err) => console.error(`[DBOTS] Failed to post to Discord Bots. ${err}`)); 23 | } 24 | } 25 | 26 | module.exports = Stats; 27 | -------------------------------------------------------------------------------- /util/Util.js: -------------------------------------------------------------------------------- 1 | class Util { 2 | static cleanXML(str) { 3 | return str 4 | .replace(/(
)/g, '') 5 | .replace(/(')/g, '\'') 6 | .replace(/(—)/g, '—') 7 | .replace(/("|")/g, '"') 8 | .replace(/(&)/g, '&') 9 | .replace(/(\[i\]|\[\/i\])/g, '*'); 10 | } 11 | } 12 | 13 | module.exports = Util; 14 | --------------------------------------------------------------------------------