import { AuditLogEvent, GuildAuditLogsEntry, GuildChannel, Webhook } from "discord.js"; import type Discord from "discord.js"; import type { NucleusClient } from "../utils/client.js"; export const event = "webhookUpdate"; interface accType { before: Record; after: Record; } export async function callback(client: NucleusClient, channel: Discord.GuildChannel) { try { const { getAuditLog, isLogging, log, NucleusColors, entry, renderUser, renderChannel, renderDelta } = client.logger; if (!await isLogging(channel.guild.id, "webhookUpdate")) return; const auditCreate = (await getAuditLog(channel.guild, AuditLogEvent.WebhookCreate)) .filter((entry: GuildAuditLogsEntry) => (entry.target as Webhook)!.id === channel.id)[0]!; const auditDelete = (await getAuditLog(channel.guild, AuditLogEvent.WebhookDelete)) .filter((entry: GuildAuditLogsEntry) => (entry.target as Webhook)!.id === channel.id)[0]; const auditUpdate = (await getAuditLog(channel.guild, AuditLogEvent.WebhookUpdate)) .filter((entry: GuildAuditLogsEntry) => (entry.target as Webhook)!.id === channel.id)[0]; if (!auditUpdate && !auditDelete) return; let action: "Create" | "Update" | "Delete" = "Create"; let list: Record | string> = {}; const createTimestamp = auditCreate.createdTimestamp; const deleteTimestamp = auditDelete ? auditDelete.createdTimestamp : 0; const updateTimestamp = auditUpdate ? auditUpdate.createdTimestamp : 0; if (updateTimestamp > createTimestamp && updateTimestamp > deleteTimestamp && auditUpdate) { const { before, after } = auditUpdate.changes.reduce((acc: accType, change) => { acc.before[change.key] = change.old?.toString()!; acc.after[change.key] = change.new?.toString()!; return acc; }, { before: {}, after: {} } ); if (before["name"] !== after["name"]) list["name"] = entry([before["name"]!, after["name"]!], `${before["name"]} -> ${after["name"]}`); if (before["channel_id"] !== after["channel_id"]) list["channel"] = entry( [before["channel_id"]!, after["channel_id"]!], renderChannel(await client.channels.fetch(before["channel_id"]!) as GuildChannel) + " -> " + renderChannel(await client.channels.fetch(after["channel_id"]!) as GuildChannel) ); if (!Object.keys(list).length) return; list["created"] = entry( (auditUpdate.target! as Extract).createdTimestamp, renderDelta((auditUpdate.target! as Extract).createdTimestamp) ); list["edited"] = entry(after["editedTimestamp"]!, renderDelta(Date.now())); list["editedBy"] = entry(auditUpdate.executor!.id, renderUser(auditUpdate.executor!)); action = "Update"; } else if (deleteTimestamp > createTimestamp && deleteTimestamp > updateTimestamp && auditDelete) { const { before } = auditDelete.changes.reduce((acc: accType, change) => { acc.before[change.key] = change.old?.toString()!; acc.after[change.key] = change.new?.toString()!; return acc; }, { before: {}, after: {} } ); list = { name: entry(before["name"]!, `${before["name"]}`), channel: entry(before["channel_id"]!, renderChannel((await client.channels.fetch(before["channel_id"]!)) as GuildChannel)), created: entry((auditDelete.target! as Extract).createdTimestamp, renderDelta((auditDelete.target! as Extract).createdTimestamp)), deleted: entry(Date.now(), renderDelta(Date.now())), deletedBy: entry( auditDelete.executor!.id, renderUser((await channel.guild.members.fetch(auditDelete.executor!.id)).user) ) }; action = "Delete"; } else { const { before } = auditDelete!.changes.reduce((acc: accType, change) => { acc.before[change.key] = change.old?.toString()!; acc.after[change.key] = change.new?.toString()!; return acc; }, { before: {}, after: {} } ); list = { name: entry(before["name"]!, `${before["name"]}`), channel: entry(before["channel_id"]!, renderChannel(await client.channels.fetch(before["channel_id"]!) as GuildChannel)), createdBy: entry( auditCreate.executor!.id, renderUser((await channel.guild.members.fetch(auditCreate.executor!.id)).user) ), created: entry(Date.now(), renderDelta(Date.now())) }; } const cols = { Create: "green", Update: "yellow", Delete: "red" }; const data = { meta: { type: "webhook" + action, displayName: `Webhook ${action}d`, calculateType: "webhookUpdate", color: NucleusColors[cols[action] as keyof typeof NucleusColors], emoji: "WEBHOOK." + action.toUpperCase(), timestamp: Date.now() }, list: list, hidden: { guild: channel.guild.id } }; log(data); } catch (e) { console.log(e); } }