forked from Galactic/modmail
linter pass
This commit is contained in:
parent
775b063c42
commit
4bfcc8c737
77
.eslintrc.js
77
.eslintrc.js
@ -1,24 +1,30 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
'env': {
|
"env": {
|
||||||
'commonjs': true,
|
"es6": true,
|
||||||
'es2021': true,
|
"node": true
|
||||||
'node': true
|
|
||||||
},
|
},
|
||||||
'extends': 'eslint:recommended',
|
"extends": "eslint:recommended",
|
||||||
'parserOptions': {
|
"globals": {
|
||||||
'ecmaVersion': 12
|
"Atomics": "readonly",
|
||||||
|
"SharedArrayBuffer": "readonly"
|
||||||
},
|
},
|
||||||
'rules': {
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 2020,
|
||||||
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
"accessor-pairs": "warn",
|
"accessor-pairs": "warn",
|
||||||
"array-callback-return": "warn",
|
"array-callback-return": "warn",
|
||||||
"arrow-parens": "warn",
|
"array-bracket-newline": [ "warn", "consistent" ],
|
||||||
|
"array-bracket-spacing": [ "warn", "always", { "objectsInArrays": false, "arraysInArrays": false }],
|
||||||
|
// "arrow-parens": "warn",
|
||||||
"arrow-spacing": "warn",
|
"arrow-spacing": "warn",
|
||||||
"block-scoped-var": "warn",
|
"block-scoped-var": "warn",
|
||||||
"block-spacing": "warn",
|
"block-spacing": [ "warn", "always" ],
|
||||||
"brace-style": "warn",
|
"brace-style": [ "warn", "1tbs" ],
|
||||||
"callback-return": "warn",
|
"callback-return": "warn",
|
||||||
"camelcase": "warn",
|
"camelcase": "warn",
|
||||||
"comma-dangle": "warn",
|
"comma-dangle": [ "warn", "only-multiline" ],
|
||||||
"comma-spacing": [
|
"comma-spacing": [
|
||||||
"warn",
|
"warn",
|
||||||
{
|
{
|
||||||
@ -38,6 +44,10 @@ module.exports = {
|
|||||||
"allowKeywords": true
|
"allowKeywords": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"dot-location": [
|
||||||
|
"error",
|
||||||
|
"property"
|
||||||
|
],
|
||||||
"eol-last": [
|
"eol-last": [
|
||||||
"warn",
|
"warn",
|
||||||
"never"
|
"never"
|
||||||
@ -55,18 +65,13 @@ module.exports = {
|
|||||||
"id-blacklist": "warn",
|
"id-blacklist": "warn",
|
||||||
"id-match": "warn",
|
"id-match": "warn",
|
||||||
"implicit-arrow-linebreak": "warn",
|
"implicit-arrow-linebreak": "warn",
|
||||||
"indent": [
|
"indent": "warn",
|
||||||
"warn",
|
|
||||||
4,
|
|
||||||
{
|
|
||||||
"SwitchCase": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"init-declarations": "warn",
|
"init-declarations": "warn",
|
||||||
"jsx-quotes": "warn",
|
"jsx-quotes": [ "warn", "prefer-single" ],
|
||||||
"key-spacing": "warn",
|
"key-spacing": [ "warn", { "beforeColon": false, "afterColon": true }],
|
||||||
|
"keyword-spacing": [ "warn", { "after": true, "before": true }],
|
||||||
"linebreak-style": [
|
"linebreak-style": [
|
||||||
"warn",
|
"error",
|
||||||
"windows"
|
"windows"
|
||||||
],
|
],
|
||||||
"lines-around-comment": "warn",
|
"lines-around-comment": "warn",
|
||||||
@ -98,13 +103,14 @@ module.exports = {
|
|||||||
"no-floating-decimal": "warn",
|
"no-floating-decimal": "warn",
|
||||||
"no-implicit-coercion": "warn",
|
"no-implicit-coercion": "warn",
|
||||||
"no-implicit-globals": "warn",
|
"no-implicit-globals": "warn",
|
||||||
"no-implied-eval": "warn",
|
"no-implied-eval": "error",
|
||||||
"no-import-assign": "warn",
|
"no-import-assign": "warn",
|
||||||
"no-invalid-this": "warn",
|
"no-invalid-this": "warn",
|
||||||
"no-iterator": "warn",
|
"no-iterator": "warn",
|
||||||
"no-label-var": "warn",
|
"no-label-var": "warn",
|
||||||
// "no-labels": "warn",
|
// "no-labels": "warn",
|
||||||
"no-lone-blocks": "warn",
|
"no-lone-blocks": "warn",
|
||||||
|
"no-lonely-if": "warn",
|
||||||
"no-loop-func": "warn",
|
"no-loop-func": "warn",
|
||||||
"no-mixed-requires": "warn",
|
"no-mixed-requires": "warn",
|
||||||
"no-multi-assign": "warn",
|
"no-multi-assign": "warn",
|
||||||
@ -113,6 +119,7 @@ module.exports = {
|
|||||||
"no-multiple-empty-lines": "warn",
|
"no-multiple-empty-lines": "warn",
|
||||||
"no-native-reassign": "warn",
|
"no-native-reassign": "warn",
|
||||||
"no-negated-in-lhs": "warn",
|
"no-negated-in-lhs": "warn",
|
||||||
|
"no-negated-condition": "error",
|
||||||
"no-nested-ternary": "warn",
|
"no-nested-ternary": "warn",
|
||||||
"no-new": "warn",
|
"no-new": "warn",
|
||||||
"no-new-func": "warn",
|
"no-new-func": "warn",
|
||||||
@ -135,14 +142,16 @@ module.exports = {
|
|||||||
"no-sequences": "warn",
|
"no-sequences": "warn",
|
||||||
"no-setter-return": "warn",
|
"no-setter-return": "warn",
|
||||||
"no-spaced-func": "warn",
|
"no-spaced-func": "warn",
|
||||||
|
"no-shadow": "error",
|
||||||
"no-tabs": "warn",
|
"no-tabs": "warn",
|
||||||
"no-template-curly-in-string": "warn",
|
"no-template-curly-in-string": "error",
|
||||||
"no-throw-literal": "warn",
|
"no-throw-literal": "warn",
|
||||||
"no-undef-init": "warn",
|
"no-undef-init": "error",
|
||||||
|
"no-undefined": "error",
|
||||||
"no-unmodified-loop-condition": "warn",
|
"no-unmodified-loop-condition": "warn",
|
||||||
"no-unneeded-ternary": "warn",
|
"no-unneeded-ternary": "error",
|
||||||
"no-unused-expressions": "warn",
|
"no-unused-expressions": "warn",
|
||||||
"no-use-before-define": "warn",
|
"no-use-before-define": "error",
|
||||||
"no-useless-call": "warn",
|
"no-useless-call": "warn",
|
||||||
"no-useless-computed-key": "warn",
|
"no-useless-computed-key": "warn",
|
||||||
"no-useless-concat": "warn",
|
"no-useless-concat": "warn",
|
||||||
@ -151,22 +160,25 @@ module.exports = {
|
|||||||
"no-useless-return": "warn",
|
"no-useless-return": "warn",
|
||||||
"no-var": "warn",
|
"no-var": "warn",
|
||||||
"no-void": "warn",
|
"no-void": "warn",
|
||||||
"no-whitespace-before-property": "warn",
|
"no-whitespace-before-property": "error",
|
||||||
"nonblock-statement-body-position": "warn",
|
"nonblock-statement-body-position": "warn",
|
||||||
"object-curly-spacing": [
|
"object-curly-spacing": [
|
||||||
"warn",
|
"warn",
|
||||||
"always"
|
"always"
|
||||||
],
|
],
|
||||||
|
"object-property-newline": [ "warn", { "allowAllPropertiesOnSameLine": true }],
|
||||||
"object-shorthand": "warn",
|
"object-shorthand": "warn",
|
||||||
"one-var-declaration-per-line": "warn",
|
"one-var-declaration-per-line": "warn",
|
||||||
"operator-assignment": "warn",
|
"operator-assignment": "warn",
|
||||||
|
"operator-linebreak": [ "warn", "before" ],
|
||||||
"padding-line-between-statements": "warn",
|
"padding-line-between-statements": "warn",
|
||||||
|
"padded-blocks": [ "warn", { "switches": "never" }, { "allowSingleLineBlocks": true }],
|
||||||
"prefer-arrow-callback": "warn",
|
"prefer-arrow-callback": "warn",
|
||||||
"prefer-const": "warn",
|
"prefer-const": "warn",
|
||||||
"prefer-destructuring": "warn",
|
"prefer-destructuring": "warn",
|
||||||
"prefer-exponentiation-operator": "warn",
|
"prefer-exponentiation-operator": "warn",
|
||||||
"prefer-numeric-literals": "warn",
|
"prefer-numeric-literals": "warn",
|
||||||
"prefer-object-spread": "warn",
|
"prefer-object-spread": "error",
|
||||||
"prefer-promise-reject-errors": "warn",
|
"prefer-promise-reject-errors": "warn",
|
||||||
"prefer-regex-literals": "warn",
|
"prefer-regex-literals": "warn",
|
||||||
"prefer-rest-params": "warn",
|
"prefer-rest-params": "warn",
|
||||||
@ -174,17 +186,20 @@ module.exports = {
|
|||||||
"require-jsdoc": "warn",
|
"require-jsdoc": "warn",
|
||||||
"require-unicode-regexp": "warn",
|
"require-unicode-regexp": "warn",
|
||||||
"rest-spread-spacing": "warn",
|
"rest-spread-spacing": "warn",
|
||||||
"semi": "warn",
|
"semi": "error",
|
||||||
"semi-spacing": "warn",
|
"semi-spacing": "warn",
|
||||||
"semi-style": [
|
"semi-style": [
|
||||||
"warn",
|
"warn",
|
||||||
"last"
|
"last"
|
||||||
],
|
],
|
||||||
"space-before-blocks": "warn",
|
"space-before-blocks": "warn",
|
||||||
|
"space-before-function-paren": [ "error", "always" ],
|
||||||
"space-in-parens": [
|
"space-in-parens": [
|
||||||
"warn",
|
"warn",
|
||||||
"never"
|
"never"
|
||||||
],
|
],
|
||||||
|
"spaced-comment": [ "warn", "always" ],
|
||||||
|
"strict": "warn",
|
||||||
"switch-colon-spacing": "warn",
|
"switch-colon-spacing": "warn",
|
||||||
"symbol-description": "warn",
|
"symbol-description": "warn",
|
||||||
"template-curly-spacing": [
|
"template-curly-spacing": [
|
||||||
@ -198,7 +213,7 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
"vars-on-top": "warn",
|
"vars-on-top": "warn",
|
||||||
"wrap-iife": "warn",
|
"wrap-iife": "warn",
|
||||||
"wrap-regex": "warn",
|
"wrap-regex": "error",
|
||||||
"yield-star-spacing": "warn",
|
"yield-star-spacing": "warn",
|
||||||
"yoda": [
|
"yoda": [
|
||||||
"warn",
|
"warn",
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -10,3 +10,4 @@ modmail_cache
|
|||||||
persistent_cache.json
|
persistent_cache.json
|
||||||
canned_replies.json
|
canned_replies.json
|
||||||
config - server.js
|
config - server.js
|
||||||
|
old.eslintrc.js
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
const CacheHandler = require('./abstractions/CacheHandler');
|
||||||
|
|
||||||
class Cache {
|
class JsonCache extends CacheHandler {
|
||||||
|
|
||||||
constructor(client) {
|
constructor (client) {
|
||||||
|
|
||||||
|
super(client);
|
||||||
|
|
||||||
const opts = client._options;
|
const opts = client._options;
|
||||||
this.client = client;
|
|
||||||
this.logger = client.logger;
|
this.logger = client.logger;
|
||||||
|
|
||||||
this.saveInterval = opts.saveInterval;
|
this.saveInterval = opts.saveInterval;
|
||||||
@ -23,7 +25,7 @@ class Cache {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
load() {
|
load () {
|
||||||
|
|
||||||
if (this._ready) return;
|
if (this._ready) return;
|
||||||
|
|
||||||
@ -31,27 +33,27 @@ class Cache {
|
|||||||
this.logger.info('Loading cache');
|
this.logger.info('Loading cache');
|
||||||
const raw = JSON.parse(fs.readFileSync('./persistent_cache.json', { encoding: 'utf-8' }));
|
const raw = JSON.parse(fs.readFileSync('./persistent_cache.json', { encoding: 'utf-8' }));
|
||||||
const entries = Object.entries(raw);
|
const entries = Object.entries(raw);
|
||||||
for (const [key, val] of entries) this[key] = val;
|
for (const [ key, val ] of entries) this[key] = val;
|
||||||
} else {
|
} else {
|
||||||
this.logger.info('Cache file missing, creating...');
|
this.logger.info('Cache file missing, creating...');
|
||||||
this.save();
|
this.savePersistentCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cacheSaveInterval = setInterval(this.save.bind(this), 10 * 60 * 1000);
|
this.cacheSaveInterval = setInterval(this.savePersistentCache.bind(this), 10 * 60 * 1000);
|
||||||
this.modmailSaveInterval = setInterval(this.saveModmailHistory.bind(this), this.saveInterval * 60 * 1000, this.client.modmail);
|
this.modmailSaveInterval = setInterval(this.saveModmailHistory.bind(this), this.saveInterval * 60 * 1000, this.client.modmail);
|
||||||
this._ready = true;
|
this._ready = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
save() {
|
savePersistentCache () {
|
||||||
this.logger.debug('Saving cache');
|
this.logger.debug('Saving cache');
|
||||||
fs.writeFileSync('./persistent_cache.json', JSON.stringify(this.json));
|
fs.writeFileSync('./persistent_cache.json', JSON.stringify(this.json));
|
||||||
}
|
}
|
||||||
|
|
||||||
saveModmailHistory() {
|
saveModmailHistory () {
|
||||||
|
|
||||||
if (!this.updatedThreads.length) return;
|
if (!this.updatedThreads.length) return;
|
||||||
const toSave = [...this.updatedThreads];
|
const toSave = [ ...this.updatedThreads ];
|
||||||
this.updatedThreads = [];
|
this.updatedThreads = [];
|
||||||
this.client.logger.debug(`Saving modmail data`);
|
this.client.logger.debug(`Saving modmail data`);
|
||||||
if (!fs.existsSync('./modmail_cache')) fs.mkdirSync('./modmail_cache');
|
if (!fs.existsSync('./modmail_cache')) fs.mkdirSync('./modmail_cache');
|
||||||
@ -67,7 +69,7 @@ class Cache {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadModmailHistory(userId) {
|
loadModmailHistory (userId) {
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
@ -90,7 +92,7 @@ class Cache {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get json() {
|
get json () {
|
||||||
return {
|
return {
|
||||||
queue: this.queue,
|
queue: this.queue,
|
||||||
channels: this.channels,
|
channels: this.channels,
|
||||||
@ -101,4 +103,4 @@ class Cache {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Cache;
|
module.exports = JsonCache;
|
@ -1,6 +1,6 @@
|
|||||||
class ChannelHandler {
|
class ChannelHandler {
|
||||||
|
|
||||||
constructor(modmail, opts) {
|
constructor (modmail, opts) {
|
||||||
|
|
||||||
this.modmail = modmail;
|
this.modmail = modmail;
|
||||||
this.client = modmail.client;
|
this.client = modmail.client;
|
||||||
@ -19,7 +19,7 @@ class ChannelHandler {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init () {
|
||||||
|
|
||||||
this.mainServer = this.modmail.mainServer;
|
this.mainServer = this.modmail.mainServer;
|
||||||
this.bansServer = this.modmail.bansServer;
|
this.bansServer = this.modmail.bansServer;
|
||||||
@ -41,7 +41,7 @@ class ChannelHandler {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async send(target, embed, newEntry) {
|
async send (target, embed, newEntry) {
|
||||||
|
|
||||||
// Load & update the users past modmails
|
// Load & update the users past modmails
|
||||||
const history = await this.cache.loadModmailHistory(target.id)
|
const history = await this.cache.loadModmailHistory(target.id)
|
||||||
@ -71,7 +71,7 @@ class ChannelHandler {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async setReadState(target, channel, staff, state) {
|
async setReadState (target, channel, staff, state) {
|
||||||
|
|
||||||
const history = await this.cache.loadModmailHistory(target)
|
const history = await this.cache.loadModmailHistory(target)
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
@ -106,7 +106,7 @@ class ChannelHandler {
|
|||||||
* @return {TextChannel}
|
* @return {TextChannel}
|
||||||
* @memberof ChannelHandler
|
* @memberof ChannelHandler
|
||||||
*/
|
*/
|
||||||
load(target, history) {
|
load (target, history) {
|
||||||
|
|
||||||
if (this.awaitingChannel[target.id]) return this.awaitingChannel[target.id];
|
if (this.awaitingChannel[target.id]) return this.awaitingChannel[target.id];
|
||||||
// eslint-disable-next-line no-async-promise-executor
|
// eslint-disable-next-line no-async-promise-executor
|
||||||
@ -135,8 +135,8 @@ class ChannelHandler {
|
|||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: '__User Data__',
|
name: '__User Data__',
|
||||||
value: `**User:** <@${user.id}>\n` +
|
value: `**User:** <@${user.id}>\n`
|
||||||
`**Account created:** ${user.createdAt.toDateString()}\n`,
|
+ `**Account created:** ${user.createdAt.toDateString()}\n`,
|
||||||
inline: false
|
inline: false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -151,9 +151,9 @@ class ChannelHandler {
|
|||||||
} else embed.description = `**__USER IS IN APPEAL SERVER__**`;
|
} else embed.description = `**__USER IS IN APPEAL SERVER__**`;
|
||||||
} else if (member) embed.fields.push({
|
} else if (member) embed.fields.push({
|
||||||
name: '__Member Data__',
|
name: '__Member Data__',
|
||||||
value: `**Nickname:** ${member.nickname || 'N/A'}\n` +
|
value: `**Nickname:** ${member.nickname || 'N/A'}\n`
|
||||||
`**Server join date:** ${member.joinedAt.toDateString()}\n` +
|
+ `**Server join date:** ${member.joinedAt.toDateString()}\n`
|
||||||
`**Roles:** ${member.roles.cache.filter((r) => r.id !== guild.roles.everyone.id).map((r) => `<@&${r.id}>`).join(' ')}`,
|
+ `**Roles:** ${member.roles.cache.filter((r) => r.id !== guild.roles.everyone.id).map((r) => `<@&${r.id}>`).join(' ')}`,
|
||||||
inline: false
|
inline: false
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -166,10 +166,12 @@ class ChannelHandler {
|
|||||||
if (!entry) continue;
|
if (!entry) continue;
|
||||||
if ([ 'read', 'unread' ].includes(entry.readState)) continue;
|
if ([ 'read', 'unread' ].includes(entry.readState)) continue;
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-shadow
|
||||||
const user = await this.client.resolveUser(entry.author).catch(this.client.logger.error.bind(this.client.logger));
|
const user = await this.client.resolveUser(entry.author).catch(this.client.logger.error.bind(this.client.logger));
|
||||||
const mem = await this.modmail.getMember(user.id).catch(this.client.logger.error.bind(this.client.logger));
|
const mem = await this.modmail.getMember(user.id).catch(this.client.logger.error.bind(this.client.logger));
|
||||||
if (!user) return reject(new Error(`Failed to find user`));
|
if (!user) return reject(new Error(`Failed to find user`));
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-shadow
|
||||||
const embed = {
|
const embed = {
|
||||||
footer: {
|
footer: {
|
||||||
text: user.id
|
text: user.id
|
||||||
@ -201,7 +203,7 @@ class ChannelHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the right category
|
// Ensure the right category
|
||||||
//if (channel.parentID !== this.newMail.id)
|
// if (channel.parentID !== this.newMail.id)
|
||||||
await channel.edit({ parentID: this.newMail.id, lockPermissions: true }).catch((err) => {
|
await channel.edit({ parentID: this.newMail.id, lockPermissions: true }).catch((err) => {
|
||||||
this.client.logger.error(`Error during channel transition:\n${err.stack}`);
|
this.client.logger.error(`Error during channel transition:\n${err.stack}`);
|
||||||
});
|
});
|
||||||
@ -221,7 +223,7 @@ class ChannelHandler {
|
|||||||
* @param {object} { age, count, force } age: how long the channel has to be without activity to be deleted, count: how many channels to act on, force: whether to ignore answered status
|
* @param {object} { age, count, force } age: how long the channel has to be without activity to be deleted, count: how many channels to act on, force: whether to ignore answered status
|
||||||
* @memberof Modmail
|
* @memberof Modmail
|
||||||
*/
|
*/
|
||||||
async sweepChannels({ age, count, force = false } = {}) {
|
async sweepChannels ({ age, count, force = false } = {}) {
|
||||||
|
|
||||||
this.client.logger.info(`Sweeping graveyard`);
|
this.client.logger.info(`Sweeping graveyard`);
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
@ -240,11 +242,11 @@ class ChannelHandler {
|
|||||||
if (!lastMessage || now - lastMessage.createdTimestamp > age || count && channelCount <= count) {
|
if (!lastMessage || now - lastMessage.createdTimestamp > age || count && channelCount <= count) {
|
||||||
await channel.delete().then((ch) => {
|
await channel.delete().then((ch) => {
|
||||||
const chCache = this.cache.channels;
|
const chCache = this.cache.channels;
|
||||||
const _cached = Object.entries(chCache).find(([, val]) => {
|
const _cached = Object.entries(chCache).find(([ , val ]) => {
|
||||||
return val === ch.id;
|
return val === ch.id;
|
||||||
});
|
});
|
||||||
if (_cached) {
|
if (_cached) {
|
||||||
const [userId] = _cached;
|
const [ userId ] = _cached;
|
||||||
delete this.modmail.cache.channels[userId];
|
delete this.modmail.cache.channels[userId];
|
||||||
}
|
}
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
@ -279,7 +281,7 @@ class ChannelHandler {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async overflow() { // Overflows new modmail category into read
|
async overflow () { // Overflows new modmail category into read
|
||||||
const channels = this.newMail.children.sort((a, b) => {
|
const channels = this.newMail.children.sort((a, b) => {
|
||||||
if (!a.lastMessage) return -1;
|
if (!a.lastMessage) return -1;
|
||||||
if (!b.lastMessage) return 1;
|
if (!b.lastMessage) return 1;
|
||||||
|
@ -10,7 +10,7 @@ const Cache = require('./Cache');
|
|||||||
|
|
||||||
class ModmailClient extends Client {
|
class ModmailClient extends Client {
|
||||||
|
|
||||||
constructor(options) {
|
constructor (options) {
|
||||||
|
|
||||||
super(options.clientOptions);
|
super(options.clientOptions);
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ class ModmailClient extends Client {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async init() {
|
async init () {
|
||||||
|
|
||||||
this.registry.loadCommands();
|
this.registry.loadCommands();
|
||||||
|
|
||||||
@ -51,13 +51,13 @@ class ModmailClient extends Client {
|
|||||||
|
|
||||||
process.on('exit', () => {
|
process.on('exit', () => {
|
||||||
this.logger.warn('process exiting');
|
this.logger.warn('process exiting');
|
||||||
this.cache.save();
|
this.cache.savePersistentCache();
|
||||||
this.cache.saveModmailHistory(this.modmail);
|
this.cache.saveModmailHistory(this.modmail);
|
||||||
});
|
});
|
||||||
process.on('SIGINT', () => {
|
process.on('SIGINT', () => {
|
||||||
this.logger.warn('received sigint');
|
this.logger.warn('received sigint');
|
||||||
//this.cache.save();
|
// this.cache.save();
|
||||||
//this.cache.saveModmailHistory(this.modmail);
|
// this.cache.saveModmailHistory(this.modmail);
|
||||||
// eslint-disable-next-line no-process-exit
|
// eslint-disable-next-line no-process-exit
|
||||||
process.exit();
|
process.exit();
|
||||||
});
|
});
|
||||||
@ -66,7 +66,7 @@ class ModmailClient extends Client {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ready() {
|
ready () {
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
if (this._ready) resolve();
|
if (this._ready) resolve();
|
||||||
@ -75,7 +75,7 @@ class ModmailClient extends Client {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleMessage(message) {
|
async handleMessage (message) {
|
||||||
|
|
||||||
if (!this._ready) return;
|
if (!this._ready) return;
|
||||||
if (message.author.bot) return;
|
if (message.author.bot) return;
|
||||||
@ -90,13 +90,13 @@ class ModmailClient extends Client {
|
|||||||
|
|
||||||
const { prefix } = this;
|
const { prefix } = this;
|
||||||
const { channel, guild, content, member } = message;
|
const { channel, guild, content, member } = message;
|
||||||
if (![this.mainServer.id, this.bansServer?.id || '0'].includes(guild.id)) return;
|
if (![ this.mainServer.id, this.bansServer?.id || '0' ].includes(guild.id)) return;
|
||||||
if (!content || !content.startsWith(prefix)) return;
|
if (!content || !content.startsWith(prefix)) return;
|
||||||
|
|
||||||
const roles = member.roles.cache.map((r) => r.id);
|
const roles = member.roles.cache.map((r) => r.id);
|
||||||
if(!roles.some((r) => this._options.staffRoles.includes(r)) && !member.hasPermission('ADMINISTRATOR')) return;
|
if (!roles.some((r) => this._options.staffRoles.includes(r)) && !member.hasPermission('ADMINISTRATOR')) return;
|
||||||
|
|
||||||
const [rawCommand, ...args] = content.split(' ');
|
const [ rawCommand, ...args ] = content.split(' ');
|
||||||
const commandName = rawCommand.substring(prefix.length);
|
const commandName = rawCommand.substring(prefix.length);
|
||||||
const command = this.registry.find(commandName);
|
const command = this.registry.find(commandName);
|
||||||
if (!command) return;
|
if (!command) return;
|
||||||
@ -127,32 +127,32 @@ class ModmailClient extends Client {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveUser(...args) {
|
resolveUser (...args) {
|
||||||
return this.resolver.resolveUser(...args);
|
return this.resolver.resolveUser(...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveUsers(...args) {
|
resolveUsers (...args) {
|
||||||
return this.resolver.resolveUsers(...args);
|
return this.resolver.resolveUsers(...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveChannels(...args) {
|
resolveChannels (...args) {
|
||||||
return this.resolver.resolveChannels(...args);
|
return this.resolver.resolveChannels(...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveChannel(...args) {
|
resolveChannel (...args) {
|
||||||
return this.resolver.resolveChannel(...args);
|
return this.resolver.resolveChannel(...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
async prompt(str, { author, channel, time }) {
|
async prompt (str, { author, channel, time }) {
|
||||||
|
|
||||||
if (!channel && author) channel = await author.createDM();
|
if (!channel && author) channel = await author.createDM();
|
||||||
if (!channel) throw new Error(`Missing channel for prompt, must pass at least author.`);
|
if (!channel) throw new Error(`Missing channel for prompt, must pass at least author.`);
|
||||||
await channel.send(str);
|
await channel.send(str);
|
||||||
return channel.awaitMessages((m) => m.author.id === author.id, { max: 1, time: time || 30000, errors: ['time'] })
|
return channel.awaitMessages((m) => m.author.id === author.id, { max: 1, time: time || 30000, errors: [ 'time' ] })
|
||||||
.then((collected) => {
|
.then((collected) => {
|
||||||
return collected.first();
|
return collected.first();
|
||||||
})
|
})
|
||||||
.catch((error) => { //eslint-disable-line no-unused-vars, handle-callback-err
|
.catch((error) => { // eslint-disable-line no-unused-vars, handle-callback-err
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
class Command {
|
class Command {
|
||||||
|
|
||||||
constructor(client, options) {
|
constructor (client, options) {
|
||||||
|
|
||||||
Object.entries(options).forEach(([key, val]) => {
|
Object.entries(options).forEach(([ key, val ]) => {
|
||||||
this[key] = val;
|
this[key] = val;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ class Command {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute() {
|
async execute () {
|
||||||
throw new Error(`Missing execute in ${this.name}`);
|
throw new Error(`Missing execute in ${this.name}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ class Modmail {
|
|||||||
// A lot of this can probably be simplified but I wrote all of this in 2 days and I cba to fix this atm
|
// A lot of this can probably be simplified but I wrote all of this in 2 days and I cba to fix this atm
|
||||||
// TODO: Fix everything
|
// TODO: Fix everything
|
||||||
|
|
||||||
constructor(client) {
|
constructor (client) {
|
||||||
|
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.cache = client.cache;
|
this.cache = client.cache;
|
||||||
@ -35,7 +35,7 @@ class Modmail {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async init() {
|
async init () {
|
||||||
|
|
||||||
this.mainServer = this.client.mainServer;
|
this.mainServer = this.client.mainServer;
|
||||||
if (!this.mainServer) throw new Error(`Missing main server`);
|
if (!this.mainServer) throw new Error(`Missing main server`);
|
||||||
@ -62,7 +62,7 @@ class Modmail {
|
|||||||
let logStr = `Started modmail handler for ${this.mainServer.name}`;
|
let logStr = `Started modmail handler for ${this.mainServer.name}`;
|
||||||
if (this.bansServer) logStr += ` with ${this.bansServer.name} for ban appeals`;
|
if (this.bansServer) logStr += ` with ${this.bansServer.name} for ban appeals`;
|
||||||
this.client.logger.info(logStr);
|
this.client.logger.info(logStr);
|
||||||
//this.client.logger.info(`Fetching messages from discord for modmail`);
|
// this.client.logger.info(`Fetching messages from discord for modmail`);
|
||||||
// TODO: Fetch messages from discord in modmail channels
|
// TODO: Fetch messages from discord in modmail channels
|
||||||
|
|
||||||
this.channels.init();
|
this.channels.init();
|
||||||
@ -70,16 +70,16 @@ class Modmail {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getMember(user) {
|
async getMember (user) {
|
||||||
|
|
||||||
let result = this.mainServer.members.cache.get(user);
|
let result = this.mainServer.members.cache.get(user);
|
||||||
if(!result) result = await this.mainServer.members.fetch(user).catch(() => {
|
if (!result) result = await this.mainServer.members.fetch(user).catch(() => {
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!result && this.bansServer) {
|
if (!result && this.bansServer) {
|
||||||
result = this.bansServer.members.cache.get(user);
|
result = this.bansServer.members.cache.get(user);
|
||||||
if(!result) result = await this.bansServer.members.fetch(user).catch(() => {
|
if (!result) result = await this.bansServer.members.fetch(user).catch(() => {
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
if (result) result.inAppealServer = true;
|
if (result) result.inAppealServer = true;
|
||||||
@ -89,7 +89,7 @@ class Modmail {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUser(user) {
|
async getUser (user) {
|
||||||
|
|
||||||
let result = this.client.users.cache.get(user);
|
let result = this.client.users.cache.get(user);
|
||||||
if (!result) result = await this.client.users.fetch(user).catch(() => {
|
if (!result) result = await this.client.users.fetch(user).catch(() => {
|
||||||
@ -99,7 +99,7 @@ class Modmail {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleUser(message) {
|
async handleUser (message) {
|
||||||
|
|
||||||
const { author, content } = message;
|
const { author, content } = message;
|
||||||
const member = await this.getMember(author.id);
|
const member = await this.getMember(author.id);
|
||||||
@ -107,7 +107,7 @@ class Modmail {
|
|||||||
|
|
||||||
const now = Math.floor(Date.now() / 1000);
|
const now = Math.floor(Date.now() / 1000);
|
||||||
const lastActivity = this.client.cache.lastActivity[author.id];
|
const lastActivity = this.client.cache.lastActivity[author.id];
|
||||||
//console.log(now - lastActivity, lastActivity, now)
|
// console.log(now - lastActivity, lastActivity, now)
|
||||||
if (!lastActivity || now - lastActivity > 30 * 60) {
|
if (!lastActivity || now - lastActivity > 30 * 60) {
|
||||||
await author.send(`Thank you for your message, we'll get back to you soon!`);
|
await author.send(`Thank you for your message, we'll get back to you soon!`);
|
||||||
}
|
}
|
||||||
@ -117,22 +117,18 @@ class Modmail {
|
|||||||
|
|
||||||
// Anti spam
|
// Anti spam
|
||||||
if (!this.spammers[author.id]) this.spammers[author.id] = { start: now, count: 1, timeout: false, warned: false };
|
if (!this.spammers[author.id]) this.spammers[author.id] = { start: now, count: 1, timeout: false, warned: false };
|
||||||
else {
|
else if (this.spammers[author.id].timeout) {
|
||||||
if (this.spammers[author.id].timeout) {
|
if (now - this.spammers[author.id].start > 5 * 60) this.spammers[author.id] = { start: now, count: 1, timeout: false, warned: false };
|
||||||
if (now - this.spammers[author.id].start > 5 * 60) this.spammers[author.id] = { start: now, count: 1, timeout: false, warned: false };
|
else return;
|
||||||
else return;
|
} else if (this.spammers[author.id].count > 5 && now - this.spammers[author.id].start < 15) {
|
||||||
} else if (this.spammers[author.id].count > 5 && now - this.spammers[author.id].start < 15) {
|
this.spammers[author.id].timeout = true;
|
||||||
this.spammers[author.id].timeout = true;
|
if (!this.spammers[author.id].warned) {
|
||||||
if (!this.spammers[author.id].warned) {
|
this.spammers[author.id].warned = true;
|
||||||
this.spammers[author.id].warned = true;
|
await author.send(`I've blocked you for spamming, please try again in 5 minutes`);
|
||||||
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.`);
|
||||||
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 this.spammers[author.id].count++;
|
|
||||||
}
|
}
|
||||||
}
|
} else if (now - this.spammers[author.id].start > 15) this.spammers[author.id] = { start: now, count: 1, timeout: false, warned: false };
|
||||||
|
else this.spammers[author.id].count++;
|
||||||
|
|
||||||
const pastModmail = await this.cache.loadModmailHistory(author.id)
|
const pastModmail = await this.cache.loadModmailHistory(author.id)
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
@ -187,7 +183,7 @@ class Modmail {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendCannedResponse({ message, responseName, anon }) {
|
async sendCannedResponse ({ message, responseName, anon }) {
|
||||||
|
|
||||||
const content = this.getCanned(responseName);
|
const content = this.getCanned(responseName);
|
||||||
if (!content) return {
|
if (!content) return {
|
||||||
@ -200,7 +196,7 @@ class Modmail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send reply from channel
|
// Send reply from channel
|
||||||
async sendResponse({ message, content, anon }) {
|
async sendResponse ({ message, content, anon }) {
|
||||||
|
|
||||||
const { channel, member, author } = message;
|
const { channel, member, author } = message;
|
||||||
if (!this.categories.includes(channel.parentID)) return {
|
if (!this.categories.includes(channel.parentID)) return {
|
||||||
@ -210,7 +206,7 @@ class Modmail {
|
|||||||
|
|
||||||
// Resolve target user from cache
|
// Resolve target user from cache
|
||||||
const chCache = this.cache.channels;
|
const chCache = this.cache.channels;
|
||||||
const result = Object.entries(chCache).find(([, val]) => {
|
const result = Object.entries(chCache).find(([ , val ]) => {
|
||||||
return val === channel.id;
|
return val === channel.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -220,7 +216,7 @@ class Modmail {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Ensure target exists, this should never run into issues
|
// Ensure target exists, this should never run into issues
|
||||||
const [userId] = result;
|
const [ userId ] = result;
|
||||||
const targetMember = await this.getMember(userId);
|
const targetMember = await this.getMember(userId);
|
||||||
if (!targetMember) return {
|
if (!targetMember) return {
|
||||||
error: true,
|
error: true,
|
||||||
@ -234,7 +230,7 @@ class Modmail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send modmail with the modmail command
|
// Send modmail with the modmail command
|
||||||
async sendModmail({ message, content, anon, target }) {
|
async sendModmail ({ message, content, anon, target }) {
|
||||||
|
|
||||||
const targetMember = await this.getMember(target.id);
|
const targetMember = await this.getMember(target.id);
|
||||||
if (!targetMember) return {
|
if (!targetMember) return {
|
||||||
@ -254,7 +250,7 @@ class Modmail {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async send({ target, staff, anon, content }) {
|
async send ({ target, staff, anon, content }) {
|
||||||
|
|
||||||
const embed = {
|
const embed = {
|
||||||
author: {
|
author: {
|
||||||
@ -286,7 +282,7 @@ class Modmail {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async changeReadState(message, args, state = 'read') {
|
async changeReadState (message, args, state = 'read') {
|
||||||
|
|
||||||
const { author } = message;
|
const { author } = message;
|
||||||
|
|
||||||
@ -301,14 +297,14 @@ class Modmail {
|
|||||||
if (args.length) {
|
if (args.length) {
|
||||||
|
|
||||||
// Eventually support marking several threads read at the same time
|
// Eventually support marking several threads read at the same time
|
||||||
const [id] = args;
|
const [ id ] = args;
|
||||||
user = await this.client.resolveUser(id, true);
|
user = await this.client.resolveUser(id, true);
|
||||||
let channel = await this.client.resolveChannel(id);
|
let channel = await this.client.resolveChannel(id);
|
||||||
|
|
||||||
if (channel) {
|
if (channel) {
|
||||||
|
|
||||||
const chCache = this.cache.channels;
|
const chCache = this.cache.channels;
|
||||||
const result = Object.entries(chCache).find(([, val]) => {
|
const result = Object.entries(chCache).find(([ , val ]) => {
|
||||||
return val === channel.id;
|
return val === channel.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -334,7 +330,7 @@ class Modmail {
|
|||||||
if (!response) {
|
if (!response) {
|
||||||
const { channel } = message;
|
const { channel } = message;
|
||||||
const chCache = this.cache.channels;
|
const chCache = this.cache.channels;
|
||||||
const result = Object.entries(chCache).find(([, val]) => {
|
const result = Object.entries(chCache).find(([ , val ]) => {
|
||||||
return val === channel.id;
|
return val === channel.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -343,7 +339,7 @@ class Modmail {
|
|||||||
msg: `This doesn't seem to be a valid modmail channel. Cache might be out of sync. **[MISSING TARGET]**`
|
msg: `This doesn't seem to be a valid modmail channel. Cache might be out of sync. **[MISSING TARGET]**`
|
||||||
};
|
};
|
||||||
|
|
||||||
const [userId] = result;
|
const [ userId ] = result;
|
||||||
user = await this.getUser(userId);
|
user = await this.getUser(userId);
|
||||||
response = await this.channels.setReadState(userId, channel, author, state);
|
response = await this.channels.setReadState(userId, channel, author, state);
|
||||||
}
|
}
|
||||||
@ -355,7 +351,7 @@ class Modmail {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendReminder() {
|
async sendReminder () {
|
||||||
|
|
||||||
const channel = this.reminderChannel;
|
const channel = this.reminderChannel;
|
||||||
const amount = this.queue.length;
|
const amount = this.queue.length;
|
||||||
@ -379,7 +375,7 @@ class Modmail {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async log({ author, content, action, target }) {
|
async log ({ author, content, action, target }) {
|
||||||
|
|
||||||
const embed = {
|
const embed = {
|
||||||
author: {
|
author: {
|
||||||
@ -400,11 +396,11 @@ class Modmail {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getCanned(name) {
|
getCanned (name) {
|
||||||
return this.replies[name.toLowerCase()];
|
return this.replies[name.toLowerCase()];
|
||||||
}
|
}
|
||||||
|
|
||||||
loadReplies() {
|
loadReplies () {
|
||||||
|
|
||||||
this.client.logger.info('Loading canned replies');
|
this.client.logger.info('Loading canned replies');
|
||||||
if (!fs.existsSync('./canned_replies.json')) return {};
|
if (!fs.existsSync('./canned_replies.json')) return {};
|
||||||
@ -412,7 +408,7 @@ class Modmail {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
saveReplies() {
|
saveReplies () {
|
||||||
|
|
||||||
this.client.logger.info('Saving canned replies');
|
this.client.logger.info('Saving canned replies');
|
||||||
fs.writeFileSync('./canned_replies.json', JSON.stringify(this.replies));
|
fs.writeFileSync('./canned_replies.json', JSON.stringify(this.replies));
|
||||||
|
@ -4,7 +4,7 @@ const fs = require('fs');
|
|||||||
|
|
||||||
class Registry {
|
class Registry {
|
||||||
|
|
||||||
constructor(client) {
|
constructor (client) {
|
||||||
|
|
||||||
this.client = client;
|
this.client = client;
|
||||||
|
|
||||||
@ -12,13 +12,13 @@ class Registry {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
find(name) {
|
find (name) {
|
||||||
|
|
||||||
return this.commands.find((c) => c.name === name.toLowerCase() || c.aliases?.includes(name.toLowerCase()));
|
return this.commands.find((c) => c.name === name.toLowerCase() || c.aliases?.includes(name.toLowerCase()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadCommands() {
|
loadCommands () {
|
||||||
|
|
||||||
const commandsDir = path.join(process.cwd(), 'structure', 'commands');
|
const commandsDir = path.join(process.cwd(), 'structure', 'commands');
|
||||||
const files = fs.readdirSync(commandsDir);
|
const files = fs.readdirSync(commandsDir);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
class Resolver {
|
class Resolver {
|
||||||
|
|
||||||
constructor(client) {
|
constructor (client) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -12,9 +12,9 @@ class Resolver {
|
|||||||
* @returns {Promise<Array<User>> || boolean} Array of resolved users or false if none were resolved
|
* @returns {Promise<Array<User>> || boolean} Array of resolved users or false if none were resolved
|
||||||
* @memberof Resolver
|
* @memberof Resolver
|
||||||
*/
|
*/
|
||||||
async resolveUsers(resolveables = [], strict = false) {
|
async resolveUsers (resolveables = [], strict = false) {
|
||||||
|
|
||||||
if (typeof resolveables === 'string') resolveables = [resolveables];
|
if (typeof resolveables === 'string') resolveables = [ resolveables ];
|
||||||
if (resolveables.length === 0) return false;
|
if (resolveables.length === 0) return false;
|
||||||
const { users } = this.client;
|
const { users } = this.client;
|
||||||
const resolved = [];
|
const resolved = [];
|
||||||
@ -23,7 +23,7 @@ class Resolver {
|
|||||||
|
|
||||||
if ((/<@!?([0-9]{17,21})>/u).test(resolveable)) {
|
if ((/<@!?([0-9]{17,21})>/u).test(resolveable)) {
|
||||||
|
|
||||||
const [, id] = resolveable.match(/<@!?([0-9]{17,21})>/u);
|
const [ , id ] = resolveable.match(/<@!?([0-9]{17,21})>/u);
|
||||||
const user = await users.fetch(id).catch((err) => {
|
const user = await users.fetch(id).catch((err) => {
|
||||||
if (err.code === 10013) return false;
|
if (err.code === 10013) return false;
|
||||||
// this.client.logger.warn(err); return false;
|
// this.client.logger.warn(err); return false;
|
||||||
@ -33,7 +33,7 @@ class Resolver {
|
|||||||
|
|
||||||
} else if ((/(id:)?([0-9]{17,21})/u).test(resolveable)) {
|
} else if ((/(id:)?([0-9]{17,21})/u).test(resolveable)) {
|
||||||
|
|
||||||
const [, , id] = resolveable.match(/(id:)?([0-9]{17,21})/u);
|
const [ , , id ] = resolveable.match(/(id:)?([0-9]{17,21})/u);
|
||||||
const user = await users.fetch(id).catch((err) => {
|
const user = await users.fetch(id).catch((err) => {
|
||||||
if (err.code === 10013) return false;
|
if (err.code === 10013) return false;
|
||||||
// this.client.logger.warn(err); return false;
|
// this.client.logger.warn(err); return false;
|
||||||
@ -63,11 +63,11 @@ class Resolver {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async resolveUser(resolveable, strict) {
|
async resolveUser (resolveable, strict) {
|
||||||
|
|
||||||
if (!resolveable) return false;
|
if (!resolveable) return false;
|
||||||
if (resolveable instanceof Array) throw new Error('Resolveable cannot be of type Array, use resolveUsers for resolving arrays of users');
|
if (resolveable instanceof Array) throw new Error('Resolveable cannot be of type Array, use resolveUsers for resolving arrays of users');
|
||||||
const result = await this.resolveUsers([resolveable], strict);
|
const result = await this.resolveUsers([ resolveable ], strict);
|
||||||
return result ? result[0] : false;
|
return result ? result[0] : false;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -82,9 +82,9 @@ class Resolver {
|
|||||||
* @returns {Promise<Array<GuildChannel>> || Promise<Boolean>} an array of guild channels or false if none were resolved
|
* @returns {Promise<Array<GuildChannel>> || Promise<Boolean>} an array of guild channels or false if none were resolved
|
||||||
* @memberof Resolver
|
* @memberof Resolver
|
||||||
*/
|
*/
|
||||||
async resolveChannels(resolveables = [], strict = false, guild = null, filter = () => true) {
|
async resolveChannels (resolveables = [], strict = false, guild = null, filter = () => true) {
|
||||||
|
|
||||||
if (typeof resolveables === 'string') resolveables = [resolveables];
|
if (typeof resolveables === 'string') resolveables = [ resolveables ];
|
||||||
if (resolveables.length === 0) return false;
|
if (resolveables.length === 0) return false;
|
||||||
if (!guild) guild = this.client.mainServer;
|
if (!guild) guild = this.client.mainServer;
|
||||||
const CM = guild.channels;
|
const CM = guild.channels;
|
||||||
@ -102,9 +102,10 @@ class Resolver {
|
|||||||
|
|
||||||
if (id.test(resolveable)) {
|
if (id.test(resolveable)) {
|
||||||
const match = resolveable.match(id);
|
const match = resolveable.match(id);
|
||||||
const [, ch] = match;
|
const [ , ch ] = match;
|
||||||
|
|
||||||
const channel = await this.client.channels.fetch(ch).catch((e) => { }); //eslint-disable-line no-empty, no-empty-function, no-unused-vars
|
// eslint-disable-next-line no-shadow
|
||||||
|
const channel = await this.client.channels.fetch(ch).catch((e) => { }); // eslint-disable-line no-empty, no-empty-function, no-unused-vars
|
||||||
|
|
||||||
if (channel && filter(channel)) resolved.push(channel);
|
if (channel && filter(channel)) resolved.push(channel);
|
||||||
|
|
||||||
@ -112,6 +113,7 @@ class Resolver {
|
|||||||
const match = resolveable.match(name);
|
const match = resolveable.match(name);
|
||||||
const ch = match[1].toLowerCase();
|
const ch = match[1].toLowerCase();
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-shadow
|
||||||
const channel = CM.cache.sort((a, b) => a.name.length - b.name.length).filter(filter).filter((c) => {
|
const channel = CM.cache.sort((a, b) => a.name.length - b.name.length).filter(filter).filter((c) => {
|
||||||
if (!strict) return c.name.toLowerCase().includes(ch);
|
if (!strict) return c.name.toLowerCase().includes(ch);
|
||||||
return c.name.toLowerCase() === ch;
|
return c.name.toLowerCase() === ch;
|
||||||
@ -127,11 +129,11 @@ class Resolver {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async resolveChannel(resolveable, strict, guild, filter) {
|
async resolveChannel (resolveable, strict, guild, filter) {
|
||||||
|
|
||||||
if (!resolveable) return false;
|
if (!resolveable) return false;
|
||||||
if (resolveable instanceof Array) throw new Error('Resolveable cannot be of type Array, use resolveChannels for resolving arrays of channels');
|
if (resolveable instanceof Array) throw new Error('Resolveable cannot be of type Array, use resolveChannels for resolving arrays of channels');
|
||||||
const result = await this.resolveChannels([resolveable], strict, guild, filter);
|
const result = await this.resolveChannels([ resolveable ], strict, guild, filter);
|
||||||
return result ? result[0] : false;
|
return result ? result[0] : false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,18 +2,18 @@ const Command = require('../Command');
|
|||||||
|
|
||||||
class CannedReply extends Command {
|
class CannedReply extends Command {
|
||||||
|
|
||||||
constructor(client) {
|
constructor (client) {
|
||||||
super(client, {
|
super(client, {
|
||||||
name: 'cannedreply',
|
name: 'cannedreply',
|
||||||
aliases: ['cr', 'canned'],
|
aliases: [ 'cr', 'canned' ],
|
||||||
showUsage: true,
|
showUsage: true,
|
||||||
usage: `<canned response name>`
|
usage: `<canned response name>`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(message, { args }) {
|
async execute (message, { args }) {
|
||||||
|
|
||||||
const [first] = args.map((a) => a);
|
const [ first ] = args.map((a) => a);
|
||||||
// eslint-disable-next-line prefer-const
|
// eslint-disable-next-line prefer-const
|
||||||
let { channel, content, _caller } = message,
|
let { channel, content, _caller } = message,
|
||||||
anon = false;
|
anon = false;
|
||||||
@ -22,13 +22,14 @@ class CannedReply extends Command {
|
|||||||
if (op === 'anon') {
|
if (op === 'anon') {
|
||||||
anon = true;
|
anon = true;
|
||||||
content = content.replace(first, '');
|
content = content.replace(first, '');
|
||||||
} else if (['create', 'delete'].includes(op)) {
|
} else if ([ 'create', 'delete' ].includes(op)) {
|
||||||
return this.createCanned(op, args, message);
|
return this.createCanned(op, args, message);
|
||||||
} else if (['list'].includes(first.toLowerCase(op))) {
|
} else if ([ 'list' ].includes(first.toLowerCase(op))) {
|
||||||
|
|
||||||
const list = Object.entries(this.client.modmail.replies);
|
const list = Object.entries(this.client.modmail.replies);
|
||||||
let str = '';
|
let str = '';
|
||||||
for (const [name, content] of list) {
|
// eslint-disable-next-line no-shadow
|
||||||
|
for (const [ name, content ] of list) {
|
||||||
if (str.length + content.length > 2000) {
|
if (str.length + content.length > 2000) {
|
||||||
await channel.send(str).catch(this.client.logger.error.bind(this.client.logger));
|
await channel.send(str).catch(this.client.logger.error.bind(this.client.logger));
|
||||||
str = '';
|
str = '';
|
||||||
@ -42,13 +43,13 @@ class CannedReply extends Command {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async createCanned(op, args, { channel, author }) {
|
async createCanned (op, args, { channel, author }) {
|
||||||
|
|
||||||
if (args.length < 1) return {
|
if (args.length < 1) return {
|
||||||
error: true,
|
error: true,
|
||||||
msg: 'Missing reply name'
|
msg: 'Missing reply name'
|
||||||
};
|
};
|
||||||
const [_name, ...rest] = args;
|
const [ _name, ...rest ] = args;
|
||||||
|
|
||||||
const name = _name.toLowerCase();
|
const name = _name.toLowerCase();
|
||||||
const canned = this.client.modmail.replies;
|
const canned = this.client.modmail.replies;
|
||||||
@ -63,7 +64,7 @@ class CannedReply extends Command {
|
|||||||
if (canned[name]) {
|
if (canned[name]) {
|
||||||
confirmation = await this.client.prompt(`A canned reply by the name ${name} already exists, would you like to overwrite it?`, { channel, author });
|
confirmation = await this.client.prompt(`A canned reply by the name ${name} already exists, would you like to overwrite it?`, { channel, author });
|
||||||
if (!confirmation) return 'Timed out.';
|
if (!confirmation) return 'Timed out.';
|
||||||
confirmation = ['y', 'yes', 'ok'].includes(confirmation.content.toLowerCase());
|
confirmation = [ 'y', 'yes', 'ok' ].includes(confirmation.content.toLowerCase());
|
||||||
if (!confirmation) return 'Cancelled';
|
if (!confirmation) return 'Cancelled';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,20 +5,20 @@ const Command = require('../Command');
|
|||||||
|
|
||||||
class Eval extends Command {
|
class Eval extends Command {
|
||||||
|
|
||||||
constructor(client) {
|
constructor (client) {
|
||||||
super(client, {
|
super(client, {
|
||||||
name: 'eval',
|
name: 'eval',
|
||||||
aliases: ['e']
|
aliases: [ 'e' ]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(message, { clean }) {
|
async execute (message, { clean }) {
|
||||||
|
|
||||||
if (!this.client._options.evalAccess.includes(message.author.id)) return;
|
if (!this.client._options.evalAccess.includes(message.author.id)) return;
|
||||||
const { guild, author, member, client, channel } = message; //eslint-disable-line no-unused-vars
|
const { guild, author, member, client, channel } = message; // eslint-disable-line no-unused-vars
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let evaled = eval(clean); //eslint-disable-line no-eval
|
let evaled = eval(clean); // eslint-disable-line no-eval
|
||||||
if (evaled instanceof Promise) await evaled;
|
if (evaled instanceof Promise) await evaled;
|
||||||
if (typeof evaled !== 'string') evaled = inspect(evaled);
|
if (typeof evaled !== 'string') evaled = inspect(evaled);
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ class Eval extends Command {
|
|||||||
.replace(new RegExp(this.client.token, 'gu'), '<redacted>')
|
.replace(new RegExp(this.client.token, 'gu'), '<redacted>')
|
||||||
.replace(new RegExp(username, 'gu'), '<redacted>');
|
.replace(new RegExp(username, 'gu'), '<redacted>');
|
||||||
|
|
||||||
//if (args.log) guild._debugLog(`[${message.author.tag}] Evaluation Success: ${evaled}`);
|
// if (args.log) guild._debugLog(`[${message.author.tag}] Evaluation Success: ${evaled}`);
|
||||||
|
|
||||||
if (evaled.length > 1850) {
|
if (evaled.length > 1850) {
|
||||||
evaled = `${evaled.substring(0, 1850)}...`;
|
evaled = `${evaled.substring(0, 1850)}...`;
|
||||||
@ -41,7 +41,7 @@ class Eval extends Command {
|
|||||||
|
|
||||||
let msg = `${error}${error.stack ? `\n${error.stack}` : ''}`;
|
let msg = `${error}${error.stack ? `\n${error.stack}` : ''}`;
|
||||||
|
|
||||||
//if (args.log) guild._debugLog(`[${message.author.tag}] Evaluation Fail: ${msg}`);
|
// if (args.log) guild._debugLog(`[${message.author.tag}] Evaluation Fail: ${msg}`);
|
||||||
if (msg.length > 2000) msg = `${msg.substring(0, 1900)}...`;
|
if (msg.length > 2000) msg = `${msg.substring(0, 1900)}...`;
|
||||||
await channel.send(
|
await channel.send(
|
||||||
`Evaluation failed.\`\`\`js\n${msg}\`\`\``,
|
`Evaluation failed.\`\`\`js\n${msg}\`\`\``,
|
||||||
|
@ -2,25 +2,25 @@ const Command = require('../Command');
|
|||||||
|
|
||||||
class ModmailID extends Command {
|
class ModmailID extends Command {
|
||||||
|
|
||||||
constructor(client) {
|
constructor (client) {
|
||||||
super(client, {
|
super(client, {
|
||||||
name: 'id',
|
name: 'id',
|
||||||
aliases: ['mmid']
|
aliases: [ 'mmid' ]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(message, { args }) {
|
async execute (message, { args }) {
|
||||||
|
|
||||||
let channel = null;
|
let channel = null;
|
||||||
if (args?.length) {
|
if (args?.length) {
|
||||||
const [ch] = args;
|
const [ ch ] = args;
|
||||||
channel = await this.client.resolveChannel(ch);
|
channel = await this.client.resolveChannel(ch);
|
||||||
} else {
|
} else {
|
||||||
({ channel } = message);
|
({ channel } = message);
|
||||||
}
|
}
|
||||||
|
|
||||||
const chCache = this.client.cache.channels;
|
const chCache = this.client.cache.channels;
|
||||||
const result = Object.entries(chCache).find(([, val]) => {
|
const result = Object.entries(chCache).find(([ , val ]) => {
|
||||||
return val === channel.id;
|
return val === channel.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ class ModmailID extends Command {
|
|||||||
msg: `This doesn't seem to be a valid modmail channel. Cache might be out of sync. **[MISSING TARGET]**`
|
msg: `This doesn't seem to be a valid modmail channel. Cache might be out of sync. **[MISSING TARGET]**`
|
||||||
};
|
};
|
||||||
|
|
||||||
const [userId] = result;
|
const [ userId ] = result;
|
||||||
return userId;
|
return userId;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,16 +2,16 @@ const Command = require('../Command');
|
|||||||
|
|
||||||
class Logs extends Command {
|
class Logs extends Command {
|
||||||
|
|
||||||
constructor(client) {
|
constructor (client) {
|
||||||
super(client, {
|
super(client, {
|
||||||
name: 'logs',
|
name: 'logs',
|
||||||
aliases: ['mmlogs', 'mmhistory', 'mmlog'],
|
aliases: [ 'mmlogs', 'mmhistory', 'mmlog' ],
|
||||||
showUsage: true,
|
showUsage: true,
|
||||||
usage: '<user> [page]'
|
usage: '<user> [page]'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(message, { args }) {
|
async execute (message, { args }) {
|
||||||
|
|
||||||
const user = await this.client.resolveUser(args[0]);
|
const user = await this.client.resolveUser(args[0]);
|
||||||
let pageNr = 1;
|
let pageNr = 1;
|
||||||
@ -27,7 +27,7 @@ class Logs extends Command {
|
|||||||
const { member, channel } = message;
|
const { member, channel } = message;
|
||||||
const history = await this.client.cache.loadModmailHistory(user.id);
|
const history = await this.client.cache.loadModmailHistory(user.id);
|
||||||
if (!history.length) return 'Not found in modmail DB';
|
if (!history.length) return 'Not found in modmail DB';
|
||||||
const page = this.paginate([...history].filter((e) => !('readState' in e)).reverse(), pageNr, 10);
|
const page = this.paginate([ ...history ].filter((e) => !('readState' in e)).reverse(), pageNr, 10);
|
||||||
|
|
||||||
const embed = {
|
const embed = {
|
||||||
author: {
|
author: {
|
||||||
@ -43,6 +43,7 @@ class Logs extends Command {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (const entry of page.items) {
|
for (const entry of page.items) {
|
||||||
|
// eslint-disable-next-line no-shadow
|
||||||
const user = await this.client.resolveUser(entry.author);
|
const user = await this.client.resolveUser(entry.author);
|
||||||
embed.fields.push({
|
embed.fields.push({
|
||||||
name: `${user.tag}${entry.anon ? ' (ANON)' : ''} @ ${new Date(entry.timestamp).toUTCString()}`,
|
name: `${user.tag}${entry.anon ? ' (ANON)' : ''} @ ${new Date(entry.timestamp).toUTCString()}`,
|
||||||
@ -54,7 +55,7 @@ class Logs extends Command {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
paginate(items, page = 1, pageLength = 10) {
|
paginate (items, page = 1, pageLength = 10) {
|
||||||
const maxPage = Math.ceil(items.length / pageLength);
|
const maxPage = Math.ceil(items.length / pageLength);
|
||||||
if (page < 1) page = 1;
|
if (page < 1) page = 1;
|
||||||
if (page > maxPage) page = maxPage;
|
if (page > maxPage) page = maxPage;
|
||||||
|
@ -2,13 +2,13 @@ const Command = require('../Command');
|
|||||||
|
|
||||||
class Markread extends Command {
|
class Markread extends Command {
|
||||||
|
|
||||||
constructor(client) {
|
constructor (client) {
|
||||||
super(client, {
|
super(client, {
|
||||||
name: 'markread'
|
name: 'markread'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(message, { args }) {
|
async execute (message, { args }) {
|
||||||
|
|
||||||
return this.client.modmail.changeReadState(message, args);
|
return this.client.modmail.changeReadState(message, args);
|
||||||
|
|
||||||
|
@ -2,13 +2,13 @@ const Command = require('../Command');
|
|||||||
|
|
||||||
class Markunread extends Command {
|
class Markunread extends Command {
|
||||||
|
|
||||||
constructor(client) {
|
constructor (client) {
|
||||||
super(client, {
|
super(client, {
|
||||||
name: 'markunread'
|
name: 'markunread'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(message, { args }) {
|
async execute (message, { args }) {
|
||||||
|
|
||||||
return this.client.modmail.changeReadState(message, args, 'unread');
|
return this.client.modmail.changeReadState(message, args, 'unread');
|
||||||
|
|
||||||
|
@ -2,19 +2,19 @@ const Command = require('../Command');
|
|||||||
|
|
||||||
class Modmail extends Command {
|
class Modmail extends Command {
|
||||||
|
|
||||||
constructor(client) {
|
constructor (client) {
|
||||||
super(client, {
|
super(client, {
|
||||||
name: 'modmail',
|
name: 'modmail',
|
||||||
aliases: ['mm'],
|
aliases: [ 'mm' ],
|
||||||
showUsage: true,
|
showUsage: true,
|
||||||
usage: `<user> <content>`
|
usage: `<user> <content>`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(message, { args }) {
|
async execute (message, { args }) {
|
||||||
|
|
||||||
// eslint-disable-next-line prefer-const
|
// eslint-disable-next-line prefer-const
|
||||||
let [first, second] = args.map((a) => a);
|
let [ first, second ] = args.map((a) => a);
|
||||||
// eslint-disable-next-line prefer-const
|
// eslint-disable-next-line prefer-const
|
||||||
let { content, _caller } = message,
|
let { content, _caller } = message,
|
||||||
anon = false;
|
anon = false;
|
||||||
|
@ -2,13 +2,13 @@ const Command = require('../Command');
|
|||||||
|
|
||||||
class Ping extends Command {
|
class Ping extends Command {
|
||||||
|
|
||||||
constructor(client) {
|
constructor (client) {
|
||||||
super(client, {
|
super(client, {
|
||||||
name: 'ping'
|
name: 'ping'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute() {
|
async execute () {
|
||||||
return `PONG!`;
|
return `PONG!`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,14 +2,14 @@ const Command = require('../Command');
|
|||||||
|
|
||||||
class Queue extends Command {
|
class Queue extends Command {
|
||||||
|
|
||||||
constructor(client) {
|
constructor (client) {
|
||||||
super(client, {
|
super(client, {
|
||||||
name: 'queue',
|
name: 'queue',
|
||||||
aliases: ['mmq', 'mmqueue', 'q']
|
aliases: [ 'mmq', 'mmqueue', 'q' ]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(message) {
|
async execute (message) {
|
||||||
|
|
||||||
const { queue } = this.client.modmail;
|
const { queue } = this.client.modmail;
|
||||||
if (!queue.length) return 'Queue is empty!';
|
if (!queue.length) return 'Queue is empty!';
|
||||||
|
@ -2,18 +2,18 @@ const Command = require('../Command');
|
|||||||
|
|
||||||
class Reply extends Command {
|
class Reply extends Command {
|
||||||
|
|
||||||
constructor(client) {
|
constructor (client) {
|
||||||
super(client, {
|
super(client, {
|
||||||
name: 'reply',
|
name: 'reply',
|
||||||
aliases: ['r'],
|
aliases: [ 'r' ],
|
||||||
showUsage: true,
|
showUsage: true,
|
||||||
usage: `<reply content>`
|
usage: `<reply content>`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(message, { args }) {
|
async execute (message, { args }) {
|
||||||
|
|
||||||
const [first] = args.map((a) => a);
|
const [ first ] = args.map((a) => a);
|
||||||
// eslint-disable-next-line prefer-const
|
// eslint-disable-next-line prefer-const
|
||||||
let { content, _caller } = message,
|
let { content, _caller } = message,
|
||||||
anon = false;
|
anon = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user