blob: 804e6eaf64c7173f824cf00c7ec8b2abf60d9cbe [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;
pineafan63fc5e22022-08-04 22:04:10 +010014 if (message.author.bot) return;
PineaFan538d3752023-01-12 21:48:23 +000015 if (message.channel.isDMBased()) return;
Skyler Grey75ea9172022-08-06 10:22:23 +010016 try {
pineafan0f5cc782022-08-12 21:55:42 +010017 await statsChannelUpdate(client, await message.guild.members.fetch(message.author.id));
Skyler Grey75ea9172022-08-06 10:22:23 +010018 } catch (e) {
19 console.log(e);
20 }
pineafan813bdf42022-07-24 10:39:10 +010021
Skyler Grey11236ba2022-08-08 21:13:33 +010022 const { log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;
pineafan813bdf42022-07-24 10:39:10 +010023
pineafan63fc5e22022-08-04 22:04:10 +010024 const fileNames = await logAttachment(message);
pineafan813bdf42022-07-24 10:39:10 +010025
pineafan63fc5e22022-08-04 22:04:10 +010026 const content = message.content.toLowerCase() || "";
27 const config = await client.memory.readGuildInfo(message.guild.id);
TheCodedProfad0b8202023-02-14 14:27:09 -050028 if(config.filters.clean.channels.includes(message.channel.id)) {
29 let memberRoles = message.member!.roles.cache.map(role => role.id);
30 let roleAllow = config.filters.clean.allowed.roles.some(role => memberRoles.includes(role));
31 let userAllow = config.filters.clean.allowed.user.includes(message.author.id);
32 if(!roleAllow && !userAllow) return await message.delete();
33 }
pineafan63fc5e22022-08-04 22:04:10 +010034 const filter = getEmojiByName("ICONS.FILTER");
35 let attachmentJump = "";
Skyler Grey75ea9172022-08-06 10:22:23 +010036 if (config.logging.attachments.saved[message.channel.id + message.id]) {
Skyler Grey11236ba2022-08-08 21:13:33 +010037 attachmentJump = ` [[View attachments]](${config.logging.attachments.saved[message.channel.id + message.id]})`;
Skyler Grey75ea9172022-08-06 10:22:23 +010038 }
pineafan63fc5e22022-08-04 22:04:10 +010039 const list = {
pineafan813bdf42022-07-24 10:39:10 +010040 messageId: entry(message.id, `\`${message.id}\``),
41 sentBy: entry(message.author.id, renderUser(message.author)),
42 sentIn: entry(message.channel.id, renderChannel(message.channel)),
43 deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
44 mentions: message.mentions.users.size,
Skyler Grey11236ba2022-08-08 21:13:33 +010045 attachments: entry(message.attachments.size, message.attachments.size + attachmentJump),
pineafan813bdf42022-07-24 10:39:10 +010046 repliedTo: entry(
PineaFan538d3752023-01-12 21:48:23 +000047 (message.reference ? message.reference.messageId : null) ?? null,
Skyler Grey75ea9172022-08-06 10:22:23 +010048 message.reference
49 ? `[[Jump to message]](https://discord.com/channels/${message.guild.id}/${message.channel.id}/${message.reference.messageId})`
50 : "None"
pineafan813bdf42022-07-24 10:39:10 +010051 )
pineafan63fc5e22022-08-04 22:04:10 +010052 };
pineafan813bdf42022-07-24 10:39:10 +010053
54 if (config.filters.invite.enabled) {
Skyler Grey11236ba2022-08-08 21:13:33 +010055 if (!config.filters.invite.allowed.channels.includes(message.channel.id)) {
56 if (/(?:https?:\/\/)?discord(?:app)?\.(?:com\/invite|gg)\/[a-zA-Z0-9]+\/?/.test(content)) {
PineaFan0d06edc2023-01-17 22:10:31 +000057 messageException(message.guild.id, message.channel.id, message.id);
pineafan813bdf42022-07-24 10:39:10 +010058 message.delete();
pineafan63fc5e22022-08-04 22:04:10 +010059 const data = {
pineafan813bdf42022-07-24 10:39:10 +010060 meta: {
pineafan63fc5e22022-08-04 22:04:10 +010061 type: "messageDelete",
Skyler Grey11236ba2022-08-08 21:13:33 +010062 displayName: "Message Deleted (Automated, Contained Invite)",
pineafan63fc5e22022-08-04 22:04:10 +010063 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +010064 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +010065 emoji: "MESSAGE.DELETE",
pineafan813bdf42022-07-24 10:39:10 +010066 timestamp: new Date().getTime()
67 },
68 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +010069 start:
70 filter +
71 " Contained invite\n\n" +
Skyler Grey11236ba2022-08-08 21:13:33 +010072 (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +010073 },
74 list: list,
75 hidden: {
76 guild: message.channel.guild.id
77 }
pineafan63fc5e22022-08-04 22:04:10 +010078 };
pineafan813bdf42022-07-24 10:39:10 +010079 return log(data);
80 }
81 }
82 }
83
84 if (fileNames.files.length > 0) {
pineafan63fc5e22022-08-04 22:04:10 +010085 for (const element of fileNames.files) {
pineafan63fc5e22022-08-04 22:04:10 +010086 const url = element.url ? element.url : element.local;
TheCodedProf16113672023-02-03 16:05:23 -050087 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())) {
88 // 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 +010089 if (
Skyler Greyc634e2b2022-08-06 17:50:48 +010090 config.filters.images.NSFW &&
Skyler Grey11236ba2022-08-08 21:13:33 +010091 !(message.channel instanceof ThreadChannel ? message.channel.parent?.nsfw : message.channel.nsfw)
Skyler Grey75ea9172022-08-06 10:22:23 +010092 ) {
Skyler Greyc634e2b2022-08-06 17:50:48 +010093 if (await NSFWCheck(url)) {
PineaFan0d06edc2023-01-17 22:10:31 +000094 messageException(message.guild.id, message.channel.id, message.id);
pineafan63fc5e22022-08-04 22:04:10 +010095 await message.delete();
96 const data = {
pineafan813bdf42022-07-24 10:39:10 +010097 meta: {
pineafan63fc5e22022-08-04 22:04:10 +010098 type: "messageDelete",
99 displayName: "Message Deleted",
100 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +0100101 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100102 emoji: "MESSAGE.DELETE",
pineafan813bdf42022-07-24 10:39:10 +0100103 timestamp: new Date().getTime()
104 },
105 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100106 start:
107 filter +
Skyler Greyc634e2b2022-08-06 17:50:48 +0100108 " Image detected as NSFW\n\n" +
Skyler Grey75ea9172022-08-06 10:22:23 +0100109 (content
110 ? `**Message:**\n\`\`\`${content}\`\`\``
111 : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100112 },
113 list: list,
114 hidden: {
115 guild: message.channel.guild.id
116 }
pineafan63fc5e22022-08-04 22:04:10 +0100117 };
pineafan813bdf42022-07-24 10:39:10 +0100118 return log(data);
119 }
120 }
Skyler Greyc634e2b2022-08-06 17:50:48 +0100121 if (config.filters.wordFilter.enabled) {
122 const text = await TestImage(url);
123 const check = TestString(
124 text ?? "",
125 config.filters.wordFilter.words.loose,
126 config.filters.wordFilter.words.strict
127 );
128 if (check !== null) {
PineaFan0d06edc2023-01-17 22:10:31 +0000129 messageException(message.guild.id, message.channel.id, message.id);
Skyler Greyc634e2b2022-08-06 17:50:48 +0100130 await message.delete();
131 const data = {
132 meta: {
133 type: "messageDelete",
134 displayName: "Message Deleted",
135 calculateType: "autoModeratorDeleted",
136 color: NucleusColors.red,
137 emoji: "MESSAGE.DELETE",
138 timestamp: new Date().getTime()
139 },
140 separate: {
141 start:
142 filter +
143 " Image contained filtered word\n\n" +
144 (content
145 ? `**Message:**\n\`\`\`${content}\`\`\``
146 : "**Message:** *Message had no content*")
147 },
148 list: list,
149 hidden: {
150 guild: message.channel.guild.id
151 }
152 };
153 return log(data);
154 }
155 }
156 if (config.filters.images.size) {
157 if (url.match(/\.+(webp|png|jpg)$/gi)) {
158 if (!(await SizeCheck(element))) {
PineaFan0d06edc2023-01-17 22:10:31 +0000159 messageException(message.guild.id, message.channel.id, message.id);
Skyler Greyc634e2b2022-08-06 17:50:48 +0100160 await message.delete();
161 const data = {
162 meta: {
163 type: "messageDelete",
164 displayName: "Message Deleted",
165 calculateType: "autoModeratorDeleted",
166 color: NucleusColors.red,
167 emoji: "MESSAGE.DELETE",
168 timestamp: new Date().getTime()
169 },
170 separate: {
171 start:
172 filter +
173 " Image was too small\n\n" +
174 (content
175 ? `**Message:**\n\`\`\`${content}\`\`\``
176 : "**Message:** *Message had no content*")
177 },
178 list: list,
179 hidden: {
180 guild: message.channel.guild.id
181 }
182 };
183 return log(data);
184 }
185 }
186 }
187 }
188 if (config.filters.malware) {
189 if (!(await MalwareCheck(url))) {
PineaFan0d06edc2023-01-17 22:10:31 +0000190 messageException(message.guild.id, message.channel.id, message.id);
Skyler Greyc634e2b2022-08-06 17:50:48 +0100191 await message.delete();
192 const data = {
193 meta: {
194 type: "messageDelete",
195 displayName: "Message Deleted",
196 calculateType: "autoModeratorDeleted",
197 color: NucleusColors.red,
198 emoji: "MESSAGE.DELETE",
199 timestamp: new Date().getTime()
200 },
201 separate: {
202 start:
203 filter +
204 " File detected as malware\n\n" +
205 (content
206 ? `**Message:**\n\`\`\`${content}\`\`\``
207 : "**Message:** *Message had no content*")
208 },
209 list: list,
210 hidden: {
211 guild: message.channel.guild.id
212 }
213 };
214 return log(data);
215 }
pineafan813bdf42022-07-24 10:39:10 +0100216 }
pineafan63fc5e22022-08-04 22:04:10 +0100217 }
pineafan813bdf42022-07-24 10:39:10 +0100218 }
pineafan813bdf42022-07-24 10:39:10 +0100219
pineafan63fc5e22022-08-04 22:04:10 +0100220 const linkDetectionTypes = await LinkCheck(message);
pineafan813bdf42022-07-24 10:39:10 +0100221 if (linkDetectionTypes.length > 0) {
PineaFan0d06edc2023-01-17 22:10:31 +0000222 messageException(message.guild.id, message.channel.id, message.id);
pineafan63fc5e22022-08-04 22:04:10 +0100223 await message.delete();
224 const data = {
pineafan813bdf42022-07-24 10:39:10 +0100225 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100226 type: "messageDelete",
227 displayName: "Message Deleted",
228 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +0100229 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100230 emoji: "MESSAGE.DELETE",
pineafan813bdf42022-07-24 10:39:10 +0100231 timestamp: new Date().getTime()
232 },
233 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100234 start:
235 filter +
236 ` Link filtered as ${linkDetectionTypes[0]?.toLowerCase()}\n\n` +
Skyler Grey11236ba2022-08-08 21:13:33 +0100237 (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100238 },
239 list: list,
240 hidden: {
241 guild: message.channel.guild.id
242 }
pineafan63fc5e22022-08-04 22:04:10 +0100243 };
pineafan813bdf42022-07-24 10:39:10 +0100244 return log(data);
245 }
pineafane23c4ec2022-07-27 21:56:27 +0100246
pineafan813bdf42022-07-24 10:39:10 +0100247 if (config.filters.wordFilter.enabled) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100248 const check = TestString(
249 content,
250 config.filters.wordFilter.words.loose,
251 config.filters.wordFilter.words.strict
252 );
253 if (check !== null) {
PineaFan0d06edc2023-01-17 22:10:31 +0000254 messageException(message.guild.id, message.channel.id, message.id);
pineafan63fc5e22022-08-04 22:04:10 +0100255 await message.delete();
256 const data = {
pineafan813bdf42022-07-24 10:39:10 +0100257 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100258 type: "messageDelete",
259 displayName: "Message Deleted",
260 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +0100261 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100262 emoji: "MESSAGE.DELETE",
pineafan813bdf42022-07-24 10:39:10 +0100263 timestamp: new Date().getTime()
264 },
265 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100266 start:
267 filter +
268 " Message contained filtered word\n\n" +
Skyler Grey11236ba2022-08-08 21:13:33 +0100269 (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100270 },
271 list: list,
272 hidden: {
273 guild: message.channel.guild.id
274 }
pineafan63fc5e22022-08-04 22:04:10 +0100275 };
pineafan813bdf42022-07-24 10:39:10 +0100276 return log(data);
277 }
278 }
279
pineafane23c4ec2022-07-27 21:56:27 +0100280 if (config.filters.pings.everyone && message.mentions.everyone) {
pineafan63fc5e22022-08-04 22:04:10 +0100281 const data = {
pineafane23c4ec2022-07-27 21:56:27 +0100282 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100283 type: "everyonePing",
284 displayName: "Everyone Pinged",
285 calculateType: "messageMassPing",
pineafane23c4ec2022-07-27 21:56:27 +0100286 color: NucleusColors.yellow,
pineafan63fc5e22022-08-04 22:04:10 +0100287 emoji: "MESSAGE.PING.EVERYONE",
pineafane23c4ec2022-07-27 21:56:27 +0100288 timestamp: new Date().getTime()
289 },
290 separate: {
Skyler Grey11236ba2022-08-08 21:13:33 +0100291 start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*"
pineafane23c4ec2022-07-27 21:56:27 +0100292 },
293 list: list,
294 hidden: {
295 guild: message.channel.guild.id
pineafan813bdf42022-07-24 10:39:10 +0100296 }
pineafan63fc5e22022-08-04 22:04:10 +0100297 };
pineafane23c4ec2022-07-27 21:56:27 +0100298 return log(data);
299 }
300 if (config.filters.pings.roles) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100301 for (const roleId in message.mentions.roles) {
pineafan63fc5e22022-08-04 22:04:10 +0100302 if (!config.filters.pings.allowed.roles.includes(roleId)) {
PineaFan0d06edc2023-01-17 22:10:31 +0000303 messageException(message.guild.id, message.channel.id, message.id);
pineafan63fc5e22022-08-04 22:04:10 +0100304 await message.delete();
305 const data = {
pineafane23c4ec2022-07-27 21:56:27 +0100306 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100307 type: "rolePing",
308 displayName: "Role Pinged",
309 calculateType: "messageMassPing",
pineafane23c4ec2022-07-27 21:56:27 +0100310 color: NucleusColors.yellow,
pineafan63fc5e22022-08-04 22:04:10 +0100311 emoji: "MESSAGE.PING.ROLE",
pineafane23c4ec2022-07-27 21:56:27 +0100312 timestamp: new Date().getTime()
313 },
314 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100315 start: content
316 ? `**Message:**\n\`\`\`${content}\`\`\``
317 : "**Message:** *Message had no content*"
pineafane23c4ec2022-07-27 21:56:27 +0100318 },
319 list: list,
320 hidden: {
321 guild: message.channel.guild.id
pineafan813bdf42022-07-24 10:39:10 +0100322 }
pineafan63fc5e22022-08-04 22:04:10 +0100323 };
pineafane23c4ec2022-07-27 21:56:27 +0100324 return log(data);
pineafan813bdf42022-07-24 10:39:10 +0100325 }
326 }
pineafane23c4ec2022-07-27 21:56:27 +0100327 }
Skyler Grey11236ba2022-08-08 21:13:33 +0100328 if (message.mentions.users.size >= config.filters.pings.mass && config.filters.pings.mass) {
PineaFan0d06edc2023-01-17 22:10:31 +0000329 messageException(message.guild.id, message.channel.id, message.id);
pineafan63fc5e22022-08-04 22:04:10 +0100330 await message.delete();
331 const data = {
pineafane23c4ec2022-07-27 21:56:27 +0100332 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100333 type: "massPing",
334 displayName: "Mass Ping",
335 calculateType: "messageMassPing",
pineafane23c4ec2022-07-27 21:56:27 +0100336 color: NucleusColors.yellow,
pineafan63fc5e22022-08-04 22:04:10 +0100337 emoji: "MESSAGE.PING.MASS",
pineafane23c4ec2022-07-27 21:56:27 +0100338 timestamp: new Date().getTime()
339 },
340 separate: {
Skyler Grey11236ba2022-08-08 21:13:33 +0100341 start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*"
pineafane23c4ec2022-07-27 21:56:27 +0100342 },
343 list: list,
344 hidden: {
345 guild: message.channel.guild.id
pineafan813bdf42022-07-24 10:39:10 +0100346 }
pineafan63fc5e22022-08-04 22:04:10 +0100347 };
pineafane23c4ec2022-07-27 21:56:27 +0100348 return log(data);
pineafan813bdf42022-07-24 10:39:10 +0100349 }
350}