blob: fb18f4898d9b12d59ebaa0fe4d8847edad513132 [file] [log] [blame]
TheCodedProf9812b702023-01-18 21:01:04 -05001import { AuditLogEvent, GuildAuditLogsEntry, GuildChannel, Webhook } from "discord.js";
pineafan63fc5e22022-08-04 22:04:10 +01002import type Discord from "discord.js";
PineaFan752af462022-12-31 21:59:38 +00003import type { NucleusClient } from "../utils/client.js";
pineafan63fc5e22022-08-04 22:04:10 +01004export const event = "webhookUpdate";
pineafanda6e5342022-07-03 10:03:16 +01005
TheCodedProf9812b702023-01-18 21:01:04 -05006interface accType {
7 before: Record<string, string>;
8 after: Record<string, string>;
9}
10
PineaFan752af462022-12-31 21:59:38 +000011export async function callback(client: NucleusClient, channel: Discord.GuildChannel) {
pineafanda6e5342022-07-03 10:03:16 +010012 try {
TheCodedProf6ec331b2023-02-20 12:13:06 -050013 const { getAuditLog, isLogging, log, NucleusColors, entry, renderUser, renderChannel, renderDelta } = client.logger;
14 if (!await isLogging(channel.guild.id, "webhookUpdate")) return;
TheCodedProfa16d1672023-01-18 18:58:34 -050015 const auditCreate = (await getAuditLog(channel.guild, AuditLogEvent.WebhookCreate))
PineaFan638eb132023-01-19 10:41:22 +000016 .filter((entry: GuildAuditLogsEntry) => (entry.target as Webhook)!.id === channel.id)[0]!;
TheCodedProfa16d1672023-01-18 18:58:34 -050017 const auditDelete = (await getAuditLog(channel.guild, AuditLogEvent.WebhookDelete))
PineaFan638eb132023-01-19 10:41:22 +000018 .filter((entry: GuildAuditLogsEntry) => (entry.target as Webhook)!.id === channel.id)[0];
TheCodedProfa16d1672023-01-18 18:58:34 -050019 const auditUpdate = (await getAuditLog(channel.guild, AuditLogEvent.WebhookUpdate))
PineaFan638eb132023-01-19 10:41:22 +000020 .filter((entry: GuildAuditLogsEntry) => (entry.target as Webhook)!.id === channel.id)[0];
TheCodedProfa16d1672023-01-18 18:58:34 -050021
PineaFan638eb132023-01-19 10:41:22 +000022 if (!auditUpdate && !auditDelete) return;
pineafan3a02ea32022-08-11 21:35:04 +010023 let action: "Create" | "Update" | "Delete" = "Create";
24 let list: Record<string, ReturnType<typeof entry> | string> = {};
PineaFan638eb132023-01-19 10:41:22 +000025 const createTimestamp = auditCreate.createdTimestamp;
26 const deleteTimestamp = auditDelete ? auditDelete.createdTimestamp : 0;
27 const updateTimestamp = auditUpdate ? auditUpdate.createdTimestamp : 0;
28 if (updateTimestamp > createTimestamp && updateTimestamp > deleteTimestamp && auditUpdate) {
TheCodedProf9812b702023-01-18 21:01:04 -050029 const { before, after } = auditUpdate.changes.reduce((acc: accType, change) => {
30 acc.before[change.key] = change.old?.toString()!;
31 acc.after[change.key] = change.new?.toString()!;
Skyler Grey75ea9172022-08-06 10:22:23 +010032 return acc;
33 },
34 { before: {}, after: {} }
pineafanda6e5342022-07-03 10:03:16 +010035 );
TheCodedProf9812b702023-01-18 21:01:04 -050036 if (before["name"] !== after["name"])
37 list["name"] = entry([before["name"]!, after["name"]!], `${before["name"]} -> ${after["name"]}`);
38 if (before["channel_id"] !== after["channel_id"])
pineafan3a02ea32022-08-11 21:35:04 +010039 list["channel"] = entry(
TheCodedProf9812b702023-01-18 21:01:04 -050040 [before["channel_id"]!, after["channel_id"]!],
41 renderChannel(await client.channels.fetch(before["channel_id"]!) as GuildChannel) +
Skyler Grey75ea9172022-08-06 10:22:23 +010042 " -> " +
TheCodedProf9812b702023-01-18 21:01:04 -050043 renderChannel(await client.channels.fetch(after["channel_id"]!) as GuildChannel)
Skyler Grey75ea9172022-08-06 10:22:23 +010044 );
45 if (!Object.keys(list).length) return;
Skyler Greyf21323a2022-08-13 23:58:22 +010046 list["created"] = entry(
TheCodedProf9812b702023-01-18 21:01:04 -050047 (auditUpdate.target! as Extract<GuildAuditLogsEntry, {createdTimestamp: number}>).createdTimestamp,
48 renderDelta((auditUpdate.target! as Extract<GuildAuditLogsEntry, {createdTimestamp: number}>).createdTimestamp)
Skyler Greyf21323a2022-08-13 23:58:22 +010049 );
TheCodedProf6ec331b2023-02-20 12:13:06 -050050 list["edited"] = entry(after["editedTimestamp"]!, renderDelta(Date.now()));
TheCodedProf9812b702023-01-18 21:01:04 -050051 list["editedBy"] = entry(auditUpdate.executor!.id, renderUser(auditUpdate.executor!));
pineafan63fc5e22022-08-04 22:04:10 +010052 action = "Update";
PineaFan638eb132023-01-19 10:41:22 +000053 } else if (deleteTimestamp > createTimestamp && deleteTimestamp > updateTimestamp && auditDelete) {
TheCodedProf9812b702023-01-18 21:01:04 -050054 const { before } = auditDelete.changes.reduce((acc: accType, change) => {
55 acc.before[change.key] = change.old?.toString()!;
56 acc.after[change.key] = change.new?.toString()!;
Skyler Grey75ea9172022-08-06 10:22:23 +010057 return acc;
58 },
59 { before: {}, after: {} }
pineafanda6e5342022-07-03 10:03:16 +010060 );
61 list = {
TheCodedProf9812b702023-01-18 21:01:04 -050062 name: entry(before["name"]!, `${before["name"]}`),
63 channel: entry(before["channel_id"]!, renderChannel((await client.channels.fetch(before["channel_id"]!)) as GuildChannel)),
PineaFan638eb132023-01-19 10:41:22 +000064 created: entry((auditDelete.target! as Extract<GuildAuditLogsEntry, {createdTimestamp: number}>).createdTimestamp, renderDelta((auditDelete.target! as Extract<GuildAuditLogsEntry, {createdTimestamp: number}>).createdTimestamp)),
TheCodedProf6ec331b2023-02-20 12:13:06 -050065 deleted: entry(Date.now(), renderDelta(Date.now())),
Skyler Grey75ea9172022-08-06 10:22:23 +010066 deletedBy: entry(
TheCodedProf9812b702023-01-18 21:01:04 -050067 auditDelete.executor!.id,
68 renderUser((await channel.guild.members.fetch(auditDelete.executor!.id)).user)
Skyler Grey75ea9172022-08-06 10:22:23 +010069 )
pineafan63fc5e22022-08-04 22:04:10 +010070 };
pineafan63fc5e22022-08-04 22:04:10 +010071 action = "Delete";
pineafanda6e5342022-07-03 10:03:16 +010072 } else {
PineaFan638eb132023-01-19 10:41:22 +000073 const { before } = auditDelete!.changes.reduce((acc: accType, change) => {
TheCodedProf9812b702023-01-18 21:01:04 -050074 acc.before[change.key] = change.old?.toString()!;
75 acc.after[change.key] = change.new?.toString()!;
Skyler Grey75ea9172022-08-06 10:22:23 +010076 return acc;
77 },
78 { before: {}, after: {} }
pineafanda6e5342022-07-03 10:03:16 +010079 );
80 list = {
TheCodedProf9812b702023-01-18 21:01:04 -050081 name: entry(before["name"]!, `${before["name"]}`),
82 channel: entry(before["channel_id"]!, renderChannel(await client.channels.fetch(before["channel_id"]!) as GuildChannel)),
Skyler Grey75ea9172022-08-06 10:22:23 +010083 createdBy: entry(
TheCodedProf9812b702023-01-18 21:01:04 -050084 auditCreate.executor!.id,
85 renderUser((await channel.guild.members.fetch(auditCreate.executor!.id)).user)
Skyler Grey75ea9172022-08-06 10:22:23 +010086 ),
TheCodedProf6ec331b2023-02-20 12:13:06 -050087 created: entry(Date.now(), renderDelta(Date.now()))
pineafan63fc5e22022-08-04 22:04:10 +010088 };
pineafanda6e5342022-07-03 10:03:16 +010089 }
pineafan63fc5e22022-08-04 22:04:10 +010090 const cols = {
Skyler Grey75ea9172022-08-06 10:22:23 +010091 Create: "green",
92 Update: "yellow",
93 Delete: "red"
pineafan63fc5e22022-08-04 22:04:10 +010094 };
95 const data = {
pineafanda6e5342022-07-03 10:03:16 +010096 meta: {
pineafan63fc5e22022-08-04 22:04:10 +010097 type: "webhook" + action,
pineafanda6e5342022-07-03 10:03:16 +010098 displayName: `Webhook ${action}d`,
pineafan63fc5e22022-08-04 22:04:10 +010099 calculateType: "webhookUpdate",
PineaFan638eb132023-01-19 10:41:22 +0000100 color: NucleusColors[cols[action] as keyof typeof NucleusColors],
pineafanda6e5342022-07-03 10:03:16 +0100101 emoji: "WEBHOOK." + action.toUpperCase(),
TheCodedProf6ec331b2023-02-20 12:13:06 -0500102 timestamp: Date.now()
pineafanda6e5342022-07-03 10:03:16 +0100103 },
104 list: list,
105 hidden: {
106 guild: channel.guild.id
107 }
pineafan63fc5e22022-08-04 22:04:10 +0100108 };
pineafanda6e5342022-07-03 10:03:16 +0100109 log(data);
Skyler Grey75ea9172022-08-06 10:22:23 +0100110 } catch (e) {
111 console.log(e);
112 }
pineafanda6e5342022-07-03 10:03:16 +0100113}