enable/disable and message logging

This commit is contained in:
nolan 2020-07-28 11:49:34 -07:00
parent 4a6298bd57
commit 97e34af8c4
6 changed files with 151 additions and 132 deletions

View File

@ -35,7 +35,6 @@
"warn",
"never"
],
"consistent-return": "warn",
"consistent-this": "warn",
"dot-notation": [
"warn",

View File

@ -61,7 +61,8 @@ class StorageManager {
if(!this.providers.has(message.provider)) return this._send(shard, { error: true, message: `Invalid provider, expected 'mongodb' or 'mariadb', got '${message.provider}'`, transactionID: message.transactionID });
if(!message.request) return this._send(shard, { error: true, message: `Missing request.`, transactionID: message.transactionID });
const response = await this.providers.get(message.provider)._query(message.request).catch((error) => {
const response = await this.providers.get(message.provider)._query(message.request)
.catch((error) => {
this.manager.logger.write('error', `Provider ${message.provider} errored: ${error}`, shard);
});

View File

@ -15,13 +15,12 @@ class Resolver {
* @returns
* @memberof Resolver
*/
<<<<<<< HEAD
resolveComponent(arg, strict = true, type) {
resolveComponent(arg, strict = true, type = 'any') {
const string = arg.toLowerCase();
const components = this.client.registry.components
.filter((c) => c.type === type)
.filter((c) => type === 'any' ? ['command', 'setting'].includes(c.type) : c.type === type)
.filter(strict ? filterExact(string) : filterInexact(string)); //eslint-disable-line no-use-before-define
return components.first();
@ -29,9 +28,6 @@ class Resolver {
}
components(str = '', type, exact = true) {
=======
components(str = '', type = 'any', exact = true) {
>>>>>>> 79e0bce3b5fd9afe59f5c5e7d8bbc4a78f518acd
const string = str.toLowerCase();

View File

@ -1,3 +1,5 @@
const { MessageAttachment, WebhookClient } = require('discord.js');
const { Observer } = require('../../../interfaces/');
const { Util } = require('../../../../util');
@ -27,105 +29,27 @@ class GuildLogger extends Observer {
super(client, {
name: 'guildLogger',
priority: 3,
disabled: true
priority: 3
// disabled: true
});
this.hooks = [
['message', this.storeAttachment.bind(this)], //Attachment logging
['messageDelete', this.messageDelete.bind(this)],
['messageDeleteBulk', this.messageDeleteBulk.bind(this)],
['messageUpdate', this.messageEdit.bind(this)],
['voiceStateUpdate', this.voiceState.bind(this)],
['guildBanAdd', this.ban.bind(this)],
['guildBanRemove', this.unban.bind(this)],
['guildMemberAdd', this.memberJoin.bind(this)],
['guildMemberRemove', this.memberLeave.bind(this)],
['guildMemberUpdate', this.memberUpdate.bind(this)]
// ['message', this.storeAttachment.bind(this)], //Attachment logging
['messageDelete', this.messageDelete.bind(this)]
// ['messageDeleteBulk', this.messageDeleteBulk.bind(this)],
// ['messageUpdate', this.messageEdit.bind(this)],
// ['voiceStateUpdate', this.voiceState.bind(this)],
// ['guildBanAdd', this.ban.bind(this)],
// ['guildBanRemove', this.unban.bind(this)],
// ['guildMemberAdd', this.memberJoin.bind(this)],
// ['guildMemberRemove', this.memberLeave.bind(this)],
// ['guildMemberUpdate', this.memberUpdate.bind(this)]
];
}
async storeAttachment(message) {
const { guild, member, author, channel } = message;
if(!guild || author.bot) return;
if(!message.attachments.size) return;
console.log('Store call');
const settings = await guild.settings(),
setting = settings.messageLog,
roles = member.roles.cache.map((r) => r.id),
{ ignoredRoles } = setting;
//if(guild._settings.premium < CONSTANTS.IMAGES.PREMIUM_LIMIT) return;
if(!setting.attachments || setting.ignoredChannels.includes(channel.id)) return;
if(setting.ignoredRoles.length && roles.length) for(const role of ignoredRoles) if(roles.includes(role)) return;
console.log('Can store');
const attachments = message.attachments.values();
for(const attachment of attachments) {
const TH = this.client.transactionHandler;
const { size, name, id } = attachment;
const fsize = size/CONSTANTS.IMAGES.MB_DIVIDER; // File size in MB
if(fsize > CONSTANTS.IMAGES.UPLOAD_LIMIT[guild.premiumTier]) continue;
const buffer = await Util.downloadAsBuffer(attachment.url).catch((err) => {
this.client.logger.error(err); return null;
});
if(!buffer) return;
const data = {
buffer,
id
};
try {
//TODO: test this
//const start = Date.now();
const result = await TH.send({
provider: 'mongodb',
request: {
type: 'insertOne',
collection: 'attachment_logs',
data
}
});
//console.log(`Took ${Date.now()-start}ms to insert image.`);
//console.log(result);
const metadata = {
database_ID: result.insertedId,
id,
guild: guild.id,
message: message.id,
author: author.id,
name,
size,
timestamp: Math.floor(Date.now()/1000),
removeAt: Math.floor(Date.now()/1000 + guild._settings.premium * CONSTANTS.WEEK * 0.25)
};
//console.log(metadata);
await TH.send({
provider: 'mongodb',
request: {
type: 'insertOne',
collection: 'attachment_logs_index',
data: metadata
}
});
//console.log(`Took ${Date.now()-start}ms to insert entire entry.`);
} catch (err) {
this.client.logger.error('Something went wrong with storing image to db:\n' + err.stack);
}
}
this.attachmentWebhook = new WebhookClient(
this.client._options.moderation.attachments.webhook.id,
this.client._options.moderation.attachments.webhook.token
);
}
@ -138,35 +62,138 @@ class GuildLogger extends Observer {
async messageDelete(message) {
if(message.author.bot) return;
if(!this.client._built
|| message.webhookID
|| message.author.bot
|| !message.guild
|| !message.guild.available) return;
const { guild } = message;
if (!guild) return;
await message.guild.settings();
if (!message.member) message.member = await guild.members.fetch(message.author);
const { member, channel, author } = message;
if (!message.member) message.member = await message.guild.members.fetch(message.author.id);
const settings = await guild.settings();
const chatlogs = settings.messageLog;
if (!chatlogs || !chatlogs.channel) return;
const { messageLog } = message.guild._settings;
if(!messageLog.channel) return undefined;
const { ignoredRoles, ignoredChannels } = chatlogs;
const logChannel = await guild.resolveChannel(chatlogs.channel);
if(!logChannel) return;
const { ignoredRoles, ignoredChannels } = messageLog;
const logChannel = await message.guild.resolveChannel(messageLog.channel);
if(!logChannel) return undefined;
const perms = logChannel.permissionsFor(guild.me);
if(!perms.has('SEND_MESSAGES') || !perms.has('VIEW_CHANNEL')) return;
const perms = logChannel.permissionsFor(message.guild.me);
if(!perms.has('SEND_MESSAGES') || !perms.has('VIEW_CHANNEL')) return undefined;
if (ignoredRoles.length && member.roles.cache.size) {
const roles = member.roles.cache.map((r) => r.id);
if(ignoredRoles.length && message.member.roles.cache.size) {
const roles = message.member.roles.cache.map((r) => r.id);
for (const role of ignoredRoles) {
if (roles.includes(role)) return;
if (roles.includes(role)) return undefined;
}
}
if (ignoredChannels && ignoredChannels.includes(channel.id)) return;
if(ignoredChannels && ignoredChannels.includes(message.channel.id)) return undefined;
if (message.attachments.size) return this.logAttachment({ msgID: message.id, guildID: guild.id, channelID: channel.id, logChannel });
const embed = {
author: {
name: `${message.author.tag} (${message.author.id})`,
icon_url: message.author.displayAvatarURL({ size: 32 }) //eslint-disable-line camelcase
},
description: Util.escapeMarkdown(message.content).replace(/\\n/gu, ' '),
color: CONSTANTS.COLORS.RED,
footer: {
text: `Message deleted in #${message.channel.name} | Message ID: ${message.id}`
},
timestamp: message.createdAt
};
const uploadedFiles = [];
if(message.attachments.size > 0 && messageLog.attachments) {
const imageExtensions = ['.png', '.webp', '.jpg', '.jpeg', '.gif'];
const data = await this.client.transactionHandler.send({
provider: 'mongodb',
request: {
collection: 'messages',
type: 'findOne',
query: {
id: message.id
}
}
});
const attachments = await this.client.transactionHandler.send({
provider: 'mongodb',
request: {
collection: 'attachments',
type: 'find',
query: {
_id: { $in: data.attachments.filter((a) => a.index).map((a) => a.index) }
}
}
});
const sortedAttachments = data.attachments.sort((a, b) => b.size-a.size);
const files = [];
for(const attachment of sortedAttachments) {
const attachmentData = attachments.find((a) => a.attachmentId === attachment.id);
if(attachmentData) {
attachmentData.buffer = Buffer.from(attachmentData.buffer, 'base64');
const messageAttachment = new MessageAttachment(attachmentData.buffer, attachment.name, { size: attachment.size });
if(messageAttachment.size < CONSTANTS.IMAGES.UPLOAD_LIMIT[message.guild.premiumTier]*CONSTANTS.IMAGES.MB_DIVIDER) {
if(imageExtensions.includes(attachment.extension) && uploadedFiles.length === 0) {
uploadedFiles.push(messageAttachment);
embed.image = {
url: `attachment://${attachment.name}`
};
} else {
if(messageAttachment.size > 8*CONSTANTS.IMAGES.MB_DIVIDER) {
const combined = uploadedFiles.length > 0 ? uploadedFiles.map((f) => f.size).reduce((p, v) => p+v) : 0;
if((combined + messageAttachment.size)/CONSTANTS.IMAGES.MB_DIVIDER < CONSTANTS.IMAGES.UPLOAD_LIMIT[message.guild.premiumTier]) {
uploadedFiles.push(messageAttachment);
}
} else {
files.push(messageAttachment);
}
}
}
}
}
let currentFiles = [];
const uploaded = [];
const upload = async (files) => {
const attachmentMessage = await this.attachmentWebhook.send(null, files).catch((error) => console.error(error));
attachmentMessage.attachments.map((a) => uploaded.push(`[${a.filename} (${(a.size/CONSTANTS.IMAGES.MB_DIVIDER).toFixed(2)}mb)](${a.url})`));
console.log(attachmentMessage.attachments);
};
for(const file of files) {
const currentMb = currentFiles.length > 0 ? currentFiles.map((f) => f.size).reduce((p, v) => p+v) : 0;
if(currentMb + file.size > 8*CONSTANTS.IMAGES.MB_DIVIDER) {
await upload(currentFiles);
currentFiles = [];
} else {
currentFiles.push(file);
}
}
if(currentFiles.length > 0) {
await upload(currentFiles);
}
console.log(uploaded.length);
if(uploaded.length > 0) {
embed.description += `\n\n**${uploadedFiles.length > 0 ? 'Additional ' : ''}Attachment${uploaded.length > 1 ? 's' : ''}:** ${uploaded.join(', ')}`;
}
}
message.respond(null, { embed, files: uploadedFiles });
/*
if(message.attachments.size > 0) {
return this.logAttachment({ msgID: message.id, guildID: guild.id, channelID: channel.id, logChannel });
}
const embed = {
title: message.format('MSGLOG_DELETE_TITLE', { author: Util.escapeMarkdown(author.tag), channel: channel.name }),
@ -179,6 +206,7 @@ class GuildLogger extends Observer {
};
await logChannel.send({ embed });
*/
}

View File

@ -55,8 +55,8 @@ class MessageCache extends Observer {
if(!this.client._built
|| message.webhookID
|| message.author.bot
|| !message.guild.available
|| !message.guild) return undefined;
|| !message.guild
|| !message.guild.available) return undefined;
await message.guild.settings();
@ -126,11 +126,7 @@ class MessageCache extends Observer {
}
const buffer = await Util.downloadAsBuffer(attachment.proxyURL || attachment.url).catch((err) => {
<<<<<<< HEAD
this.client.logger.error(`Failed to download buffer for "${chalk.bold(data.name)}".\n${err.stack || err}`);
=======
this.client.logger.error(`Failed to save buffer with image data: ${data} ${data.name}\n${err.stack || err}`);
>>>>>>> 79e0bce3b5fd9afe59f5c5e7d8bbc4a78f518acd
return null;
});

View File

@ -94,7 +94,7 @@ const Message = Structures.extend('Message', (Message) => {
}
async respond(str, opts = { attachments: [], embed: null }) {
async respond(str, opts = { files: [], embed: null }) {
if(typeof str === 'string') {
if(opts.emoji) {
@ -105,8 +105,7 @@ const Message = Structures.extend('Message', (Message) => {
if(opts.reply) str = `<@!${this.author.id}> ${str}`;
}
//console.log(str)
this._pending = await this.channel.send(str, { files: opts.attachments, embed: opts.embed });
this._pending = await this.channel.send(str, { files: opts.files, embed: opts.embed });
return this._pending;
}