galactic-bot/structure/client/components/observers/GuildLogging.js

550 lines
22 KiB
JavaScript
Raw Normal View History

2020-09-05 22:57:46 +02:00
/* eslint-disable no-labels */
2020-07-28 20:49:34 +02:00
const { MessageAttachment, WebhookClient } = require('discord.js');
2020-06-18 16:07:39 +02:00
const { Observer } = require('../../../interfaces/');
2020-08-17 22:24:23 +02:00
const { Util, Constants: { EmbedLimits } } = require('../../../../util');
const { stripIndents } = require('common-tags');
const moment = require('moment');
2020-06-18 16:07:39 +02:00
2020-06-18 23:00:32 +02:00
const CONSTANTS = {
COLORS: {
RED: 16711680, // message delete
YELLOW: 15120384, // message edit
2020-06-19 20:30:30 +02:00
LIGHT_BLUE: 11337726, // message pin
BLUE: 479397
2020-06-20 22:27:23 +02:00
},
IMAGES: {
PREMIUM_LIMIT: 2,
UPLOAD_LIMIT: {
'0': 8,
'1': 8,
'2': 50,
'3': 100
},
MB_DIVIDER: 1024*1024
},
WEEK: 7 * 24 * 60 * 60
2020-06-18 23:00:32 +02:00
};
2020-06-18 16:07:39 +02:00
class GuildLogger extends Observer {
constructor(client) {
super(client, {
name: 'guildLogger',
2021-06-09 01:45:34 +02:00
priority: 3,
disabled: false
2020-06-18 16:07:39 +02:00
});
this.hooks = [
2020-08-06 00:13:39 +02:00
['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)]
2020-06-18 16:07:39 +02:00
];
2020-07-28 20:49:34 +02:00
this.attachmentWebhook = new WebhookClient(
this.client._options.moderation.attachments.webhook.id,
this.client._options.moderation.attachments.webhook.token
);
2020-06-18 16:07:39 +02:00
}
2020-07-28 20:49:34 +02:00
//TODO: Figure this thing out, this should be called from messageDelete and rawMessageDelete if any attachments are present
//data should be an object containing the necessary information to query for the attachment from the db, and the relevant information to log it
//Will figure this out once I get to that point
async logAttachment(data) {
}
2020-06-18 16:07:39 +02:00
2020-07-28 20:49:34 +02:00
async messageDelete(message) {
2020-06-20 22:27:23 +02:00
2020-07-28 20:49:34 +02:00
if(!this.client._built
|| message.webhookID
|| message.author.bot
|| !message.guild
|| !message.guild.available) return;
2020-06-20 22:27:23 +02:00
2020-07-28 20:49:34 +02:00
await message.guild.settings();
2021-06-09 01:45:34 +02:00
if (!message.member) message.member = await message.guild.members.fetch(message.author.id).catch();
2020-06-20 22:27:23 +02:00
2020-07-28 20:49:34 +02:00
const { messageLog } = message.guild._settings;
if(!messageLog.channel) return undefined;
2021-05-31 23:43:31 +02:00
const { bypass, ignore } = messageLog;
2020-07-28 20:49:34 +02:00
const logChannel = await message.guild.resolveChannel(messageLog.channel);
if(!logChannel) return undefined;
2020-06-20 22:27:23 +02:00
2020-07-28 20:49:34 +02:00
const perms = logChannel.permissionsFor(message.guild.me);
2020-08-08 21:16:13 +02:00
if (!perms.has('SEND_MESSAGES') || !perms.has('VIEW_CHANNEL') || !perms.has('EMBED_LINKS')) return undefined;
2020-06-20 22:27:23 +02:00
2021-05-31 23:43:31 +02:00
if(bypass.length && message.member.roles.cache.size) {
2020-07-28 20:49:34 +02:00
const roles = message.member.roles.cache.map((r) => r.id);
2021-05-31 23:43:31 +02:00
for (const role of bypass) {
2020-07-28 20:49:34 +02:00
if (roles.includes(role)) return undefined;
}
}
2021-05-31 23:43:31 +02:00
if (ignore && ignore.includes(message.channel.id)) return undefined;
2020-09-30 18:22:32 +02:00
const hook = await message.guild.getWebhook('messageLog');
2020-06-20 22:27:23 +02:00
2020-07-28 20:49:34 +02:00
const embed = {
author: {
name: `${message.author.tag} (${message.author.id})`,
icon_url: message.author.displayAvatarURL({ size: 32 }) //eslint-disable-line camelcase
},
2021-06-09 20:37:41 +02:00
description: Util.escapeMarkdown(message.content)?.replace(/\\n/gu, ' '),
2020-07-28 20:49:34 +02:00
color: CONSTANTS.COLORS.RED,
footer: {
text: `Message deleted in #${message.channel.name} | Message ID: ${message.id}`
},
timestamp: message.createdAt
};
2021-05-08 11:33:41 +02:00
2020-09-30 18:22:32 +02:00
if (message.filtered) {
embed.fields = [
{
name: message.format('MSGLOG_FILTERED'),
2020-09-30 23:02:54 +02:00
value: stripIndents`
${message.format(message.filtered.preset ? 'MSGLOG_FILTERED_PRESET' : 'MSGLOG_FILTERED_VALUE', { ...message.filtered })}
${message.filtered.sanctioned ? message.format('MSGLOG_FILTERED_SANCTIONED') : ''}
`// + ()
2020-09-30 18:22:32 +02:00
}
];
}
2020-07-28 20:49:34 +02:00
const uploadedFiles = [];
if(message.attachments.size > 0 && messageLog.attachments) {
const imageExtensions = ['.png', '.webp', '.jpg', '.jpeg', '.gif'];
const data = await this.client.storageManager.mongodb.messages.findOne({
id: message.id
2020-07-28 20:49:34 +02:00
});
2020-06-20 22:27:23 +02:00
2020-09-30 18:22:32 +02:00
if (data) {
const attachments = await this.client.storageManager.mongodb.attachments.find({
_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) {
2021-05-08 11:33:41 +02:00
2020-09-30 18:22:32 +02:00
const attachmentData = attachments.find((a) => a.attachmentId === attachment.id);
2021-05-08 11:33:41 +02:00
2020-09-30 18:22:32 +02:00
if (attachmentData) {
2021-06-09 17:31:15 +02:00
// Mongo does some weird serialisation of buffer data, so to access the actual buffer, you have to go 1 level deeper
attachmentData.buffer = attachmentData.buffer.buffer; //Buffer.from(attachmentData.buffer, 'base64');
2020-09-30 18:22:32 +02:00
const messageAttachment = new MessageAttachment(attachmentData.buffer, attachment.name, { size: attachment.size });
2021-05-08 11:33:41 +02:00
2020-09-30 18:22:32 +02:00
if (messageAttachment.size < CONSTANTS.IMAGES.UPLOAD_LIMIT[message.guild.premiumTier] * CONSTANTS.IMAGES.MB_DIVIDER) {
2021-05-08 11:33:41 +02:00
2020-09-30 18:22:32 +02:00
if (imageExtensions.includes(attachment.extension) && uploadedFiles.length === 0) {
2021-05-08 11:33:41 +02:00
2020-09-30 18:22:32 +02:00
uploadedFiles.push(messageAttachment);
embed.image = {
url: `attachment://${attachment.name}`
};
2021-05-08 11:33:41 +02:00
2020-07-28 20:49:34 +02:00
} else {
2021-05-08 11:33:41 +02:00
2020-09-30 18:22:32 +02:00
if (messageAttachment.size > 8 * CONSTANTS.IMAGES.MB_DIVIDER) {
2021-05-08 11:33:41 +02:00
2020-09-30 18:22:32 +02:00
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);
}
2021-05-08 11:33:41 +02:00
2020-09-30 18:22:32 +02:00
} else {
files.push(messageAttachment);
}
2020-07-28 20:49:34 +02:00
}
}
}
}
2020-06-20 22:27:23 +02:00
2020-09-30 18:22:32 +02:00
let currentFiles = [];
const uploaded = [];
const upload = async (files) => {
const attachmentMessage = await this.attachmentWebhook.send(null, files).catch((error) => this.client.logger.error(error));
attachmentMessage.attachments.map((a) => uploaded.push(`[${a.filename} (${(a.size / CONSTANTS.IMAGES.MB_DIVIDER).toFixed(2)}mb)](${a.url})`));
};
2021-06-09 17:31:15 +02:00
2020-09-30 18:22:32 +02:00
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);
}
}
2020-06-18 16:07:39 +02:00
2020-09-30 18:22:32 +02:00
if (currentFiles.length > 0) {
2020-07-28 20:49:34 +02:00
await upload(currentFiles);
}
2020-06-18 16:07:39 +02:00
2020-09-30 18:22:32 +02:00
if (uploaded.length > 0) {
embed.description += `\n\n**${uploadedFiles.length > 0 ? 'Additional ' : ''}Attachment${uploaded.length > 1 ? 's' : ''}:** ${uploaded.join(', ')}`;
}
2020-07-28 20:49:34 +02:00
}
2020-06-18 16:07:39 +02:00
2020-07-28 20:49:34 +02:00
}
2020-06-19 20:30:30 +02:00
2020-09-30 18:22:32 +02:00
hook.send({ embeds: [embed], files: uploadedFiles });
2020-06-18 16:07:39 +02:00
2020-07-28 20:49:34 +02:00
/*
if(message.attachments.size > 0) {
return this.logAttachment({ msgID: message.id, guildID: guild.id, channelID: channel.id, logChannel });
}
2020-06-18 16:07:39 +02:00
2020-06-18 23:00:32 +02:00
const embed = {
2020-06-19 20:30:30 +02:00
title: message.format('MSGLOG_DELETE_TITLE', { author: Util.escapeMarkdown(author.tag), channel: channel.name }),
2020-06-18 23:00:32 +02:00
description: message.content,
footer: {
text: message.format('MSGLOG_DELETE_FOOTER', { msgID: message.id, userID: author.id })
},
color: CONSTANTS.COLORS.RED,
timestamp: message.createdAt
};
await logChannel.send({ embed });
2020-07-28 20:49:34 +02:00
*/
2020-06-18 16:07:39 +02:00
}
async messageDeleteBulk(messages) {
2020-08-17 22:24:23 +02:00
//Status: Should be complete, though additional testing might be necessary
const { guild, channel } = messages.first();
if (!guild) return;
const settings = await guild.settings();
const chatlogs = settings.messageLog;
if (!chatlogs.channel) return;
2021-06-09 02:39:14 +02:00
const { ignore, bypass } = chatlogs;
if (ignore.includes(channel.id)) return;
2020-08-17 22:24:23 +02:00
const hook = await guild.getWebhook('messageLog');
if(!hook) return;
const cutOff = EmbedLimits.fieldValue;// - 3;
const fields = [];
2021-06-09 02:46:54 +02:00
messages = messages.filter((msg) => !msg.author.bot);
2020-08-17 22:24:23 +02:00
//Compile messages into fields that can be compiled into embeds
2020-09-05 22:57:46 +02:00
messageLoop: //Oldest messages first
2020-08-17 22:24:23 +02:00
for (const message of messages.array().sort((a, b) => b.createdTimestamp - a.createdTimestamp)) {
2021-06-09 19:25:37 +02:00
let { member, content } = message;
const { author, id } = message;
2020-08-17 22:24:23 +02:00
2020-09-05 22:57:46 +02:00
if (author.bot) continue;
if (!member || member.partial) member = await guild.members.fetch(message.author.id).catch(() => {
return false;
});
2020-08-17 22:24:23 +02:00
if (member && member.roles.cache.size) {
const roles = member.roles.cache.map((role) => role.id);
for (const role of roles) {
2021-06-09 02:39:14 +02:00
if (bypass.includes(role)) continue messageLoop;
2020-08-17 22:24:23 +02:00
}
}
//const attStr = message.attachments.map((att) => `${att.name} (${att.id})`).join(', ');
const value = stripIndents`${content ? content.substring(0, cutOff) : message.format('BULK_DELETE_NO_CONTENT')}`;
//${message.attachments.size > 0 ? `__(Attachments: ${attStr})__` : '' }
fields.push({
name: `${Util.escapeMarkdown(author.tag)} @ ${moment.utc(message.createdAt).format('D/M/YYYY H:m:s')} UTC (MSG ID: ${id})`,
value
});
if (content && content.length > cutOff) fields.push({
2020-09-05 22:57:46 +02:00
name: '\u200b',
value: content.substring(cutOff)
2020-08-17 22:24:23 +02:00
});
}
//Compile embeds
const embedCutoff = EmbedLimits.embed - 100;
const embeds = [];
2020-09-05 22:57:46 +02:00
const embed = { // title gets set later
2020-08-17 22:24:23 +02:00
fields: [],
color: CONSTANTS.COLORS.RED
};
2020-09-30 19:04:38 +02:00
let length = 0; // Embed total length
fields.reduce((_embed, field) => {
2020-08-17 22:24:23 +02:00
//Make sure the total character count doesn't exceed the limit
const fieldLength = field.name.length + field.value.length;
2020-09-30 19:04:38 +02:00
if (_embed.fields.length < EmbedLimits.fieldObjects && length + fieldLength < embedCutoff) {
_embed.fields.push(field);
2020-08-17 22:24:23 +02:00
} else {
//"clone" the embed into the array
2020-09-30 19:04:38 +02:00
embeds.push({ ..._embed });
_embed.fields = [field];
2020-08-17 22:24:23 +02:00
length = 0;
}
length += fieldLength;
2020-09-30 19:04:38 +02:00
return _embed;
2020-08-17 22:24:23 +02:00
}, embed);
embeds.push(embed);
//Post messages
let showed = 0;
for (let i = 0; i < embeds.length; i++) {
const embed = embeds[i];
//Amount of messages showing
const x = embed.fields.filter((field) => field.name !== '\u200b').length;
embed.title = guild.format('BULK_DELETE_TITLE', { embedNr: i + 1, channel: channel.name });
embed.footer = { text: guild.format('BULK_DELETE_FOOTER', { rangeStart: showed + 1, rangeEnd: showed += x, total: messages.size }) };
const result = await hook.send({ embeds: [embed] }).catch((err) => {
//Unknown webhook -> webhook was deleted, remove it from db so it doesn't make any more unnecessary calls
if (err.code === 10015) {
guild.updateWebhook('messageLog');
} else this.client.logger.error(err.stack);
return { error: true };
});
if (result.error) break;
}
2020-06-18 16:07:39 +02:00
}
async messageEdit(oldMessage, newMessage) {
2020-08-17 22:24:23 +02:00
//Status: Uses webhook, complete
2020-06-18 23:00:32 +02:00
// embeds loading in (ex. when a link is posted) would cause a message edit event
2020-08-17 22:24:23 +02:00
if(oldMessage.embeds.length !== newMessage.embeds.length && oldMessage.content === newMessage.content) return;
2020-06-19 20:30:30 +02:00
if(oldMessage.author.bot) return;
2020-06-18 23:00:32 +02:00
const { guild } = oldMessage;
if (!guild) return;
if (!oldMessage.member) oldMessage.member = await guild.members.fetch(oldMessage.author);
const { member, channel, author } = oldMessage;
const settings = await guild.settings();
const chatlogs = settings.messageLog;
2020-06-19 20:30:30 +02:00
if (!chatlogs.channel) return;
2020-06-18 23:00:32 +02:00
2021-06-09 02:39:14 +02:00
const { ignore, bypass } = chatlogs;
2020-08-17 22:24:23 +02:00
const hook = await guild.getWebhook('messageLog');
if (!hook) return;
2020-06-18 23:00:32 +02:00
2021-06-09 02:39:14 +02:00
if (bypass && member.roles.cache.size) {
const roles = member.roles.cache.map((r) => r.id);
2021-06-09 02:39:14 +02:00
for (const role of bypass) {
if (roles.includes(role)) return;
}
}
2020-06-18 23:00:32 +02:00
2021-06-09 02:39:14 +02:00
if (ignore && ignore.includes(channel.id)) return;
2020-06-18 23:00:32 +02:00
if(oldMessage.content === newMessage.content && oldMessage.pinned !== newMessage.pinned) {
const embed = {
2020-06-19 20:30:30 +02:00
title: oldMessage.format('MSGLOG_PINNED_TITLE', { author: Util.escapeMarkdown(author.tag), channel: channel.name, pinned: oldMessage.format('PIN_TOGGLE', { toggle: newMessage.pinned }, true) }),
2020-06-18 23:00:32 +02:00
description: oldMessage.format('MSGLOG_EDIT_JUMP', { guild: guild.id, channel: channel.id, message: oldMessage.id }),
color: CONSTANTS.COLORS.LIGHT_BLUE
};
2020-06-18 23:00:32 +02:00
if(oldMessage.content.length) embed.description += '\n' + oldMessage.content.substring(0, 1900);
if(oldMessage.attachments.size) {
const img = oldMessage.attachments.first();
if(img.height && img.width) embed.image = { url: img.url };
2020-06-18 23:00:32 +02:00
}
2020-08-17 22:24:23 +02:00
await hook.send({ embeds: [embed] }).catch(this.client.logger.error);
2020-06-18 23:00:32 +02:00
} else {
const embed = {
2020-06-19 20:30:30 +02:00
title: oldMessage.format('MSGLOG_EDIT_TITLE', { author: Util.escapeMarkdown(author.tag), channel: channel.name }),
2020-06-18 23:00:32 +02:00
footer: {
text: oldMessage.format('MSGLOG_EDIT_FOOTER', { msgID: oldMessage.id, userID: author.id })
},
description: oldMessage.format('MSGLOG_EDIT_JUMP', { guild: guild.id, channel: channel.id, message: oldMessage.id }),
color: CONSTANTS.COLORS.YELLOW,
timestamp: oldMessage.createdAt,
fields: [
2020-06-19 20:30:30 +02:00
// {
// name: oldMessage.format('MSGLOG_EDIT_OLD'),
// value: oldMessage.content.length > 1024 ? oldMessage.content.substring(0, 1021) + '...' : oldMessage.content
// },
// {
// name: oldMessage.format('MSGLOG_EDIT_NEW'),
// value: newMessage.content.length > 1024 ? newMessage.content.substring(0, 1021) + '...' : newMessage.content
// }
2020-06-18 23:00:32 +02:00
]
};
2020-06-19 20:30:30 +02:00
const oldCon = oldMessage.content,
newCon = newMessage.content;
2020-06-19 20:30:30 +02:00
//Original content
embed.fields.push({
name: oldMessage.format('MSGLOG_EDIT_OLD'),
2020-09-05 22:57:46 +02:00
// eslint-disable-next-line no-nested-ternary
value: oldCon.length > 1024 ? oldCon.substring(0, 1021) + '...' : oldCon.length ? oldCon : '\u200b'
2020-06-19 20:30:30 +02:00
});
if(oldCon.length > 1024) embed.fields.push({
name: '\u200b',
value: '...' + oldCon.substring(1021)
});
//Edited content
embed.fields.push({
name: oldMessage.format('MSGLOG_EDIT_NEW'),
value: newCon.length > 1024 ? newCon.substring(0, 1021) + '...' : newCon
});
if(newCon.length > 1024) embed.fields.push({
name: '\u200b',
value: '...' + newCon.substring(1021)
});
2020-06-19 20:30:30 +02:00
//if(oldMessage.content.length > 1024) embed.description += '\n' + oldMessage.format('MSGLOG_EDIT_OLD_CUTOFF');
//if(newMessage.content.length > 1024) embed.description += '\n' + oldMessage.format('MSGLOG_EDIT_NEW_CUTOFF');
2020-06-18 23:00:32 +02:00
2020-08-17 22:24:23 +02:00
await hook.send({ embeds: [embed] }).catch((err) => {
this.client.logger.error('Error in message edit:\n' + err.stack);
2020-06-19 20:30:30 +02:00
});
2020-06-18 23:00:32 +02:00
}
2020-06-18 16:07:39 +02:00
}
async voiceState(oldState, newState) {
2020-06-19 20:30:30 +02:00
if(oldState.channel && newState.channel && oldState.channel === newState.channel) return;
const { guild, member } = oldState;
//TODO: add checks for disconnecting bot from vc when left alone in one (music player)
const settings = await guild.settings();
const setting = settings.voiceLog;
if(!setting || !setting.channel) return;
const logChannel = await guild.resolveChannel(setting.channel);
if(!logChannel) return;
const perms = logChannel.permissionsFor(guild.me);
2020-08-08 21:16:13 +02:00
if (!perms.has('SEND_MESSAGES') || !perms.has('VIEW_CHANNEL') || !perms.has('EMBED_LINKS')) return;
2020-06-19 20:30:30 +02:00
let index = null;
const langParams = {
nickname: member.nickname ? `\`(${member.nickname})\`` : '',
tag: Util.escapeMarkdown(member.user.tag),
id: member.id,
oldChannel: oldState.channel?.name,
newChannel: newState.channel?.name
};
2020-06-19 20:30:30 +02:00
if(!oldState.channel && newState.channel) index = 'VCLOG_JOIN';
else if(oldState.channel && newState.channel) index = 'VCLOG_SWITCH';
else index = 'VCLOG_LEAVE';
this.client.rateLimiter.queueSend(logChannel, guild.format(index, langParams).trim());
2020-06-18 16:07:39 +02:00
}
async ban(guild, user) {
}
async unban(guild, user) {
}
2020-06-19 20:30:30 +02:00
_replaceTags(text, member) {
2020-06-20 22:27:23 +02:00
const { user, guild } = member;
2020-06-19 20:30:30 +02:00
return text
.replace(/\{mention\}/gu, `<@${member.id}>`)
.replace(/\{tag\}/gu, Util.escapeMarkdown(user.tag))
.replace(/\{user\}/gu, Util.escapeMarkdown(user.username))
.replace(/\{serversize\}/gu, guild.memberCount)
.replace(/\{servername\}/gu, guild.name)
.replace(/\{accage\}/gu, this.client.resolver.timeAgo(Date.now()/1000 - user.createdTimestamp/1000)) //.replace(/a/, '1')
.replace(/\{id\}/gu, user.id)
2020-06-19 20:30:30 +02:00
.trim();
}
2020-06-18 16:07:39 +02:00
async memberJoin(member) {
2020-06-19 20:30:30 +02:00
const { guild } = member;
const settings = await guild.settings();
const setting = settings.memberLog;
if(!setting.channel) return;
const logChannel = await guild.resolveChannel(setting.channel);
if(!logChannel) return;
const perms = logChannel.permissionsFor(guild.me);
2020-08-08 21:16:13 +02:00
if (!perms.has('SEND_MESSAGES') || !perms.has('VIEW_CHANNEL') || !perms.has('EMBED_LINKS')) return;
2020-06-19 20:30:30 +02:00
let { joinMessage } = setting;
joinMessage = this._replaceTags(joinMessage, member);
this.client.rateLimiter.queueSend(logChannel, joinMessage);
2020-06-19 20:30:30 +02:00
2020-06-18 16:07:39 +02:00
}
async memberLeave(member) {
2020-06-19 20:30:30 +02:00
const { guild } = member;
const settings = await guild.settings();
const setting = settings.memberLog;
if(!setting.channel) return;
const logChannel = await guild.resolveChannel(setting.channel);
if(!logChannel) return;
const perms = logChannel.permissionsFor(guild.me);
2020-08-08 21:16:13 +02:00
if (!perms.has('SEND_MESSAGES') || !perms.has('VIEW_CHANNEL') || !perms.has('EMBED_LINKS')) return;
2020-06-19 20:30:30 +02:00
let { leaveMessage } = setting;
leaveMessage = this._replaceTags(leaveMessage, member);
this.client.rateLimiter.queueSend(logChannel, leaveMessage);
2020-06-19 20:30:30 +02:00
2020-06-18 16:07:39 +02:00
}
async memberUpdate(oldMember, newMember) {
2020-06-19 20:30:30 +02:00
if(oldMember.nickname === newMember.nickname) return;
const { guild, user } = oldMember;
const settings = await guild.settings();
const setting = settings.nicknameLog;
if(!setting.channel) return;
const logChannel = await guild.resolveChannel(setting.channel);
if(!logChannel) return;
const perms = logChannel.permissionsFor(guild.me);
2020-08-08 21:16:13 +02:00
if (!perms.has('SEND_MESSAGES') || !perms.has('VIEW_CHANNEL') || !perms.has('EMBED_LINKS')) return;
2020-06-19 20:30:30 +02:00
const oldNick = oldMember.nickname || oldMember.user.username;
const newNick = newMember.nickname || newMember.user.username;
const embed = {
title: guild.format('NICKLOG_TITLE', { user: Util.escapeMarkdown(user.tag) }),
description: guild.format('NICKLOG_DESCRIPTION', { oldNick, newNick }),
footer: {
text: guild.format('NICKLOG_FOOTER', { id: user.id })
},
color: CONSTANTS.COLORS.BLUE
};
logChannel.send({ embed });
2020-06-19 20:30:30 +02:00
2020-06-18 16:07:39 +02:00
}
}
module.exports = GuildLogger;