DiscordTickets/src/lib/logging.js

243 lines
7.0 KiB
JavaScript
Raw Normal View History

2022-07-19 17:57:19 +03:00
const {
cleanCodeBlockContent,
EmbedBuilder,
} = require('discord.js');
2022-07-17 16:13:44 +03:00
const { diff: getDiff } = require('object-diffy');
const uuidRegex = /[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}/g;
2022-07-20 00:34:45 +03:00
const exists = thing => typeof thing === 'string' ? thing.length > 0 : thing !== null && thing !== undefined;
2022-07-20 00:34:45 +03:00
const arrToObj = obj => {
for (const key in obj) {
if (obj[key] instanceof Array && obj[key][0]?.id) {
const temp = {};
obj[key].forEach(v => (temp[v.id] = v));
obj[key] = temp;
}
}
return obj;
};
2022-07-17 16:13:44 +03:00
function makeDiff({
original, updated,
}) {
2022-07-20 00:34:45 +03:00
const diff = getDiff(arrToObj(original), arrToObj(updated));
2022-07-17 16:13:44 +03:00
const fields = [];
for (const key in diff) {
if (key === 'createdAt') continue; // object-diffy doesn't like dates
2022-07-20 00:34:45 +03:00
const from = exists(diff[key].from) ? `- ${String(diff[key].from).replace(/\n/g, '\\n')}\n` : '';
2022-07-21 03:25:37 +03:00
const to = exists(diff[key].to) ? `+ ${String(diff[key].to).replace(/\n/g, '\\n')}\n` : '';
2022-07-17 16:13:44 +03:00
fields.push({
2022-07-17 20:59:58 +03:00
inline: true,
name: key.replace(uuidRegex, $1 => $1.split('-')[0]),
2022-07-19 17:57:19 +03:00
value: `\`\`\`diff\n${cleanCodeBlockContent(from + to)}\n\`\`\``,
2022-07-17 16:13:44 +03:00
});
}
return fields;
}
2022-07-17 00:18:50 +03:00
/**
* @param {import("client")} client
* @param {string} guildId
* @returns {import("discord.js").TextChannel?}
*/
async function getLogChannel(client, guildId) {
const { logChannel: channelId } = await client.prisma.guild.findUnique({
select: { logChannel: true },
where: { id: guildId },
});
return channelId && client.channels.cache.get(channelId);
}
/**
* @param {import("client")} client
* @param {object} details
* @param {string} details.guildId
* @param {string} details.userId
* @param {string} details.action
*/
async function logAdminEvent(client, {
guildId, userId, action, target, diff,
}) {
const settings = await client.prisma.guild.findUnique({
select: {
footer: true,
locale: true,
logChannel: true,
},
where: { id: guildId },
});
2022-08-09 01:37:47 +03:00
/** @type {import("discord.js").Guild} */
const guild = client.guilds.cache.get(guildId);
const member = await guild.members.fetch(userId);
client.log.info.settings(`${member.user.tag} ${action}d ${target.type} ${target.id}`);
2022-07-17 00:18:50 +03:00
if (!settings.logChannel) return;
2022-07-21 03:25:37 +03:00
const colour = action === 'create'
? 'Green' : action === 'update'
? 'Orange' : action === 'delete'
? 'Red' : 'Default';
2022-07-17 00:18:50 +03:00
const getMessage = client.i18n.getLocale(settings.locale);
const i18nOptions = {
2022-08-09 01:37:47 +03:00
user: `<@${member.user.id}>`,
2022-07-17 00:18:50 +03:00
verb: getMessage(`log.admin.verb.${action}`),
};
const channel = client.channels.cache.get(settings.logChannel);
if (!channel) return;
const embeds = [
2022-07-18 23:53:17 +03:00
new EmbedBuilder()
2022-07-21 03:25:37 +03:00
.setColor(colour)
.setAuthor({
2022-08-09 01:37:47 +03:00
iconURL: member.displayAvatarURL(),
name: member.displayName,
})
.setTitle(getMessage('log.admin.title.joined', {
...i18nOptions,
targetType: getMessage(`log.admin.title.target.${target.type}`),
verb: getMessage(`log.admin.verb.${action}`),
}))
.setDescription(getMessage('log.admin.description.joined', {
...i18nOptions,
targetType: getMessage(`log.admin.description.target.${target.type}`),
verb: getMessage(`log.admin.verb.${action}`),
}))
2022-07-18 23:53:17 +03:00
.addFields([
{
name: getMessage(`log.admin.title.target.${target.type}`),
2022-10-29 02:54:38 +03:00
value: target.name ? `${target.name} (\`${target.id}\`)` : target.id,
2022-07-18 23:53:17 +03:00
},
]),
];
2022-07-17 16:13:44 +03:00
if (diff?.original && Object.entries(makeDiff(diff)).length) {
embeds.push(
2022-07-18 23:53:17 +03:00
new EmbedBuilder()
2022-07-21 03:25:37 +03:00
.setColor(colour)
.setTitle(getMessage('log.admin.changes'))
.setFields(makeDiff(diff)),
);
}
return await channel.send({ embeds });
2022-07-17 00:18:50 +03:00
}
2022-08-09 01:37:47 +03:00
/**
* @param {import("client")} client
* @param {object} details
* @param {string} details.guildId
* @param {string} details.userId
* @param {string} details.action
*/
async function logTicketEvent(client, {
2022-09-05 14:43:27 +03:00
userId, action, target, diff,
2022-08-09 01:37:47 +03:00
}) {
const ticket = await client.prisma.ticket.findUnique({
include: { guild: true },
where: { id: target.id },
});
if (!ticket) return;
/** @type {import("discord.js").Guild} */
const guild = client.guilds.cache.get(ticket.guild.id);
const member = await guild.members.fetch(userId);
2022-08-09 01:43:22 +03:00
client.log.info.tickets(`${member.user.tag} ${client.i18n.getMessage('en-GB', `log.ticket.verb.${action}`)} ticket ${target.id}`);
2022-08-09 01:37:47 +03:00
if (!ticket.guild.logChannel) return;
const colour = action === 'create'
? 'Aqua' : action === 'close'
2022-09-05 14:43:27 +03:00
? 'DarkAqua' : action === 'update'
? 'Purple' : action === 'claim'
? 'LuminousVividPink' : action === 'unclaim'
? 'DarkVividPink' : 'Default';
2022-08-09 01:37:47 +03:00
const getMessage = client.i18n.getLocale(ticket.guild.locale);
const i18nOptions = {
user: `<@${member.user.id}>`,
verb: getMessage(`log.ticket.verb.${action}`),
};
const channel = client.channels.cache.get(ticket.guild.logChannel);
if (!channel) return;
const embeds = [
new EmbedBuilder()
.setColor(colour)
.setAuthor({
iconURL: member.displayAvatarURL(),
name: member.displayName,
})
2022-09-05 14:43:27 +03:00
.setTitle(getMessage('log.ticket.title', i18nOptions))
.setDescription(getMessage('log.ticket.description', i18nOptions))
2022-08-09 01:37:47 +03:00
.addFields([
{
name: getMessage('log.ticket.ticket'),
2022-10-29 02:54:38 +03:00
value: target.name ? `${target.name} (\`${target.id}\`)` : target.id,
2022-08-09 01:37:47 +03:00
},
]),
];
if (diff?.original && Object.entries(makeDiff(diff)).length) {
2022-09-05 14:43:27 +03:00
embeds.push(
new EmbedBuilder()
.setColor(colour)
.setTitle(getMessage('log.admin.changes'))
.setFields(makeDiff(diff)),
);
}
2022-08-09 01:37:47 +03:00
return await channel.send({ embeds });
}
2022-10-18 19:25:31 +03:00
/**
* @param {import("client")} client
* @param {object} details
* @param {string} details.action
* @param {import("discord.js").Message} details.target
* @param {import("@prisma/client").Ticket & {guild: import("@prisma/client").Guild}} details.ticket
*/
async function logMessageEvent(client, {
action, target, ticket, diff,
}) {
if (!ticket) return;
client.log.info.tickets(`${target.member.user.tag} ${client.i18n.getMessage('en-GB', `log.message.verb.${action}`)} message ${target.id}`);
if (!ticket.guild.logChannel) return;
const colour = action === 'update'
? 'Purple' : action === 'delete'
? 'DarkPurple' : 'Default';
const getMessage = client.i18n.getLocale(ticket.guild.locale);
const i18nOptions = {
user: `<@${target.member.user.id}>`,
verb: getMessage(`log.message.verb.${action}`),
};
const channel = client.channels.cache.get(ticket.guild.logChannel);
if (!channel) return;
const embeds = [
new EmbedBuilder()
.setColor(colour)
.setAuthor({
iconURL: target.member.displayAvatarURL(),
name: target.member.displayName,
})
.setTitle(getMessage('log.message.title', i18nOptions))
.setDescription(getMessage('log.message.description', i18nOptions))
.addFields([
{
name: getMessage('log.message.message'),
value: `[${target.id}](${target.url})`,
},
]),
];
if (diff?.original && Object.entries(makeDiff(diff)).length) {
2022-10-18 19:25:31 +03:00
embeds.push(
new EmbedBuilder()
.setColor(colour)
.setTitle(getMessage('log.admin.changes'))
.setFields(makeDiff(diff)),
);
}
return await channel.send({ embeds });
}
2022-07-17 00:18:50 +03:00
module.exports = {
getLogChannel,
logAdminEvent,
2022-10-18 19:25:31 +03:00
logMessageEvent,
2022-08-09 01:37:47 +03:00
logTicketEvent,
2022-07-17 00:18:50 +03:00
};