blob: 53de4df99d91c7f88c277564d81a46644e739e0c [file] [log] [blame]
pineafan63fc5e22022-08-04 22:04:10 +01001// eslint-disable-next-line @typescript-eslint/ban-ts-comment
Skyler Grey75ea9172022-08-06 10:22:23 +01002// @ts-expect-error
pineafan63fc5e22022-08-04 22:04:10 +01003import { HaikuClient } from "jshaiku";
Skyler Grey75ea9172022-08-06 10:22:23 +01004import {
5 LinkCheck,
6 MalwareCheck,
7 NSFWCheck,
8 SizeCheck,
9 TestString,
10 TestImage
11} from "../reflex/scanners.js";
pineafan63fc5e22022-08-04 22:04:10 +010012import logAttachment from "../premium/attachmentLogs.js";
13import createLogException from "../utils/createLogException.js";
14import getEmojiByName from "../utils/getEmojiByName.js";
15import client from "../utils/client.js";
Skyler Grey75ea9172022-08-06 10:22:23 +010016import { callback as a } from "../reflex/statsChannelUpdate.js";
pineafan63fc5e22022-08-04 22:04:10 +010017import type { Message } from "discord.js";
pineafan813bdf42022-07-24 10:39:10 +010018
pineafan63fc5e22022-08-04 22:04:10 +010019export const event = "messageCreate";
pineafan813bdf42022-07-24 10:39:10 +010020
pineafan63fc5e22022-08-04 22:04:10 +010021export async function callback(_client: HaikuClient, message: Message) {
Skyler Grey75ea9172022-08-06 10:22:23 +010022 if (!message) return;
23 if (!message.guild) return;
pineafan63fc5e22022-08-04 22:04:10 +010024 if (message.author.bot) return;
25 if (message.channel.type === "DM") return;
Skyler Grey75ea9172022-08-06 10:22:23 +010026 try {
27 await a(client, await message.guild.members.fetch(message.author.id));
28 } catch (e) {
29 console.log(e);
30 }
pineafan813bdf42022-07-24 10:39:10 +010031
Skyler Grey75ea9172022-08-06 10:22:23 +010032 const {
33 log,
34 NucleusColors,
35 entry,
36 renderUser,
37 renderDelta,
38 renderChannel
39 } = client.logger;
pineafan813bdf42022-07-24 10:39:10 +010040
pineafan63fc5e22022-08-04 22:04:10 +010041 const fileNames = await logAttachment(message);
pineafan813bdf42022-07-24 10:39:10 +010042
pineafan63fc5e22022-08-04 22:04:10 +010043 const content = message.content.toLowerCase() || "";
44 const config = await client.memory.readGuildInfo(message.guild.id);
45 const filter = getEmojiByName("ICONS.FILTER");
46 let attachmentJump = "";
Skyler Grey75ea9172022-08-06 10:22:23 +010047 if (config.logging.attachments.saved[message.channel.id + message.id]) {
48 attachmentJump = ` [[View attachments]](${
49 config.logging.attachments.saved[message.channel.id + message.id]
50 })`;
51 }
pineafan63fc5e22022-08-04 22:04:10 +010052 const list = {
pineafan813bdf42022-07-24 10:39:10 +010053 messageId: entry(message.id, `\`${message.id}\``),
54 sentBy: entry(message.author.id, renderUser(message.author)),
55 sentIn: entry(message.channel.id, renderChannel(message.channel)),
56 deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
57 mentions: message.mentions.users.size,
Skyler Grey75ea9172022-08-06 10:22:23 +010058 attachments: entry(
59 message.attachments.size,
60 message.attachments.size + attachmentJump
61 ),
pineafan813bdf42022-07-24 10:39:10 +010062 repliedTo: entry(
63 message.reference ? message.reference.messageId : null,
Skyler Grey75ea9172022-08-06 10:22:23 +010064 message.reference
65 ? `[[Jump to message]](https://discord.com/channels/${message.guild.id}/${message.channel.id}/${message.reference.messageId})`
66 : "None"
pineafan813bdf42022-07-24 10:39:10 +010067 )
pineafan63fc5e22022-08-04 22:04:10 +010068 };
pineafan813bdf42022-07-24 10:39:10 +010069
70 if (config.filters.invite.enabled) {
Skyler Grey75ea9172022-08-06 10:22:23 +010071 if (
72 !config.filters.invite.allowed.channels.includes(message.channel.id)
73 ) {
74 if (
75 /(?:https?:\/\/)?discord(?:app)?\.(?:com\/invite|gg)\/[a-zA-Z0-9]+\/?/.test(
76 content
77 )
78 ) {
79 createLogException(
80 message.guild.id,
81 message.channel.id,
82 message.id
83 );
pineafan813bdf42022-07-24 10:39:10 +010084 message.delete();
pineafan63fc5e22022-08-04 22:04:10 +010085 const data = {
pineafan813bdf42022-07-24 10:39:10 +010086 meta: {
pineafan63fc5e22022-08-04 22:04:10 +010087 type: "messageDelete",
Skyler Grey75ea9172022-08-06 10:22:23 +010088 displayName:
89 "Message Deleted (Automated, Contained Invite)",
pineafan63fc5e22022-08-04 22:04:10 +010090 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +010091 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +010092 emoji: "MESSAGE.DELETE",
pineafan813bdf42022-07-24 10:39:10 +010093 timestamp: new Date().getTime()
94 },
95 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +010096 start:
97 filter +
98 " Contained invite\n\n" +
99 (content
100 ? `**Message:**\n\`\`\`${content}\`\`\``
101 : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100102 },
103 list: list,
104 hidden: {
105 guild: message.channel.guild.id
106 }
pineafan63fc5e22022-08-04 22:04:10 +0100107 };
pineafan813bdf42022-07-24 10:39:10 +0100108 return log(data);
109 }
110 }
111 }
112
113 if (fileNames.files.length > 0) {
pineafan63fc5e22022-08-04 22:04:10 +0100114 for (const element of fileNames.files) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100115 if (!message) return;
pineafan63fc5e22022-08-04 22:04:10 +0100116 const url = element.url ? element.url : element.local;
pineafane23c4ec2022-07-27 21:56:27 +0100117 if (url !== undefined) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100118 if (
119 /\.(jpg|jpeg|png|gif|gifv|webm|webp|mp4|wav|mp3|ogg)$/.test(
120 url
121 )
122 ) {
123 if (
124 config.filters.images.NSFW &&
125 !(message.channel.type === "GUILD_PUBLIC_THREAD"
126 ? false
127 : message.channel.nsfw)
128 ) {
pineafan813bdf42022-07-24 10:39:10 +0100129 if (await NSFWCheck(url)) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100130 createLogException(
131 message.guild.id,
132 message.channel.id,
133 message.id
134 );
pineafan63fc5e22022-08-04 22:04:10 +0100135 await message.delete();
136 const data = {
pineafan813bdf42022-07-24 10:39:10 +0100137 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100138 type: "messageDelete",
139 displayName: "Message Deleted",
140 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +0100141 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100142 emoji: "MESSAGE.DELETE",
pineafan813bdf42022-07-24 10:39:10 +0100143 timestamp: new Date().getTime()
144 },
145 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100146 start:
147 filter +
148 " Image detected as NSFW\n\n" +
149 (content
150 ? `**Message:**\n\`\`\`${content}\`\`\``
151 : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100152 },
153 list: list,
154 hidden: {
155 guild: message.channel.guild.id
156 }
pineafan63fc5e22022-08-04 22:04:10 +0100157 };
pineafan813bdf42022-07-24 10:39:10 +0100158 return log(data);
159 }
160 }
161 if (config.filters.wordFilter.enabled) {
pineafan63fc5e22022-08-04 22:04:10 +0100162 const text = await TestImage(url);
Skyler Grey75ea9172022-08-06 10:22:23 +0100163 const check = TestString(
164 text ?? "",
165 config.filters.wordFilter.words.loose,
166 config.filters.wordFilter.words.strict
167 );
168 if (check !== null) {
169 createLogException(
170 message.guild.id,
171 message.channel.id,
172 message.id
173 );
pineafan63fc5e22022-08-04 22:04:10 +0100174 await message.delete();
175 const data = {
pineafane23c4ec2022-07-27 21:56:27 +0100176 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100177 type: "messageDelete",
178 displayName: "Message Deleted",
179 calculateType: "autoModeratorDeleted",
pineafane23c4ec2022-07-27 21:56:27 +0100180 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100181 emoji: "MESSAGE.DELETE",
pineafane23c4ec2022-07-27 21:56:27 +0100182 timestamp: new Date().getTime()
183 },
184 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100185 start:
186 filter +
187 " Image contained filtered word\n\n" +
188 (content
189 ? `**Message:**\n\`\`\`${content}\`\`\``
190 : "**Message:** *Message had no content*")
pineafane23c4ec2022-07-27 21:56:27 +0100191 },
192 list: list,
193 hidden: {
194 guild: message.channel.guild.id
pineafan813bdf42022-07-24 10:39:10 +0100195 }
pineafan63fc5e22022-08-04 22:04:10 +0100196 };
pineafane23c4ec2022-07-27 21:56:27 +0100197 return log(data);
pineafan813bdf42022-07-24 10:39:10 +0100198 }
199 }
200 if (config.filters.images.size) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100201 if (url.match(/\.+(webp|png|jpg)$/gi)) {
202 if (!(await SizeCheck(element))) {
203 createLogException(
204 message.guild.id,
205 message.channel.id,
206 message.id
207 );
pineafan63fc5e22022-08-04 22:04:10 +0100208 await message.delete();
209 const data = {
pineafan813bdf42022-07-24 10:39:10 +0100210 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100211 type: "messageDelete",
212 displayName: "Message Deleted",
213 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +0100214 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100215 emoji: "MESSAGE.DELETE",
pineafan813bdf42022-07-24 10:39:10 +0100216 timestamp: new Date().getTime()
217 },
218 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100219 start:
220 filter +
221 " Image was too small\n\n" +
222 (content
223 ? `**Message:**\n\`\`\`${content}\`\`\``
224 : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100225 },
226 list: list,
227 hidden: {
228 guild: message.channel.guild.id
229 }
pineafan63fc5e22022-08-04 22:04:10 +0100230 };
pineafan813bdf42022-07-24 10:39:10 +0100231 return log(data);
232 }
233 }
234 }
235 }
236 if (config.filters.malware) {
237 if (!MalwareCheck(url)) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100238 createLogException(
239 message.guild.id,
240 message.channel.id,
241 message.id
242 );
pineafan63fc5e22022-08-04 22:04:10 +0100243 await message.delete();
244 const data = {
pineafan813bdf42022-07-24 10:39:10 +0100245 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100246 type: "messageDelete",
247 displayName: "Message Deleted",
248 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +0100249 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100250 emoji: "MESSAGE.DELETE",
pineafan813bdf42022-07-24 10:39:10 +0100251 timestamp: new Date().getTime()
252 },
253 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100254 start:
255 filter +
256 " File detected as malware\n\n" +
257 (content
258 ? `**Message:**\n\`\`\`${content}\`\`\``
259 : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100260 },
261 list: list,
262 hidden: {
263 guild: message.channel.guild.id
264 }
pineafan63fc5e22022-08-04 22:04:10 +0100265 };
pineafan813bdf42022-07-24 10:39:10 +0100266 return log(data);
267 }
268 }
269 }
pineafan63fc5e22022-08-04 22:04:10 +0100270 }
pineafan813bdf42022-07-24 10:39:10 +0100271 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100272 if (!message) return;
pineafan813bdf42022-07-24 10:39:10 +0100273
pineafan63fc5e22022-08-04 22:04:10 +0100274 const linkDetectionTypes = await LinkCheck(message);
pineafan813bdf42022-07-24 10:39:10 +0100275 if (linkDetectionTypes.length > 0) {
pineafan63fc5e22022-08-04 22:04:10 +0100276 createLogException(message.guild.id, message.channel.id, message.id);
277 await message.delete();
278 const data = {
pineafan813bdf42022-07-24 10:39:10 +0100279 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100280 type: "messageDelete",
281 displayName: "Message Deleted",
282 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +0100283 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100284 emoji: "MESSAGE.DELETE",
pineafan813bdf42022-07-24 10:39:10 +0100285 timestamp: new Date().getTime()
286 },
287 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100288 start:
289 filter +
290 ` Link filtered as ${linkDetectionTypes[0]?.toLowerCase()}\n\n` +
291 (content
292 ? `**Message:**\n\`\`\`${content}\`\`\``
293 : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100294 },
295 list: list,
296 hidden: {
297 guild: message.channel.guild.id
298 }
pineafan63fc5e22022-08-04 22:04:10 +0100299 };
pineafan813bdf42022-07-24 10:39:10 +0100300 return log(data);
301 }
pineafane23c4ec2022-07-27 21:56:27 +0100302
pineafan813bdf42022-07-24 10:39:10 +0100303 if (config.filters.wordFilter.enabled) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100304 const check = TestString(
305 content,
306 config.filters.wordFilter.words.loose,
307 config.filters.wordFilter.words.strict
308 );
309 if (check !== null) {
310 createLogException(
311 message.guild.id,
312 message.channel.id,
313 message.id
314 );
pineafan63fc5e22022-08-04 22:04:10 +0100315 await message.delete();
316 const data = {
pineafan813bdf42022-07-24 10:39:10 +0100317 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100318 type: "messageDelete",
319 displayName: "Message Deleted",
320 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +0100321 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100322 emoji: "MESSAGE.DELETE",
pineafan813bdf42022-07-24 10:39:10 +0100323 timestamp: new Date().getTime()
324 },
325 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100326 start:
327 filter +
328 " Message contained filtered word\n\n" +
329 (content
330 ? `**Message:**\n\`\`\`${content}\`\`\``
331 : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100332 },
333 list: list,
334 hidden: {
335 guild: message.channel.guild.id
336 }
pineafan63fc5e22022-08-04 22:04:10 +0100337 };
pineafan813bdf42022-07-24 10:39:10 +0100338 return log(data);
339 }
340 }
341
pineafane23c4ec2022-07-27 21:56:27 +0100342 if (config.filters.pings.everyone && message.mentions.everyone) {
pineafan63fc5e22022-08-04 22:04:10 +0100343 const data = {
pineafane23c4ec2022-07-27 21:56:27 +0100344 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100345 type: "everyonePing",
346 displayName: "Everyone Pinged",
347 calculateType: "messageMassPing",
pineafane23c4ec2022-07-27 21:56:27 +0100348 color: NucleusColors.yellow,
pineafan63fc5e22022-08-04 22:04:10 +0100349 emoji: "MESSAGE.PING.EVERYONE",
pineafane23c4ec2022-07-27 21:56:27 +0100350 timestamp: new Date().getTime()
351 },
352 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100353 start: content
354 ? `**Message:**\n\`\`\`${content}\`\`\``
355 : "**Message:** *Message had no content*"
pineafane23c4ec2022-07-27 21:56:27 +0100356 },
357 list: list,
358 hidden: {
359 guild: message.channel.guild.id
pineafan813bdf42022-07-24 10:39:10 +0100360 }
pineafan63fc5e22022-08-04 22:04:10 +0100361 };
pineafane23c4ec2022-07-27 21:56:27 +0100362 return log(data);
363 }
364 if (config.filters.pings.roles) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100365 for (const roleId in message.mentions.roles) {
366 if (!message) return;
pineafan63fc5e22022-08-04 22:04:10 +0100367 if (!config.filters.pings.allowed.roles.includes(roleId)) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100368 createLogException(
369 message.guild.id,
370 message.channel.id,
371 message.id
372 );
pineafan63fc5e22022-08-04 22:04:10 +0100373 await message.delete();
374 const data = {
pineafane23c4ec2022-07-27 21:56:27 +0100375 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100376 type: "rolePing",
377 displayName: "Role Pinged",
378 calculateType: "messageMassPing",
pineafane23c4ec2022-07-27 21:56:27 +0100379 color: NucleusColors.yellow,
pineafan63fc5e22022-08-04 22:04:10 +0100380 emoji: "MESSAGE.PING.ROLE",
pineafane23c4ec2022-07-27 21:56:27 +0100381 timestamp: new Date().getTime()
382 },
383 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100384 start: content
385 ? `**Message:**\n\`\`\`${content}\`\`\``
386 : "**Message:** *Message had no content*"
pineafane23c4ec2022-07-27 21:56:27 +0100387 },
388 list: list,
389 hidden: {
390 guild: message.channel.guild.id
pineafan813bdf42022-07-24 10:39:10 +0100391 }
pineafan63fc5e22022-08-04 22:04:10 +0100392 };
pineafane23c4ec2022-07-27 21:56:27 +0100393 return log(data);
pineafan813bdf42022-07-24 10:39:10 +0100394 }
395 }
pineafane23c4ec2022-07-27 21:56:27 +0100396 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100397 if (
398 message.mentions.users.size >= config.filters.pings.mass &&
399 config.filters.pings.mass
400 ) {
pineafan63fc5e22022-08-04 22:04:10 +0100401 createLogException(message.guild.id, message.channel.id, message.id);
402 await message.delete();
403 const data = {
pineafane23c4ec2022-07-27 21:56:27 +0100404 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100405 type: "massPing",
406 displayName: "Mass Ping",
407 calculateType: "messageMassPing",
pineafane23c4ec2022-07-27 21:56:27 +0100408 color: NucleusColors.yellow,
pineafan63fc5e22022-08-04 22:04:10 +0100409 emoji: "MESSAGE.PING.MASS",
pineafane23c4ec2022-07-27 21:56:27 +0100410 timestamp: new Date().getTime()
411 },
412 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100413 start: content
414 ? `**Message:**\n\`\`\`${content}\`\`\``
415 : "**Message:** *Message had no content*"
pineafane23c4ec2022-07-27 21:56:27 +0100416 },
417 list: list,
418 hidden: {
419 guild: message.channel.guild.id
pineafan813bdf42022-07-24 10:39:10 +0100420 }
pineafan63fc5e22022-08-04 22:04:10 +0100421 };
pineafane23c4ec2022-07-27 21:56:27 +0100422 return log(data);
pineafan813bdf42022-07-24 10:39:10 +0100423 }
424}