blob: 5788f610cd91cb91ac9f9725af055cee2d9b6931 [file] [log] [blame]
import { AuditLogEvent, GuildAuditLogsEntry, GuildMember } from "discord.js";
import type { NucleusClient } from "../utils/client.js";
import type { LoggerOptions } from "../utils/log.js";
import { generalException } from "../utils/createTemporaryStorage.js";
export const event = "guildMemberUpdate";
export async function callback(client: NucleusClient, before: GuildMember, after: GuildMember) {
const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = client.logger;
if(!before.roles.cache.equals(after.roles.cache)) {
const auditLog = (await getAuditLog(after.guild, AuditLogEvent.MemberRoleUpdate))
.filter((entry: GuildAuditLogsEntry) => (entry.target as GuildMember)!.id === after.id)[0];
if (!auditLog) return;
if (client.noLog.includes(`${after.guild.id}${after.id}${auditLog.id}`)) return;
generalException(`${after.guild.id}${after.id}${auditLog.id}`);
if (auditLog.executor!.id !== client.user!.id) {
const rolesAdded = after.roles.cache.filter(role => !before.roles.cache.has(role.id));
const rolesRemoved = before.roles.cache.filter(role => !after.roles.cache.has(role.id));
let displayName = "Roles Removed";
let color = NucleusColors.red;
let emoji = "GUILD.ROLES.DELETE";
if(rolesAdded.size > 0 && rolesRemoved.size > 0) {displayName = "Roles Changed"; color = NucleusColors.yellow; emoji = "GUILD.ROLES.EDIT";}
else if(rolesAdded.size > 0) {displayName = "Roles Added"; color = NucleusColors.green; emoji = "GUILD.ROLES.CREATE";}
const removedEntry = rolesRemoved.map(role => role.id);
const addedEntry = rolesAdded.map(role => role.id);
let list = {
memberId: entry(after.id, `\`${after.id}\``),
name: entry(after.user.id, renderUser(after.user)),
};
if (rolesAdded.size > 0) {
list = Object.assign(list, {rolesAdded: entry(addedEntry, addedEntry.map(id => `<@&${id}>`).join(", "))});
}
if (rolesRemoved.size > 0) {
list = Object.assign(list, {rolesRemoved: entry(removedEntry, removedEntry.map(id => `<@&${id}>`).join(", "))});
}
list = Object.assign(list, {
changed: entry(Date.now(), renderDelta(Date.now())),
changedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!))
});
let data: LoggerOptions = {
meta: {
type: "memberUpdate",
displayName: displayName,
calculateType: "guildMemberUpdate",
color: color,
emoji: emoji,
timestamp: Date.now()
},
list: {},
hidden: {
guild: after.guild.id
}
};
if(rolesAdded.size > 0) {
list = Object.assign(list, {rolesAdded: entry(addedEntry, addedEntry.map(id => `<@&${id}>`).join(", "))});
}
if(rolesRemoved.size > 0) {
list = Object.assign(list, {rolesRemoved: entry(removedEntry, removedEntry.map(id => `<@&${id}>`).join(", "))});
}
data = Object.assign(data, {list: list});
log(data);
}
}
const auditLog = (await getAuditLog(after.guild, AuditLogEvent.MemberUpdate))
.filter((entry: GuildAuditLogsEntry) => (entry.target as GuildMember)!.id === after.id)[0];
if (!auditLog) return;
if (auditLog.executor!.id === client.user!.id) return;
if (before.nickname !== after.nickname) {
await client.database.history.create(
"nickname",
after.guild.id,
after.user,
auditLog.executor,
null,
before.nickname ?? before.user.username,
after.nickname ?? after.user.username
);
const data = {
meta: {
type: "memberUpdate",
displayName: "Nickname Changed",
calculateType: "guildMemberUpdate",
color: NucleusColors.yellow,
emoji: "PUNISH.NICKNAME.YELLOW",
timestamp: Date.now()
},
list: {
memberId: entry(after.id, `\`${after.id}\``),
name: entry(after.user.id, renderUser(after.user)),
before: entry(before.nickname, before.nickname ? before.nickname : "*None*"),
after: entry(after.nickname, after.nickname ? after.nickname : "*None*"),
changed: entry(Date.now(), renderDelta(Date.now())),
changedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!))
},
hidden: {
guild: after.guild.id
}
};
log(data);
}
if (
(before.communicationDisabledUntilTimestamp ?? 0) < Date.now() &&
new Date(after.communicationDisabledUntil ?? 0).getTime() > Date.now()
) {
await client.database.history.create(
"mute",
after.guild.id,
after.user,
auditLog.executor,
auditLog.reason,
null,
null,
null
);
const data = {
meta: {
type: "memberMute",
displayName: "Muted",
calculateType: "guildMemberPunish",
color: NucleusColors.yellow,
emoji: "PUNISH.MUTE.YELLOW",
timestamp: Date.now()
},
list: {
memberId: entry(after.id, `\`${after.id}\``),
name: entry(after.user.id, renderUser(after.user)),
mutedUntil: entry(
after.communicationDisabledUntilTimestamp,
renderDelta(after.communicationDisabledUntilTimestamp!)
),
muted: entry(Date.now(), renderDelta(Date.now())),
mutedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!)),
reason: entry(auditLog.reason, auditLog.reason ? auditLog.reason : "\n> *No reason provided*")
},
hidden: {
guild: after.guild.id
}
};
log(data);
client.database.eventScheduler.schedule("naturalUnmute", after.communicationDisabledUntil?.toISOString()!, {
guild: after.guild.id,
user: after.id,
expires: after.communicationDisabledUntilTimestamp
});
}
if (
after.communicationDisabledUntil === null &&
before.communicationDisabledUntilTimestamp !== null &&
Date.now() >= auditLog.createdTimestamp
) {
await client.database.history.create(
"unmute",
after.guild.id,
after.user,
auditLog.executor,
null,
null,
null,
null
);
const data = {
meta: {
type: "memberUnmute",
displayName: "Unmuted",
calculateType: "guildMemberPunish",
color: NucleusColors.green,
emoji: "PUNISH.MUTE.GREEN",
timestamp: Date.now()
},
list: {
memberId: entry(after.id, `\`${after.id}\``),
name: entry(after.user.id, renderUser(after.user)),
unmuted: entry(Date.now(), renderDelta(Date.now())),
unmutedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!))
},
hidden: {
guild: after.guild.id
}
};
log(data);
client.database.eventScheduler.cancel("naturalUnmute", {
guild: after.guild.id,
user: after.id,
expires: before.communicationDisabledUntilTimestamp
});
}
}