const { stripIndents } = require('common-tags'); 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. 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(); this.duration = opts.duration || null; //How long the event will last. Must be in milliseconds. this.expiration = opts.duration ? opts.duration + this.timestamp : null; //When the event will expire this.reason = opts.reason; this.points = 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. this._logMessage = null; //The message embed sent in the moderation-log. Full message content, not the ID. this._resolved = false; } async log(opts) { const { moderationLog, moderationPoints } = this.guild._settings; if(moderationLog.channel) { if(moderationLog.infractions.includes(this.type.toLowerCase())) { const channel = this.client.resolver.resolveChannel(moderationLog.channel, true, this.guild); 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.`); } } if(moderationPoints.enabled) { if(this.arguments.points) { this.points = parseInt(this.arguments.points.value); } else { this.points = moderationPoints.points[this.type] || 0; } } if(this.guild._settings.dmInfraction.value && this.targetType === 'user') { try { await this.target.send(this.message.format('INFRACTION_DIRECTMESSAGE', { guild: this.guild.name }), { embed: this.embed() }); } catch(e) {} //eslint-disable-line no-empty } await this.save(); } async save() { await this.client.transactionHandler.send({ provider: 'mongodb', request: { type: 'insertOne', data: this.json } }).catch((error) => { this.client.logger.error(`There was an issue saving infraction data to the database.\n${error.stack || error}`); }); } embed(jumpTo = false) { let description = this.message.format('INFRACTION_DESCRIPTION', { type: this.type, moderator: `${this.executor.tag} (${this.executor.id})`, reason: this.reason }); if(this.duration) { description += this.message.format('INFRACTION_DESCRIPTIONDURATION', { duration: this._duration() }); } if(jumpTo) { description += this.message.format; } 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 }; } 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, expiration: this.expiration, reason: this.reason, timestamp: this.timestamp }; } get targetName() { return this.targetType === 'user' ? this.target.tag : `#${this.target.name}`; } get targetIcon() { return this.targetType === 'user' ? this.target.displayAvatarURL() : this.guild.iconURL(); } //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;