blob: dce1959b93500450ec0c17d1ca0da7b72e95d766 [file] [log] [blame]
pineafan813bdf42022-07-24 10:39:10 +01001import { LinkCheck, MalwareCheck, NSFWCheck, SizeCheck, TestString, TestImage } from '../reflex/scanners.js'
2import logAttachment from '../premium/attachmentLogs.js'
3import createLogException from '../utils/createLogException.js'
pineafan813bdf42022-07-24 10:39:10 +01004import getEmojiByName from '../utils/getEmojiByName.js'
5
6export const event = 'messageCreate'
7
8export async function callback(client, message) {
9 if(!message) return;
10 if (message.author.bot) return
11 if (message.channel.type === 'dm') return
12
13 const { log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger
14
15 let fileNames = await logAttachment(message);
16
17 let content = message.content.toLowerCase() || ''
18 let config = await client.memory.readGuildInfo(message.guild.id);
19 const filter = getEmojiByName("ICONS.FILTER")
20 let attachmentJump = ""
pineafan02ba0232022-07-24 22:16:15 +010021 if (config.logging.attachments.saved[message.channel.id + message.id]) { attachmentJump = ` [[View attachments]](${config.logging.attachments.saved[message.channel.id + message.id]})` }
pineafan813bdf42022-07-24 10:39:10 +010022 let list = {
23 messageId: entry(message.id, `\`${message.id}\``),
24 sentBy: entry(message.author.id, renderUser(message.author)),
25 sentIn: entry(message.channel.id, renderChannel(message.channel)),
26 deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
27 mentions: message.mentions.users.size,
28 attachments: entry(message.attachments.size, message.attachments.size + attachmentJump),
29 repliedTo: entry(
30 message.reference ? message.reference.messageId : null,
31 message.reference ? `[[Jump to message]](https://discord.com/channels/${message.guild.id}/${message.channel.id}/${message.reference.messageId})` : "None"
32 )
33 }
34
35 if (config.filters.invite.enabled) {
36 if (!config.filters.invite.allowed.users.includes(message.author.id) ||
37 !config.filters.invite.allowed.channels.includes(message.channel.id) ||
38 !message.author.roles.cache.some(role => config.filters.invite.allowed.roles.includes(role.id))
39 ) {
40 if ((/(?:https?:\/\/)?discord(?:app)?\.(?:com\/invite|gg)\/[a-zA-Z0-9]+\/?/.test(content))) {
41 createLogException(message.guild.id, message.channel.id, message.id)
42 message.delete();
43 let data = {
44 meta: {
45 type: 'messageDelete',
46 displayName: 'Message Deleted (Automated, Contained Invite)',
47 calculateType: 'autoModeratorDeleted',
48 color: NucleusColors.red,
49 emoji: 'MESSAGE.DELETE',
50 timestamp: new Date().getTime()
51 },
52 separate: {
53 start: filter + " Contained invite\n\n" + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : '**Message:** *Message had no content*'),
54 },
55 list: list,
56 hidden: {
57 guild: message.channel.guild.id
58 }
59 }
60 return log(data);
61 }
62 }
63 }
64
65 if (fileNames.files.length > 0) {
pineafan02ba0232022-07-24 22:16:15 +010066 for (let element of fileNames.files) {
pineafan813bdf42022-07-24 10:39:10 +010067 if(!message) return;
68 let url = element.url ? element.url : element.local
69 if (url != undefined) {
70 if(/\.(jpg|jpeg|png|gif|gifv|webm|webp|mp4|wav|mp3|ogg)$/.test(url)) {
71 if (config.filters.images.NSFW && !message.channel.nsfw) {
72 if (await NSFWCheck(url)) {
73 createLogException(message.guild.id, message.channel.id, message.id)
74 await message.delete()
75 let data = {
76 meta: {
77 type: 'messageDelete',
78 displayName: 'Message Deleted',
79 calculateType: 'autoModeratorDeleted',
80 color: NucleusColors.red,
81 emoji: 'MESSAGE.DELETE',
82 timestamp: new Date().getTime()
83 },
84 separate: {
85 start: filter + " Image detected as NSFW\n\n" + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : '**Message:** *Message had no content*'),
86 },
87 list: list,
88 hidden: {
89 guild: message.channel.guild.id
90 }
91 }
92 return log(data);
93 }
94 }
95 if (config.filters.wordFilter.enabled) {
96 let text = await TestImage(url)
97 if (config.filters.wordFilter.enabled) {
98 let check = TestString(text, config.filters.wordFilter.words.loose, config.filters.wordFilter.words.strict)
99 if(check !== null) {
100 createLogException(message.guild.id, message.channel.id, message.id)
101 await message.delete()
102 let data = {
103 meta: {
104 type: 'messageDelete',
105 displayName: 'Message Deleted',
106 calculateType: 'autoModeratorDeleted',
107 color: NucleusColors.red,
108 emoji: 'MESSAGE.DELETE',
109 timestamp: new Date().getTime()
110 },
111 separate: {
112 start: filter + " Image contained filtered word\n\n" + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : '**Message:** *Message had no content*'),
113 },
114 list: list,
115 hidden: {
116 guild: message.channel.guild.id
117 }
118 }
119 return log(data);
120 }
121 }
122 }
123 if (config.filters.images.size) {
124 if(url.match(/\.+(webp|png|jpg)$/gi)) {
125 if(!await SizeCheck(element)) {
126 createLogException(message.guild.id, message.channel.id, message.id)
127 await message.delete()
128 let data = {
129 meta: {
130 type: 'messageDelete',
131 displayName: 'Message Deleted',
132 calculateType: 'autoModeratorDeleted',
133 color: NucleusColors.red,
134 emoji: 'MESSAGE.DELETE',
135 timestamp: new Date().getTime()
136 },
137 separate: {
138 start: filter + " Image was too small\n\n" + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : '**Message:** *Message had no content*'),
139 },
140 list: list,
141 hidden: {
142 guild: message.channel.guild.id
143 }
144 }
145 return log(data);
146 }
147 }
148 }
149 }
150 if (config.filters.malware) {
151 if (!MalwareCheck(url)) {
152 createLogException(message.guild.id, message.channel.id, message.id)
153 await message.delete()
154 let 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: filter + " File detected as malware\n\n" + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : '**Message:** *Message had no content*'),
165 },
166 list: list,
167 hidden: {
168 guild: message.channel.guild.id
169 }
170 }
171 return log(data);
172 }
173 }
174 }
pineafan02ba0232022-07-24 22:16:15 +0100175 };
pineafan813bdf42022-07-24 10:39:10 +0100176 }
177 if(!message) return;
178
179 let linkDetectionTypes = await LinkCheck(message)
180 if (linkDetectionTypes.length > 0) {
181 createLogException(message.guild.id, message.channel.id, message.id)
182 await message.delete()
183 let data = {
184 meta: {
185 type: 'messageDelete',
186 displayName: `Message Deleted`,
187 calculateType: 'autoModeratorDeleted',
188 color: NucleusColors.red,
189 emoji: 'MESSAGE.DELETE',
190 timestamp: new Date().getTime()
191 },
192 separate: {
193 start: filter + ` Link filtered as ${linkDetectionTypes[0].toLowerCase()}\n\n` + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : '**Message:** *Message had no content*'),
194 },
195 list: list,
196 hidden: {
197 guild: message.channel.guild.id
198 }
199 }
200 return log(data);
201 }
202 if (config.filters.wordFilter.enabled) {
203 let check = TestString(content, config.filters.wordFilter.words.loose, config.filters.wordFilter.words.strict)
204 if(check !== null) {
205 createLogException(message.guild.id, message.channel.id, message.id)
206 await message.delete()
207 let data = {
208 meta: {
209 type: 'messageDelete',
210 displayName: 'Message Deleted',
211 calculateType: 'autoModeratorDeleted',
212 color: NucleusColors.red,
213 emoji: 'MESSAGE.DELETE',
214 timestamp: new Date().getTime()
215 },
216 separate: {
217 start: filter + ` Message contained filtered word\n\n` + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : '**Message:** *Message had no content*'),
218 },
219 list: list,
220 hidden: {
221 guild: message.channel.guild.id
222 }
223 }
224 return log(data);
225 }
226 }
227
228 if (!config.filters.pings.allowed.users.includes(message.author.id) ||
229 !config.filters.pings.allowed.channels.includes(message.channel.id) ||
230 !message.author.roles.cache.some(role => config.filters.pings.allowed.roles.includes(role.id))
231 ) {
232 if (config.filters.pings.everyone && message.mentions.everyone) {
233 let data = {
234 meta: {
235 type: 'everyonePing',
236 displayName: 'Everyone Pinged',
237 calculateType: 'messageMassPing',
238 color: NucleusColors.yellow,
239 emoji: 'MESSAGE.PING.EVERYONE',
240 timestamp: new Date().getTime()
241 },
242 separate: {
243 start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : '**Message:** *Message had no content*',
244 },
245 list: list,
246 hidden: {
247 guild: message.channel.guild.id
248 }
249 }
250 return log(data);
251 }
252 if (config.filters.pings.roles) {
253 for(let role of message.mentions.roles) {
254 if(!message) return;
255 if (!config.filters.pings.allowed.roles.includes(role.id)) {
256 createLogException(message.guild.id, message.channel.id, message.id)
257 await message.delete()
258 let data = {
259 meta: {
260 type: 'rolePing',
261 displayName: 'Role Pinged',
262 calculateType: 'messageMassPing',
263 color: NucleusColors.yellow,
264 emoji: 'MESSAGE.PING.ROLE',
265 timestamp: new Date().getTime()
266 },
267 separate: {
268 start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : '**Message:** *Message had no content*',
269 },
270 list: list,
271 hidden: {
272 guild: message.channel.guild.id
273 }
274 }
275 return log(data);
276 }
277 }
278 }
279 if (message.mentions.users.size >= config.filters.pings.mass && config.filters.pings.mass) {
280 createLogException(message.guild.id, message.channel.id, message.id)
281 await message.delete()
282 let data = {
283 meta: {
284 type: 'massPing',
285 displayName: `Mass Ping`,
286 calculateType: 'messageMassPing',
287 color: NucleusColors.yellow,
288 emoji: 'MESSAGE.PING.MASS',
289 timestamp: new Date().getTime()
290 },
291 separate: {
292 start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : '**Message:** *Message had no content*',
293 },
294 list: list,
295 hidden: {
296 guild: message.channel.guild.id
297 }
298 }
299 return log(data);
300 }
301 }
302}