blob: bbb6a32e3b1b13986b55e286cd68c2c21dbfeb01 [file] [log] [blame]
pineafan63fc5e22022-08-04 22:04:10 +01001// eslint-disable-next-line @typescript-eslint/ban-ts-comment
2// @ts-ignore
3import { HaikuClient } from "jshaiku";
4import { LinkCheck, MalwareCheck, NSFWCheck, SizeCheck, TestString, TestImage } from "../reflex/scanners.js";
5import logAttachment from "../premium/attachmentLogs.js";
6import createLogException from "../utils/createLogException.js";
7import getEmojiByName from "../utils/getEmojiByName.js";
8import client from "../utils/client.js";
9import {callback as a} from "../reflex/statsChannelUpdate.js";
10import type { Message } from "discord.js";
pineafan813bdf42022-07-24 10:39:10 +010011
pineafan63fc5e22022-08-04 22:04:10 +010012export const event = "messageCreate";
pineafan813bdf42022-07-24 10:39:10 +010013
pineafan63fc5e22022-08-04 22:04:10 +010014export async function callback(_client: HaikuClient, message: Message) {
pineafan813bdf42022-07-24 10:39:10 +010015 if(!message) return;
pineafan63fc5e22022-08-04 22:04:10 +010016 if(!message.guild) return;
17 if (message.author.bot) return;
18 if (message.channel.type === "DM") return;
19 try { await a(client, await message.guild.members.fetch(message.author.id)); } catch(e) { console.log(e);}
pineafan813bdf42022-07-24 10:39:10 +010020
pineafan63fc5e22022-08-04 22:04:10 +010021 const { log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;
pineafan813bdf42022-07-24 10:39:10 +010022
pineafan63fc5e22022-08-04 22:04:10 +010023 const fileNames = await logAttachment(message);
pineafan813bdf42022-07-24 10:39:10 +010024
pineafan63fc5e22022-08-04 22:04:10 +010025 const content = message.content.toLowerCase() || "";
26 const config = await client.memory.readGuildInfo(message.guild.id);
27 const filter = getEmojiByName("ICONS.FILTER");
28 let attachmentJump = "";
29 if (config.logging.attachments.saved[message.channel.id + message.id]) { attachmentJump = ` [[View attachments]](${config.logging.attachments.saved[message.channel.id + message.id]})`; }
30 const list = {
pineafan813bdf42022-07-24 10:39:10 +010031 messageId: entry(message.id, `\`${message.id}\``),
32 sentBy: entry(message.author.id, renderUser(message.author)),
33 sentIn: entry(message.channel.id, renderChannel(message.channel)),
34 deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
35 mentions: message.mentions.users.size,
36 attachments: entry(message.attachments.size, message.attachments.size + attachmentJump),
37 repliedTo: entry(
38 message.reference ? message.reference.messageId : null,
39 message.reference ? `[[Jump to message]](https://discord.com/channels/${message.guild.id}/${message.channel.id}/${message.reference.messageId})` : "None"
40 )
pineafan63fc5e22022-08-04 22:04:10 +010041 };
pineafan813bdf42022-07-24 10:39:10 +010042
43 if (config.filters.invite.enabled) {
pineafan63fc5e22022-08-04 22:04:10 +010044 if (!config.filters.invite.allowed.channels.includes(message.channel.id)) {
pineafan813bdf42022-07-24 10:39:10 +010045 if ((/(?:https?:\/\/)?discord(?:app)?\.(?:com\/invite|gg)\/[a-zA-Z0-9]+\/?/.test(content))) {
pineafan63fc5e22022-08-04 22:04:10 +010046 createLogException(message.guild.id, message.channel.id, message.id);
pineafan813bdf42022-07-24 10:39:10 +010047 message.delete();
pineafan63fc5e22022-08-04 22:04:10 +010048 const data = {
pineafan813bdf42022-07-24 10:39:10 +010049 meta: {
pineafan63fc5e22022-08-04 22:04:10 +010050 type: "messageDelete",
51 displayName: "Message Deleted (Automated, Contained Invite)",
52 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +010053 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +010054 emoji: "MESSAGE.DELETE",
pineafan813bdf42022-07-24 10:39:10 +010055 timestamp: new Date().getTime()
56 },
57 separate: {
pineafan63fc5e22022-08-04 22:04:10 +010058 start: filter + " Contained invite\n\n" + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +010059 },
60 list: list,
61 hidden: {
62 guild: message.channel.guild.id
63 }
pineafan63fc5e22022-08-04 22:04:10 +010064 };
pineafan813bdf42022-07-24 10:39:10 +010065 return log(data);
66 }
67 }
68 }
69
70 if (fileNames.files.length > 0) {
pineafan63fc5e22022-08-04 22:04:10 +010071 for (const element of fileNames.files) {
pineafan813bdf42022-07-24 10:39:10 +010072 if(!message) return;
pineafan63fc5e22022-08-04 22:04:10 +010073 const url = element.url ? element.url : element.local;
pineafane23c4ec2022-07-27 21:56:27 +010074 if (url !== undefined) {
pineafan813bdf42022-07-24 10:39:10 +010075 if(/\.(jpg|jpeg|png|gif|gifv|webm|webp|mp4|wav|mp3|ogg)$/.test(url)) {
pineafan63fc5e22022-08-04 22:04:10 +010076 if (config.filters.images.NSFW && !(
77 message.channel.type === "GUILD_PUBLIC_THREAD" ? false : message.channel.nsfw
78 )) {
pineafan813bdf42022-07-24 10:39:10 +010079 if (await NSFWCheck(url)) {
pineafan63fc5e22022-08-04 22:04:10 +010080 createLogException(message.guild.id, message.channel.id, message.id);
81 await message.delete();
82 const data = {
pineafan813bdf42022-07-24 10:39:10 +010083 meta: {
pineafan63fc5e22022-08-04 22:04:10 +010084 type: "messageDelete",
85 displayName: "Message Deleted",
86 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +010087 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +010088 emoji: "MESSAGE.DELETE",
pineafan813bdf42022-07-24 10:39:10 +010089 timestamp: new Date().getTime()
90 },
91 separate: {
pineafan63fc5e22022-08-04 22:04:10 +010092 start: filter + " Image detected as NSFW\n\n" + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +010093 },
94 list: list,
95 hidden: {
96 guild: message.channel.guild.id
97 }
pineafan63fc5e22022-08-04 22:04:10 +010098 };
pineafan813bdf42022-07-24 10:39:10 +010099 return log(data);
100 }
101 }
102 if (config.filters.wordFilter.enabled) {
pineafan63fc5e22022-08-04 22:04:10 +0100103 const text = await TestImage(url);
104 const check = TestString(text ?? "", config.filters.wordFilter.words.loose, config.filters.wordFilter.words.strict);
pineafane23c4ec2022-07-27 21:56:27 +0100105 if(check !== null) {
pineafan63fc5e22022-08-04 22:04:10 +0100106 createLogException(message.guild.id, message.channel.id, message.id);
107 await message.delete();
108 const data = {
pineafane23c4ec2022-07-27 21:56:27 +0100109 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100110 type: "messageDelete",
111 displayName: "Message Deleted",
112 calculateType: "autoModeratorDeleted",
pineafane23c4ec2022-07-27 21:56:27 +0100113 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100114 emoji: "MESSAGE.DELETE",
pineafane23c4ec2022-07-27 21:56:27 +0100115 timestamp: new Date().getTime()
116 },
117 separate: {
pineafan63fc5e22022-08-04 22:04:10 +0100118 start: filter + " Image contained filtered word\n\n" + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
pineafane23c4ec2022-07-27 21:56:27 +0100119 },
120 list: list,
121 hidden: {
122 guild: message.channel.guild.id
pineafan813bdf42022-07-24 10:39:10 +0100123 }
pineafan63fc5e22022-08-04 22:04:10 +0100124 };
pineafane23c4ec2022-07-27 21:56:27 +0100125 return log(data);
pineafan813bdf42022-07-24 10:39:10 +0100126 }
127 }
128 if (config.filters.images.size) {
129 if(url.match(/\.+(webp|png|jpg)$/gi)) {
130 if(!await SizeCheck(element)) {
pineafan63fc5e22022-08-04 22:04:10 +0100131 createLogException(message.guild.id, message.channel.id, message.id);
132 await message.delete();
133 const data = {
pineafan813bdf42022-07-24 10:39:10 +0100134 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100135 type: "messageDelete",
136 displayName: "Message Deleted",
137 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +0100138 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100139 emoji: "MESSAGE.DELETE",
pineafan813bdf42022-07-24 10:39:10 +0100140 timestamp: new Date().getTime()
141 },
142 separate: {
pineafan63fc5e22022-08-04 22:04:10 +0100143 start: filter + " Image was too small\n\n" + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100144 },
145 list: list,
146 hidden: {
147 guild: message.channel.guild.id
148 }
pineafan63fc5e22022-08-04 22:04:10 +0100149 };
pineafan813bdf42022-07-24 10:39:10 +0100150 return log(data);
151 }
152 }
153 }
154 }
155 if (config.filters.malware) {
156 if (!MalwareCheck(url)) {
pineafan63fc5e22022-08-04 22:04:10 +0100157 createLogException(message.guild.id, message.channel.id, message.id);
158 await message.delete();
159 const data = {
pineafan813bdf42022-07-24 10:39:10 +0100160 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100161 type: "messageDelete",
162 displayName: "Message Deleted",
163 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +0100164 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100165 emoji: "MESSAGE.DELETE",
pineafan813bdf42022-07-24 10:39:10 +0100166 timestamp: new Date().getTime()
167 },
168 separate: {
pineafan63fc5e22022-08-04 22:04:10 +0100169 start: filter + " File detected as malware\n\n" + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100170 },
171 list: list,
172 hidden: {
173 guild: message.channel.guild.id
174 }
pineafan63fc5e22022-08-04 22:04:10 +0100175 };
pineafan813bdf42022-07-24 10:39:10 +0100176 return log(data);
177 }
178 }
179 }
pineafan63fc5e22022-08-04 22:04:10 +0100180 }
pineafan813bdf42022-07-24 10:39:10 +0100181 }
182 if(!message) return;
183
pineafan63fc5e22022-08-04 22:04:10 +0100184 const linkDetectionTypes = await LinkCheck(message);
pineafan813bdf42022-07-24 10:39:10 +0100185 if (linkDetectionTypes.length > 0) {
pineafan63fc5e22022-08-04 22:04:10 +0100186 createLogException(message.guild.id, message.channel.id, message.id);
187 await message.delete();
188 const data = {
pineafan813bdf42022-07-24 10:39:10 +0100189 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100190 type: "messageDelete",
191 displayName: "Message Deleted",
192 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +0100193 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100194 emoji: "MESSAGE.DELETE",
pineafan813bdf42022-07-24 10:39:10 +0100195 timestamp: new Date().getTime()
196 },
197 separate: {
pineafan63fc5e22022-08-04 22:04:10 +0100198 start: filter + ` Link filtered as ${linkDetectionTypes[0]?.toLowerCase()}\n\n` + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100199 },
200 list: list,
201 hidden: {
202 guild: message.channel.guild.id
203 }
pineafan63fc5e22022-08-04 22:04:10 +0100204 };
pineafan813bdf42022-07-24 10:39:10 +0100205 return log(data);
206 }
pineafane23c4ec2022-07-27 21:56:27 +0100207
pineafan813bdf42022-07-24 10:39:10 +0100208 if (config.filters.wordFilter.enabled) {
pineafan63fc5e22022-08-04 22:04:10 +0100209 const check = TestString(content, config.filters.wordFilter.words.loose, config.filters.wordFilter.words.strict);
pineafan813bdf42022-07-24 10:39:10 +0100210 if(check !== null) {
pineafan63fc5e22022-08-04 22:04:10 +0100211 createLogException(message.guild.id, message.channel.id, message.id);
212 await message.delete();
213 const data = {
pineafan813bdf42022-07-24 10:39:10 +0100214 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100215 type: "messageDelete",
216 displayName: "Message Deleted",
217 calculateType: "autoModeratorDeleted",
pineafan813bdf42022-07-24 10:39:10 +0100218 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100219 emoji: "MESSAGE.DELETE",
pineafan813bdf42022-07-24 10:39:10 +0100220 timestamp: new Date().getTime()
221 },
222 separate: {
pineafan63fc5e22022-08-04 22:04:10 +0100223 start: filter + " Message contained filtered word\n\n" + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
pineafan813bdf42022-07-24 10:39:10 +0100224 },
225 list: list,
226 hidden: {
227 guild: message.channel.guild.id
228 }
pineafan63fc5e22022-08-04 22:04:10 +0100229 };
pineafan813bdf42022-07-24 10:39:10 +0100230 return log(data);
231 }
232 }
233
pineafane23c4ec2022-07-27 21:56:27 +0100234 if (config.filters.pings.everyone && message.mentions.everyone) {
pineafan63fc5e22022-08-04 22:04:10 +0100235 const data = {
pineafane23c4ec2022-07-27 21:56:27 +0100236 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100237 type: "everyonePing",
238 displayName: "Everyone Pinged",
239 calculateType: "messageMassPing",
pineafane23c4ec2022-07-27 21:56:27 +0100240 color: NucleusColors.yellow,
pineafan63fc5e22022-08-04 22:04:10 +0100241 emoji: "MESSAGE.PING.EVERYONE",
pineafane23c4ec2022-07-27 21:56:27 +0100242 timestamp: new Date().getTime()
243 },
244 separate: {
pineafan63fc5e22022-08-04 22:04:10 +0100245 start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*"
pineafane23c4ec2022-07-27 21:56:27 +0100246 },
247 list: list,
248 hidden: {
249 guild: message.channel.guild.id
pineafan813bdf42022-07-24 10:39:10 +0100250 }
pineafan63fc5e22022-08-04 22:04:10 +0100251 };
pineafane23c4ec2022-07-27 21:56:27 +0100252 return log(data);
253 }
254 if (config.filters.pings.roles) {
pineafan63fc5e22022-08-04 22:04:10 +0100255 for(const roleId in message.mentions.roles) {
pineafane23c4ec2022-07-27 21:56:27 +0100256 if(!message) return;
pineafan63fc5e22022-08-04 22:04:10 +0100257 if (!config.filters.pings.allowed.roles.includes(roleId)) {
258 createLogException(message.guild.id, message.channel.id, message.id);
259 await message.delete();
260 const data = {
pineafane23c4ec2022-07-27 21:56:27 +0100261 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100262 type: "rolePing",
263 displayName: "Role Pinged",
264 calculateType: "messageMassPing",
pineafane23c4ec2022-07-27 21:56:27 +0100265 color: NucleusColors.yellow,
pineafan63fc5e22022-08-04 22:04:10 +0100266 emoji: "MESSAGE.PING.ROLE",
pineafane23c4ec2022-07-27 21:56:27 +0100267 timestamp: new Date().getTime()
268 },
269 separate: {
pineafan63fc5e22022-08-04 22:04:10 +0100270 start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*"
pineafane23c4ec2022-07-27 21:56:27 +0100271 },
272 list: list,
273 hidden: {
274 guild: message.channel.guild.id
pineafan813bdf42022-07-24 10:39:10 +0100275 }
pineafan63fc5e22022-08-04 22:04:10 +0100276 };
pineafane23c4ec2022-07-27 21:56:27 +0100277 return log(data);
pineafan813bdf42022-07-24 10:39:10 +0100278 }
279 }
pineafane23c4ec2022-07-27 21:56:27 +0100280 }
281 if (message.mentions.users.size >= config.filters.pings.mass && config.filters.pings.mass) {
pineafan63fc5e22022-08-04 22:04:10 +0100282 createLogException(message.guild.id, message.channel.id, message.id);
283 await message.delete();
284 const data = {
pineafane23c4ec2022-07-27 21:56:27 +0100285 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100286 type: "massPing",
287 displayName: "Mass Ping",
288 calculateType: "messageMassPing",
pineafane23c4ec2022-07-27 21:56:27 +0100289 color: NucleusColors.yellow,
pineafan63fc5e22022-08-04 22:04:10 +0100290 emoji: "MESSAGE.PING.MASS",
pineafane23c4ec2022-07-27 21:56:27 +0100291 timestamp: new Date().getTime()
292 },
293 separate: {
pineafan63fc5e22022-08-04 22:04:10 +0100294 start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*"
pineafane23c4ec2022-07-27 21:56:27 +0100295 },
296 list: list,
297 hidden: {
298 guild: message.channel.guild.id
pineafan813bdf42022-07-24 10:39:10 +0100299 }
pineafan63fc5e22022-08-04 22:04:10 +0100300 };
pineafane23c4ec2022-07-27 21:56:27 +0100301 return log(data);
pineafan813bdf42022-07-24 10:39:10 +0100302 }
303}