Migrated away from static JSON configuration files in favor of environmental variables.

This commit is contained in:
chris062689 2017-09-29 19:21:48 -04:00
parent 0e7d7aad46
commit 5fe71a0e40
7 changed files with 162 additions and 162 deletions

View File

@ -5,9 +5,9 @@ WORKDIR /usr/src/app
# Install app dependencies
COPY package.json package-lock.json ./
RUN npm install --production
RUN npm install
# Bundle app source
COPY . .
ENTRYPOINT [ "npm", "run", "start-prod" ]
ENTRYPOINT [ "node", "server.js" ]

View File

@ -1,33 +0,0 @@
{
"app": "discord-bot",
"logdnaKey": "",
"enableLogdnaLogging": false,
"enableConsoleLogging": true,
"commandPrefix": ".",
"logChannel": null,
"clientLoginToken": null,
"pmReply": "Please refer to our **Frequently Asked Questions**. <https://citra-emu.org/wiki/faq/>",
"quotes": {
"faq": { "reply": "Please refer to our **Frequently Asked Questions**. <https://citra-emu.org/wiki/faq/>" },
"cpu": { "reply": "Citra requires powerful single-core performance. Refer to your CPU in this graph. Your experience with Citra won't be enjoyable in most games if it's below 1,800. <https://www.cpubenchmark.net/singleThread.html>" },
"requirements": { "reply": "Please refer to our **Frequently Asked Questions**. The only requirements for Citra are a GPU that supports at least OpenGL 3.3 and a 64-bit OS, but you definitely want a processor with the highest possible performance per core. <https://citra-emu.org/wiki/faq/>"},
"roms": { "warn": true, "reply": "Please read our __community rules__. Warez/downloading games talk is strictly prohibited. To prevent legal issues, you are not allowed to post links or refer to any kind of ROM, NAND, ISO, game, or other copyrighted material that has been illegally obtained or shared. <https://citra-emu.org/rules/>"},
"dump-game": { "reply": "Please refer to our __game dumping guides__. <https://citra-emu.org/wiki/dumping-game-cartridges/> & <https://citra-emu.org/wiki/dumping-installed-titles/>"},
"dump-system": { "reply": "Please refer to our __system dumping guide__. <https://citra-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-3ds-console/>"},
"pokemon": { "reply": "Click here to view our game compatibility list: <https://citra-emu.org/game/>"},
"alpha": { "reply": "*Citra* is currently in very early stages of development. Games usually run less than full-speed even on the best computers. Expect bugs and glitches to appear in most games. Many features found in more mature emulators are still in the works. For any major updates, please visit <https://citra-emu.org/>"},
"updates": { "reply": "You can check our latest updates on *Github*. <https://github.com/citra-emu/citra/pulse>"},
"download": { "reply": "Please only download from the official *Citra* website, as downloading from other sources is not supported here. <https://citra-emu.org/download/>"},
"legal": { "reply": "*Citra* is legal, we don't support illegal activities. Dumping your purchased games and system files from your 3DS is legal. Downloading them is not."},
"building": { "reply": "Please refer to our building guides.\nWindows: <https://citra-emu.org/wiki/building-for-windows> \nmacOS: <https://citra-emu.org/wiki/building-for-macos> \nLinux: <https://citra-emu.org/wiki/building-for-linux>"},
"controller": { "reply": "This forum topic tells you how to __configure your gamepad / controller__: <https://community.citra-emu.org/t/temporary-controller-configurations-for-citra/1061>"},
"issues": { "reply": "This forum topic lists __known issues in games and their workarounds__: <https://community.citra-emu.org/t/known-problems-typical-issues-and-their-workarounds/1317> \nPlease read it carefully. It includes help with most games"},
"forum": { "reply": "This question might be more suitable for the *Citra* forum. <https://community.citra-emu.org/>"},
"game": { "reply": "Click here to view our game compatibility list: <https://citra-emu.org/game/>"},
"log": { "reply": "This forum topic tells you how to __get the log file__: <https://community.citra-emu.org/t/how-to-upload-the-log-file/296>"}
}
}

23
env.json Normal file
View File

@ -0,0 +1,23 @@
{
"NODE_ENV": {
"description": "This defines the current environment",
"validators": [{
"name": "in",
"options": ["development", "testing", "staging", "production"]
}]
},
"LOGDNA_APP_NAME": {
"required": false,
"description": "The application name."
},
"LOGDNA_API_KEY": {
"required": false,
"description": "If set, enables application logging to the LogDNA logger service."
},
"DISCORD_LOG_CHANNEL": {
"description": "The unique ID for the channel the bot will output logs to."
},
"DISCORD_LOGIN_TOKEN": {
"description": "The login token of the bot."
}
}

View File

