blob: b106d61f79319ea2a6980d188e0544ed1124a24d [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 Grey3331c9f2023-03-05 07:34:15 +00008import { ChannelType, 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);
Skyler9f5fca82023-03-05 09:12:03 +000015
Skyler Greyda16adf2023-03-05 10:22:12 +000016 if (
17 config.autoPublish.enabled &&
18 config.autoPublish.channels.includes(message.channel.id) &&
19 message.channel.type === ChannelType.GuildAnnouncement &&
20 message.reference === null
Skyler9f5fca82023-03-05 09:12:03 +000021 ) {
PineappleFan13892c62023-03-05 07:00:07 +000022 await message.crosspost();
23 }
24
pineafan63fc5e22022-08-04 22:04:10 +010025 if (message.author.bot) return;
PineaFan538d3752023-01-12 21:48:23 +000026 if (message.channel.isDMBased()) return;
Skyler Grey75ea9172022-08-06 10:22:23 +010027 try {
pineafan0f5cc782022-08-12 21:55:42 +010028 await statsChannelUpdate(client, await message.guild.members.fetch(message.author.id));
Skyler Grey75ea9172022-08-06 10:22:23 +010029 } catch (e) {
30 console.log(e);
31 }
pineafan813bdf42022-07-24 10:39:10 +010032
TheCodedProf6ec331b2023-02-20 12:13:06 -050033 const { log, isLogging, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;
pineafan813bdf42022-07-24 10:39:10 +010034
pineafan63fc5e22022-08-04 22:04:10 +010035 const fileNames = await logAttachment(message);
pineafan813bdf42022-07-24 10:39:10 +010036
pineafan63fc5e22022-08-04 22:04:10 +010037 const content = message.content.toLowerCase() || "";
Skyler Greyda16adf2023-03-05 10:22:12 +000038 if (config.filters.clean.channels.includes(message.channel.id)) {
39 const memberRoles = message.member!.roles.cache.map((role) => role.id);
40 const roleAllow = config.filters.clean.allowed.roles.some((role) => memberRoles.includes(role));
TheCodedProff8ef7942023-03-03 15:32:32 -050041 const userAllow = config.filters.clean.allowed.users.includes(message.author.id);
Skyler Greyda16adf2023-03-05 10:22:12 +000042 if (!roleAllow && !userAllow) return await message.delete();
TheCodedProfad0b8202023-02-14 14:27:09 -050043 }
TheCodedProfbaee2c12023-02-18 16:11:06 -050044
pineafan63fc5e22022-08-04 22:04:10 +010045 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]) {
Skyler Grey11236ba2022-08-08 21:13:33 +010048 attachmentJump = ` [[View attachments]](${config.logging.attachments.saved[message.channel.id + message.id]})`;
Skyler Grey75ea9172022-08-06 10:22:23 +010049 }
pineafan63fc5e22022-08-04 22:04:10 +010050 const list = {
pineafan813bdf42022-07-24 10:39:10 +010051 messageId: entry(message.id, `\`${message.id}\``),
52 sentBy: entry(message.author.id, renderUser(message.author)),
53 sentIn: entry(message.channel.id, renderChannel(message.channel)),
TheCodedProf6ec331b2023-02-20 12:13:06 -050054 deleted: entry(Date.now(), renderDelta(Date.now())),
pineafan813bdf42022-07-24 10:39:10 +010055 mentions: message.mentions.users.size,
Skyler Grey11236ba2022-08-08 21:13:33 +010056 attachments: entry(message.attachments.size, message.attachments.size + attachmentJump),
pineafan813bdf42022-07-24 10:39:10 +010057 repliedTo: entry(
PineaFan538d3752023-01-12 21:48:23 +000058 (message.reference ? message.reference.messageId : null) ?? null,
Skyler Grey75ea9172022-08-06 10:22:23 +010059 message.reference
60 ? `[[Jump to message]](https://discord.com/channels/${message.guild.id}/${message.channel.id}/${message.reference.messageId})`
61 : "None"
pineafan813bdf42022-07-24 10:39:10 +010062 )
pineafan63fc5e22022-08-04 22:04:10 +010063 };
pineafan813bdf42022-07-24 10:39:10 +010064
65 if (config.filters.invite.enabled) {
Skyler Grey11236ba2022-08-08 21:13:33 +010066 if (!config.filters.invite.allowed.channels.includes(message.channel.id)) {
67 if (/(?:https?:\/\/)?discord(?:app)?\.(?:com\/invite|gg)\/[a-zA-Z0-9]+\/?/.test(content)) {
PineaFan0d06edc2023-01-17 22:10:31 +000068 messageException(message.guild.id, message.channel.id, message.id);
pineafan813bdf42022-07-24 10:39:10 +010069 message.delete();
pineafan63fc5e22022-08-04 22:04:10 +010070 const data = {
pineafan813bdf42022-07-24 10:39:10 +010071 meta: {
pineafan63fc5e22022-08-04 22:04:10 +010072 type: "messageDelete",
Skyler Grey11236ba2022-08-08 21:13:33 +010073 displayName: "Message Deleted (Automated, Contained Invite)",
pineafan63fc5e22022-08-04 22:04:10 +010074 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +010075 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +010076 emoji: "MESSAGE.DELETE",
TheCodedProf6ec331b2023-02-20 12:13:06 -050077 timestamp: Date.now()
pineafan813bdf42022-07-24 10:39:10 +010078 },
79 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +010080 start:
81 filter +
82 " Contained invite\n\n" +
Skyler Grey11236ba2022-08-08 21:13:33 +010083 (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +010084 },
85 list: list,
86 hidden: {
87 guild: message.channel.guild.id
88 }
pineafan63fc5e22022-08-04 22:04:10 +010089 };
pineafan813bdf42022-07-24 10:39:10 +010090 return log(data);
91 }
92 }
93 }
94
95 if (fileNames.files.length > 0) {
pineafan63fc5e22022-08-04 22:04:10 +010096 for (const element of fileNames.files) {
pineafan63fc5e22022-08-04 22:04:10 +010097 const url = element.url ? element.url : element.local;
Skyler Greyda16adf2023-03-05 10:22:12 +000098 if (
99 /\.(j(pe?g|fif)|a?png|gifv?|w(eb[mp]|av)|mp([34]|eg-\d)|ogg|avi|h\.26(4|5)|cda)$/.test(
100 url.toLowerCase()
101 )
102 ) {
TheCodedProf16113672023-02-03 16:05:23 -0500103 // 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 +0100104 if (
Skyler Greyc634e2b2022-08-06 17:50:48 +0100105 config.filters.images.NSFW &&
Skyler Grey11236ba2022-08-08 21:13:33 +0100106 !(message.channel instanceof ThreadChannel ? message.channel.parent?.nsfw : message.channel.nsfw)
Skyler Grey75ea9172022-08-06 10:22:23 +0100107 ) {
Skyler Greyc634e2b2022-08-06 17:50:48 +0100108 if (await NSFWCheck(url)) {
PineaFan0d06edc2023-01-17 22:10:31 +0000109 messageException(message.guild.id, message.channel.id, message.id);
pineafan63fc5e22022-08-04 22:04:10 +0100110 await message.delete();
111 const data = {
pineafan813bdf42022-07-24 10:39:10 +0100112 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100113 type: "messageDelete",
114 displayName: "Message Deleted",
115 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +0100116 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100117 emoji: "MESSAGE.DELETE",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500118 timestamp: Date.now()
pineafan813bdf42022-07-24 10:39:10 +0100119 },
120 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100121 start:
122 filter +
Skyler Greyc634e2b2022-08-06 17:50:48 +0100123 " Image detected as NSFW\n\n" +
Skyler Grey75ea9172022-08-06 10:22:23 +0100124 (content
125 ? `**Message:**\n\`\`\`${content}\`\`\``
126 : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100127 },
128 list: list,
129 hidden: {
130 guild: message.channel.guild.id
131 }
pineafan63fc5e22022-08-04 22:04:10 +0100132 };
pineafan813bdf42022-07-24 10:39:10 +0100133 return log(data);
134 }
135 }
Skyler Greyc634e2b2022-08-06 17:50:48 +0100136 if (config.filters.wordFilter.enabled) {
137 const text = await TestImage(url);
138 const check = TestString(
139 text ?? "",
140 config.filters.wordFilter.words.loose,
141 config.filters.wordFilter.words.strict
142 );
143 if (check !== null) {
PineaFan0d06edc2023-01-17 22:10:31 +0000144 messageException(message.guild.id, message.channel.id, message.id);
Skyler Greyc634e2b2022-08-06 17:50:48 +0100145 await message.delete();
146 const data = {
147 meta: {
148 type: "messageDelete",
149 displayName: "Message Deleted",
150 calculateType: "autoModeratorDeleted",
151 color: NucleusColors.red,
152 emoji: "MESSAGE.DELETE",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500153 timestamp: Date.now()
Skyler Greyc634e2b2022-08-06 17:50:48 +0100154 },
155 separate: {
156 start:
157 filter +
158 " Image contained filtered word\n\n" +
159 (content
160 ? `**Message:**\n\`\`\`${content}\`\`\``
161 : "**Message:** *Message had no content*")
162 },
163 list: list,
164 hidden: {
165 guild: message.channel.guild.id
166 }
167 };
168 return log(data);
169 }
170 }
171 if (config.filters.images.size) {
172 if (url.match(/\.+(webp|png|jpg)$/gi)) {
173 if (!(await SizeCheck(element))) {
PineaFan0d06edc2023-01-17 22:10:31 +0000174 messageException(message.guild.id, message.channel.id, message.id);
Skyler Greyc634e2b2022-08-06 17:50:48 +0100175 await message.delete();
176 const data = {
177 meta: {
178 type: "messageDelete",
179 displayName: "Message Deleted",
180 calculateType: "autoModeratorDeleted",
181 color: NucleusColors.red,
182 emoji: "MESSAGE.DELETE",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500183 timestamp: Date.now()
Skyler Greyc634e2b2022-08-06 17:50:48 +0100184 },
185 separate: {
186 start:
187 filter +
188 " Image was too small\n\n" +
189 (content
190 ? `**Message:**\n\`\`\`${content}\`\`\``
191 : "**Message:** *Message had no content*")
192 },
193 list: list,
194 hidden: {
195 guild: message.channel.guild.id
196 }
197 };
198 return log(data);
199 }
200 }
201 }
202 }
203 if (config.filters.malware) {
204 if (!(await MalwareCheck(url))) {
PineaFan0d06edc2023-01-17 22:10:31 +0000205 messageException(message.guild.id, message.channel.id, message.id);
Skyler Greyc634e2b2022-08-06 17:50:48 +0100206 await message.delete();
207 const data = {
208 meta: {
209 type: "messageDelete",
210 displayName: "Message Deleted",
211 calculateType: "autoModeratorDeleted",
212 color: NucleusColors.red,
213 emoji: "MESSAGE.DELETE",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500214 timestamp: Date.now()
Skyler Greyc634e2b2022-08-06 17:50:48 +0100215 },
216 separate: {
217 start:
218 filter +
219 " File detected as malware\n\n" +
220 (content
221 ? `**Message:**\n\`\`\`${content}\`\`\``
222 : "**Message:** *Message had no content*")
223 },
224 list: list,
225 hidden: {
226 guild: message.channel.guild.id
227 }
228 };
229 return log(data);
230 }
pineafan813bdf42022-07-24 10:39:10 +0100231 }
pineafan63fc5e22022-08-04 22:04:10 +0100232 }
pineafan813bdf42022-07-24 10:39:10 +0100233 }
pineafan813bdf42022-07-24 10:39:10 +0100234
pineafan63fc5e22022-08-04 22:04:10 +0100235 const linkDetectionTypes = await LinkCheck(message);
pineafan813bdf42022-07-24 10:39:10 +0100236 if (linkDetectionTypes.length > 0) {
PineaFan0d06edc2023-01-17 22:10:31 +0000237 messageException(message.guild.id, message.channel.id, message.id);
pineafan63fc5e22022-08-04 22:04:10 +0100238 await message.delete();
239 const data = {
pineafan813bdf42022-07-24 10:39:10 +0100240 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100241 type: "messageDelete",
242 displayName: "Message Deleted",
243 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +0100244 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100245 emoji: "MESSAGE.DELETE",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500246 timestamp: Date.now()
pineafan813bdf42022-07-24 10:39:10 +0100247 },
248 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100249 start:
250 filter +
251 ` Link filtered as ${linkDetectionTypes[0]?.toLowerCase()}\n\n` +
Skyler Grey11236ba2022-08-08 21:13:33 +0100252 (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100253 },
254 list: list,
255 hidden: {
256 guild: message.channel.guild.id
257 }
pineafan63fc5e22022-08-04 22:04:10 +0100258 };
pineafan813bdf42022-07-24 10:39:10 +0100259 return log(data);
260 }
pineafane23c4ec2022-07-27 21:56:27 +0100261
pineafan813bdf42022-07-24 10:39:10 +0100262 if (config.filters.wordFilter.enabled) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100263 const check = TestString(
264 content,
265 config.filters.wordFilter.words.loose,
266 config.filters.wordFilter.words.strict
267 );
268 if (check !== null) {
PineaFan0d06edc2023-01-17 22:10:31 +0000269 messageException(message.guild.id, message.channel.id, message.id);
pineafan63fc5e22022-08-04 22:04:10 +0100270 await message.delete();
271 const data = {
pineafan813bdf42022-07-24 10:39:10 +0100272 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100273 type: "messageDelete",
274 displayName: "Message Deleted",
275 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +0100276 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100277 emoji: "MESSAGE.DELETE",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500278 timestamp: Date.now()
pineafan813bdf42022-07-24 10:39:10 +0100279 },
280 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100281 start:
282 filter +
283 " Message contained filtered word\n\n" +
Skyler Grey11236ba2022-08-08 21:13:33 +0100284 (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100285 },
286 list: list,
287 hidden: {
288 guild: message.channel.guild.id
289 }
pineafan63fc5e22022-08-04 22:04:10 +0100290 };
pineafan813bdf42022-07-24 10:39:10 +0100291 return log(data);
292 }
293 }
294
pineafane23c4ec2022-07-27 21:56:27 +0100295 if (config.filters.pings.everyone && message.mentions.everyone) {
Skyler Greyda16adf2023-03-05 10:22:12 +0000296 if (!(await isLogging(message.guild.id, "messageMassPing"))) return;
pineafan63fc5e22022-08-04 22:04:10 +0100297 const data = {
pineafane23c4ec2022-07-27 21:56:27 +0100298 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100299 type: "everyonePing",
300 displayName: "Everyone Pinged",
301 calculateType: "messageMassPing",
pineafane23c4ec2022-07-27 21:56:27 +0100302 color: NucleusColors.yellow,
pineafan63fc5e22022-08-04 22:04:10 +0100303 emoji: "MESSAGE.PING.EVERYONE",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500304 timestamp: Date.now()
pineafane23c4ec2022-07-27 21:56:27 +0100305 },
306 separate: {
Skyler Grey11236ba2022-08-08 21:13:33 +0100307 start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*"
pineafane23c4ec2022-07-27 21:56:27 +0100308 },
309 list: list,
310 hidden: {
311 guild: message.channel.guild.id
pineafan813bdf42022-07-24 10:39:10 +0100312 }
pineafan63fc5e22022-08-04 22:04:10 +0100313 };
pineafane23c4ec2022-07-27 21:56:27 +0100314 return log(data);
315 }
316 if (config.filters.pings.roles) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100317 for (const roleId in message.mentions.roles) {
pineafan63fc5e22022-08-04 22:04:10 +0100318 if (!config.filters.pings.allowed.roles.includes(roleId)) {
PineaFan0d06edc2023-01-17 22:10:31 +0000319 messageException(message.guild.id, message.channel.id, message.id);
pineafan63fc5e22022-08-04 22:04:10 +0100320 await message.delete();
Skyler Greyda16adf2023-03-05 10:22:12 +0000321 if (!(await isLogging(message.guild.id, "messageMassPing"))) return;
pineafan63fc5e22022-08-04 22:04:10 +0100322 const data = {
pineafane23c4ec2022-07-27 21:56:27 +0100323 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100324 type: "rolePing",
325 displayName: "Role Pinged",
326 calculateType: "messageMassPing",
pineafane23c4ec2022-07-27 21:56:27 +0100327 color: NucleusColors.yellow,
pineafan63fc5e22022-08-04 22:04:10 +0100328 emoji: "MESSAGE.PING.ROLE",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500329 timestamp: Date.now()
pineafane23c4ec2022-07-27 21:56:27 +0100330 },
331 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100332 start: content
333 ? `**Message:**\n\`\`\`${content}\`\`\``
334 : "**Message:** *Message had no content*"
pineafane23c4ec2022-07-27 21:56:27 +0100335 },
336 list: list,
337 hidden: {
338 guild: message.channel.guild.id
pineafan813bdf42022-07-24 10:39:10 +0100339 }
pineafan63fc5e22022-08-04 22:04:10 +0100340 };
pineafane23c4ec2022-07-27 21:56:27 +0100341 return log(data);
pineafan813bdf42022-07-24 10:39:10 +0100342 }
343 }
pineafane23c4ec2022-07-27 21:56:27 +0100344 }
Skyler Grey11236ba2022-08-08 21:13:33 +0100345 if (message.mentions.users.size >= config.filters.pings.mass && config.filters.pings.mass) {
PineaFan0d06edc2023-01-17 22:10:31 +0000346 messageException(message.guild.id, message.channel.id, message.id);
pineafan63fc5e22022-08-04 22:04:10 +0100347 await message.delete();
Skyler Greyda16adf2023-03-05 10:22:12 +0000348 if (!(await isLogging(message.guild.id, "messageMassPing"))) return;
pineafan63fc5e22022-08-04 22:04:10 +0100349 const data = {
pineafane23c4ec2022-07-27 21:56:27 +0100350 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100351 type: "massPing",
352 displayName: "Mass Ping",
353 calculateType: "messageMassPing",
pineafane23c4ec2022-07-27 21:56:27 +0100354 color: NucleusColors.yellow,
pineafan63fc5e22022-08-04 22:04:10 +0100355 emoji: "MESSAGE.PING.MASS",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500356 timestamp: Date.now()
pineafane23c4ec2022-07-27 21:56:27 +0100357 },
358 separate: {
Skyler Grey11236ba2022-08-08 21:13:33 +0100359 start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*"
pineafane23c4ec2022-07-27 21:56:27 +0100360 },
361 list: list,
362 hidden: {
363 guild: message.channel.guild.id
pineafan813bdf42022-07-24 10:39:10 +0100364 }
pineafan63fc5e22022-08-04 22:04:10 +0100365 };
pineafane23c4ec2022-07-27 21:56:27 +0100366 return log(data);
pineafan813bdf42022-07-24 10:39:10 +0100367 }
368}