From e11afbe4976e7565a4951802e02c310ed69fd1a3 Mon Sep 17 00:00:00 2001 From: McJeffr Date: Sat, 7 May 2022 22:24:29 +0200 Subject: [PATCH] Added react messages to welcome channel for notification roles. --- config/default.js | 2 + locales/en.json | 6 ++- src/Helper/BotDeterminer.js | 8 ++++ src/Helper/ChannelRetriever.js | 18 ++++++++ src/Helper/RoleRetriever.js | 18 ++++++++ src/Utility/RolePoster.js | 80 ++++++++++++++++++++++++++++++++++ 6 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 src/Helper/BotDeterminer.js create mode 100644 src/Helper/ChannelRetriever.js create mode 100644 src/Helper/RoleRetriever.js create mode 100644 src/Utility/RolePoster.js diff --git a/config/default.js b/config/default.js index 7d345c3..0bc03a3 100644 --- a/config/default.js +++ b/config/default.js @@ -39,6 +39,7 @@ module.exports = { deletedLogsRoom: '615737464643911680', trickcordTreatRoom: '766318346424680460', broadcastRoom: '380086729526345739', + welcomeRoom: '148149183226970113', trickcordTreatDeleteTime: ONE_MINUTE_IN_MS, games: { aliases: { @@ -172,6 +173,7 @@ module.exports = { minez: '793166203782692884', wir: '793166266096418837', slaughter: '857759646807097345', + annihilation: '972561980336525362', }, clearers: [ { diff --git a/locales/en.json b/locales/en.json index c4dcd58..5d95f60 100644 --- a/locales/en.json +++ b/locales/en.json @@ -116,5 +116,7 @@ "@{username}#{discriminator} was banned after excessive pinging": "@{username}#{discriminator} was banned after excessive pinging", "Locking this room, making it not close automatically after inactivity.": "Locking this room, making it not close automatically after inactivity.", "Unlocking this room, making it automatically close after inactivity.": "Unlocking this room, making it automatically close after inactivity.", - "Could not (un)lock channel at this time. Try again in a bit!": "Could not (un)lock channel at this time. Try again in a bit!" -} + "Could not (un)lock channel at this time. Try again in a bit!": "Could not (un)lock channel at this time. Try again in a bit!", + "React to the messages below to enable notifications for your favorite gamemodes!\n_You can disable notifications again using `!notifyremove `_": "React to the messages below to enable notifications for your favorite gamemodes!\n_You can disable notifications again using `!notifyremove `_", + "React to get notifications for `{gamemode}`": "React to get notifications for `{gamemode}`" +} \ No newline at end of file diff --git a/src/Helper/BotDeterminer.js b/src/Helper/BotDeterminer.js new file mode 100644 index 0000000..57b6b12 --- /dev/null +++ b/src/Helper/BotDeterminer.js @@ -0,0 +1,8 @@ +module.exports = { + isBot: function (discordClient, id) { + return id === discordClient.user.id; + }, + isPostedByBot: function (discordClient, message) { + return message.author.id === discordClient.user.id; + }, +}; diff --git a/src/Helper/ChannelRetriever.js b/src/Helper/ChannelRetriever.js new file mode 100644 index 0000000..2c53a89 --- /dev/null +++ b/src/Helper/ChannelRetriever.js @@ -0,0 +1,18 @@ +module.exports = { + retrieveChannel: function (guild, channelId) { + const discordChannel = guild.channels.cache.get(channelId); + if (discordChannel) { + return discordChannel; + } + }, + retrieveChannels: function (guild, channelIds) { + const channels = []; + channelIds.forEach((channelId) => { + const discordChannel = this.retrieveChannel(guild, channelId); + if (discordChannel) { + channels.push(discordChannel); + } + }); + return channels; + }, +}; diff --git a/src/Helper/RoleRetriever.js b/src/Helper/RoleRetriever.js new file mode 100644 index 0000000..993322a --- /dev/null +++ b/src/Helper/RoleRetriever.js @@ -0,0 +1,18 @@ +module.exports = { + retrieveRole: function (guild, roleId) { + const role = guild.roles.cache.get(roleId); + if (role) { + return role; + } + }, + retrieveRoles: function (guild, roleIds) { + const roles = []; + roleIds.forEach((roleId) => { + const role = this.retrieveRole(guild, roleId); + if (role) { + roles.push(role); + } + }); + return roles; + }, +}; diff --git a/src/Utility/RolePoster.js b/src/Utility/RolePoster.js new file mode 100644 index 0000000..acba043 --- /dev/null +++ b/src/Utility/RolePoster.js @@ -0,0 +1,80 @@ +const BotModule = require("../BotModule"); +const BotDeterminer = require("../Helper/BotDeterminer"); +const ChannelRetriever = require("../Helper/ChannelRetriever"); +const RoleRetriever = require("../Helper/RoleRetriever"); + +const localizedMessages = { + notificationRoleInfo: + "React to the messages below to enable notifications for your favorite gamemodes!\n_You can disable notifications again using `!notifyremove `_", + notificationRole: "React to get notifications for `{gamemode}`", +}; + +module.exports = BotModule.extend({ + config: null, + dependencies: { + config: "config", + i18n: "i18n", + }, + initialize: function (dependencyGraph) { + this._super(dependencyGraph); + + this.discordClient.once("ready", async () => { + /* Fetch all configuration */ + const guild = this.discordClient.guilds.cache.first(); + const welcomeChannelId = this.config.welcomeRoom; + if (!welcomeChannelId) { + return; + } + const welcomeChannel = ChannelRetriever.retrieveChannel(guild, welcomeChannelId); + if (!welcomeChannel) { + return; + } + const notificationRoleConfig = this.config.notificationRoles; + if (!notificationRoleConfig) { + return; + } + const notificationRoleIds = Object.keys(notificationRoleConfig).map((name) => notificationRoleConfig[name]); + const nameMappedNotificationRoleIds = Object.keys(notificationRoleConfig).reduce((acc, name) => { + acc[notificationRoleConfig[name]] = name; + return acc; + }, {}); + const notificationRoles = RoleRetriever.retrieveRoles(guild, notificationRoleIds); + if (!notificationRoles) { + return; + } + + /* Delete all previous messages posted by the bot in the welcome channel */ + const messages = await welcomeChannel.messages.fetch({ limit: 50 }); + await Promise.all( + messages.map(async (message) => { + if (BotDeterminer.isPostedByBot(this.discordClient, message)) { + await message.delete(); + } + }) + ); + + /* Post new messages for every notification role with a reaction listener */ + await welcomeChannel.send(this.i18n.__mf(localizedMessages.notificationRoleInfo)); + await welcomeChannel.send("** **"); + const roleMessages = []; + for (const role of notificationRoles) { + const message = await welcomeChannel.send( + this.i18n.__mf(localizedMessages.notificationRole, { gamemode: nameMappedNotificationRoleIds[role.id] }) + ); + await message.react("📨"); + roleMessages.push({ messageId: message.id, role }); + } + this.discordClient.on("messageReactionAdd", async (event, user) => { + const messageId = event.message.id; + const roleMessage = roleMessages.find((roleMessage) => roleMessage.messageId === messageId); + if (!roleMessage || BotDeterminer.isBot(this.discordClient, user.id)) { + return; + } + const member = await guild.members.fetch(user.id); + await member.roles.add(roleMessage.role); + await event.remove(); // Because there is no easy way to remove a single user's reaction in discord.js + await event.message.react("📨"); + }); + }); + }, +});