diff --git a/config.default.jsonc b/config.default.jsonc index 339eec6..8b29480 100644 --- a/config.default.jsonc +++ b/config.default.jsonc @@ -103,6 +103,14 @@ // API key is shared with google "youtube": { "enabled": true + }, + "autopaste": { + "enabled": true, + // Make sure the ids are all strings, not numbers + "immuneRoleIds": [], + "maxLength": 100, + "pasteFooterContent": "", + "pasteApi": "" } } } diff --git a/src/modules/autopaste.ts b/src/modules/autopaste.ts new file mode 100644 index 0000000..b7029ca --- /dev/null +++ b/src/modules/autopaste.ts @@ -0,0 +1,115 @@ +/** + * @file This file contains the necessary information for autopasting messages + */ +import {Colors, EmbedBuilder, Events, Message, Role} from 'discord.js'; +import * as util from '../core/util.js'; +import {request} from 'undici'; + +const autopaste = new util.RootModule( + 'autopaste', + 'Autopaste messages over a certain length', + [] +); + +autopaste.onInitialize(async () => { + // Only defines and checks everything once so it isn't redefined on every message + const maxLength: number = autopaste.config.maxLength; + + if (!maxLength) { + util.logEvent( + util.EventCategory.Warning, + 'autopaste', + "Config error: The max length isn't set or is invalid, the autopaste module will be disabled.", + 1 + ); + return; + } + + const API_URL: string = autopaste.config.pasteApi; + + if (!API_URL || !API_URL.startsWith('http')) { + util.logEvent( + util.EventCategory.Warning, + 'autopaste', + "Config error: The API URL isn't set or is invalid, the autopaste module will be disabled.", + 1 + ); + return; + } + + const immuneRoles: string[] = autopaste.config.immuneRoleIds; + + const headers = { + 'Linx-Expiry': '1800', + 'Linx-Randomize': 'yes', + Accept: 'application/json', + }; + + // The main message listener + util.client.on(Events.MessageCreate, async (message: Message) => { + if (message.content.length <= maxLength) { + return; + } + + // Makes sure the author doesn't have any immune roles + for (const roleIds of immuneRoles) { + // The role is found from the cache and only THEN is ITs id checked, done to make sure you + // can't just put a role name in the list and then create a new role with the same name + const role: Role | undefined = message.guild!.roles.cache.find( + role => role.id === roleIds + ); + + if (role !== undefined && message.member!.roles.cache.has(role.id)) { + return; + } + } + const content: string = message.content; + + // Pastes the message contents + const response = await request(API_URL, { + method: 'PUT', + headers: headers, + body: JSON.stringify(content), + }); + + // Parses the response data + let responseData = ''; + + for await (const data of response.body) { + responseData += data; + } + + const parsedResponse = JSON.parse(responseData); + const url = parsedResponse.url; + + if (!url) { + util.logEvent( + util.EventCategory.Warning, + 'autopaste', + `call to ${API_URL} failed! Response code ${response.statusCode}`, + 1 + ); + return; + } + + const embed: EmbedBuilder = new EmbedBuilder() + .setColor(Colors.Blue) + .setAuthor({ + name: `Paste by ${message.author.tag}`, + iconURL: message.author.displayAvatarURL(), + }) + .setDescription(message.content.substring(0, 100).replace('\n', '')) + .addFields({ + name: 'Paste link', + value: url, + }) + .setFooter({ + text: autopaste.config.pasteFooterContent, + }); + + await message.delete(); + await message.channel.send({embeds: [embed]}); + }); +}); + +export default autopaste;