galactic-bot/structure/moderation/interfaces/Infraction.js

219 lines
7.4 KiB
JavaScript
Raw Normal View History

2020-06-04 19:59:09 +02:00
const { Util } = require('../../../util/');
const Constants = {
MaxCharacters: 1024 // Max embed description is 2048 characters, however some of those description characters are going to usernames, types, filler text, etc.
};
class Infraction {
constructor(client, opts = {}) {
this.client = client;
this.message = opts.message;
this.arguments = opts.arguments;
this.target = opts.target; //User or channel being targeted.
2020-04-17 22:18:29 +02:00
this.targetType = opts.targetType; // 'user' or 'channel'.
this.executor = opts.executor; //Whoever executed the command.
this.guild = opts.guild;
this.channel = opts.channel;
this.case = null;
this.type = opts.type; //What type of infraction (mute, kick, etc.)
this.timestamp = new Date().getTime();
2020-06-04 19:59:09 +02:00
this.duration = opts.duration || null; //How long the action will last. Must be in milliseconds.
this.reason = opts.reason.length ? opts.reason : 'N/A';
this.silent = opts.silent;
this.points = 0;
2020-06-04 19:59:09 +02:00
this.totalPoints = 0;
this.expiration = 0;
this.color = opts.color; //Infraction-defined hexadecimal value to dictate what color the embed is.
this.dictionary = opts.dictionary || {}; // { past: 'banned', present: 'ban' } Infraction-defined object for the correct spellings.
2020-06-04 19:59:09 +02:00
this._logMessage = null; //The message embed sent in the moderation-log. Full message, not the ID.
this._dmMessage = null; //The message embed sent in the target's direct messages. Full message, not the ID.
}
2020-06-04 19:59:09 +02:00
async log() {
if(this.silent) {
try {
await this.message.delete();
} catch(e) {} //eslint-disable-line no-empty
}
const { moderationLog, moderationPoints } = this.guild._settings;
2020-06-04 19:59:09 +02:00
/* Handling */
if(moderationPoints.enabled) {
if(this.arguments.points) {
this.points = parseInt(this.arguments.points.value);
} else {
this.points = moderationPoints.points[this.type] || 0;
}
if(this.arguments.expiration) {
this.expiration = parseInt(this.arguments.expiration.value);
} else {
this.expiration = moderationPoints.expirations[this.type] || 0;
}
if(this.targetType === 'user') {
this.totalPoints = await this.target.totalPoints(this.guild, this.points);
}
}
this.guild._settings.caseId++;
this.case = this.guild._settings.caseId;
await this.guild._updateSettings({
caseId: this.case
});
console.log(`points: ${this.points}, total points: ${this.totalPoints}, expiration: ${this.expiration}`);
/* Logging */
if(moderationLog.channel) {
if(moderationLog.infractions.includes(this.type.toLowerCase())) {
const channel = this.client.resolver.resolveChannel(moderationLog.channel, true, this.guild);
2020-06-04 19:59:09 +02:00
if(!channel) return undefined;
this._logMessage = await channel.send('', { embed: this.embed() });
} else {
this.client.logger.debug(`Did not log infraction ${this.type} because it is not in the infractions.`);
}
}
2020-06-04 19:59:09 +02:00
if(this.guild._settings.dmInfraction.enabled
&& this.targetType === 'user') {
2020-06-04 19:59:09 +02:00
let message = this.guild._settings.dmInfraction.custom[this.type] || this.guild._settings.dmInfraction.custom.default;
if(!message) message = "";
message = message
.replace(/\{(guild|server)\}/ugim, this.guild.name)
.replace(/\{user\}/ugim, this.target.tag)
.replace(/\{infraction\}/ugim, this.dictionary.past); //add more if you want i should probably add a better system for this...
try {
2020-06-04 19:59:09 +02:00
this._dmMessage = await this.target.send(message, {
embed: this.embed()
});
} catch(e) {} //eslint-disable-line no-empty
}
2020-06-04 19:59:09 +02:00
//might be useful for automod related stuff
// this.client.emit('infractionUpdate', {
// action: 'new',
// infraction: this
// });
return this.save();
}
2020-04-17 22:18:29 +02:00
async save() {
await this.client.transactionHandler.send({
2020-04-17 22:18:29 +02:00
provider: 'mongodb',
request: {
type: 'insertOne',
2020-06-04 19:59:09 +02:00
collection: 'infractions',
data: this.json
2020-04-17 22:18:29 +02:00
}
}).catch((error) => {
this.client.logger.error(`There was an issue saving infraction data to the database.\n${error.stack || error}`);
});
}
2020-06-04 19:59:09 +02:00
embed() {
let description = this.message.format('INFRACTION_DESCRIPTION', {
2020-06-04 19:59:09 +02:00
type: this.dictionary.past.toUpperCase(),
moderator: `${Util.escapeMarkdown(this.executor.tag)}`,
reason: this.reason.length > Constants.MaxCharacters ? `${this.reason.substring(0, Constants.MaxCharacters-3)}...` : this.reason
});
if(this.duration) {
2020-06-04 19:59:09 +02:00
description += `\n${this.message.format('INFRACTION_DESCRIPTIONDURATION', { duration: this._duration() })}`;
}
2020-06-04 19:59:09 +02:00
if(this.points) {
description += `\n${this.message.format('INFRACTION_DESCRIPTIONPOINTS', { points: this.points, total: this.totalPoints })}`;
}
if(!this.silent) {
description += `\n${this.message.format('INFRACTION_DESCRIPTIONJUMPTO', { name: 'Message', link: `https://discord.com/channels/${this.guild.id}/${this.channel.id}/${this.message.id}` })}`;
}
return {
author: {
name: `${this.targetName} (${this.target.id})`,
icon_url: this.targetIcon //eslint-disable-line camelcase
},
timestamp: new Date(),
color: this.color,
footer: {
text: `》 Case ${this.case}`
},
description
};
2020-04-17 22:18:29 +02:00
}
get json() {
return {
id: `${this.guild.id}:${this.case}`,
guild: this.guild.id,
channel: this.channel ? this.channel.id : null,
message: this.message ? this.message.id : null,
executor: this.executor.id,
target: this.target.id,
targetType: this.targetType,
type: this.type,
case: this.case,
duration: this.duration,
reason: this.reason,
2020-06-04 19:59:09 +02:00
timestamp: this.timestamp,
points: this.points,
expiration: this.expiration
2020-04-17 22:18:29 +02:00
};
}
get targetName() {
return this.targetType === 'user'
? this.target.tag
2020-04-17 22:18:29 +02:00
: `#${this.target.name}`;
}
get targetIcon() {
return this.targetType === 'user'
? this.target.displayAvatarURL()
: this.guild.iconURL();
}
2020-06-04 19:59:09 +02:00
get _reason() {
let str = `[targetId:${this.target.id}] Executed by ${this.executor.tag} (${this.executor.id}) because: ${this.reason}`;
if(str.length > 512) str = `${this.reason.substring(0, 509)}...`;
return str;
}
//Super Functions
_succeed() {
return {
error: false,
infraction: this
};
}
_fail(message, opts) {
return {
error: true,
infraction: this,
reason: this.message.format(message, opts)
};
}
}
module.exports = Infraction;