import { Message, TextChannel } from "discord.js"; import { getRepository } from "typeorm"; import { FileOnlyChannel } from "@shared/db/entity/FileOnlyChannel"; import { Event, BotEventData, Plugin } from "src/model/plugin"; @Plugin export class FileOnlyChannelChecker { private urlPattern = /(?:((?:https?|ftp):\/\/)|ww)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?/; @Event("message") async processMessage(data: BotEventData, msg: Message): Promise { if (data.actionsDone) return; const repo = getRepository(FileOnlyChannel); const entry = await repo.findOne(msg.channel.id); if (!entry) return; // Has attachments; is fine if (msg.attachments.size > 0) return; // Has a link if(this.urlPattern.test(msg.content)) return; msg.delete(); // Non-default system message (e.g. pin or thread create) => there is no one to warn, so just remove it to keep the channel clean if (msg.type != "DEFAULT") return; const ch = msg.guild?.channels.resolve(entry.warningMessageChannelId); if(ch instanceof TextChannel) ch.send(`> ${msg.content.replace(/\n/g, "\n> ")}\n\n${msg.author.toString()} Channel ${msg.channel.toString()} is only meant for sharing links and files! If you want to post text-only messages, do so in ${ch.toString()}!`); data.actionsDone = true; } }