@ -1,43 +1,32 @@
const config = require('config');
const winston = require('winston');
const logdna = require('logdna');
const ip = require('ip');
const os = require("os");
const logdna = require('logdna');
winston.emitErrs = true;
const logger = new winston.Logger({
var logger = new winston.Logger({
level: 'debug',
transports: [
new winston.transports.File({
filename: 'log.log',
level: 'debug'
})
new (winston.transports.Console)(),
],
handleExceptions: true,
humanReadableUnhandledException: true,
exitOnError: false,
meta: true,
meta: true
});
if (config.enableLogdnaLogging === true && config.logdnaKey) {
// Setup logging for LogDNA cloud logging.
// Setup logging for LogDNA cloud logging.
if (process.env.LOGDNA_API_KEY) {
logger.add(winston.transports.Logdna, {
level: 'info',
app: 'discord-bot',
index_meta: true,
key: config.logdnaKey,
key: process.env.LOGDNA_API_KEY,
ip: ip.address(),
hostname: os.hostname(),
app: config.app
});
logger.debug('[logging] Started LogDNA winston transport.');
} else if (config.enableLogdna === true) {
throw "Attempted to enable LogDNA transport without a key!";
}
if (config.enableConsoleLogging === true) {
logger.add(winston.transports.Console, {
level: 'silly',
colorize: true
hostname: os.hostname()
});
logger.info('Started LogDNA winston transport.');
}
module.exports = logger;

200
package-lock.json generated
View File

@ -18,6 +18,16 @@
"json-stable-stringify": "1.0.1"
}
},
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
},
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
},
"asn1": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
@ -84,11 +94,39 @@
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"requires": {
"ansi-styles": "2.2.1",
"escape-string-regexp": "1.0.5",
"has-ansi": "2.0.0",
"strip-ansi": "3.0.1",
"supports-color": "2.0.0"
}
},
"checkenv": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/checkenv/-/checkenv-1.2.2.tgz",
"integrity": "sha1-55ZdO9Iu60BfJdG/qLx9Dv41vDg=",
"requires": {
"chalk": "1.1.3",
"validator": "4.9.0",
"window-size": "0.1.4",
"wrap-ansi": "2.1.0"
}
},
"co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
},
"code-point-at": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
},
"colors": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
@ -107,15 +145,6 @@
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
"integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
},
"config": {
"version": "1.26.1",
"resolved": "https://registry.npmjs.org/config/-/config-1.26.1.tgz",
"integrity": "sha1-9kfOMsNF6AunOo6qeppLTlspDKE=",
"requires": {
"json5": "0.4.0",
"os-homedir": "1.0.2"
}
},
"cookiejar": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.1.tgz",
@ -135,25 +164,6 @@
"moment-timezone": "0.5.13"
}
},
"cross-env": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.0.2.tgz",
"integrity": "sha1-05/S+ijBtc+5HnBY0e/otPywEzQ=",
"requires": {
"cross-spawn": "5.1.0",
"is-windows": "1.0.1"
}
},
"cross-spawn": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
"integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
"requires": {
"lru-cache": "4.1.1",
"shebang-command": "1.2.0",
"which": "1.3.0"
}
},
"cryptiles": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
@ -204,6 +214,11 @@
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"depd": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz",
"integrity": "sha1-4b2Cxqq2ztlluXuIsX7T5SjKGMM="
},
"discord.js": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-10.0.1.tgz",
@ -223,6 +238,11 @@
"jsbn": "0.1.1"
}
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"extend": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
@ -292,6 +312,14 @@
"har-schema": "1.0.5"
}
},
"has-ansi": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
"requires": {
"ansi-regex": "2.1.1"
}
},
"hawk": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
@ -333,6 +361,14 @@
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
"integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
},
"is-fullwidth-code-point": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"requires": {
"number-is-nan": "1.0.1"
}
},
"is-nan": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.2.1.tgz",
@ -346,21 +382,11 @@
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
},
"is-windows": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.1.tgz",
"integrity": "sha1-MQ23D3QtJZoWo2kgK1GvhCMzENk="
},
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
},
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
},
"isstream": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
@ -390,11 +416,6 @@
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
},
"json5": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/json5/-/json5-0.4.0.tgz",
"integrity": "sha1-BUNS5MTIDIbAkjh31EneF2pzLI0="
},
"jsonify": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
@ -441,15 +462,6 @@
"resolved": "https://registry.npmjs.org/long-timeout/-/long-timeout-0.1.1.tgz",
"integrity": "sha1-lyHXiLR+C8taJMLivuGg2lXatRQ="
},
"lru-cache": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
"integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
"requires": {
"pseudomap": "1.0.2",
"yallist": "2.1.2"
}
},
"methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@ -501,6 +513,11 @@
"sorted-array-functions": "1.0.0"
}
},
"number-is-nan": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
},
"oauth-sign": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
@ -524,11 +541,6 @@
"resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
"integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8="
},
"os-homedir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
},
"performance-now": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
@ -539,11 +551,6 @@
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
},
"pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
},
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
@ -619,19 +626,6 @@
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
},
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
"integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
"requires": {
"shebang-regex": "1.0.0"
}
},
"shebang-regex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
},
"sntp": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
@ -680,11 +674,29 @@
"safe-buffer": "5.1.1"
}
},
"string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"requires": {
"code-point-at": "1.1.0",
"is-fullwidth-code-point": "1.0.0",
"strip-ansi": "3.0.1"
}
},
"stringstream": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
"integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg="
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"requires": {
"ansi-regex": "2.1.1"
}
},
"superagent": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/superagent/-/superagent-2.3.0.tgz",
@ -702,6 +714,11 @@
"readable-stream": "2.3.3"
}
},
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
},
"tough-cookie": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz",
@ -738,6 +755,14 @@
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
"integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g=="
},
"validator": {
"version": "4.9.0",
"resolved": "https://registry.npmjs.org/validator/-/validator-4.9.0.tgz",
"integrity": "sha1-CC/84qdhSP8HqOienCukOq8S7Ew=",
"requires": {
"depd": "1.1.0"
}
},
"verror": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
@ -755,13 +780,10 @@
}
}
},
"which": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
"integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
"requires": {
"isexe": "2.0.0"
}
"window-size": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz",
"integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY="
},
"winston": {
"version": "2.3.1",
@ -783,6 +805,15 @@
}
}
},
"wrap-ansi": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
"requires": {
"string-width": "1.0.2",
"strip-ansi": "3.0.1"
}
},
"ws": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/ws/-/ws-1.1.4.tgz",
@ -791,11 +822,6 @@
"options": "0.0.6",
"ultron": "1.0.2"
}
},
"yallist": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
}
}
}

