mirror of https://github.com/clickscodes/nucleus
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
113 lines
5.8 KiB
113 lines
5.8 KiB
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<string, string>;
|
|
after: Record<string, string>;
|
|
}
|
|
|
|
export async function callback(client: NucleusClient, channel: Discord.GuildChannel) {
|
|
try {
|
|
const { getAuditLog, log, NucleusColors, entry, renderUser, renderChannel, renderDelta } = client.logger;
|
|
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, ReturnType<typeof entry> | 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<GuildAuditLogsEntry, {createdTimestamp: number}>).createdTimestamp,
|
|
renderDelta((auditUpdate.target! as Extract<GuildAuditLogsEntry, {createdTimestamp: number}>).createdTimestamp)
|
|
);
|
|
list["edited"] = entry(after["editedTimestamp"]!, renderDelta(new Date().getTime()));
|
|
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<GuildAuditLogsEntry, {createdTimestamp: number}>).createdTimestamp, renderDelta((auditDelete.target! as Extract<GuildAuditLogsEntry, {createdTimestamp: number}>).createdTimestamp)),
|
|
deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
|
|
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(new Date().getTime(), renderDelta(new Date().getTime()))
|
|
};
|
|
}
|
|
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: new Date().getTime()
|
|
},
|
|
list: list,
|
|
hidden: {
|
|
guild: channel.guild.id
|
|
}
|
|
};
|
|
log(data);
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
}
|