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