blob: 2f3a077171347915f767b771b73f2621e0de3a19 [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";
4import createLogException from "../utils/createLogException.js";
5import 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);
28 const filter = getEmojiByName("ICONS.FILTER");
29 let attachmentJump = "";
Skyler Grey75ea9172022-08-06 10:22:23 +010030 if (config.logging.attachments.saved[message.channel.id + message.id]) {
Skyler Grey11236ba2022-08-08 21:13:33 +010031 attachmentJump = ` [[View attachments]](${config.logging.attachments.saved[message.channel.id + message.id]})`;
Skyler Grey75ea9172022-08-06 10:22:23 +010032 }
pineafan63fc5e22022-08-04 22:04:10 +010033 const list = {
pineafan813bdf42022-07-24 10:39:10 +010034 messageId: entry(message.id, `\`${message.id}\``),
35 sentBy: entry(message.author.id, renderUser(message.author)),
36 sentIn: entry(message.channel.id, renderChannel(message.channel)),
37 deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
38 mentions: message.mentions.users.size,
Skyler Grey11236ba2022-08-08 21:13:33 +010039 attachments: entry(message.attachments.size, message.attachments.size + attachmentJump),
pineafan813bdf42022-07-24 10:39:10 +010040 repliedTo: entry(
PineaFan538d3752023-01-12 21:48:23 +000041 (message.reference ? message.reference.messageId : null) ?? null,
Skyler Grey75ea9172022-08-06 10:22:23 +010042 message.reference
43 ? `[[Jump to message]](https://discord.com/channels/${message.guild.id}/${message.channel.id}/${message.reference.messageId})`
44 : "None"
pineafan813bdf42022-07-24 10:39:10 +010045 )
pineafan63fc5e22022-08-04 22:04:10 +010046 };
pineafan813bdf42022-07-24 10:39:10 +010047
48 if (config.filters.invite.enabled) {
Skyler Grey11236ba2022-08-08 21:13:33 +010049 if (!config.filters.invite.allowed.channels.includes(message.channel.id)) {
50 if (/(?:https?:\/\/)?discord(?:app)?\.(?:com\/invite|gg)\/[a-zA-Z0-9]+\/?/.test(content)) {
51 createLogException(message.guild.id, message.channel.id, message.id);
pineafan813bdf42022-07-24 10:39:10 +010052 message.delete();
pineafan63fc5e22022-08-04 22:04:10 +010053 const data = {
pineafan813bdf42022-07-24 10:39:10 +010054 meta: {
pineafan63fc5e22022-08-04 22:04:10 +010055 type: "messageDelete",
Skyler Grey11236ba2022-08-08 21:13:33 +010056 displayName: "Message Deleted (Automated, Contained Invite)",
pineafan63fc5e22022-08-04 22:04:10 +010057 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +010058 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +010059 emoji: "MESSAGE.DELETE",
pineafan813bdf42022-07-24 10:39:10 +010060 timestamp: new Date().getTime()
61 },
62 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +010063 start:
64 filter +
65 " Contained invite\n\n" +
Skyler Grey11236ba2022-08-08 21:13:33 +010066 (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +010067 },
68 list: list,
69 hidden: {
70 guild: message.channel.guild.id
71 }
pineafan63fc5e22022-08-04 22:04:10 +010072 };
pineafan813bdf42022-07-24 10:39:10 +010073 return log(data);
74 }
75 }
76 }
77
78 if (fileNames.files.length > 0) {
pineafan63fc5e22022-08-04 22:04:10 +010079 for (const element of fileNames.files) {
pineafan63fc5e22022-08-04 22:04:10 +010080 const url = element.url ? element.url : element.local;
Skyler Grey11236ba2022-08-08 21:13:33 +010081 if (/\.(jpg|jpeg|png|gif|gifv|webm|webp|mp4|wav|mp3|ogg)$/.test(url)) {
Skyler Grey75ea9172022-08-06 10:22:23 +010082 if (
Skyler Greyc634e2b2022-08-06 17:50:48 +010083 config.filters.images.NSFW &&
Skyler Grey11236ba2022-08-08 21:13:33 +010084 !(message.channel instanceof ThreadChannel ? message.channel.parent?.nsfw : message.channel.nsfw)
Skyler Grey75ea9172022-08-06 10:22:23 +010085 ) {
Skyler Greyc634e2b2022-08-06 17:50:48 +010086 if (await NSFWCheck(url)) {
Skyler Grey11236ba2022-08-08 21:13:33 +010087 createLogException(message.guild.id, message.channel.id, message.id);
pineafan63fc5e22022-08-04 22:04:10 +010088 await message.delete();
89 const data = {
pineafan813bdf42022-07-24 10:39:10 +010090 meta: {
pineafan63fc5e22022-08-04 22:04:10 +010091 type: "messageDelete",
92 displayName: "Message Deleted",
93 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +010094 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +010095 emoji: "MESSAGE.DELETE",
pineafan813bdf42022-07-24 10:39:10 +010096 timestamp: new Date().getTime()
97 },
98 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +010099 start:
100 filter +
Skyler Greyc634e2b2022-08-06 17:50:48 +0100101 " Image detected as NSFW\n\n" +
Skyler Grey75ea9172022-08-06 10:22:23 +0100102 (content
103 ? `**Message:**\n\`\`\`${content}\`\`\``
104 : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100105 },
106 list: list,
107 hidden: {
108 guild: message.channel.guild.id
109 }
pineafan63fc5e22022-08-04 22:04:10 +0100110 };
pineafan813bdf42022-07-24 10:39:10 +0100111 return log(data);
112 }
113 }
Skyler Greyc634e2b2022-08-06 17:50:48 +0100114 if (config.filters.wordFilter.enabled) {
115 const text = await TestImage(url);
116 const check = TestString(
117 text ?? "",
118 config.filters.wordFilter.words.loose,
119 config.filters.wordFilter.words.strict
120 );
121 if (check !== null) {
Skyler Grey11236ba2022-08-08 21:13:33 +0100122 createLogException(message.guild.id, message.channel.id, message.id);
Skyler Greyc634e2b2022-08-06 17:50:48 +0100123 await message.delete();
124 const data = {
125 meta: {
126 type: "messageDelete",
127 displayName: "Message Deleted",
128 calculateType: "autoModeratorDeleted",
129 color: NucleusColors.red,
130 emoji: "MESSAGE.DELETE",
131 timestamp: new Date().getTime()
132 },
133 separate: {
134 start:
135 filter +
136 " Image contained filtered word\n\n" +
137 (content
138 ? `**Message:**\n\`\`\`${content}\`\`\``
139 : "**Message:** *Message had no content*")
140 },
141 list: list,
142 hidden: {
143 guild: message.channel.guild.id
144 }
145 };
146 return log(data);
147 }
148 }
149 if (config.filters.images.size) {
150 if (url.match(/\.+(webp|png|jpg)$/gi)) {
151 if (!(await SizeCheck(element))) {
Skyler Grey11236ba2022-08-08 21:13:33 +0100152 createLogException(message.guild.id, message.channel.id, message.id);
Skyler Greyc634e2b2022-08-06 17:50:48 +0100153 await message.delete();
154 const data = {
155 meta: {
156 type: "messageDelete",
157 displayName: "Message Deleted",
158 calculateType: "autoModeratorDeleted",
159 color: NucleusColors.red,
160 emoji: "MESSAGE.DELETE",
161 timestamp: new Date().getTime()
162 },
163 separate: {
164 start:
165 filter +
166 " Image was too small\n\n" +
167 (content
168 ? `**Message:**\n\`\`\`${content}\`\`\``
169 : "**Message:** *Message had no content*")
170 },
171 list: list,
172 hidden: {
173 guild: message.channel.guild.id
174 }
175 };
176 return log(data);
177 }
178 }
179 }
180 }
181 if (config.filters.malware) {
182 if (!(await MalwareCheck(url))) {
Skyler Grey11236ba2022-08-08 21:13:33 +0100183 createLogException(message.guild.id, message.channel.id, message.id);
Skyler Greyc634e2b2022-08-06 17:50:48 +0100184 await message.delete();
185 const data = {
186 meta: {
187 type: "messageDelete",
188 displayName: "Message Deleted",
189 calculateType: "autoModeratorDeleted",
190 color: NucleusColors.red,
191 emoji: "MESSAGE.DELETE",
192 timestamp: new Date().getTime()
193 },
194 separate: {
195 start:
196 filter +
197 " File detected as malware\n\n" +
198 (content
199 ? `**Message:**\n\`\`\`${content}\`\`\``
200 : "**Message:** *Message had no content*")
201 },
202 list: list,
203 hidden: {
204 guild: message.channel.guild.id
205 }
206 };
207 return log(data);
208 }
pineafan813bdf42022-07-24 10:39:10 +0100209 }
pineafan63fc5e22022-08-04 22:04:10 +0100210 }
pineafan813bdf42022-07-24 10:39:10 +0100211 }
pineafan813bdf42022-07-24 10:39:10 +0100212
pineafan63fc5e22022-08-04 22:04:10 +0100213 const linkDetectionTypes = await LinkCheck(message);
pineafan813bdf42022-07-24 10:39:10 +0100214 if (linkDetectionTypes.length > 0) {
pineafan63fc5e22022-08-04 22:04:10 +0100215 createLogException(message.guild.id, message.channel.id, message.id);
216 await message.delete();
217 const data = {
pineafan813bdf42022-07-24 10:39:10 +0100218 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100219 type: "messageDelete",
220 displayName: "Message Deleted",
221 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +0100222 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100223 emoji: "MESSAGE.DELETE",
pineafan813bdf42022-07-24 10:39:10 +0100224 timestamp: new Date().getTime()
225 },
226 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100227 start:
228 filter +
229 ` Link filtered as ${linkDetectionTypes[0]?.toLowerCase()}\n\n` +
Skyler Grey11236ba2022-08-08 21:13:33 +0100230 (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100231 },
232 list: list,
233 hidden: {
234 guild: message.channel.guild.id
235 }
pineafan63fc5e22022-08-04 22:04:10 +0100236 };
pineafan813bdf42022-07-24 10:39:10 +0100237 return log(data);
238 }
pineafane23c4ec2022-07-27 21:56:27 +0100239
pineafan813bdf42022-07-24 10:39:10 +0100240 if (config.filters.wordFilter.enabled) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100241 const check = TestString(
242 content,
243 config.filters.wordFilter.words.loose,
244 config.filters.wordFilter.words.strict
245 );
246 if (check !== null) {
Skyler Grey11236ba2022-08-08 21:13:33 +0100247 createLogException(message.guild.id, message.channel.id, message.id);
pineafan63fc5e22022-08-04 22:04:10 +0100248 await message.delete();
249 const data = {
pineafan813bdf42022-07-24 10:39:10 +0100250 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100251 type: "messageDelete",
252 displayName: "Message Deleted",
253 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +0100254 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100255 emoji: "MESSAGE.DELETE",
pineafan813bdf42022-07-24 10:39:10 +0100256 timestamp: new Date().getTime()
257 },
258 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100259 start:
260 filter +
261 " Message contained filtered word\n\n" +
Skyler Grey11236ba2022-08-08 21:13:33 +0100262 (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100263 },
264 list: list,
265 hidden: {
266 guild: message.channel.guild.id
267 }
pineafan63fc5e22022-08-04 22:04:10 +0100268 };
pineafan813bdf42022-07-24 10:39:10 +0100269 return log(data);
270 }
271 }
272
pineafane23c4ec2022-07-27 21:56:27 +0100273 if (config.filters.pings.everyone && message.mentions.everyone) {
pineafan63fc5e22022-08-04 22:04:10 +0100274 const data = {
pineafane23c4ec2022-07-27 21:56:27 +0100275 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100276 type: "everyonePing",
277 displayName: "Everyone Pinged",
278 calculateType: "messageMassPing",
pineafane23c4ec2022-07-27 21:56:27 +0100279 color: NucleusColors.yellow,
pineafan63fc5e22022-08-04 22:04:10 +0100280 emoji: "MESSAGE.PING.EVERYONE",
pineafane23c4ec2022-07-27 21:56:27 +0100281 timestamp: new Date().getTime()
282 },
283 separate: {
Skyler Grey11236ba2022-08-08 21:13:33 +0100284 start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*"
pineafane23c4ec2022-07-27 21:56:27 +0100285 },
286 list: list,
287 hidden: {
288 guild: message.channel.guild.id
pineafan813bdf42022-07-24 10:39:10 +0100289 }
pineafan63fc5e22022-08-04 22:04:10 +0100290 };
pineafane23c4ec2022-07-27 21:56:27 +0100291 return log(data);
292 }
293 if (config.filters.pings.roles) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100294 for (const roleId in message.mentions.roles) {
pineafan63fc5e22022-08-04 22:04:10 +0100295 if (!config.filters.pings.allowed.roles.includes(roleId)) {
Skyler Grey11236ba2022-08-08 21:13:33 +0100296 createLogException(message.guild.id, message.channel.id, message.id);
pineafan63fc5e22022-08-04 22:04:10 +0100297 await message.delete();
298 const data = {
pineafane23c4ec2022-07-27 21:56:27 +0100299 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100300 type: "rolePing",
301 displayName: "Role Pinged",
302 calculateType: "messageMassPing",
pineafane23c4ec2022-07-27 21:56:27 +0100303 color: NucleusColors.yellow,
pineafan63fc5e22022-08-04 22:04:10 +0100304 emoji: "MESSAGE.PING.ROLE",
pineafane23c4ec2022-07-27 21:56:27 +0100305 timestamp: new Date().getTime()
306 },
307 separate: {
Skyler Grey75ea9172022-08-06 10:22:23 +0100308 start: content
309 ? `**Message:**\n\`\`\`${content}\`\`\``
310 : "**Message:** *Message had no content*"
pineafane23c4ec2022-07-27 21:56:27 +0100311 },
312 list: list,
313 hidden: {
314 guild: message.channel.guild.id
pineafan813bdf42022-07-24 10:39:10 +0100315 }
pineafan63fc5e22022-08-04 22:04:10 +0100316 };
pineafane23c4ec2022-07-27 21:56:27 +0100317 return log(data);
pineafan813bdf42022-07-24 10:39:10 +0100318 }
319 }
pineafane23c4ec2022-07-27 21:56:27 +0100320 }
Skyler Grey11236ba2022-08-08 21:13:33 +0100321 if (message.mentions.users.size >= config.filters.pings.mass && config.filters.pings.mass) {
pineafan63fc5e22022-08-04 22:04:10 +0100322 createLogException(message.guild.id, message.channel.id, message.id);
323 await message.delete();
324 const data = {
pineafane23c4ec2022-07-27 21:56:27 +0100325 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100326 type: "massPing",
327 displayName: "Mass Ping",
328 calculateType: "messageMassPing",
pineafane23c4ec2022-07-27 21:56:27 +0100329 color: NucleusColors.yellow,
pineafan63fc5e22022-08-04 22:04:10 +0100330 emoji: "MESSAGE.PING.MASS",
pineafane23c4ec2022-07-27 21:56:27 +0100331 timestamp: new Date().getTime()
332 },
333 separate: {
Skyler Grey11236ba2022-08-08 21:13:33 +0100334 start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**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}