From 505cbd239be12998908d4896f83d2e6953093997 Mon Sep 17 00:00:00 2001 From: 01zulfi <85733202+01zulfi@users.noreply.github.com> Date: Sat, 24 Feb 2024 15:33:26 +0500 Subject: [PATCH] feat: update rules service --- config.js | 1 + new-era-commands/slash/update-rules.js | 12 +++ services/update-rules/index.js | 3 + services/update-rules/update-rules.service.js | 81 +++++++++++++++++++ 4 files changed, 97 insertions(+) create mode 100644 new-era-commands/slash/update-rules.js create mode 100644 services/update-rules/index.js create mode 100644 services/update-rules/update-rules.service.js diff --git a/config.js b/config.js index 19ad2003..992536ae 100644 --- a/config.js +++ b/config.js @@ -13,6 +13,7 @@ const config = { gettingHiredChannelId: process.env.DISCORD_GETTING_HIRED_CHANNEL_ID, botSpamPlaygroundChannelId: '513125912070455296', FAQChannelId: '823266307293839401', + rulesChannelId: '693244715839127653', }, roles: { NOBOTRoleId: '783764176178774036', diff --git a/new-era-commands/slash/update-rules.js b/new-era-commands/slash/update-rules.js new file mode 100644 index 00000000..30a8b364 --- /dev/null +++ b/new-era-commands/slash/update-rules.js @@ -0,0 +1,12 @@ +const { SlashCommandBuilder, PermissionFlagsBits } = require("discord.js"); +const UpdateRulesService = require("../../services/update-rules/update-rules.service"); + +module.exports = { + data: new SlashCommandBuilder() + .setName("updaterules") + .setDescription("update rules in the #rules channel") + .setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages), + execute: async (interaction) => { + await UpdateRulesService.handleInteraction(interaction); + }, +}; diff --git a/services/update-rules/index.js b/services/update-rules/index.js new file mode 100644 index 00000000..b7e4189c --- /dev/null +++ b/services/update-rules/index.js @@ -0,0 +1,3 @@ +const UpdateRulesService = require("./update-rules.service"); + +module.exports = UpdateRulesService; diff --git a/services/update-rules/update-rules.service.js b/services/update-rules/update-rules.service.js new file mode 100644 index 00000000..432ce44a --- /dev/null +++ b/services/update-rules/update-rules.service.js @@ -0,0 +1,81 @@ +const { EmbedBuilder } = require("discord.js"); +const config = require("../../config"); + +class UpdateRulesService { + static EmbedDescriptionCharacterLimit = 4096; + + // regex for [rule-name]: # (my rule name) + static Delimiter = /(\[rule-name\]: # \(.+\))/; + + static async handleInteraction(interaction) { + let rawRules; + try { + rawRules = await UpdateRulesService.fetchRules(); + } catch (error) { + console.log(error); + await interaction.reply("Failed to update rules"); + return; + } + + const rulesEmbeds = UpdateRulesService.createRulesEmbeds(rawRules); + const rulesChannel = interaction.guild.channels.cache.get( + config.channels.rulesChannelId + ); + await UpdateRulesService.deletePreviousRules(rulesChannel); + await interaction.reply("i'm doing the thing, wait..."); + await UpdateRulesService.sendRules(rulesEmbeds, rulesChannel); + await interaction.editReply("Rules updated"); + } + + static async fetchRules() { + const response = await fetch( + "https://raw.githubusercontent.com/TheOdinProject/top-meta/main/community-rules.md" + ); + const rules = await response.text(); + return rules; + } + + static createRulesEmbeds(rawRules) { + return UpdateRulesService.segments( + rawRules, + UpdateRulesService.EmbedDescriptionCharacterLimit, + UpdateRulesService.Delimiter + ).map((chunk) => + new EmbedBuilder().setColor("#cc9543").setDescription(chunk) + ); + } + + static async sendRules(rulesEmbeds, rulesChannel) { + await Promise.all( + rulesEmbeds.map(async (e) => { + await rulesChannel.send({ embeds: [e] }); + }) + ); + } + + static async deletePreviousRules(rulesChannel) { + // might need to increase limit if there are more than 20 messages + const prev = await rulesChannel.messages.fetch({ limit: 20 }); + prev.forEach((message) => message.delete()); + } + + static segments(string, length, delimiter) { + const segmentedString = string + // for whatever reason, discord ain't parsing these emojis. fine i'll do it myself + .replaceAll("✅", "✅") + .replaceAll("❌", "❌") + .split(delimiter) + .filter((chunk) => !chunk.match(delimiter)); + + for (let i = 0; i < segmentedString.length; i += 1) { + if (segmentedString[i].length >= length) { + segmentedString[i] = segmentedString[i].match( + new RegExp(`.{1,${length}}`, "g") + ); + } + } + return segmentedString.flat(Infinity); + } +} + +module.exports = UpdateRulesService;