View File

@ -3,18 +3,13 @@
"version": "1.0.0",
"description": "Citra bot for Discord",
"author": "chris062689 <chris062689@gmail.com>",
"scripts": {
"start-dev": "cross-env NODE_ENV=development node server.js",
"start-prod": "cross-env NODE_ENV=production node server.js"
},
"preferGlobal": true,
"private": true,
"subdomain": "citra-emu",
"analyze": true,
"license": "GPL-2.0+",
"dependencies": {
"config": "^1.24.0",
"cross-env": "^5.0.2",
"checkenv": "^1.2.2",
"discord.js": "^10.0.1",
"ip": "^1.1.5",
"logdna": "^1.2.3",

View File

@ -1,13 +1,17 @@
// Check for environmental variables.
require('checkenv').check();
const discord = require('discord.js');
const fs = require('fs');
const path = require('path');
const config = require('config');
const schedule = require('node-schedule');
const logger = require('./logging.js');
const app = require('./app.js');
const data = require('./data.js');
var responses = require('./data/responses.json');
var cachedModules = [];
var cachedTriggers = [];
var client = new discord.Client();
@ -16,10 +20,6 @@ process.on('unhandledRejection', function onError(err) {
logger.error(err);
});
// Verify configuration options are set properly.
if (!config.logChannel) { throw 'Log Channel is missing from the configuration file.'; }
if (!config.clientLoginToken) { throw 'Client Login Token is missing from the configuration file.'; }
function findArray(haystack, arr) {
return arr.some(function (v) {
return haystack.indexOf(v) >= 0;
@ -28,7 +28,7 @@ function findArray(haystack, arr) {
client.on('ready', () => {
// Initalize app channels.
app.logChannel = client.channels.get(config.logChannel);
app.logChannel = client.channels.get(process.env.DISCORD_LOG_CHANNEL);
app.guild = app.logChannel.guild;
logger.info('Bot is now online and connected to server.');
@ -57,24 +57,24 @@ schedule.scheduleJob({ hour: 3, minute: 30 }, function(){
client.on('message', message => {
if (message.author.bot && message.content.startsWith('.ban') == false) { return; }
if (message.guild == null) {
if (message.guild == null && responses.pmReply) {
// We want to log PM attempts.
logger.info(`${message.author.username} ${message.author} [PM]: ${message.content}`);
app.logChannel.sendMessage(`${message.author} [PM]: ${message.content}`);
message.reply(config.pmReply);
message.reply(responses.pmReply);
return;
}
logger.verbose(`${message.author.username} ${message.author} [Channel: ${message.channel.name} ${message.channel}]: ${message.content}`);
if (message.content.startsWith(config.commandPrefix)) {
if (message.content.startsWith('.')) {
let cmd = message.content.split(' ')[0].slice(1);
// Check by the name of the command.
let cachedModule = cachedModules[`${cmd}.js`];
let cachedModuleType = 'Command';
// Check by the quotes in the configuration.
if (cachedModule == null) { cachedModule = config.quotes[cmd]; cachedModuleType = 'Quote'; }
if (cachedModule == null) { cachedModule = responses.quotes[cmd]; cachedModuleType = 'Quote'; }
if (cachedModule) {
// Check access permissions.
@ -157,5 +157,5 @@ require("fs").readdirSync('./triggers/').forEach(function(file) {
data.readWarnings();
data.readBans();
client.login(config.clientLoginToken);
client.login(process.env.DISCORD_LOGIN_TOKEN);
logger.info('Startup completed. Established connection to Discord.');