diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..b6f1c45 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +.eslintrc.js +old.eslintrc.js +.gitignore + +node_modules + +canned_replies.json +persistent_cache.json +config.js +logs/* diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..abbde5e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,6 @@ +FROM node:lts-alpine3.12 +WORKDIR /modmail +COPY . . +RUN yarn install --production +VOLUME [ "/modmail/modmail_cache" ] +CMD ["node", "index.js"] \ No newline at end of file diff --git a/package.json b/package.json index 7f2d28c..acc61c0 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "nodemon": "^2.0.7" }, "dependencies": { - "chalk": "^4.1.1", + "chalk": "^5.0.0", "diagnostics": "^2.0.2", "discord.js": "^12.5.3", "moment": "^2.29.1", diff --git a/structure/Modmail.js b/structure/Modmail.js index ff88cc7..51c2d74 100644 --- a/structure/Modmail.js +++ b/structure/Modmail.js @@ -113,27 +113,27 @@ class Modmail { const now = Math.floor(Date.now() / 1000); const { cache } = this; - // Anti spam - if (!this.spammers[author.id]) this.spammers[author.id] = { start: now, count: 1, timeout: false, warned: false }; - else if (this.spammers[author.id].timeout) { + // Anti spam -- never seen user + if (!this.spammers[author.id]) this.spammers[author.id] = { + start: now, // when counting started + count: 1, // # messages + timeout: false, // timed out? + warned: false // warned? + }; + else if (this.spammers[author.id].timeout) { // User was timed out, check if 5 minutes have passsed, if so, reset their timeout else ignore them if (now - this.spammers[author.id].start > 5 * 60) this.spammers[author.id] = { start: now, count: 1, timeout: false, warned: false }; else return; } else if (this.spammers[author.id].count > 5 && now - this.spammers[author.id].start < 15) { + // Has sent more than 5 messages in less than 15 seconds at this point, time them out this.spammers[author.id].timeout = true; - if (!this.spammers[author.id].warned) { + if (!this.spammers[author.id].warned) { // Let them know they've been timed out, toggle the warned property so it doesn't send the warning every time this.spammers[author.id].warned = true; await author.send(`I've blocked you for spamming, please try again in 5 minutes`); if (cache._channels[author.id]) await cache._channels[author.id].send(`I've blocked ${author.tag} from DMing me as they were spamming.`); } - } else if (now - this.spammers[author.id].start > 15) this.spammers[author.id] = { start: now, count: 1, timeout: false, warned: false }; + } else if (now - this.spammers[author.id].start > 15) this.spammers[author.id] = { start: now, count: 1, timeout: false, warned: false }; // Enough time has passed, reset the object else this.spammers[author.id].count++; - const lastActivity = this.cache.lastActivity[author.id]; - if (!lastActivity || now - lastActivity > 30 * 60) { - await author.send(`Thank you for your message, we'll get back to you soon!`); - } - this.cache.lastActivity[author.id] = now; - if (this.disabled) { let reason = `Modmail has been disabled for the time being`; if (this.disabledReason) reason += ` for the following reason:\n\n${this.disabledReason}`; @@ -141,6 +141,12 @@ class Modmail { return author.send(reason); } + const lastActivity = this.cache.lastActivity[author.id]; + if (!lastActivity || now - lastActivity > 30 * 60) { // No point in sending this for *every* message + await author.send(`Thank you for your message, we'll get back to you soon!`); + } + this.cache.lastActivity[author.id] = now; + const pastModmail = await this.cache.loadModmailHistory(author.id) .catch((err) => { this.client.logger.error(`Error during loading of past mail:\n${err.stack}`); diff --git a/structure/Registry.js b/structure/Registry.js index 1e49758..ae934b3 100644 --- a/structure/Registry.js +++ b/structure/Registry.js @@ -34,7 +34,7 @@ class Registry { } const command = new commandClass(this.client); - if (this.commands.has(command.name)) this.client.logger(`Command by name ${command.name} already exists, skipping duplicate at path ${commandPath}`); + if (this.commands.has(command.name)) this.client.logger.warn(`Command by name ${command.name} already exists, skipping duplicate at path ${commandPath}`); else this.commands.set(command.name, command); } diff --git a/yarn.lock b/yarn.lock index ac3c95f..6c6bf2f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -261,7 +261,7 @@ chalk@^2.0.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: +chalk@^4.0.0, chalk@^4.1.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -269,6 +269,11 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: ansi-styles "^4.1.0" supports-color "^7.1.0" +chalk@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.0.0.tgz#bd96c6bb8e02b96e08c0c3ee2a9d90e050c7b832" + integrity sha512-/duVOqst+luxCQRKEo4bNxinsOQtMP80ZYm7mMqzuh5PociNL0PvmHFvREJ9ueYL2TxlHjBcmLCdmocx9Vg+IQ== + chokidar@^3.2.2: version "3.5.2" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75"