import { APIEmbedField, APIRole, AuditLogEvent, Guild, GuildAuditLogsEntry, RoleFlags, SnowflakeUtil } from 'discord.js'; import { Database } from '../../shared/Database'; import { CreateDefaultEmbed, formatChanges, formatExtras, formatSnowflake, getTargetType } from '../../utils'; const IGNORED_ACTIONS = [ AuditLogEvent.MemberMove, AuditLogEvent.AutoModerationFlagToChannel // Handled by automod. ]; async function shouldLog(entry: GuildAuditLogsEntry, guild: Guild): Promise { if (!entry.executorId) return true; if (IGNORED_ACTIONS.some(a => entry.action == a)) return false; if (entry.action == AuditLogEvent.MemberRoleUpdate) { return await shouldLogRoleChanges(entry as GuildAuditLogsEntry, guild); } return true; } async function shouldLogRoleChanges(entry: GuildAuditLogsEntry, guild: Guild): Promise { for (const change of entry.changes) { // Get role changes from the log. const roles = (await Promise.all((change.new! as Pick[]).map(c => guild.roles.fetch(c.id)))); // Check if role is part of onboarding. for (const role of roles) { if (role && !role.flags.has(RoleFlags.InPrompt)) return true; } } return false; } export default { event: 'guildAuditLogEntryCreate', handler: async (entry: GuildAuditLogsEntry, guild: Guild) => { if (!await shouldLog(entry, guild)) return; const settings = await Database.getOrCreateSettings(guild.id); if (!settings.audit_logs_channel_id) return; const channel = await guild.channels.fetch(settings.audit_logs_channel_id); if (!channel || !channel.isSendable()) return; const fields: APIEmbedField[] = [ { name: 'Actor', value: `<@${entry.executorId}>`, inline: true } ]; if (entry.targetId) { const targetType = getTargetType(entry.action); fields.push({ name: 'Target', value: formatSnowflake(entry.targetId, targetType), inline: true }); } if (entry.reason) { fields.push({ name: 'Reason', value: entry.reason, inline: true }); } if (entry.changes && entry.changes.length > 0) { fields.push({ name: 'Changes', value: formatChanges(entry), inline: false }); } if (entry.extra) { fields.push({ name: 'Options', value: formatExtras(entry, guild), inline: false }); } await channel.send({ embeds: [{ ...CreateDefaultEmbed(guild.client), title: Object.keys(AuditLogEvent)[Object.values(AuditLogEvent).indexOf(entry.action)], timestamp: new Date(Number(SnowflakeUtil.decode(entry.id).timestamp)).toISOString(), fields: fields, }] }); } };