├── .dockerignore ├── .env.example ├── .eslintrc.js ├── .gitignore ├── Dockerfile ├── Dockerfile-native ├── LICENSE ├── README.md ├── docker-compose-example.yml ├── package-lock.json ├── package.json └── src ├── bot.js └── commands └── ping.js /.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | Dockerfile-native 3 | .env 4 | .dockerignore 5 | .gitignore 6 | 7 | *.log 8 | 9 | node_modules 10 | .git 11 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # Put your bot's Discord token here -- get it at https://discord.com/developers/applications and make sure to enable the server membr intent 2 | BOT_TOKEN= 3 | BOT_PREFIX=$ 4 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'env': { 3 | 'commonjs': true, 4 | 'es2020': true, 5 | 'node': true 6 | }, 7 | 'extends': 'eslint:recommended', 8 | 'parserOptions': { 9 | 'ecmaVersion': 11 10 | }, 11 | 'rules': { 12 | 'indent': [ 13 | 'error', 14 | 4 15 | ], 16 | 'linebreak-style': [ 17 | 'error', 18 | 'unix' 19 | ], 20 | 'quotes': [ 21 | 'error', 22 | 'single' 23 | ], 24 | 'semi': [ 25 | 'error', 26 | 'never' 27 | ] 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | config.json 3 | .env 4 | docker-compose.yml 5 | *.log 6 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Run/build with alpine image that has only runtime support 3 | # 4 | # NOTE: If you need to install dependencies that require native compilation, 5 | # consider using the Dockerfile-native example in this repo 6 | # 7 | FROM node:12-alpine as runtime 8 | 9 | WORKDIR /usr/src/app 10 | 11 | COPY package.json . 12 | COPY package-lock.json . 13 | COPY src ./src 14 | RUN npm ci --only=prod 15 | 16 | CMD [ "npm", "start" ] 17 | 18 | -------------------------------------------------------------------------------- /Dockerfile-native: -------------------------------------------------------------------------------- 1 | # Install dependencies with full node 12 image that has node-gyp build support 2 | FROM node:12 as builder 3 | 4 | WORKDIR /usr/src/app 5 | 6 | COPY package.json . 7 | COPY package-lock.json . 8 | 9 | RUN npm ci --only=prod 10 | 11 | # Run with alpine image that has only runtime support 12 | FROM node:12-alpine as runtime 13 | 14 | WORKDIR /usr/src/app 15 | 16 | COPY --from=builder /usr/src/app . 17 | COPY src ./src 18 | 19 | CMD [ "npm", "start" ] 20 | 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 RayzrDev 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bot Base 2 | 3 | > A simple Discord.js bot base. 4 | 5 | This is an extremely simple Discord.js bot base with a config loader / validator, a command handler, and a simple ping command. All code should be pretty self-explanatory. 6 | 7 | ## Hack the source, Luke! 8 | 9 | 1. Fork the repo 10 | 2. Clone your newly made fork 11 | 3. Run `npm ci` to install all dependecies 12 | 4. Copy the `.env.example` file that is provided to `.env` and fill out all provided variables 13 | 5. Run the bot with `npm start` 14 | 15 | It should be pretty simple to make your own commands, expand the command handler, etc. 16 | 17 | It would be appreciated if you would provide a link back to this original version though. 18 | 19 | ## Building docker images 20 | 21 | You can pretty easily build a docker image out of your bot using the provided `Dockerfile` and `Dockerfile-native`. To build your docker image, run the following inside your project: 22 | 23 | ```bash 24 | docker build . -t myname/my-cool-bot 25 | ``` 26 | 27 | If you have native dependencies that require a full node environment to install, either replace `Dockerfile` with `Dockerfile-native` or run the following: 28 | 29 | ```bash 30 | docker build -f Dockerfile-native . -t myname/my-cool-bot 31 | ``` 32 | 33 | Then to run the built docker image, attach to its virtual terminal, and read from your `.env` file, run the following: 34 | 35 | ```bash 36 | docker run -it --env-file .env myname/my-cool-bot 37 | ``` 38 | 39 | Hit ^C to kill the bot while it's running. See more about running docker images on the official docs for [docker run](https://docs.docker.com/engine/reference/commandline/run/). 40 | 41 | ## Using docker-compose to run multiple instances 42 | 43 | I've included a sample `docker-compose-example.yml` file which you can use to set up a `docker-compose.yml` file to use with, well, docker-compose. This allows you to easily run a number of instances of the same bot with different tokens, prefixes, etc, which is great if you want to do things like managed hosting for customers who pay you to host bots for them. 44 | 45 | Just copy `docker-compose-example.yml` to `docker-compose.yml`, tweak the environment variables and service names for each instance you want to run, and then use the following for reference: 46 | 47 | ```bash 48 | # if you want to see terminal output: 49 | docker-compose up 50 | # otherwise, run this to create the containers detached: 51 | docker-compose up -d 52 | # to start/stop: 53 | docker-compose start 54 | docker-compose stop 55 | # to remove the containers: 56 | docker-compose down 57 | ``` 58 | -------------------------------------------------------------------------------- /docker-compose-example.yml: -------------------------------------------------------------------------------- 1 | version: '3.8' 2 | 3 | services: 4 | bot-1: 5 | image: myname/my-cool-bot:latest 6 | environment: 7 | BOT_TOKEN: "some_cool_token" 8 | # Have to use $$ here because $ is a special character, this is the same as a "$" prefix 9 | BOT_PREFIX: "$$" 10 | bot-2: 11 | image: myname/my-cool-bot:latest 12 | environment: 13 | BOT_TOKEN: "some_other_cool_token" 14 | BOT_PREFIX: "!" 15 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bot-base", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/code-frame": { 8 | "version": "7.10.4", 9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", 10 | "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", 11 | "dev": true, 12 | "requires": { 13 | "@babel/highlight": "^7.10.4" 14 | } 15 | }, 16 | "@babel/helper-validator-identifier": { 17 | "version": "7.10.4", 18 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", 19 | "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", 20 | "dev": true 21 | }, 22 | "@babel/highlight": { 23 | "version": "7.10.4", 24 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", 25 | "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", 26 | "dev": true, 27 | "requires": { 28 | "@babel/helper-validator-identifier": "^7.10.4", 29 | "chalk": "^2.0.0", 30 | "js-tokens": "^4.0.0" 31 | }, 32 | "dependencies": { 33 | "chalk": { 34 | "version": "2.4.2", 35 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 36 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 37 | "dev": true, 38 | "requires": { 39 | "ansi-styles": "^3.2.1", 40 | "escape-string-regexp": "^1.0.5", 41 | "supports-color": "^5.3.0" 42 | } 43 | } 44 | } 45 | }, 46 | "@discordjs/collection": { 47 | "version": "0.1.6", 48 | "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz", 49 | "integrity": "sha512-utRNxnd9kSS2qhyivo9lMlt5qgAUasH2gb7BEOn6p0efFh24gjGomHzWKMAPn2hEReOPQZCJaRKoURwRotKucQ==" 50 | }, 51 | "@discordjs/form-data": { 52 | "version": "3.0.1", 53 | "resolved": "https://registry.npmjs.org/@discordjs/form-data/-/form-data-3.0.1.tgz", 54 | "integrity": "sha512-ZfFsbgEXW71Rw/6EtBdrP5VxBJy4dthyC0tpQKGKmYFImlmmrykO14Za+BiIVduwjte0jXEBlhSKf0MWbFp9Eg==", 55 | "requires": { 56 | "asynckit": "^0.4.0", 57 | "combined-stream": "^1.0.8", 58 | "mime-types": "^2.1.12" 59 | } 60 | }, 61 | "@eslint/eslintrc": { 62 | "version": "0.1.3", 63 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.1.3.tgz", 64 | "integrity": "sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA==", 65 | "dev": true, 66 | "requires": { 67 | "ajv": "^6.12.4", 68 | "debug": "^4.1.1", 69 | "espree": "^7.3.0", 70 | "globals": "^12.1.0", 71 | "ignore": "^4.0.6", 72 | "import-fresh": "^3.2.1", 73 | "js-yaml": "^3.13.1", 74 | "lodash": "^4.17.19", 75 | "minimatch": "^3.0.4", 76 | "strip-json-comments": "^3.1.1" 77 | } 78 | }, 79 | "@types/color-name": { 80 | "version": "1.1.1", 81 | "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", 82 | "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", 83 | "dev": true 84 | }, 85 | "abort-controller": { 86 | "version": "3.0.0", 87 | "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", 88 | "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", 89 | "requires": { 90 | "event-target-shim": "^5.0.0" 91 | } 92 | }, 93 | "acorn": { 94 | "version": "7.4.0", 95 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", 96 | "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", 97 | "dev": true 98 | }, 99 | "acorn-jsx": { 100 | "version": "5.3.1", 101 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", 102 | "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", 103 | "dev": true 104 | }, 105 | "ajv": { 106 | "version": "6.12.5", 107 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", 108 | "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", 109 | "dev": true, 110 | "requires": { 111 | "fast-deep-equal": "^3.1.1", 112 | "fast-json-stable-stringify": "^2.0.0", 113 | "json-schema-traverse": "^0.4.1", 114 | "uri-js": "^4.2.2" 115 | } 116 | }, 117 | "ansi-colors": { 118 | "version": "4.1.1", 119 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", 120 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", 121 | "dev": true 122 | }, 123 | "ansi-regex": { 124 | "version": "5.0.0", 125 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 126 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", 127 | "dev": true 128 | }, 129 | "ansi-styles": { 130 | "version": "3.2.1", 131 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 132 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 133 | "dev": true, 134 | "requires": { 135 | "color-convert": "^1.9.0" 136 | } 137 | }, 138 | "argparse": { 139 | "version": "1.0.10", 140 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 141 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 142 | "dev": true, 143 | "requires": { 144 | "sprintf-js": "~1.0.2" 145 | } 146 | }, 147 | "astral-regex": { 148 | "version": "1.0.0", 149 | "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", 150 | "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", 151 | "dev": true 152 | }, 153 | "asynckit": { 154 | "version": "0.4.0", 155 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 156 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 157 | }, 158 | "balanced-match": { 159 | "version": "1.0.0", 160 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 161 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 162 | "dev": true 163 | }, 164 | "brace-expansion": { 165 | "version": "1.1.11", 166 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 167 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 168 | "dev": true, 169 | "requires": { 170 | "balanced-match": "^1.0.0", 171 | "concat-map": "0.0.1" 172 | } 173 | }, 174 | "callsites": { 175 | "version": "3.1.0", 176 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 177 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 178 | "dev": true 179 | }, 180 | "chalk": { 181 | "version": "4.1.0", 182 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", 183 | "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", 184 | "dev": true, 185 | "requires": { 186 | "ansi-styles": "^4.1.0", 187 | "supports-color": "^7.1.0" 188 | }, 189 | "dependencies": { 190 | "ansi-styles": { 191 | "version": "4.2.1", 192 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", 193 | "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", 194 | "dev": true, 195 | "requires": { 196 | "@types/color-name": "^1.1.1", 197 | "color-convert": "^2.0.1" 198 | } 199 | }, 200 | "color-convert": { 201 | "version": "2.0.1", 202 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 203 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 204 | "dev": true, 205 | "requires": { 206 | "color-name": "~1.1.4" 207 | } 208 | }, 209 | "color-name": { 210 | "version": "1.1.4", 211 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 212 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 213 | "dev": true 214 | }, 215 | "has-flag": { 216 | "version": "4.0.0", 217 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 218 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 219 | "dev": true 220 | }, 221 | "supports-color": { 222 | "version": "7.2.0", 223 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 224 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 225 | "dev": true, 226 | "requires": { 227 | "has-flag": "^4.0.0" 228 | } 229 | } 230 | } 231 | }, 232 | "color-convert": { 233 | "version": "1.9.3", 234 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 235 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 236 | "dev": true, 237 | "requires": { 238 | "color-name": "1.1.3" 239 | } 240 | }, 241 | "color-name": { 242 | "version": "1.1.3", 243 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 244 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 245 | "dev": true 246 | }, 247 | "combined-stream": { 248 | "version": "1.0.8", 249 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 250 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 251 | "requires": { 252 | "delayed-stream": "~1.0.0" 253 | } 254 | }, 255 | "concat-map": { 256 | "version": "0.0.1", 257 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 258 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 259 | "dev": true 260 | }, 261 | "cross-spawn": { 262 | "version": "7.0.3", 263 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 264 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 265 | "dev": true, 266 | "requires": { 267 | "path-key": "^3.1.0", 268 | "shebang-command": "^2.0.0", 269 | "which": "^2.0.1" 270 | } 271 | }, 272 | "debug": { 273 | "version": "4.2.0", 274 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", 275 | "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", 276 | "dev": true, 277 | "requires": { 278 | "ms": "2.1.2" 279 | } 280 | }, 281 | "deep-is": { 282 | "version": "0.1.3", 283 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 284 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 285 | "dev": true 286 | }, 287 | "delayed-stream": { 288 | "version": "1.0.0", 289 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 290 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 291 | }, 292 | "discord.js": { 293 | "version": "12.5.1", 294 | "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-12.5.1.tgz", 295 | "integrity": "sha512-VwZkVaUAIOB9mKdca0I5MefPMTQJTNg0qdgi1huF3iwsFwJ0L5s/Y69AQe+iPmjuV6j9rtKoG0Ta0n9vgEIL6w==", 296 | "requires": { 297 | "@discordjs/collection": "^0.1.6", 298 | "@discordjs/form-data": "^3.0.1", 299 | "abort-controller": "^3.0.0", 300 | "node-fetch": "^2.6.1", 301 | "prism-media": "^1.2.2", 302 | "setimmediate": "^1.0.5", 303 | "tweetnacl": "^1.0.3", 304 | "ws": "^7.3.1" 305 | } 306 | }, 307 | "doctrine": { 308 | "version": "3.0.0", 309 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 310 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 311 | "dev": true, 312 | "requires": { 313 | "esutils": "^2.0.2" 314 | } 315 | }, 316 | "dotenv": { 317 | "version": "8.2.0", 318 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", 319 | "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" 320 | }, 321 | "emoji-regex": { 322 | "version": "7.0.3", 323 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 324 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 325 | "dev": true 326 | }, 327 | "enquirer": { 328 | "version": "2.3.6", 329 | "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", 330 | "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", 331 | "dev": true, 332 | "requires": { 333 | "ansi-colors": "^4.1.1" 334 | } 335 | }, 336 | "escape-string-regexp": { 337 | "version": "1.0.5", 338 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 339 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 340 | "dev": true 341 | }, 342 | "eslint": { 343 | "version": "7.10.0", 344 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.10.0.tgz", 345 | "integrity": "sha512-BDVffmqWl7JJXqCjAK6lWtcQThZB/aP1HXSH1JKwGwv0LQEdvpR7qzNrUT487RM39B5goWuboFad5ovMBmD8yA==", 346 | "dev": true, 347 | "requires": { 348 | "@babel/code-frame": "^7.0.0", 349 | "@eslint/eslintrc": "^0.1.3", 350 | "ajv": "^6.10.0", 351 | "chalk": "^4.0.0", 352 | "cross-spawn": "^7.0.2", 353 | "debug": "^4.0.1", 354 | "doctrine": "^3.0.0", 355 | "enquirer": "^2.3.5", 356 | "eslint-scope": "^5.1.1", 357 | "eslint-utils": "^2.1.0", 358 | "eslint-visitor-keys": "^1.3.0", 359 | "espree": "^7.3.0", 360 | "esquery": "^1.2.0", 361 | "esutils": "^2.0.2", 362 | "file-entry-cache": "^5.0.1", 363 | "functional-red-black-tree": "^1.0.1", 364 | "glob-parent": "^5.0.0", 365 | "globals": "^12.1.0", 366 | "ignore": "^4.0.6", 367 | "import-fresh": "^3.0.0", 368 | "imurmurhash": "^0.1.4", 369 | "is-glob": "^4.0.0", 370 | "js-yaml": "^3.13.1", 371 | "json-stable-stringify-without-jsonify": "^1.0.1", 372 | "levn": "^0.4.1", 373 | "lodash": "^4.17.19", 374 | "minimatch": "^3.0.4", 375 | "natural-compare": "^1.4.0", 376 | "optionator": "^0.9.1", 377 | "progress": "^2.0.0", 378 | "regexpp": "^3.1.0", 379 | "semver": "^7.2.1", 380 | "strip-ansi": "^6.0.0", 381 | "strip-json-comments": "^3.1.0", 382 | "table": "^5.2.3", 383 | "text-table": "^0.2.0", 384 | "v8-compile-cache": "^2.0.3" 385 | } 386 | }, 387 | "eslint-scope": { 388 | "version": "5.1.1", 389 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", 390 | "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", 391 | "dev": true, 392 | "requires": { 393 | "esrecurse": "^4.3.0", 394 | "estraverse": "^4.1.1" 395 | } 396 | }, 397 | "eslint-utils": { 398 | "version": "2.1.0", 399 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", 400 | "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", 401 | "dev": true, 402 | "requires": { 403 | "eslint-visitor-keys": "^1.1.0" 404 | } 405 | }, 406 | "eslint-visitor-keys": { 407 | "version": "1.3.0", 408 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", 409 | "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", 410 | "dev": true 411 | }, 412 | "espree": { 413 | "version": "7.3.0", 414 | "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", 415 | "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", 416 | "dev": true, 417 | "requires": { 418 | "acorn": "^7.4.0", 419 | "acorn-jsx": "^5.2.0", 420 | "eslint-visitor-keys": "^1.3.0" 421 | } 422 | }, 423 | "esprima": { 424 | "version": "4.0.1", 425 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 426 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 427 | "dev": true 428 | }, 429 | "esquery": { 430 | "version": "1.3.1", 431 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", 432 | "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", 433 | "dev": true, 434 | "requires": { 435 | "estraverse": "^5.1.0" 436 | }, 437 | "dependencies": { 438 | "estraverse": { 439 | "version": "5.2.0", 440 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", 441 | "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", 442 | "dev": true 443 | } 444 | } 445 | }, 446 | "esrecurse": { 447 | "version": "4.3.0", 448 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 449 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 450 | "dev": true, 451 | "requires": { 452 | "estraverse": "^5.2.0" 453 | }, 454 | "dependencies": { 455 | "estraverse": { 456 | "version": "5.2.0", 457 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", 458 | "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", 459 | "dev": true 460 | } 461 | } 462 | }, 463 | "estraverse": { 464 | "version": "4.3.0", 465 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 466 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 467 | "dev": true 468 | }, 469 | "esutils": { 470 | "version": "2.0.3", 471 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 472 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 473 | "dev": true 474 | }, 475 | "event-target-shim": { 476 | "version": "5.0.1", 477 | "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", 478 | "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" 479 | }, 480 | "fast-deep-equal": { 481 | "version": "3.1.3", 482 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 483 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 484 | "dev": true 485 | }, 486 | "fast-json-stable-stringify": { 487 | "version": "2.1.0", 488 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 489 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 490 | "dev": true 491 | }, 492 | "fast-levenshtein": { 493 | "version": "2.0.6", 494 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 495 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 496 | "dev": true 497 | }, 498 | "file-entry-cache": { 499 | "version": "5.0.1", 500 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", 501 | "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", 502 | "dev": true, 503 | "requires": { 504 | "flat-cache": "^2.0.1" 505 | } 506 | }, 507 | "flat-cache": { 508 | "version": "2.0.1", 509 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", 510 | "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", 511 | "dev": true, 512 | "requires": { 513 | "flatted": "^2.0.0", 514 | "rimraf": "2.6.3", 515 | "write": "1.0.3" 516 | } 517 | }, 518 | "flatted": { 519 | "version": "2.0.2", 520 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", 521 | "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", 522 | "dev": true 523 | }, 524 | "fs.realpath": { 525 | "version": "1.0.0", 526 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 527 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 528 | "dev": true 529 | }, 530 | "functional-red-black-tree": { 531 | "version": "1.0.1", 532 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 533 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", 534 | "dev": true 535 | }, 536 | "glob": { 537 | "version": "7.1.6", 538 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 539 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 540 | "dev": true, 541 | "requires": { 542 | "fs.realpath": "^1.0.0", 543 | "inflight": "^1.0.4", 544 | "inherits": "2", 545 | "minimatch": "^3.0.4", 546 | "once": "^1.3.0", 547 | "path-is-absolute": "^1.0.0" 548 | } 549 | }, 550 | "glob-parent": { 551 | "version": "5.1.1", 552 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", 553 | "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", 554 | "dev": true, 555 | "requires": { 556 | "is-glob": "^4.0.1" 557 | } 558 | }, 559 | "globals": { 560 | "version": "12.4.0", 561 | "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", 562 | "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", 563 | "dev": true, 564 | "requires": { 565 | "type-fest": "^0.8.1" 566 | } 567 | }, 568 | "has-flag": { 569 | "version": "3.0.0", 570 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 571 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 572 | "dev": true 573 | }, 574 | "ignore": { 575 | "version": "4.0.6", 576 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", 577 | "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", 578 | "dev": true 579 | }, 580 | "import-fresh": { 581 | "version": "3.2.1", 582 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", 583 | "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", 584 | "dev": true, 585 | "requires": { 586 | "parent-module": "^1.0.0", 587 | "resolve-from": "^4.0.0" 588 | } 589 | }, 590 | "imurmurhash": { 591 | "version": "0.1.4", 592 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 593 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 594 | "dev": true 595 | }, 596 | "inflight": { 597 | "version": "1.0.6", 598 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 599 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 600 | "dev": true, 601 | "requires": { 602 | "once": "^1.3.0", 603 | "wrappy": "1" 604 | } 605 | }, 606 | "inherits": { 607 | "version": "2.0.4", 608 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 609 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 610 | "dev": true 611 | }, 612 | "is-extglob": { 613 | "version": "2.1.1", 614 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 615 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 616 | "dev": true 617 | }, 618 | "is-fullwidth-code-point": { 619 | "version": "2.0.0", 620 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 621 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 622 | "dev": true 623 | }, 624 | "is-glob": { 625 | "version": "4.0.1", 626 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 627 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 628 | "dev": true, 629 | "requires": { 630 | "is-extglob": "^2.1.1" 631 | } 632 | }, 633 | "isexe": { 634 | "version": "2.0.0", 635 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 636 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 637 | "dev": true 638 | }, 639 | "js-tokens": { 640 | "version": "4.0.0", 641 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 642 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 643 | "dev": true 644 | }, 645 | "js-yaml": { 646 | "version": "3.14.0", 647 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", 648 | "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", 649 | "dev": true, 650 | "requires": { 651 | "argparse": "^1.0.7", 652 | "esprima": "^4.0.0" 653 | } 654 | }, 655 | "json-schema-traverse": { 656 | "version": "0.4.1", 657 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 658 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 659 | "dev": true 660 | }, 661 | "json-stable-stringify-without-jsonify": { 662 | "version": "1.0.1", 663 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 664 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 665 | "dev": true 666 | }, 667 | "levn": { 668 | "version": "0.4.1", 669 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 670 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 671 | "dev": true, 672 | "requires": { 673 | "prelude-ls": "^1.2.1", 674 | "type-check": "~0.4.0" 675 | } 676 | }, 677 | "lodash": { 678 | "version": "4.17.20", 679 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", 680 | "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", 681 | "dev": true 682 | }, 683 | "mime-db": { 684 | "version": "1.44.0", 685 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", 686 | "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" 687 | }, 688 | "mime-types": { 689 | "version": "2.1.27", 690 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", 691 | "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", 692 | "requires": { 693 | "mime-db": "1.44.0" 694 | } 695 | }, 696 | "minimatch": { 697 | "version": "3.0.4", 698 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 699 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 700 | "dev": true, 701 | "requires": { 702 | "brace-expansion": "^1.1.7" 703 | } 704 | }, 705 | "minimist": { 706 | "version": "1.2.5", 707 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 708 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", 709 | "dev": true 710 | }, 711 | "mkdirp": { 712 | "version": "0.5.5", 713 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", 714 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", 715 | "dev": true, 716 | "requires": { 717 | "minimist": "^1.2.5" 718 | } 719 | }, 720 | "ms": { 721 | "version": "2.1.2", 722 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 723 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 724 | "dev": true 725 | }, 726 | "natural-compare": { 727 | "version": "1.4.0", 728 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 729 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 730 | "dev": true 731 | }, 732 | "node-fetch": { 733 | "version": "2.6.1", 734 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", 735 | "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" 736 | }, 737 | "once": { 738 | "version": "1.4.0", 739 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 740 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 741 | "dev": true, 742 | "requires": { 743 | "wrappy": "1" 744 | } 745 | }, 746 | "optionator": { 747 | "version": "0.9.1", 748 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", 749 | "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", 750 | "dev": true, 751 | "requires": { 752 | "deep-is": "^0.1.3", 753 | "fast-levenshtein": "^2.0.6", 754 | "levn": "^0.4.1", 755 | "prelude-ls": "^1.2.1", 756 | "type-check": "^0.4.0", 757 | "word-wrap": "^1.2.3" 758 | } 759 | }, 760 | "parent-module": { 761 | "version": "1.0.1", 762 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 763 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 764 | "dev": true, 765 | "requires": { 766 | "callsites": "^3.0.0" 767 | } 768 | }, 769 | "path-is-absolute": { 770 | "version": "1.0.1", 771 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 772 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 773 | "dev": true 774 | }, 775 | "path-key": { 776 | "version": "3.1.1", 777 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 778 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 779 | "dev": true 780 | }, 781 | "prelude-ls": { 782 | "version": "1.2.1", 783 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 784 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 785 | "dev": true 786 | }, 787 | "prism-media": { 788 | "version": "1.2.2", 789 | "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.2.tgz", 790 | "integrity": "sha512-I+nkWY212lJ500jLe4tN9tWO7nRiBAVdMv76P9kffZjYhw20raMlW1HSSvS+MLXC9MmbNZCazMrAr+5jEEgTuw==" 791 | }, 792 | "progress": { 793 | "version": "2.0.3", 794 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 795 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", 796 | "dev": true 797 | }, 798 | "punycode": { 799 | "version": "2.1.1", 800 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 801 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 802 | "dev": true 803 | }, 804 | "regexpp": { 805 | "version": "3.1.0", 806 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", 807 | "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", 808 | "dev": true 809 | }, 810 | "resolve-from": { 811 | "version": "4.0.0", 812 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 813 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 814 | "dev": true 815 | }, 816 | "rimraf": { 817 | "version": "2.6.3", 818 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", 819 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", 820 | "dev": true, 821 | "requires": { 822 | "glob": "^7.1.3" 823 | } 824 | }, 825 | "semver": { 826 | "version": "7.3.2", 827 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", 828 | "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", 829 | "dev": true 830 | }, 831 | "setimmediate": { 832 | "version": "1.0.5", 833 | "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", 834 | "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" 835 | }, 836 | "shebang-command": { 837 | "version": "2.0.0", 838 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 839 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 840 | "dev": true, 841 | "requires": { 842 | "shebang-regex": "^3.0.0" 843 | } 844 | }, 845 | "shebang-regex": { 846 | "version": "3.0.0", 847 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 848 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 849 | "dev": true 850 | }, 851 | "slice-ansi": { 852 | "version": "2.1.0", 853 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", 854 | "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", 855 | "dev": true, 856 | "requires": { 857 | "ansi-styles": "^3.2.0", 858 | "astral-regex": "^1.0.0", 859 | "is-fullwidth-code-point": "^2.0.0" 860 | } 861 | }, 862 | "sprintf-js": { 863 | "version": "1.0.3", 864 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 865 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 866 | "dev": true 867 | }, 868 | "string-width": { 869 | "version": "3.1.0", 870 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 871 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 872 | "dev": true, 873 | "requires": { 874 | "emoji-regex": "^7.0.1", 875 | "is-fullwidth-code-point": "^2.0.0", 876 | "strip-ansi": "^5.1.0" 877 | }, 878 | "dependencies": { 879 | "ansi-regex": { 880 | "version": "4.1.0", 881 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 882 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 883 | "dev": true 884 | }, 885 | "strip-ansi": { 886 | "version": "5.2.0", 887 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 888 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 889 | "dev": true, 890 | "requires": { 891 | "ansi-regex": "^4.1.0" 892 | } 893 | } 894 | } 895 | }, 896 | "strip-ansi": { 897 | "version": "6.0.0", 898 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 899 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 900 | "dev": true, 901 | "requires": { 902 | "ansi-regex": "^5.0.0" 903 | } 904 | }, 905 | "strip-json-comments": { 906 | "version": "3.1.1", 907 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 908 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 909 | "dev": true 910 | }, 911 | "supports-color": { 912 | "version": "5.5.0", 913 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 914 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 915 | "dev": true, 916 | "requires": { 917 | "has-flag": "^3.0.0" 918 | } 919 | }, 920 | "table": { 921 | "version": "5.4.6", 922 | "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", 923 | "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", 924 | "dev": true, 925 | "requires": { 926 | "ajv": "^6.10.2", 927 | "lodash": "^4.17.14", 928 | "slice-ansi": "^2.1.0", 929 | "string-width": "^3.0.0" 930 | } 931 | }, 932 | "text-table": { 933 | "version": "0.2.0", 934 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 935 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 936 | "dev": true 937 | }, 938 | "tweetnacl": { 939 | "version": "1.0.3", 940 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", 941 | "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" 942 | }, 943 | "type-check": { 944 | "version": "0.4.0", 945 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 946 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 947 | "dev": true, 948 | "requires": { 949 | "prelude-ls": "^1.2.1" 950 | } 951 | }, 952 | "type-fest": { 953 | "version": "0.8.1", 954 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", 955 | "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", 956 | "dev": true 957 | }, 958 | "uri-js": { 959 | "version": "4.4.0", 960 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", 961 | "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", 962 | "dev": true, 963 | "requires": { 964 | "punycode": "^2.1.0" 965 | } 966 | }, 967 | "v8-compile-cache": { 968 | "version": "2.1.1", 969 | "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", 970 | "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", 971 | "dev": true 972 | }, 973 | "which": { 974 | "version": "2.0.2", 975 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 976 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 977 | "dev": true, 978 | "requires": { 979 | "isexe": "^2.0.0" 980 | } 981 | }, 982 | "word-wrap": { 983 | "version": "1.2.3", 984 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 985 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 986 | "dev": true 987 | }, 988 | "wrappy": { 989 | "version": "1.0.2", 990 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 991 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 992 | "dev": true 993 | }, 994 | "write": { 995 | "version": "1.0.3", 996 | "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", 997 | "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", 998 | "dev": true, 999 | "requires": { 1000 | "mkdirp": "^0.5.1" 1001 | } 1002 | }, 1003 | "ws": { 1004 | "version": "7.4.0", 1005 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.0.tgz", 1006 | "integrity": "sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ==" 1007 | } 1008 | } 1009 | } 1010 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bot-base", 3 | "version": "1.0.0", 4 | "description": "A simple Discord.js bot base.", 5 | "main": "src/bot.js", 6 | "repository": "https://github.com/RayzrDev/bot-base.git", 7 | "author": "Rayzr522 ", 8 | "license": "MIT", 9 | "dependencies": { 10 | "discord.js": "^12.5.1", 11 | "dotenv": "^8.2.0" 12 | }, 13 | "scripts": { 14 | "start": "node .", 15 | "lint": "eslint src" 16 | }, 17 | "devDependencies": { 18 | "eslint": "^7.10.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/bot.js: -------------------------------------------------------------------------------- 1 | // Built-in libraries from Node.JS 2 | const path = require('path') 3 | const fs = require('fs') 4 | // Only import the Client class from Discord.js 5 | const { Client, Intents } = require('discord.js') 6 | 7 | require('dotenv').config() 8 | 9 | // Super fancy config loader/validator 10 | const config = (() => { 11 | const token = process.env.BOT_TOKEN 12 | 13 | // If there isn't a token, the bot won't start, but if there is then 14 | // we want to make sure it's a valid bot token 15 | if (!token) { 16 | console.error('Missing BOT_TOKEN environment variable') 17 | process.exit(1) 18 | } 19 | 20 | if (!/^[a-zA-Z0-9_.-]{59}$/.test(token)) { 21 | console.error('Invalid bot token!') 22 | process.exit(1) 23 | } 24 | 25 | const prefix = process.env.BOT_PREFIX 26 | 27 | if (!prefix) { 28 | console.error('Missing BOT_PREFIX environment variable') 29 | process.exit(1) 30 | } 31 | 32 | return { token, prefix } 33 | })() 34 | 35 | // Store the commands in a Map (slightly better than a raw object) 36 | const commands = new Map() 37 | // Define gateway intents 38 | const intents = new Intents([ 39 | Intents.NON_PRIVILEGED, // include all non-privileged intents, would be better to specify which ones you actually need 40 | "GUILD_MEMBERS", // lets you request guild members 41 | ]); 42 | // Create the client 43 | const bot = new Client({ partials: ['MESSAGE', 'CHANNEL', 'REACTION'], ws: { intents }, fetchAllMembers: true, disableEveryone: true }) 44 | 45 | // Store the config and commands on the bot variable so as to make them 46 | // easily accessible in commands and other files 47 | bot.config = config 48 | bot.commands = commands 49 | 50 | // Read every file in ./commands and filter out the non-JS files 51 | fs.readdirSync(path.resolve(__dirname, 'commands')) 52 | .filter(f => f.endsWith('.js')) 53 | .forEach(f => { 54 | // Attempt to load the file 55 | console.log(`Loading command ${f}`) 56 | try { 57 | // Require the raw file 58 | let command = require(`./commands/${f}`) 59 | // Validate that there's a run function and a valid help object 60 | if (typeof command.run !== 'function') { 61 | throw 'Command is missing a run function!' 62 | } else if (!command.help || !command.help.name) { 63 | throw 'Command is missing a valid help object!' 64 | } 65 | // Store the command in the map based on its name 66 | commands.set(command.help.name, command) 67 | } catch (error) { 68 | // Log any errors from the validator or from requiring the file 69 | console.error(`Failed to load command ${f}: ${error}`) 70 | } 71 | }) 72 | 73 | bot.on('ready', () => { 74 | console.log(`Logged in as ${bot.user.tag} (ID: ${bot.user.id})`) 75 | bot.generateInvite({ permissions: [ 76 | 'SEND_MESSAGES', 77 | 'MANAGE_MESSAGES', 78 | // Here are some other common permissions you might want to include: 79 | // (Complete list can be found at https://discord.js.org/#/docs/main/stable/class/Permissions?scrollTo=s-FLAGS) 80 | // 81 | // *** General moderation permissions: 82 | // 'KICK_MEMBERS', 83 | // 'BAN_MEMBERS', 84 | // *** Guild settings permissions: 85 | // 'MANAGE_CHANNELS', 86 | // 'MANAGE_GUILD', 87 | // 'MANAGE_NICKNAMES', 88 | // 'MANAGE_ROLES', 89 | // *** Voice permissions: 90 | // 'CONNECT', 91 | // 'SPEAK', 92 | // *** Voice moderation permissions: 93 | // 'MOVE_MEMBERS', 94 | // 'MUTE_MEMBERS', 95 | // 'DEAFEN_MEMBERS', 96 | ]}).then(invite => { 97 | // After generating the invite, log it to the console 98 | console.log(`Click here to invite the bot to your guild:\n${invite}`) 99 | }) 100 | }) 101 | 102 | bot.on('message', message => { 103 | // Ignore messages from bots and from DMs (non-guild channels) 104 | if (message.author.bot || !message.guild) { 105 | return 106 | } 107 | 108 | // Just a shorthand variable 109 | let { content } = message 110 | // Ignore any messages that don't start with the configurable prefix 111 | if (!content.startsWith(config.prefix)) { 112 | return 113 | } 114 | 115 | // Take all the text after the prefix and split it into an array, 116 | // splitting at every space (so 'hello world' becomes ['hello', 'world']) 117 | let split = content.substr(config.prefix.length).split(' ') 118 | // Get the command label (which is the first word after the prefix) 119 | let label = split[0] 120 | // Get the rest of the words after the prefix 121 | let args = split.slice(1) 122 | 123 | // If there's a command with that given label... 124 | if (commands.get(label)) { 125 | // ... get the command with that label and run it with the bot, the 126 | // message variable, and the args as parameters 127 | commands.get(label).run(bot, message, args) 128 | } 129 | }) 130 | 131 | // Only run the bot if the token was provided 132 | config.token && bot.login(config.token) 133 | -------------------------------------------------------------------------------- /src/commands/ping.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-unused-vars 2 | exports.run = (bot, msg, args) => { 3 | msg.channel.send(':watch: | Ping!').then(m => { 4 | m.edit(`:watch: | Pong! \`${m.createdTimestamp - msg.createdTimestamp}ms\``) 5 | }) 6 | } 7 | 8 | exports.help = { 9 | name: 'ping', 10 | usage: 'ping', 11 | description: 'Pings the bot to check its connection speed.' 12 | } 13 | --------------------------------------------------------------------------------