blob: 9730e17162a031610aa8fbf9e21b841600c7a8f2 [file] [log] [blame]
TheCodedProf309d6182023-01-18 18:10:29 -05001import { GuildChannel, AuditLogEvent, ChannelType, TextChannel, VoiceChannel, StageChannel } from 'discord.js';
2import type { GuildAuditLogsEntry } from 'discord.js';
3//@ts-expect-error
pineafan63fc5e22022-08-04 22:04:10 +01004import humanizeDuration from "humanize-duration";
PineaFane6ba7882023-01-18 20:41:16 +00005import type { NucleusClient } from "../utils/client.js";
pineafan63fc5e22022-08-04 22:04:10 +01006import getEmojiByName from "../utils/getEmojiByName.js";
TheCodedProfb493b8a2023-01-18 21:11:00 -05007import c from "../utils/client.js";
8let entry = c.logger.entry;
pineafan32767212022-03-14 21:27:39 +00009
TheCodedProf309d6182023-01-18 18:10:29 -050010const channelTypeEmoji: Record<number, string> = {
11 0: "Text", // Text channel
12 2: "Voice", // Voice channel
13 5: "Announcement", // Announcement channel
14 13: "Stage", // Stage channel
15 15: "Forum", // Forum channel
16 99: "Rules" // Rules channel
17};
18
19interface channelChanges {
TheCodedProfb493b8a2023-01-18 21:11:00 -050020 channelId: ReturnType<typeof entry>;
21 channel: ReturnType<typeof entry>;
22 edited: ReturnType<typeof entry>;
23 editedBy: ReturnType<typeof entry>;
24 type?: ReturnType<typeof entry>;
25 name?: ReturnType<typeof entry>;
26 position?: ReturnType<typeof entry>;
27 description?: ReturnType<typeof entry>;
28 nsfw?: ReturnType<typeof entry>;
29 slowmode?: ReturnType<typeof entry>;
30 topic?: ReturnType<typeof entry>;
31 bitrate?: ReturnType<typeof entry>;
32 userLimit?: ReturnType<typeof entry>;
33 rateLimitPerUser?: ReturnType<typeof entry>;
34 parent?: ReturnType<typeof entry>;
35 permissionOverwrites?: ReturnType<typeof entry>;
36 region?: ReturnType<typeof entry>;
37 maxUsers?: ReturnType<typeof entry>;
TheCodedProf309d6182023-01-18 18:10:29 -050038}
39
40
41
pineafan63fc5e22022-08-04 22:04:10 +010042export const event = "channelUpdate";
pineafan32767212022-03-14 21:27:39 +000043
PineaFane6ba7882023-01-18 20:41:16 +000044export async function callback(client: NucleusClient, oldChannel: GuildChannel, newChannel: GuildChannel) {
45 const config = await client.memory.readGuildInfo(newChannel.guild.id);
TheCodedProfb493b8a2023-01-18 21:11:00 -050046 const { getAuditLog, log, NucleusColors, renderDelta, renderUser, renderChannel } = client.logger;
47 entry = client.logger.entry;
PineaFane6ba7882023-01-18 20:41:16 +000048 if (newChannel.parent && newChannel.parent.id === config.tickets.category) return;
pineafan32767212022-03-14 21:27:39 +000049
TheCodedProf309d6182023-01-18 18:10:29 -050050 const auditLog: GuildAuditLogsEntry<AuditLogEvent.ChannelUpdate> = (await getAuditLog(newChannel.guild, AuditLogEvent.ChannelUpdate))
51 .filter((entry: GuildAuditLogsEntry) => (entry.target as GuildChannel)!.id === newChannel.id)[0] as GuildAuditLogsEntry<AuditLogEvent.ChannelUpdate>;
52 if (auditLog.executor!.id === client.user!.id) return;
pineafan32767212022-03-14 21:27:39 +000053
Skyler Grey75ea9172022-08-06 10:22:23 +010054 let emoji: string;
55 let readableType: string;
56 let displayName: string;
TheCodedProf309d6182023-01-18 18:10:29 -050057 const changes: channelChanges = {
PineaFane6ba7882023-01-18 20:41:16 +000058 channelId: entry(newChannel.id, `\`${newChannel.id}\``),
59 channel: entry(newChannel.id, renderChannel(newChannel)),
pineafan63fc5e22022-08-04 22:04:10 +010060 edited: entry(new Date().getTime(), renderDelta(new Date().getTime())),
TheCodedProf309d6182023-01-18 18:10:29 -050061 editedBy: entry(auditLog.executor!.id, renderUser((await newChannel.guild.members.fetch(auditLog.executor!.id)).user)),
pineafan63fc5e22022-08-04 22:04:10 +010062 };
PineaFane6ba7882023-01-18 20:41:16 +000063 if (oldChannel.name !== newChannel.name) changes.name = entry([oldChannel.name, newChannel.name], `${oldChannel.name} -> ${newChannel.name}`);
64 if (oldChannel.position !== newChannel.position)
TheCodedProf60a1f492023-01-18 16:59:20 -050065 changes.position = entry([oldChannel.position.toString(), newChannel.position.toString()], `${oldChannel.position} -> ${newChannel.position}`);
pineafan63fc5e22022-08-04 22:04:10 +010066
PineaFane6ba7882023-01-18 20:41:16 +000067 switch (newChannel.type) {
TheCodedProf309d6182023-01-18 18:10:29 -050068 case ChannelType.GuildText: {
Skyler Grey75ea9172022-08-06 10:22:23 +010069 emoji = "CHANNEL.TEXT.EDIT";
70 readableType = "Text";
71 displayName = "Text Channel";
TheCodedProf309d6182023-01-18 18:10:29 -050072 let oldTopic = (oldChannel as TextChannel).topic,
73 newTopic = (newChannel as TextChannel).topic;
Skyler Grey75ea9172022-08-06 10:22:23 +010074 if (oldTopic) {
75 if (oldTopic.length > 256)
Skyler Grey11236ba2022-08-08 21:13:33 +010076 oldTopic = `\`\`\`\n${oldTopic.replace("`", "'").substring(0, 253) + "..."}\n\`\`\``;
Skyler Grey75ea9172022-08-06 10:22:23 +010077 else oldTopic = `\`\`\`\n${oldTopic.replace("`", "'")}\n\`\`\``;
78 } else {
79 oldTopic = "None";
80 }
81 if (newTopic) {
82 if (newTopic.length > 256)
Skyler Grey11236ba2022-08-08 21:13:33 +010083 newTopic = `\`\`\`\n${newTopic.replace("`", "'").substring(0, 253) + "..."}\n\`\`\``;
Skyler Grey75ea9172022-08-06 10:22:23 +010084 else newTopic = `\`\`\`\n${newTopic.replace("`", "'")}\n\`\`\``;
85 } else {
86 newTopic = "None";
87 }
88 const nsfw = ["", ""];
TheCodedProf309d6182023-01-18 18:10:29 -050089console.log((oldChannel as TextChannel).rateLimitPerUser, (newChannel as TextChannel).rateLimitPerUser);
90 nsfw[0] = (oldChannel as TextChannel).nsfw ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`;
91 nsfw[1] = (newChannel as TextChannel).nsfw ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`;
92 if ((oldChannel as TextChannel).topic !== (newChannel as TextChannel).topic)
93 changes.description = entry([(oldChannel as TextChannel).topic ?? "", (newChannel as TextChannel).topic ?? ""], `\nBefore: ${oldTopic}\nAfter: ${newTopic}`);
94 if ((oldChannel as TextChannel).nsfw !== (newChannel as TextChannel).nsfw) changes.nsfw = entry([(oldChannel as TextChannel).nsfw ? "On" : "Off", (newChannel as TextChannel).nsfw ? "On" : "Off"], `${nsfw[0]} -> ${nsfw[1]}`);
95 if ((oldChannel as TextChannel).rateLimitPerUser !== (newChannel as TextChannel).rateLimitPerUser && (oldChannel as TextChannel).rateLimitPerUser !== undefined)
Skyler Grey75ea9172022-08-06 10:22:23 +010096 changes.rateLimitPerUser = entry(
TheCodedProf309d6182023-01-18 18:10:29 -050097 [((oldChannel as TextChannel).rateLimitPerUser ?? 0).toString(), ((newChannel as TextChannel).rateLimitPerUser ?? 0).toString()],
98 `${humanizeDuration((oldChannel as TextChannel).rateLimitPerUser * 1000)} -> ${humanizeDuration((newChannel as TextChannel).rateLimitPerUser * 1000)}`
Skyler Grey75ea9172022-08-06 10:22:23 +010099 );
pineafan63fc5e22022-08-04 22:04:10 +0100100
Skyler Grey75ea9172022-08-06 10:22:23 +0100101 break;
102 }
TheCodedProf309d6182023-01-18 18:10:29 -0500103 case ChannelType.GuildAnnouncement: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100104 emoji = "CHANNEL.TEXT.EDIT";
TheCodedProf309d6182023-01-18 18:10:29 -0500105 readableType = "Announcement";
106 displayName = "Announcment Channel";
107 let oldTopic = (oldChannel as TextChannel).topic,
108 newTopic = (newChannel as TextChannel).topic;
Skyler Grey75ea9172022-08-06 10:22:23 +0100109 if (oldTopic) {
110 if (oldTopic.length > 256)
Skyler Grey11236ba2022-08-08 21:13:33 +0100111 oldTopic = `\`\`\`\n${oldTopic.replace("`", "'").substring(0, 253) + "..."}\n\`\`\``;
Skyler Grey75ea9172022-08-06 10:22:23 +0100112 else oldTopic = `\`\`\`\n${oldTopic.replace("`", "'")}\n\`\`\``;
113 } else {
114 oldTopic = "None";
115 }
116 if (newTopic) {
117 if (newTopic.length > 256)
Skyler Grey11236ba2022-08-08 21:13:33 +0100118 newTopic = `\`\`\`\n${newTopic.replace("`", "'").substring(0, 253) + "..."}\n\`\`\``;
Skyler Grey75ea9172022-08-06 10:22:23 +0100119 else newTopic = `\`\`\`\n${newTopic.replace("`", "'")}\n\`\`\``;
120 } else {
121 newTopic = "None";
122 }
TheCodedProf309d6182023-01-18 18:10:29 -0500123 if ((oldChannel as TextChannel).nsfw !== (newChannel as TextChannel).nsfw)
124 changes.nsfw = entry([(oldChannel as TextChannel).nsfw ? "On" : "Off", (newChannel as TextChannel).nsfw ? "On" : "Off"], `${(oldChannel as TextChannel).nsfw ? "On" : "Off"} -> ${(newChannel as TextChannel).nsfw ? "On" : "Off"}`);
Skyler Grey75ea9172022-08-06 10:22:23 +0100125 break;
126 }
TheCodedProf309d6182023-01-18 18:10:29 -0500127 case ChannelType.GuildVoice: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100128 emoji = "CHANNEL.VOICE.EDIT";
129 readableType = "Voice";
130 displayName = "Voice Channel";
TheCodedProf309d6182023-01-18 18:10:29 -0500131 if ((oldChannel as VoiceChannel).bitrate !== (newChannel as VoiceChannel).bitrate)
132 changes.bitrate = entry([(oldChannel as VoiceChannel).bitrate.toString(), (newChannel as VoiceChannel).bitrate.toString()], `${(oldChannel as VoiceChannel).bitrate} -> ${(newChannel as VoiceChannel).bitrate}`);
133 if ((oldChannel as VoiceChannel).userLimit !== (newChannel as VoiceChannel).userLimit)
Skyler Grey75ea9172022-08-06 10:22:23 +0100134 changes.maxUsers = entry(
TheCodedProf309d6182023-01-18 18:10:29 -0500135 [(oldChannel as VoiceChannel).userLimit.toString(), (newChannel as VoiceChannel).userLimit.toString()],
136 `${(oldChannel as VoiceChannel).userLimit ? (oldChannel as VoiceChannel).userLimit : "Unlimited"} -> ${(newChannel as VoiceChannel).userLimit}`
Skyler Grey75ea9172022-08-06 10:22:23 +0100137 );
TheCodedProf309d6182023-01-18 18:10:29 -0500138 if ((oldChannel as VoiceChannel).rtcRegion !== (newChannel as VoiceChannel).rtcRegion)
Skyler Grey75ea9172022-08-06 10:22:23 +0100139 changes.region = entry(
TheCodedProf309d6182023-01-18 18:10:29 -0500140 [(oldChannel as VoiceChannel).rtcRegion ?? "Automatic", (newChannel as VoiceChannel).rtcRegion ?? "Automatic"],
141 `${(oldChannel as VoiceChannel).rtcRegion?.toUpperCase() || "Automatic"} -> ${(newChannel as VoiceChannel).rtcRegion?.toUpperCase() || "Automatic"}`
Skyler Grey75ea9172022-08-06 10:22:23 +0100142 );
143 break;
144 }
TheCodedProf309d6182023-01-18 18:10:29 -0500145 case ChannelType.GuildStageVoice: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100146 emoji = "CHANNEL.VOICE.EDIT";
147 readableType = "Stage";
148 displayName = "Stage Channel";
TheCodedProf309d6182023-01-18 18:10:29 -0500149 let oldTopic = (oldChannel as StageChannel).topic,
150 newTopic = (newChannel as StageChannel).topic;
Skyler Grey75ea9172022-08-06 10:22:23 +0100151 if (oldTopic) {
152 if (oldTopic.length > 256)
Skyler Grey11236ba2022-08-08 21:13:33 +0100153 oldTopic = `\`\`\`\n${oldTopic.replace("`", "'").substring(0, 253) + "..."}\n\`\`\``;
Skyler Grey75ea9172022-08-06 10:22:23 +0100154 else oldTopic = `\`\`\`\n${oldTopic.replace("`", "'")}\n\`\`\``;
155 } else {
156 oldTopic = "None";
157 }
158 if (newTopic) {
159 if (newTopic.length > 256)
Skyler Grey11236ba2022-08-08 21:13:33 +0100160 newTopic = `\`\`\`\n${newTopic.replace("`", "'").substring(0, 253) + "..."}\n\`\`\``;
Skyler Grey75ea9172022-08-06 10:22:23 +0100161 else newTopic = `\`\`\`\n${newTopic.replace("`", "'")}\n\`\`\``;
162 } else {
163 newTopic = "None";
164 }
TheCodedProf309d6182023-01-18 18:10:29 -0500165 if ((oldChannel as StageChannel).bitrate !== (newChannel as StageChannel).bitrate)
166 changes.bitrate = entry([(oldChannel as StageChannel).bitrate.toString(), (newChannel as StageChannel).bitrate.toString()], `${(oldChannel as StageChannel).bitrate} -> ${(newChannel as StageChannel).bitrate}`);
167 if ((oldChannel as StageChannel).userLimit !== (newChannel as StageChannel).userLimit)
Skyler Grey75ea9172022-08-06 10:22:23 +0100168 changes.maxUsers = entry(
TheCodedProf309d6182023-01-18 18:10:29 -0500169 [(oldChannel as StageChannel).userLimit.toString(), (newChannel as StageChannel).userLimit.toString()],
170 `${(oldChannel as StageChannel).userLimit ? (oldChannel as StageChannel).userLimit : "Unlimited"} -> ${(newChannel as StageChannel).userLimit}`
Skyler Grey75ea9172022-08-06 10:22:23 +0100171 );
TheCodedProf309d6182023-01-18 18:10:29 -0500172 if ((oldChannel as StageChannel).rtcRegion !== (newChannel as StageChannel).rtcRegion)
Skyler Grey75ea9172022-08-06 10:22:23 +0100173 changes.region = entry(
TheCodedProf309d6182023-01-18 18:10:29 -0500174 [(oldChannel as StageChannel).rtcRegion ?? "Automatic", (newChannel as StageChannel).rtcRegion ?? "Automatic"],
175 `${(oldChannel as StageChannel).rtcRegion?.toUpperCase() || "Automatic"} -> ${(newChannel as StageChannel).rtcRegion?.toUpperCase() || "Automatic"}`
Skyler Grey75ea9172022-08-06 10:22:23 +0100176 );
177 break;
178 }
TheCodedProf309d6182023-01-18 18:10:29 -0500179 case ChannelType.GuildCategory: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100180 emoji = "CHANNEL.CATEGORY.EDIT";
181 readableType = "Category";
182 displayName = "Category";
183 break;
184 }
185 default: {
186 emoji = "CHANNEL.TEXT.EDIT";
187 readableType = "Channel";
188 displayName = "Channel";
189 }
pineafan63fc5e22022-08-04 22:04:10 +0100190 }
TheCodedProf309d6182023-01-18 18:10:29 -0500191 let ocType = channelTypeEmoji[oldChannel.type],
192 ncType = channelTypeEmoji[newChannel.type];
PineaFane6ba7882023-01-18 20:41:16 +0000193 if (oldChannel.type !== newChannel.type)
TheCodedProf309d6182023-01-18 18:10:29 -0500194 changes.type = entry([ocType!, ncType!], `${ocType!} -> ${readableType}`);
pineafan63fc5e22022-08-04 22:04:10 +0100195 if (!(Object.values(changes).length - 4)) return;
196 const data = {
Skyler Grey75ea9172022-08-06 10:22:23 +0100197 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100198 type: "channelUpdate",
199 displayName: displayName + " Edited",
200 calculateType: "channelUpdate",
201 color: NucleusColors.yellow,
202 emoji: emoji,
TheCodedProf309d6182023-01-18 18:10:29 -0500203 timestamp: auditLog.createdTimestamp
pineafan63fc5e22022-08-04 22:04:10 +0100204 },
205 list: changes,
206 hidden: {
PineaFane6ba7882023-01-18 20:41:16 +0000207 guild: newChannel.guild.id
pineafane625d782022-05-09 18:04:32 +0100208 }
pineafan63fc5e22022-08-04 22:04:10 +0100209 };
210 log(data);
Skyler Grey75ea9172022-08-06 10:22:23 +0100211}
TheCodedProf309d6182023-01-18 18:10:29 -0500212//TODO: Capitialize RTC Regions