├── .gitignore ├── LICENSE ├── README.md ├── commands ├── CONTRIBUTING.md ├── avatar.js ├── cat.js ├── catfact.js ├── covid.js ├── dog.js ├── dogfact.js ├── f.js ├── help.js ├── joke.js ├── lmgtfy.js ├── momma.js ├── ping.js ├── rand-urban.js ├── translate.js ├── urban.js ├── userinfo.js ├── weather.js ├── when.js ├── where.js └── who.js ├── index.js ├── logging.js ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | 106 | # VS files 107 | *.suo 108 | .vs/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 DevSubmarine 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SubBot 2 | 3 | > This repository is now obsolete and not maintained, in favour of main [DevSubmarine Discord Bot](https://github.com/DevSubmarine/DiscordBot). 4 | 5 | The official DevSubmarine Discord Bot! 6 | 7 | Features lots of funny and silly commands to create a better user experience overall! 8 | 9 | ![Depedencies](https://img.shields.io/david/dev/DevSubmarine/SubBot?style=for-the-badge) [![codebeat badge](https://codebeat.co/badges/c2ec8ac7-df99-47dd-a0be-fea15a881dae)](https://codebeat.co/projects/github-com-devsubmarine-subbot-dev) 10 | 11 | # IMPORTANT 12 | - [Contributing] 13 | - [License] 14 | 15 | [Contributing]: https://github.com/DevSubmarine/SubBot/blob/master/commands/CONTRIBUTING.md 16 | [License]: https://github.com/DevSubmarine/SubBot/blob/master/LICENSE 17 | 18 | # Logging 19 | 20 | ## Configuring 21 | 22 | The bot is set up to use [Winston](https://github.com/winstonjs/winston) for logs, but has customized configuration loading, allowing changing logging behaviour inside of settings.json file. 23 | 24 | The logging is set up inside of `Logging` object property of settings file. If the property is missing, bot will set up simple logging to Console with 'verbose' `level` by default. 25 | 26 | The `Logging` object can have few properties, which will be used when configuring Winston. 27 | - `level` - specifies the default [logging level](https://github.com/winstonjs/winston#logging) for all transports; 28 | - `exitOnError` - whether unhandled exceptions should cause bot to exit 29 | - `silent` - will surpress all logs 30 | 31 | Additionally, at least one transport needs to be configured for logging to work. Transports can be configured with `transports` array inside of `Logging` object. Each element of the array should be an object - each object represents one transport. 32 | One property is required in each transport: `TransportType`. This property is used to tell configuration loader which Winston transport to pick. Currently, the bot supports 3 transport types: 33 | - [Console](https://github.com/winstonjs/winston/blob/master/docs/transports.md#console-transport) 34 | - [File](https://github.com/winstonjs/winston/blob/master/docs/transports.md#file-transport) 35 | - [Http](https://github.com/winstonjs/winston/blob/master/docs/transports.md#http-transport) 36 | - [DataDog](https://github.com/winstonjs/winston/blob/master/docs/transports.md#datadog-transport) 37 | 38 | Besides `TransportType`, some transport may require additional properties. All properties besides `TransportType` will be passed as-is to Winston transport object. 39 | Please refer to [Winston Transports docs](https://github.com/winstonjs/winston/blob/master/docs/transports.md) for configuration details for each transport type. 40 | 41 | Logging configuration example can be found in [settings.example.json](/settings.example.json) file. 42 | 43 | #### Logging in formatters and filters 44 | 45 | To log from separate file, simply require the logging.js (might require `..` etc if the file is in a folder). 46 | 47 | ```js 48 | var Log = require('./logging.js') 49 | 50 | Log.info('My special log message'); 51 | ``` 52 | 53 | For more information, refer to [Winston Logging docs](https://github.com/winstonjs/winston#logging). 54 | -------------------------------------------------------------------------------- /commands/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thank you for wanting to contribute to the SubBot project! Before you start, please take a quick look at the guidelines we set for contributors, to ensure a smooth collaboration! 4 | 5 | ## Issues 6 | 7 | If you want to suggest enhancements or report bugs, please open an issue! We try to give each issue to individual attention it deserves, but still - be patient until we get to yours! 8 | 9 | We created a few issue templates (for example for features requests or bug reports), which you are intended to use. If the type of issue you want to create doesn't fit a template, feel free to create an issue from scratch, but still include sufficient information for us to understand it. 10 | 11 | At this time issues will persist forever - in the future we might close issues after a certain amount of inactivity. 12 | 13 | ## Pull Requests 14 | 15 | If you worked on a new feature or fixed an open issue, please create a pull request so we can merge your work into ours. 16 | 17 | If it is not immediately apparent which feature you added or which issue you addressed, please include an adequate description in your pull request. If you still need to work on the pull request before it can be merged please open it as a draft. 18 | 19 | Note that if you do successfully terminate an issue, include Closes #issue-id in your commit message so the issue is automatically referenced. 20 | 21 | Also do note that we try to enforce consistent coding styles among the repository, which we explain in the section coding styles. We review every pull request, and we would appreciate it if you would accept the changes that we propose during our reviews. 22 | -------------------------------------------------------------------------------- /commands/avatar.js: -------------------------------------------------------------------------------- 1 | const Discord = require('discord.js'); 2 | 3 | module.exports.config = { 4 | name: "avatar", 5 | aliases: ["av"] 6 | } 7 | 8 | module.exports.run = async (client, message, args) => { 9 | const avatarEmbed = new Discord.MessageEmbed() 10 | 11 | if(!message.mentions.users.first()) 12 | { 13 | avatarEmbed.setTitle(message.author.username) 14 | avatarEmbed.setColor(3066993) 15 | avatarEmbed.setAuthor("Your Avatar!") 16 | avatarEmbed.setImage(message.author.displayAvatarURL()); 17 | } else { 18 | const user = message.mentions.users.first(); 19 | avatarEmbed.setTitle(`${user.username}'s avatar!`) 20 | avatarEmbed.setColor(3066993) 21 | avatarEmbed.setAuthor(user.username) 22 | avatarEmbed.setImage(user.displayAvatarURL()); 23 | 24 | } 25 | message.channel.send(avatarEmbed); 26 | 27 | 28 | } -------------------------------------------------------------------------------- /commands/cat.js: -------------------------------------------------------------------------------- 1 | const fetch = require('node-fetch') 2 | const Discord = require('discord.js') 3 | 4 | module.exports.config = { 5 | name: "cat", 6 | aliases: ['kitty', 'kitten'] 7 | } 8 | 9 | module.exports.run = async (client, message, args) => { 10 | let msg = await message.channel.send("Generating...") 11 | 12 | fetch(`http://aws.random.cat/meow`) 13 | .then(res => res.json()).then(body => { 14 | if(!body) return message.reply("whoops! I've broke, try again!") 15 | 16 | let cEmbed = new Discord.MessageEmbed() 17 | .setImage(body.file) 18 | .setTimestamp() 19 | 20 | message.channel.send(cEmbed) 21 | msg.delete() 22 | }) 23 | } -------------------------------------------------------------------------------- /commands/catfact.js: -------------------------------------------------------------------------------- 1 | const request = require('superagent') 2 | const Discord = require('discord.js') 3 | 4 | module.exports.config = { 5 | name: "catfact", 6 | aliases: [] 7 | } 8 | 9 | module.exports.run = async (client, message, args) => { 10 | request.get('https://catfact.ninja/fact').end((err, res) => { 11 | if (!err && res.status === 200) { 12 | message.channel.send(res.body.fact) 13 | } 14 | else { 15 | console.log(`REST call failed: ${err}`); 16 | } 17 | }); 18 | } -------------------------------------------------------------------------------- /commands/covid.js: -------------------------------------------------------------------------------- 1 | let covidapi = require('covidapi') 2 | const Discord = require('discord.js') 3 | 4 | module.exports.config = { 5 | name: "covid", 6 | aliases: [] 7 | } 8 | 9 | module.exports.run = async (client, message, args) => { 10 | 11 | if (!args[0]) message.channel.send('Please tell me which country\'s covid information you would like! If you\'d rather have global stats, do !covid global') 12 | else if (args == 'global') { 13 | const data = await covidapi.all(); 14 | 15 | const globalCovid = new Discord.MessageEmbed() 16 | .setColor('#ff6a6a') 17 | .setTitle('Global Covid Stats', ) 18 | .addField('Cases', data.cases, true) 19 | .addField('Active Cases', data.active, true) 20 | .addField('Cases Today', data.todayCases, true) 21 | .addField('Critical Cases', data.critical, true) 22 | .addField('Deaths', data.deaths, true) 23 | .addField('Recovered', data.recovered, true) 24 | } 25 | else { 26 | const countrycovid = args.join(' ') 27 | const data = await covidapi.countries({country: countrycovid}) 28 | 29 | const countryCovidEmbed = new Discord.MessageEmbed() 30 | .setColor('#ff6a6a') 31 | .setTitle(`Covid-19 stats for "${countrycovid}"`) 32 | .addField('Cases', data.cases, true) 33 | .addField('Active Cases', data.active, true) 34 | .addField('Cases Today', data.todayCases, true) 35 | .addField('Critical Cases', data.critical, true) 36 | .addField('Deaths', data.deaths, true) 37 | .addField('Recovered', data.recovered, true) 38 | 39 | message.channel.send(countryCovidEmbed) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /commands/dog.js: -------------------------------------------------------------------------------- 1 | const fetch = require('node-fetch') 2 | const Discord = require('discord.js') 3 | 4 | module.exports.config = { 5 | name: "dog", 6 | aliases: ['doggy', 'doggo'] 7 | } 8 | 9 | module.exports.run = async (client, message, args) => { 10 | let msg = await message.channel.send("Generating...") 11 | 12 | fetch(`https://dog.ceo/api/breeds/image/random`) 13 | .then(res => res.json()).then(body => { 14 | if(!body) return message.reply("whoops! I've broke, try again!") 15 | 16 | let dEmbed = new Discord.MessageEmbed() 17 | .setImage(body.message) 18 | .setTimestamp() 19 | 20 | message.channel.send(dEmbed) 21 | msg.delete(); 22 | }) 23 | } -------------------------------------------------------------------------------- /commands/dogfact.js: -------------------------------------------------------------------------------- 1 | const request = require('superagent') 2 | const Discord = require('discord.js') 3 | 4 | module.exports.config = { 5 | name: "dogfact", 6 | aliases: [] 7 | } 8 | 9 | module.exports.run = async (client, message, args) => { 10 | request.get('https://dog-api.kinduff.com/api/facts').end((err, res) => { 11 | if (!err && res.status === 200) { 12 | message.channel.send(res.body.facts[0]) 13 | } else { 14 | console.log(`REST call failed: ${err}`) 15 | } 16 | }); 17 | } -------------------------------------------------------------------------------- /commands/f.js: -------------------------------------------------------------------------------- 1 | const Discord = require('discord.js') 2 | 3 | module.exports.config = { 4 | name: "f", 5 | aliases: [] 6 | } 7 | 8 | module.exports.run = async (client, message, args) => { 9 | message.channel.send('f'); 10 | } -------------------------------------------------------------------------------- /commands/help.js: -------------------------------------------------------------------------------- 1 | const { Client, Collection, MessageEmbed} = require('discord.js') 2 | 3 | module.exports.config = { 4 | name: "help", 5 | aliases: [] 6 | } 7 | 8 | module.exports.run = async (client, message, args) => { 9 | message.channel.send('Stop begging me for help you dipshit.'); 10 | } -------------------------------------------------------------------------------- /commands/joke.js: -------------------------------------------------------------------------------- 1 | const Discord = require('discord.js') 2 | const jokes = require('discord-jokes') 3 | 4 | module.exports.config = { 5 | name: "joke", 6 | aliases: [] 7 | } 8 | 9 | module.exports.run = async (client, message, args) => { 10 | jokes.getRandomDadJoke(function (joke) { 11 | message.channel.send(joke); 12 | }) 13 | } -------------------------------------------------------------------------------- /commands/lmgtfy.js: -------------------------------------------------------------------------------- 1 | const { Client, Collection, MessageEmbed} = require('discord.js') 2 | 3 | module.exports.config = { 4 | name: "lmgtfy", 5 | aliases: [] 6 | } 7 | 8 | module.exports.run = async (client, message, args) => { 9 | if(!args[0]) message.reply('Please tell me what you would like to search.'); 10 | else { 11 | let search = args.join('+'); 12 | 13 | message.channel.send(`Possibly find the answer to your question and learn what the internet is and how to use it at `) 14 | } 15 | } -------------------------------------------------------------------------------- /commands/momma.js: -------------------------------------------------------------------------------- 1 | const request = require('superagent') 2 | const Discord = require('discord.js') 3 | 4 | module.exports.config = { 5 | name: "momma", 6 | aliases: ['momjoke', 'yomomma'] 7 | } 8 | 9 | module.exports.run = async (client, message, args) => { 10 | request 11 | .get('http://api.yomomma.info/') 12 | .end((err, res) => { 13 | if (!err && res.status === 200) { 14 | try { 15 | JSON.parse(res.text); 16 | } 17 | catch (e) { 18 | return message.reply('the API returned an unconventional response.'); 19 | } 20 | const joke = JSON.parse(res.text); 21 | message.channel.send(joke.joke); 22 | } else { 23 | console.error(`REST call failed: ${err}`); 24 | } 25 | }) 26 | } -------------------------------------------------------------------------------- /commands/ping.js: -------------------------------------------------------------------------------- 1 | const Discord = require('discord.js'); 2 | 3 | module.exports.config = { 4 | name: "ping", 5 | aliases: ["png"] 6 | } 7 | 8 | module.exports.run = async (client, message, args) => { 9 | const ping = new Discord.MessageEmbed() 10 | .setAuthor(`Pong! Latency is about \`${client.ws.ping}\` ms`) 11 | .setTimestamp(Date.now()) 12 | .setColor(3066993); 13 | message.channel.send(ping); 14 | 15 | 16 | } -------------------------------------------------------------------------------- /commands/rand-urban.js: -------------------------------------------------------------------------------- 1 | const urban = require('urban') 2 | const Discord = require('discord.js') 3 | 4 | module.exports.config = { 5 | name: "randurban", 6 | aliases: ['urbrand', 'randomurban'] 7 | } 8 | 9 | module.exports.run = async (client, message, args) => { 10 | urban.random().first(json => { 11 | const def = new Discord.MessageEmbed() 12 | .setTitle(json.word) 13 | .setDescription(json.definition) 14 | .addField('Upvotes', json.thumbs_up, true) 15 | .addField('Downvotes', json.thumbs_down, true) 16 | .setTimestamp(new Date()) 17 | .setFooter(`Written by ${json.author}`); 18 | 19 | message.channel.send(def); 20 | }); 21 | } -------------------------------------------------------------------------------- /commands/translate.js: -------------------------------------------------------------------------------- 1 | const Discord = require('discord.js') 2 | const translate = require('@vitalets/google-translate-api') 3 | 4 | module.exports.config = { 5 | name: "translate", 6 | aliases: [] 7 | } 8 | 9 | module.exports.run = async (client, message, args) => { 10 | if (!args[0]) return message.channel.send('Please tell me what you would like to translate, and to which language! Ex. !translate What would you like to translate? nameOfLanguage') 11 | else { 12 | let languageToTranslate = args.pop(); 13 | let textToTranslate = args.join(' ') 14 | 15 | if (!textToTranslate) return message.channel.send('Please tell me which text you would like to translate.') 16 | else if (!languageToTranslate) return message.channel.send('Please specify a language!') 17 | else { 18 | translate(textToTranslate, {to: languageToTranslate}).then(res => {message.channel.send(`To say "${textToTranslate}" in ${languageToTranslate}, we say "${res.text}"`)}) 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /commands/urban.js: -------------------------------------------------------------------------------- 1 | const urban = require('urban') 2 | const Discord = require('discord.js') 3 | 4 | module.exports.config = { 5 | name: "urban", 6 | aliases: ['urb', 'urbdict'] 7 | } 8 | 9 | module.exports.run = async (client, message, args) => { 10 | if (args.length < 1) { 11 | return message.channel.send('Please enter a word'); 12 | } 13 | let word = args.join(' '); 14 | console.log(word); 15 | 16 | urban(word).first(json => { 17 | if (!json) { 18 | return message.channel.send('No such word exist!'); 19 | } 20 | const def = new Discord.MessageEmbed() 21 | .setTitle(json.word) 22 | .setDescription(json.definition) 23 | .addField('Upvotes', json.thumbs_up, true) 24 | .addField('Downvotes', json.thumb_down, true) 25 | .setTimestamp(new Date()) 26 | .setFooter(`Written by ${json.author}`); 27 | 28 | message.channel.send(def); 29 | }); 30 | } -------------------------------------------------------------------------------- /commands/userinfo.js: -------------------------------------------------------------------------------- 1 | const Discord = require('discord.js') 2 | const moment = require('moment') 3 | 4 | module.exports.config = { 5 | name: "userinfo", 6 | aliases: ['user-info', 'useri'] 7 | } 8 | 9 | module.exports.run = async (client, message, args) => { 10 | 11 | if (!args[0]) message.channel.send('Please specify a user!') 12 | else { 13 | const member = message.mentions.members.last() || message.guild.members.cache.get(target) || message.member; 14 | 15 | const userInfoEmbed = new Discord.MessageEmbed() 16 | .setColor('#00B6FF') 17 | .setThumbnail(`${member.user.displayAvatarURL({dynamic: true, size: 512})}`) 18 | .setTitle(`Info for "${member.user.username}"`) 19 | .addField('Discord ID', `${member.id}`) 20 | .addField('Date created', `${moment(member.user.createdTimestamp)}`) 21 | .addField('Status', `${member.user.presence.status}`) 22 | .addField('Game', `${member.user.presence.activities || 'None'}`) 23 | .addField('Server Join Date', `${moment(member.joinedAt)}`) 24 | 25 | message.channel.send(userInfoEmbed); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /commands/weather.js: -------------------------------------------------------------------------------- 1 | const weather = require('weather-js'); 2 | const Discord = require('discord.js'); 3 | const { weatherDegreeType } = "C" 4 | module.exports.config = { 5 | name: "weather", 6 | aliases: ["wthr"] 7 | } 8 | module.exports.run = async (client, message, args) => { 9 | weather.find({search: args.join(" "), degreeType: weatherDegreeType}, function (error, result){ 10 | 11 | if(error) 12 | { 13 | message.channel.send("Please specify a location."); 14 | return message.react('👎') 15 | } 16 | if(!args[0]) 17 | { 18 | message.channel.send('Please specify a location.') 19 | return message.react('👎') 20 | } 21 | 22 | if(result === undefined || result.length === 0) 23 | { 24 | message.react('👎') 25 | const errorEmbed = new Discord.MessageEmbed() 26 | .setTitle('Couldnt find the location you provided!') 27 | .setDescription('Check your spelling in case of an error, or make sure you are providing the name of a valid location!') 28 | .setColor(15158332) 29 | message.channel.send(errorEmbed) 30 | 31 | } 32 | 33 | var current = result[0].current; 34 | var location = result[0].location; 35 | 36 | const weatherinfo = new Discord.MessageEmbed() 37 | .setDescription(`**${current.skytext}**`) 38 | .setAuthor(`Weather forecast for ${current.observationpoint}`) 39 | .setThumbnail(current.imageUrl) 40 | .setColor(3066993) 41 | .addField('Timezone', `UTC${location.timezone}`, true) 42 | .addField('Degree Type', 'Fahrenheit', true) 43 | .addField('Temperature', `${current.temperature}°`, true) 44 | .addField('Wind', current.winddisplay, true) 45 | .addField('Feels like', `${current.feelslike}°`, true) 46 | .addField('Humidity', `${current.humidity}%`, true) 47 | 48 | 49 | message.channel.send(weatherinfo) 50 | }) 51 | } 52 | 53 | 54 | -------------------------------------------------------------------------------- /commands/when.js: -------------------------------------------------------------------------------- 1 | const { Client, Collection, MessageEmbed} = require('discord.js') 2 | 3 | module.exports.config = { 4 | name: "when", 5 | aliases: [] 6 | } 7 | 8 | module.exports.run = async (client, message, args) => { 9 | if(!args[0]) message.reply('Please ask me a question.'); 10 | 11 | else { 12 | let rand = [ 13 | 'A few seconds ago.', 14 | 'Before the start of time.', 15 | 'In the upcoming second.', 16 | 'Approximately 62,209 years from now.', 17 | 'When the Earth burns down.', 18 | 'When Kim-Jong was born.', 19 | 'When Brackeys decided to quit >:(', 20 | 'When Bill Gates founded Microbox.', 21 | 'When Jesus was born.', 22 | '4,213 years ago.', 23 | '2 seconds ago.', 24 | 'Hubert Blaine Wolfeschlegelsteinhausenbergerdorff Sr.\'s birthday.', 25 | 'When I got depression looking after you degenerates.', 26 | 'Dutchy\'s birthdate.', 27 | 'When Tuvalu got it\'s independence.', 28 | 'Rhoshandiatellyneshiaunneveshenk Koyaanisquatsiuth Williams\'s niece\'s grandfather\'s father\'s daughter\'s half-birthday.', 29 | 'When you took your most recent shit.', 30 | '4.6B years ago.', 31 | 'When Buddha was born.', 32 | 'Guray\'s birthday.', 33 | 'When I was brought to life.', 34 | 'When I decide to quite looking after you degenrates.', 35 | 'In 5 minutes and 17 seconds.', 36 | '1 minute and 22 seconds ago.', 37 | 'When the Earth began forming.', 38 | '2012.', 39 | 'During Mesopotamia.', 40 | 'When you were born.', 41 | 'When Issac Newton invented the gravity.', 42 | ]; 43 | let index = (Math.floor(Math.random() * Math.floor(rand.length))); 44 | message.channel.send(rand[index]); 45 | } 46 | } -------------------------------------------------------------------------------- /commands/where.js: -------------------------------------------------------------------------------- 1 | const { Client, Collection, MessageEmbed} = require('discord.js') 2 | 3 | module.exports.config = { 4 | name: "where", 5 | aliases: [] 6 | } 7 | 8 | module.exports.run = async (client, message, args) => { 9 | if(!args[0]) message.reply('Please ask me a question.'); 10 | 11 | else { 12 | let rand = [ 13 | 'Inside you.', 14 | 'Paris.', 15 | 'London.', 16 | 'Germany', 17 | 'In your cousin\'s uncle\'s neighbour\'s grandfather\'s cat\'s dollhouse', 18 | 'Amsterdam', 19 | 'Heaven', 20 | 'In a Scandanavian torture chamber.', 21 | 'In a plane.', 22 | 'In his car.', 23 | 'Reply hazy try again.', 24 | 'Under the gutter.', 25 | 'Under your chair.', 26 | 'In the White House.', 27 | 'On Gordon Ramsey\'s chopping board.', 28 | 'In his basement.', 29 | 'In his house.', 30 | 'The beach.', 31 | 'A farm', 32 | 'Next door.', 33 | 'In your foolish thoughts.', 34 | 'On the couch.', 35 | 'In your basement.', 36 | 'Across the street.', 37 | 'Inside your monitor screen', 38 | 'In the attic.', 39 | 'North Korea.', 40 | 'Inside your liver', 41 | 'In your mom\'s basement.', 42 | ]; 43 | let index = (Math.floor(Math.random() * Math.floor(rand.length))); 44 | message.channel.send(rand[index]); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /commands/who.js: -------------------------------------------------------------------------------- 1 | const { Client, Collection, MessageEmbed} = require('discord.js') 2 | 3 | module.exports.config = { 4 | name: "who", 5 | aliases: [] 6 | } 7 | 8 | module.exports.run = async (client, message, args) => { 9 | if(!args[0]) message.reply('Please ask me a question.'); 10 | 11 | else { 12 | let rand = [ 13 | 'Guray.', 14 | 'Aqua', 15 | 'CodeMyst', 16 | 'Your cousin.', 17 | 'Your cousin\'s uncle\'s neighbour\'s grandfather\'s cat\'s doll', 18 | 'Kim.', 19 | 'Brackeys.', 20 | 'Bill Gates.', 21 | 'Your mom.', 22 | 'Your dad.', 23 | 'You.', 24 | 'Hubert Blaine Wolfeschlegelsteinhausenbergerdorff Sr.', 25 | 'Daddy.', 26 | 'Dutchy', 27 | 'The senate members of Tuvalu.', 28 | 'Rhoshandiatellyneshiaunneveshenk Koyaanisquatsiuth Williams', 29 | 'Harsh.', 30 | 'Not you.', 31 | 'Juan Joya Borja', 32 | 'Snowy', 33 | 'Me.', 34 | 'Steven Jobbers.', 35 | 'My imaginary friend', 36 | 'Your imaginary friend.', 37 | 'Your best friend', 38 | 'The people who can spell pneumonoultramicroscopicsilicovolcanoconiosis correctly.', 39 | 'Bustin Jieber.', 40 | 'A game developer.', 41 | 'Issac Newton', 42 | ]; 43 | let index = (Math.floor(Math.random() * Math.floor(rand.length))); 44 | message.channel.send(rand[index]); 45 | } 46 | } -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const {Client, Collection, MessageEmbed} = require('discord.js') 2 | 3 | const client = new Client() 4 | 5 | const prefix = '++' 6 | 7 | const fs = require("fs"); 8 | client.commands = new Collection(); 9 | client.aliases = new Collection(); 10 | 11 | fs.readdir("./commands/", (err, files) => { 12 | 13 | if(err) console.log(err) 14 | 15 | let jsfile = files.filter(f => f.split(".").pop() === "js") 16 | if(jsfile.length <= 0) { 17 | return console.log("[LOGS] Couldn't Find Commands!"); 18 | } 19 | 20 | jsfile.forEach((f, i) => { 21 | let pull = require(`./commands/${f}`); 22 | client.commands.set(pull.config.name, pull); 23 | pull.config.aliases.forEach(alias => { 24 | client.aliases.set(alias, pull.config.name) 25 | }); 26 | }); 27 | }); 28 | 29 | client.on('ready', () => { 30 | client.user.setActivity(`Looking after ${client.users.cache.size} submariners!`); 31 | console.log('Bot is on.'); 32 | }) 33 | 34 | client.on('message', async message => { 35 | if (!message.content.startsWith(prefix)) return 36 | let messageArray = message.content.split(" "); 37 | let cmd = messageArray[0]; 38 | let args = messageArray.slice(1); 39 | 40 | let commandfile = client.commands.get(cmd.slice(prefix.length)) || client.commands.get(client.aliases.get(cmd.slice(prefix.length))) 41 | if(commandfile) commandfile.run(client,message,args) 42 | }) 43 | 44 | client.on('messageUpdate', (oldMessage, newMessage) => { 45 | if (!oldMessage.guild) return; 46 | 47 | const oldMessageMention = oldMessage.mentions.members.first() 48 | const newMessageMention = newMessage.mentions.members.first() 49 | 50 | if (oldMessageMention && !newMessageMention && oldMessage.author.id !== oldMessageMention.id) { 51 | let embed = new MessageEmbed() 52 | .setColor('#ff6a6a') 53 | .setTitle("Ghost ping detected!") 54 | .addField('**Author**', oldMessage.author) 55 | .addField("**Origional Message**", oldMessage, true) 56 | .addField("**New Message**", newMessage, true) 57 | .addField('**Type**', 'Sender sent a message. Then proceeded to edit the ping out of the message.') 58 | .setTimestamp(); 59 | oldMessage.channel.send(embed) 60 | } 61 | }) 62 | 63 | client.on('messageDelete', message => { 64 | if (!message.guild) return; 65 | 66 | if (message.mentions.members.first() && message.mentions.members.first().id != message.author.id) { 67 | let embed = new MessageEmbed() 68 | .setColor('#ff6a6a') 69 | .setTitle("Ghost ping detected!") 70 | .addField('**Sender**', message.author) 71 | .addField("**Message**", message.content) 72 | .addField('**Type**', 'Sender sent a message, and then proceeded to delete it thereafter.') 73 | .setTimestamp(); 74 | message.channel.send(embed) 75 | } 76 | }) 77 | 78 | client.login('token'); 79 | -------------------------------------------------------------------------------- /logging.js: -------------------------------------------------------------------------------- 1 | var winston = require('winston'); 2 | 3 | var stringLogFormat = winston.format.combine( 4 | winston.format.colorize(), 5 | winston.format.splat(), 6 | winston.format.timestamp(), 7 | winston.format.printf(info => { 8 | var formattedTimestamp = info.timestamp.replace(/T/, ' ').replace(/\..+/, ''); 9 | var msg = info.message; 10 | if (info.label) 11 | msg = '[' + info.label + '] ' + msg; 12 | return `${formattedTimestamp} ${info.level}: ${msg}` 13 | }) 14 | ); 15 | 16 | var jsonLogFormat = winston.format.combine( 17 | winston.format.timestamp(), 18 | winston.format.json() 19 | ); 20 | 21 | function configureLogging(loggingConfiguration = undefined) { 22 | winston.clear(); 23 | 24 | if (loggingConfiguration === undefined) { 25 | winston.configure({ 26 | level: 'verbose', 27 | transports: [ 28 | new winston.transports.Console({ 29 | stderrLevels: ['error'], 30 | consoleWarnLevels: ['warn'], 31 | format: stringLogFormat, 32 | handleExceptions: true 33 | }) 34 | ] 35 | }); 36 | } 37 | else if (loggingConfiguration) { 38 | winston.configure({ 39 | level: loggingConfiguration.level, 40 | silent: loggingConfiguration.silent, 41 | exitOnError: loggingConfiguration.exitOnError, 42 | format: jsonLogFormat 43 | }); 44 | 45 | // add each supported transport 46 | if (Array.isArray(loggingConfiguration.transports)) { 47 | for (i = 0; i < loggingConfiguration.transports.length; i++) { 48 | var transportConfig = loggingConfiguration.transports[i]; 49 | 50 | switch (transportConfig.TransportType.toUpperCase()) { 51 | case "CONSOLE": 52 | winston.add(new winston.transports.Console( 53 | Object.assign({}, transportConfig, { format: stringLogFormat })) 54 | ); 55 | break; 56 | case "FILE": 57 | winston.add(new winston.transports.File( 58 | Object.assign({}, transportConfig, { format: winston.format.combine(stringLogFormat, winston.format.uncolorize()) })) 59 | ); 60 | break; 61 | case "HTTP": 62 | winston.add(new winston.transports.Http( 63 | Object.assign({}, transportConfig, { format: jsonLogFormat })) 64 | ); 65 | break; 66 | case "DATADOG": 67 | var DatadogTransport = require('datadog-winston'); 68 | winston.add(new DatadogTransport( 69 | Object.assign({}, transportConfig, { format: jsonLogFormat, ddsource: transportConfig.ddsource || 'node.js' })) 70 | ); 71 | break; 72 | } 73 | } 74 | } 75 | } 76 | 77 | return winston; 78 | } 79 | 80 | module.exports = winston; 81 | module.exports.configureLogging = configureLogging; -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "subbot", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@discordjs/collection": { 8 | "version": "0.1.6", 9 | "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz", 10 | "integrity": "sha512-utRNxnd9kSS2qhyivo9lMlt5qgAUasH2gb7BEOn6p0efFh24gjGomHzWKMAPn2hEReOPQZCJaRKoURwRotKucQ==" 11 | }, 12 | "@discordjs/form-data": { 13 | "version": "3.0.1", 14 | "resolved": "https://registry.npmjs.org/@discordjs/form-data/-/form-data-3.0.1.tgz", 15 | "integrity": "sha512-ZfFsbgEXW71Rw/6EtBdrP5VxBJy4dthyC0tpQKGKmYFImlmmrykO14Za+BiIVduwjte0jXEBlhSKf0MWbFp9Eg==", 16 | "requires": { 17 | "asynckit": "^0.4.0", 18 | "combined-stream": "^1.0.8", 19 | "mime-types": "^2.1.12" 20 | } 21 | }, 22 | "abort-controller": { 23 | "version": "3.0.0", 24 | "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", 25 | "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", 26 | "requires": { 27 | "event-target-shim": "^5.0.0" 28 | } 29 | }, 30 | "ajv": { 31 | "version": "6.12.5", 32 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", 33 | "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", 34 | "requires": { 35 | "fast-deep-equal": "^3.1.1", 36 | "fast-json-stable-stringify": "^2.0.0", 37 | "json-schema-traverse": "^0.4.1", 38 | "uri-js": "^4.2.2" 39 | } 40 | }, 41 | "asn1": { 42 | "version": "0.2.4", 43 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", 44 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", 45 | "requires": { 46 | "safer-buffer": "~2.1.0" 47 | } 48 | }, 49 | "assert-plus": { 50 | "version": "1.0.0", 51 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 52 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 53 | }, 54 | "asynckit": { 55 | "version": "0.4.0", 56 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 57 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 58 | }, 59 | "aws-sign2": { 60 | "version": "0.7.0", 61 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 62 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" 63 | }, 64 | "aws4": { 65 | "version": "1.10.1", 66 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.1.tgz", 67 | "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==" 68 | }, 69 | "bcrypt-pbkdf": { 70 | "version": "1.0.2", 71 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 72 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 73 | "requires": { 74 | "tweetnacl": "^0.14.3" 75 | }, 76 | "dependencies": { 77 | "tweetnacl": { 78 | "version": "0.14.5", 79 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 80 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" 81 | } 82 | } 83 | }, 84 | "caseless": { 85 | "version": "0.12.0", 86 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 87 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" 88 | }, 89 | "combined-stream": { 90 | "version": "1.0.8", 91 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 92 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 93 | "requires": { 94 | "delayed-stream": "~1.0.0" 95 | } 96 | }, 97 | "core-util-is": { 98 | "version": "1.0.2", 99 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 100 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 101 | }, 102 | "dashdash": { 103 | "version": "1.14.1", 104 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 105 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 106 | "requires": { 107 | "assert-plus": "^1.0.0" 108 | } 109 | }, 110 | "delayed-stream": { 111 | "version": "1.0.0", 112 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 113 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 114 | }, 115 | "discord.js": { 116 | "version": "12.3.1", 117 | "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-12.3.1.tgz", 118 | "integrity": "sha512-mSFyV/mbvzH12UXdS4zadmeUf8IMQOo/YdunubG1wWt1xjWvtaJz/s9CGsFD2B5pTw1W/LXxxUbrQjIZ/xlUdw==", 119 | "requires": { 120 | "@discordjs/collection": "^0.1.6", 121 | "@discordjs/form-data": "^3.0.1", 122 | "abort-controller": "^3.0.0", 123 | "node-fetch": "^2.6.0", 124 | "prism-media": "^1.2.2", 125 | "setimmediate": "^1.0.5", 126 | "tweetnacl": "^1.0.3", 127 | "ws": "^7.3.1" 128 | } 129 | }, 130 | "ecc-jsbn": { 131 | "version": "0.1.2", 132 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", 133 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", 134 | "requires": { 135 | "jsbn": "~0.1.0", 136 | "safer-buffer": "^2.1.0" 137 | } 138 | }, 139 | "event-target-shim": { 140 | "version": "5.0.1", 141 | "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", 142 | "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" 143 | }, 144 | "extend": { 145 | "version": "3.0.2", 146 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 147 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 148 | }, 149 | "extsprintf": { 150 | "version": "1.3.0", 151 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 152 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" 153 | }, 154 | "fast-deep-equal": { 155 | "version": "3.1.3", 156 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 157 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" 158 | }, 159 | "fast-json-stable-stringify": { 160 | "version": "2.1.0", 161 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 162 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" 163 | }, 164 | "forever-agent": { 165 | "version": "0.6.1", 166 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 167 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" 168 | }, 169 | "form-data": { 170 | "version": "2.3.3", 171 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", 172 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", 173 | "requires": { 174 | "asynckit": "^0.4.0", 175 | "combined-stream": "^1.0.6", 176 | "mime-types": "^2.1.12" 177 | } 178 | }, 179 | "fs": { 180 | "version": "0.0.1-security", 181 | "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", 182 | "integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ=" 183 | }, 184 | "getpass": { 185 | "version": "0.1.7", 186 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 187 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 188 | "requires": { 189 | "assert-plus": "^1.0.0" 190 | } 191 | }, 192 | "har-schema": { 193 | "version": "2.0.0", 194 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 195 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" 196 | }, 197 | "har-validator": { 198 | "version": "5.1.5", 199 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", 200 | "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", 201 | "requires": { 202 | "ajv": "^6.12.3", 203 | "har-schema": "^2.0.0" 204 | } 205 | }, 206 | "http-signature": { 207 | "version": "1.2.0", 208 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 209 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 210 | "requires": { 211 | "assert-plus": "^1.0.0", 212 | "jsprim": "^1.2.2", 213 | "sshpk": "^1.7.0" 214 | } 215 | }, 216 | "is-typedarray": { 217 | "version": "1.0.0", 218 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 219 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 220 | }, 221 | "isstream": { 222 | "version": "0.1.2", 223 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 224 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" 225 | }, 226 | "jsbn": { 227 | "version": "0.1.1", 228 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 229 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" 230 | }, 231 | "json-schema": { 232 | "version": "0.2.3", 233 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 234 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" 235 | }, 236 | "json-schema-traverse": { 237 | "version": "0.4.1", 238 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 239 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" 240 | }, 241 | "json-stringify-safe": { 242 | "version": "5.0.1", 243 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 244 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 245 | }, 246 | "jsprim": { 247 | "version": "1.4.1", 248 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 249 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 250 | "requires": { 251 | "assert-plus": "1.0.0", 252 | "extsprintf": "1.3.0", 253 | "json-schema": "0.2.3", 254 | "verror": "1.10.0" 255 | } 256 | }, 257 | "mime-db": { 258 | "version": "1.44.0", 259 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", 260 | "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" 261 | }, 262 | "mime-types": { 263 | "version": "2.1.27", 264 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", 265 | "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", 266 | "requires": { 267 | "mime-db": "1.44.0" 268 | } 269 | }, 270 | "node-fetch": { 271 | "version": "2.6.1", 272 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", 273 | "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" 274 | }, 275 | "oauth-sign": { 276 | "version": "0.9.0", 277 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", 278 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" 279 | }, 280 | "performance-now": { 281 | "version": "2.1.0", 282 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 283 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" 284 | }, 285 | "prism-media": { 286 | "version": "1.2.2", 287 | "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.2.tgz", 288 | "integrity": "sha512-I+nkWY212lJ500jLe4tN9tWO7nRiBAVdMv76P9kffZjYhw20raMlW1HSSvS+MLXC9MmbNZCazMrAr+5jEEgTuw==" 289 | }, 290 | "psl": { 291 | "version": "1.8.0", 292 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", 293 | "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" 294 | }, 295 | "punycode": { 296 | "version": "2.1.1", 297 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 298 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" 299 | }, 300 | "qs": { 301 | "version": "6.5.2", 302 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 303 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" 304 | }, 305 | "request": { 306 | "version": "2.88.2", 307 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", 308 | "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", 309 | "requires": { 310 | "aws-sign2": "~0.7.0", 311 | "aws4": "^1.8.0", 312 | "caseless": "~0.12.0", 313 | "combined-stream": "~1.0.6", 314 | "extend": "~3.0.2", 315 | "forever-agent": "~0.6.1", 316 | "form-data": "~2.3.2", 317 | "har-validator": "~5.1.3", 318 | "http-signature": "~1.2.0", 319 | "is-typedarray": "~1.0.0", 320 | "isstream": "~0.1.2", 321 | "json-stringify-safe": "~5.0.1", 322 | "mime-types": "~2.1.19", 323 | "oauth-sign": "~0.9.0", 324 | "performance-now": "^2.1.0", 325 | "qs": "~6.5.2", 326 | "safe-buffer": "^5.1.2", 327 | "tough-cookie": "~2.5.0", 328 | "tunnel-agent": "^0.6.0", 329 | "uuid": "^3.3.2" 330 | } 331 | }, 332 | "safe-buffer": { 333 | "version": "5.2.1", 334 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 335 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 336 | }, 337 | "safer-buffer": { 338 | "version": "2.1.2", 339 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 340 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 341 | }, 342 | "sax": { 343 | "version": "1.2.4", 344 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", 345 | "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" 346 | }, 347 | "setimmediate": { 348 | "version": "1.0.5", 349 | "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", 350 | "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" 351 | }, 352 | "sshpk": { 353 | "version": "1.16.1", 354 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", 355 | "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", 356 | "requires": { 357 | "asn1": "~0.2.3", 358 | "assert-plus": "^1.0.0", 359 | "bcrypt-pbkdf": "^1.0.0", 360 | "dashdash": "^1.12.0", 361 | "ecc-jsbn": "~0.1.1", 362 | "getpass": "^0.1.1", 363 | "jsbn": "~0.1.0", 364 | "safer-buffer": "^2.0.2", 365 | "tweetnacl": "~0.14.0" 366 | }, 367 | "dependencies": { 368 | "tweetnacl": { 369 | "version": "0.14.5", 370 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 371 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" 372 | } 373 | } 374 | }, 375 | "tough-cookie": { 376 | "version": "2.5.0", 377 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", 378 | "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", 379 | "requires": { 380 | "psl": "^1.1.28", 381 | "punycode": "^2.1.1" 382 | } 383 | }, 384 | "tunnel-agent": { 385 | "version": "0.6.0", 386 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 387 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 388 | "requires": { 389 | "safe-buffer": "^5.0.1" 390 | } 391 | }, 392 | "tweetnacl": { 393 | "version": "1.0.3", 394 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", 395 | "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" 396 | }, 397 | "uri-js": { 398 | "version": "4.4.0", 399 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", 400 | "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", 401 | "requires": { 402 | "punycode": "^2.1.0" 403 | } 404 | }, 405 | "uuid": { 406 | "version": "3.4.0", 407 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", 408 | "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" 409 | }, 410 | "verror": { 411 | "version": "1.10.0", 412 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 413 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 414 | "requires": { 415 | "assert-plus": "^1.0.0", 416 | "core-util-is": "1.0.2", 417 | "extsprintf": "^1.2.0" 418 | } 419 | }, 420 | "weather-js": { 421 | "version": "2.0.0", 422 | "resolved": "https://registry.npmjs.org/weather-js/-/weather-js-2.0.0.tgz", 423 | "integrity": "sha1-DZvNsFpPhNBrm585kAKKYB6kofw=", 424 | "requires": { 425 | "request": "2.x.x", 426 | "xml2js": "0.4.x" 427 | } 428 | }, 429 | "ws": { 430 | "version": "7.3.1", 431 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", 432 | "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==" 433 | }, 434 | "xml2js": { 435 | "version": "0.4.23", 436 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", 437 | "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", 438 | "requires": { 439 | "sax": ">=0.6.0", 440 | "xmlbuilder": "~11.0.0" 441 | } 442 | }, 443 | "xmlbuilder": { 444 | "version": "11.0.1", 445 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", 446 | "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" 447 | } 448 | } 449 | } 450 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "subbot", 3 | "version": "1.0.0", 4 | "description": "Bot for the Dev Submarine discord server", 5 | "main": "index.js", 6 | "dependencies": { 7 | "datadog-winston": "^1.0.1", 8 | "discord.js": "^12.3.1", 9 | "fs": "0.0.1-security", 10 | "node-fetch": "^2.6.1", 11 | "weather-js": "^2.0.0", 12 | "winston": "^3.2.1" 13 | }, 14 | "devDependencies": {}, 15 | "scripts": { 16 | "test": "echo \"Error: no test specified\" && exit 1" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "git+https://github.com/DevSubmarine/SubBot.git" 21 | }, 22 | "author": "", 23 | "license": "ISC", 24 | "bugs": { 25 | "url": "https://github.com/DevSubmarine/SubBot/issues" 26 | }, 27 | "homepage": "https://github.com/DevSubmarine/SubBot#readme" 28 | } 29 | --------------------------------------------------------------------------------