blob: a883ea92b39a7a0f61335c6f1a1d29788ffa370d [file] [log] [blame]
PineaFan752af462022-12-31 21:59:38 +00001import type { NucleusClient } from "../utils/client.js";
Skyler Grey11236ba2022-08-08 21:13:33 +01002import { LinkCheck, MalwareCheck, NSFWCheck, SizeCheck, TestString, TestImage } from "../reflex/scanners.js";
pineafan63fc5e22022-08-04 22:04:10 +01003import logAttachment from "../premium/attachmentLogs.js";
PineaFan0d06edc2023-01-17 22:10:31 +00004import { messageException } from "../utils/createTemporaryStorage.js";
pineafan63fc5e22022-08-04 22:04:10 +01005import getEmojiByName from "../utils/getEmojiByName.js";
6import client from "../utils/client.js";
pineafan0f5cc782022-08-12 21:55:42 +01007import { callback as statsChannelUpdate } from "../reflex/statsChannelUpdate.js";
Skyler Greyc634e2b2022-08-06 17:50:48 +01008import { Message, ThreadChannel } from "discord.js";
pineafan813bdf42022-07-24 10:39:10 +01009
pineafan63fc5e22022-08-04 22:04:10 +010010export const event = "messageCreate";
pineafan813bdf42022-07-24 10:39:10 +010011
PineaFan752af462022-12-31 21:59:38 +000012export async function callback(_client: NucleusClient, message: Message) {
Skyler Grey75ea9172022-08-06 10:22:23 +010013 if (!message.guild) return;
PineappleFan13892c62023-03-05 07:00:07 +000014 const config = await client.memory.readGuildInfo(message.guild.id);
15
16 if (config.autoPublish.enabled && config.autoPublish.channels.includes(message.channel.id)) {
17 await message.crosspost();
18 }
19
pineafan63fc5e22022-08-04 22:04:10 +010020 if (message.author.bot) return;
PineaFan538d3752023-01-12 21:48:23 +000021 if (message.channel.isDMBased()) return;
Skyler Grey75ea9172022-08-06 10:22:23 +010022 try {
pineafan0f5cc782022-08-12 21:55:42 +010023 await statsChannelUpdate(client, await message.guild.members.fetch(message.author.id));
Skyler Grey75ea9172022-08-06 10:22:23 +010024 } catch (e) {
25 console.log(e);
26 }
pineafan813bdf42022-07-24 10:39:10 +010027
Samuel Shuert27bf3cd2023-03-03 15:51:25 -050028 const { log, isLogging, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;
pineafan813bdf42022-07-24 10:39:10 +010029
pineafan63fc5e22022-08-04 22:04:10 +010030 const fileNames = await logAttachment(message);
pineafan813bdf42022-07-24 10:39:10 +010031
pineafan63fc5e22022-08-04 22:04:10 +010032 const content = message.content.toLowerCase() || "";
Samuel Shuert27bf3cd2023-03-03 15:51:25 -050033 if(config.filters.clean.channels.includes(message.channel.id)) {
34 const memberRoles = message.member!.roles.cache.map(role => role.id);
35 const roleAllow = config.filters.clean.allowed.roles.some(role => memberRoles.includes(role));
36 const userAllow = config.filters.clean.allowed.users.includes(message.author.id);
37 if(!roleAllow && !userAllow) return await message.delete();
38 }
39
pineafan63fc5e22022-08-04 22:04:10 +010040 const filter = getEmojiByName("ICONS.FILTER");
41 let attachmentJump = "";
Skyler Grey75ea9172022-08-06 10:22:23 +010042 if (config.logging.attachments.saved[message.channel.id + message.id]) {
Skyler Grey11236ba2022-08-08 21:13:33 +010043 attachmentJump = ` [[View attachments]](${config.logging.attachments.saved[message.channel.id + message.id]})`;
Skyler Grey75ea9172022-08-06 10:22:23 +010044 }
pineafan63fc5e22022-08-04 22:04:10 +010045 const list = {
pineafan813bdf42022-07-24 10:39:10 +010046 messageId: entry(message.id, `\`${message.id}\``),
47 sentBy: entry(message.author.id, renderUser(message.author)),
48 sentIn: entry(message.channel.id, renderChannel(message.channel)),
Samuel Shuert27bf3cd2023-03-03 15:51:25 -050049 deleted: entry(Date.now(), renderDelta(Date.now())),
pineafan813bdf42022-07-24 10:39:10 +010050 mentions: message.mentions.users.size,
Skyler Grey11236ba2022-08-08 21:13:33 +010051 attachments: entry(message.attachments.size, message.attachments.size + attachmentJump),
pineafan813bdf42022-07-24 10:39:10 +010052 repliedTo: entry(
PineaFan538d3752023-01-12 21:48:23 +000053 (message.reference ? message.reference.messageId : null) ?? null,
Skyler Grey75ea9172022-08-06 10:22:23 +010054 message.reference
55 ? `[[Jump to message]](https://discord.com/channels/${message.guild.id}/${message.channel.id}/${message.reference.messageId})`
56 : "None"
pineafan813bdf42022-07-24 10:39:10 +010057 )
pineafan63fc5e22022-08-04 22:04:10 +010058 };
pineafan813bdf42022-07-24 10:39:10 +010059
60 if (config.filters.invite.enabled) {
Skyler Grey11236ba2022-08-08 21:13:33 +010061 if (!config.filters.invite.allowed.channels.includes(message.channel.id)) {
62 if (/(?:https?:\/\/)?discord(?:app)?\.(?:com\/invite|gg)\/[a-zA-Z0-9]+\/?/.test(content)) {
PineaFan0d06edc2023-01-17 22:10:31 +000063 messageException(message.guild.id, message.channel.id, message.id);
pineafan813bdf42022-07-24 10:39:10 +010064 message.delete();
pineafan63fc5e22022-08-04 22:04:10 +010065 const data = {
pineafan813bdf42022-07-24 10:39:10 +010066 meta: {
pineafan63fc5e22022-08-04 22:04:10 +010067 type: "messageDelete",
Skyler Grey11236ba2022-08-08 21:13:33 +010068 displayName: "Message Deleted (Automated, Contained Invite)",
pineafan63fc5e22022-08-04 22:04:10 +010069 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +010070 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +010071 emoji: "MESSAGE.DELETE",
Samuel Shuert27bf3cd2023-03-03 15:51:25 -050072 timestamp: Date.now()
pineafan813bdf42022-07-24 10:39:10 +010073 },
74 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +010075 start:
76 filter +
77 " Contained invite\n\n" +
Skyler Grey11236ba2022-08-08 21:13:33 +010078 (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +010079 },
80 list: list,
81 hidden: {
82 guild: message.channel.guild.id
83 }
pineafan63fc5e22022-08-04 22:04:10 +010084 };
pineafan813bdf42022-07-24 10:39:10 +010085 return log(data);
86 }
87 }
88 }
89
90 if (fileNames.files.length > 0) {
pineafan63fc5e22022-08-04 22:04:10 +010091 for (const element of fileNames.files) {
pineafan63fc5e22022-08-04 22:04:10 +010092 const url = element.url ? element.url : element.local;
Samuel Shuert27bf3cd2023-03-03 15:51:25 -050093 if (/\.(j(pe?g|fif)|a?png|gifv?|w(eb[mp]|av)|mp([34]|eg-\d)|ogg|avi|h\.26(4|5)|cda)$/.test(url.toLowerCase())) {
94 // jpg|jpeg|png|apng|gif|gifv|webm|webp|mp4|wav|mp3|ogg|jfif|MPEG-#|avi|h.264|h.265
Skyler Grey75ea9172022-08-06 10:22:23 +010095 if (
Skyler Greyc634e2b2022-08-06 17:50:48 +010096 config.filters.images.NSFW &&
Skyler Grey11236ba2022-08-08 21:13:33 +010097 !(message.channel instanceof ThreadChannel ? message.channel.parent?.nsfw : message.channel.nsfw)
Skyler Grey75ea9172022-08-06 10:22:23 +010098 ) {
Skyler Greyc634e2b2022-08-06 17:50:48 +010099 if (await NSFWCheck(url)) {
PineaFan0d06edc2023-01-17 22:10:31 +0000100 messageException(message.guild.id, message.channel.id, message.id);
pineafan63fc5e22022-08-04 22:04:10 +0100101 await message.delete();
102 const data = {
pineafan813bdf42022-07-24 10:39:10 +0100103 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100104 type: "messageDelete",
105 displayName: "Message Deleted",
106 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +0100107 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100108 emoji: "MESSAGE.DELETE",
Samuel Shuert27bf3cd2023-03-03 15:51:25 -0500109 timestamp: Date.now()
pineafan813bdf42022-07-24 10:39:10 +0100110 },
111 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100112 start:
113 filter +
Skyler Greyc634e2b2022-08-06 17:50:48 +0100114 " Image detected as NSFW\n\n" +
Skyler Grey75ea9172022-08-06 10:22:23 +0100115 (content
116 ? `**Message:**\n\`\`\`${content}\`\`\``
117 : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100118 },
119 list: list,
120 hidden: {
121 guild: message.channel.guild.id
122 }
pineafan63fc5e22022-08-04 22:04:10 +0100123 };
pineafan813bdf42022-07-24 10:39:10 +0100124 return log(data);
125 }
126 }
Skyler Greyc634e2b2022-08-06 17:50:48 +0100127 if (config.filters.wordFilter.enabled) {
128 const text = await TestImage(url);
129 const check = TestString(
130 text ?? "",
131 config.filters.wordFilter.words.loose,
132 config.filters.wordFilter.words.strict
133 );
134 if (check !== null) {
PineaFan0d06edc2023-01-17 22:10:31 +0000135 messageException(message.guild.id, message.channel.id, message.id);
Skyler Greyc634e2b2022-08-06 17:50:48 +0100136 await message.delete();
137 const data = {
138 meta: {
139 type: "messageDelete",
140 displayName: "Message Deleted",
141 calculateType: "autoModeratorDeleted",
142 color: NucleusColors.red,
143 emoji: "MESSAGE.DELETE",
Samuel Shuert27bf3cd2023-03-03 15:51:25 -0500144 timestamp: Date.now()
Skyler Greyc634e2b2022-08-06 17:50:48 +0100145 },
146 separate: {
147 start:
148 filter +
149 " Image contained filtered word\n\n" +
150 (content
151 ? `**Message:**\n\`\`\`${content}\`\`\``
152 : "**Message:** *Message had no content*")
153 },
154 list: list,
155 hidden: {
156 guild: message.channel.guild.id
157 }
158 };
159 return log(data);
160 }
161 }
162 if (config.filters.images.size) {
163 if (url.match(/\.+(webp|png|jpg)$/gi)) {
164 if (!(await SizeCheck(element))) {
PineaFan0d06edc2023-01-17 22:10:31 +0000165 messageException(message.guild.id, message.channel.id, message.id);
Skyler Greyc634e2b2022-08-06 17:50:48 +0100166 await message.delete();
167 const data = {
168 meta: {
169 type: "messageDelete",
170 displayName: "Message Deleted",
171 calculateType: "autoModeratorDeleted",
172 color: NucleusColors.red,
173 emoji: "MESSAGE.DELETE",
Samuel Shuert27bf3cd2023-03-03 15:51:25 -0500174 timestamp: Date.now()
Skyler Greyc634e2b2022-08-06 17:50:48 +0100175 },
176 separate: {
177 start:
178 filter +
179 " Image was too small\n\n" +
180 (content
181 ? `**Message:**\n\`\`\`${content}\`\`\``
182 : "**Message:** *Message had no content*")
183 },
184 list: list,
185 hidden: {
186 guild: message.channel.guild.id
187 }
188 };
189 return log(data);
190 }
191 }
192 }
193 }
194 if (config.filters.malware) {
195 if (!(await MalwareCheck(url))) {
PineaFan0d06edc2023-01-17 22:10:31 +0000196 messageException(message.guild.id, message.channel.id, message.id);
Skyler Greyc634e2b2022-08-06 17:50:48 +0100197 await message.delete();
198 const data = {
199 meta: {
200 type: "messageDelete",
201 displayName: "Message Deleted",
202 calculateType: "autoModeratorDeleted",
203 color: NucleusColors.red,
204 emoji: "MESSAGE.DELETE",
Samuel Shuert27bf3cd2023-03-03 15:51:25 -0500205 timestamp: Date.now()
Skyler Greyc634e2b2022-08-06 17:50:48 +0100206 },
207 separate: {
208 start:
209 filter +
210 " File detected as malware\n\n" +
211 (content
212 ? `**Message:**\n\`\`\`${content}\`\`\``
213 : "**Message:** *Message had no content*")
214 },
215 list: list,
216 hidden: {
217 guild: message.channel.guild.id
218 }
219 };
220 return log(data);
221 }
pineafan813bdf42022-07-24 10:39:10 +0100222 }
pineafan63fc5e22022-08-04 22:04:10 +0100223 }
pineafan813bdf42022-07-24 10:39:10 +0100224 }
pineafan813bdf42022-07-24 10:39:10 +0100225
pineafan63fc5e22022-08-04 22:04:10 +0100226 const linkDetectionTypes = await LinkCheck(message);
pineafan813bdf42022-07-24 10:39:10 +0100227 if (linkDetectionTypes.length > 0) {
PineaFan0d06edc2023-01-17 22:10:31 +0000228 messageException(message.guild.id, message.channel.id, message.id);
pineafan63fc5e22022-08-04 22:04:10 +0100229 await message.delete();
230 const data = {
pineafan813bdf42022-07-24 10:39:10 +0100231 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100232 type: "messageDelete",
233 displayName: "Message Deleted",
234 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +0100235 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100236 emoji: "MESSAGE.DELETE",
Samuel Shuert27bf3cd2023-03-03 15:51:25 -0500237 timestamp: Date.now()
pineafan813bdf42022-07-24 10:39:10 +0100238 },
239 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100240 start:
241 filter +
242 ` Link filtered as ${linkDetectionTypes[0]?.toLowerCase()}\n\n` +
Skyler Grey11236ba2022-08-08 21:13:33 +0100243 (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100244 },
245 list: list,
246 hidden: {
247 guild: message.channel.guild.id
248 }
pineafan63fc5e22022-08-04 22:04:10 +0100249 };
pineafan813bdf42022-07-24 10:39:10 +0100250 return log(data);
251 }
pineafane23c4ec2022-07-27 21:56:27 +0100252
pineafan813bdf42022-07-24 10:39:10 +0100253 if (config.filters.wordFilter.enabled) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100254 const check = TestString(
255 content,
256 config.filters.wordFilter.words.loose,
257 config.filters.wordFilter.words.strict
258 );
259 if (check !== null) {
PineaFan0d06edc2023-01-17 22:10:31 +0000260 messageException(message.guild.id, message.channel.id, message.id);
pineafan63fc5e22022-08-04 22:04:10 +0100261 await message.delete();
262 const data = {
pineafan813bdf42022-07-24 10:39:10 +0100263 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100264 type: "messageDelete",
265 displayName: "Message Deleted",
266 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +0100267 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100268 emoji: "MESSAGE.DELETE",
Samuel Shuert27bf3cd2023-03-03 15:51:25 -0500269 timestamp: Date.now()
pineafan813bdf42022-07-24 10:39:10 +0100270 },
271 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100272 start:
273 filter +
274 " Message contained filtered word\n\n" +
Skyler Grey11236ba2022-08-08 21:13:33 +0100275 (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100276 },
277 list: list,
278 hidden: {
279 guild: message.channel.guild.id
280 }
pineafan63fc5e22022-08-04 22:04:10 +0100281 };
pineafan813bdf42022-07-24 10:39:10 +0100282 return log(data);
283 }
284 }
285
pineafane23c4ec2022-07-27 21:56:27 +0100286 if (config.filters.pings.everyone && message.mentions.everyone) {
Samuel Shuert27bf3cd2023-03-03 15:51:25 -0500287 if(!await isLogging(message.guild.id, "messageMassPing")) return;
pineafan63fc5e22022-08-04 22:04:10 +0100288 const data = {
pineafane23c4ec2022-07-27 21:56:27 +0100289 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100290 type: "everyonePing",
291 displayName: "Everyone Pinged",
292 calculateType: "messageMassPing",
pineafane23c4ec2022-07-27 21:56:27 +0100293 color: NucleusColors.yellow,
pineafan63fc5e22022-08-04 22:04:10 +0100294 emoji: "MESSAGE.PING.EVERYONE",
Samuel Shuert27bf3cd2023-03-03 15:51:25 -0500295 timestamp: Date.now()
pineafane23c4ec2022-07-27 21:56:27 +0100296 },
297 separate: {
Skyler Grey11236ba2022-08-08 21:13:33 +0100298 start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*"
pineafane23c4ec2022-07-27 21:56:27 +0100299 },
300 list: list,
301 hidden: {
302 guild: message.channel.guild.id
pineafan813bdf42022-07-24 10:39:10 +0100303 }
pineafan63fc5e22022-08-04 22:04:10 +0100304 };
pineafane23c4ec2022-07-27 21:56:27 +0100305 return log(data);
306 }
307 if (config.filters.pings.roles) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100308 for (const roleId in message.mentions.roles) {
pineafan63fc5e22022-08-04 22:04:10 +0100309 if (!config.filters.pings.allowed.roles.includes(roleId)) {
PineaFan0d06edc2023-01-17 22:10:31 +0000310 messageException(message.guild.id, message.channel.id, message.id);
pineafan63fc5e22022-08-04 22:04:10 +0100311 await message.delete();
Samuel Shuert27bf3cd2023-03-03 15:51:25 -0500312 if(!await isLogging(message.guild.id, "messageMassPing")) return;
pineafan63fc5e22022-08-04 22:04:10 +0100313 const data = {
pineafane23c4ec2022-07-27 21:56:27 +0100314 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100315 type: "rolePing",
316 displayName: "Role Pinged",
317 calculateType: "messageMassPing",
pineafane23c4ec2022-07-27 21:56:27 +0100318 color: NucleusColors.yellow,
pineafan63fc5e22022-08-04 22:04:10 +0100319 emoji: "MESSAGE.PING.ROLE",
Samuel Shuert27bf3cd2023-03-03 15:51:25 -0500320 timestamp: Date.now()
pineafane23c4ec2022-07-27 21:56:27 +0100321 },
322 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100323 start: content
324 ? `**Message:**\n\`\`\`${content}\`\`\``
325 : "**Message:** *Message had no content*"
pineafane23c4ec2022-07-27 21:56:27 +0100326 },
327 list: list,
328 hidden: {
329 guild: message.channel.guild.id
pineafan813bdf42022-07-24 10:39:10 +0100330 }
pineafan63fc5e22022-08-04 22:04:10 +0100331 };
pineafane23c4ec2022-07-27 21:56:27 +0100332 return log(data);
pineafan813bdf42022-07-24 10:39:10 +0100333 }
334 }
pineafane23c4ec2022-07-27 21:56:27 +0100335 }
Skyler Grey11236ba2022-08-08 21:13:33 +0100336 if (message.mentions.users.size >= config.filters.pings.mass && config.filters.pings.mass) {
PineaFan0d06edc2023-01-17 22:10:31 +0000337 messageException(message.guild.id, message.channel.id, message.id);
pineafan63fc5e22022-08-04 22:04:10 +0100338 await message.delete();
Samuel Shuert27bf3cd2023-03-03 15:51:25 -0500339 if(!await isLogging(message.guild.id, "messageMassPing")) return;
pineafan63fc5e22022-08-04 22:04:10 +0100340 const data = {
pineafane23c4ec2022-07-27 21:56:27 +0100341 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100342 type: "massPing",
343 displayName: "Mass Ping",
344 calculateType: "messageMassPing",
pineafane23c4ec2022-07-27 21:56:27 +0100345 color: NucleusColors.yellow,
pineafan63fc5e22022-08-04 22:04:10 +0100346 emoji: "MESSAGE.PING.MASS",
Samuel Shuert27bf3cd2023-03-03 15:51:25 -0500347 timestamp: Date.now()
pineafane23c4ec2022-07-27 21:56:27 +0100348 },
349 separate: {
Skyler Grey11236ba2022-08-08 21:13:33 +0100350 start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*"
pineafane23c4ec2022-07-27 21:56:27 +0100351 },
352 list: list,
353 hidden: {
354 guild: message.channel.guild.id
pineafan813bdf42022-07-24 10:39:10 +0100355 }
pineafan63fc5e22022-08-04 22:04:10 +0100356 };
pineafane23c4ec2022-07-27 21:56:27 +0100357 return log(data);
pineafan813bdf42022-07-24 10:39:10 +0100358 }
359}