file_only_channel_checker.ts 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. import { Message, TextChannel } from "discord.js";
  2. import { getRepository } from "typeorm";
  3. import { FileOnlyChannel } from "@shared/db/entity/FileOnlyChannel";
  4. import { Event, BotEventData, Plugin } from "src/model/plugin";
  5. @Plugin
  6. export class FileOnlyChannelChecker {
  7. 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*)?/;
  8. @Event("message")
  9. async processMessage(data: BotEventData, msg: Message): Promise<void> {
  10. if (data.actionsDone)
  11. return;
  12. const repo = getRepository(FileOnlyChannel);
  13. const entry = await repo.findOne(msg.channel.id);
  14. if (!entry)
  15. return;
  16. // Has attachments; is fine
  17. if (msg.attachments.size > 0)
  18. return;
  19. // Has a link
  20. if(this.urlPattern.test(msg.content))
  21. return;
  22. msg.delete();
  23. // 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
  24. if (msg.type != "DEFAULT")
  25. return;
  26. const ch = msg.guild?.channels.resolve(entry.warningMessageChannelId);
  27. if(ch instanceof TextChannel)
  28. 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()}!`);
  29. data.actionsDone = true;
  30. }
  31. }