diff options
| author | Fuwn <[email protected]> | 2025-11-08 18:18:26 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2025-11-08 18:18:26 -0800 |
| commit | 35662d812dc9bc4c5caa8be60e2854b48e1497cb (patch) | |
| tree | 7cbd34e560f37d9e26525565e70345d0cd9d2d93 | |
| parent | feat(gateway:imageDeletion): Add allowed roles (diff) | |
| download | umabotdiscord-35662d812dc9bc4c5caa8be60e2854b48e1497cb.tar.xz umabotdiscord-35662d812dc9bc4c5caa8be60e2854b48e1497cb.zip | |
feat(gateway:listeners): Add a reaction roles handler
| -rw-r--r-- | packages/gateway/src/listeners/clientReady/index.ts | 2 | ||||
| -rw-r--r-- | packages/gateway/src/listeners/index.ts | 2 | ||||
| -rw-r--r-- | packages/gateway/src/listeners/reactionRoles.ts | 99 |
3 files changed, 103 insertions, 0 deletions
diff --git a/packages/gateway/src/listeners/clientReady/index.ts b/packages/gateway/src/listeners/clientReady/index.ts index 39a2ef9..e39b8f7 100644 --- a/packages/gateway/src/listeners/clientReady/index.ts +++ b/packages/gateway/src/listeners/clientReady/index.ts @@ -6,6 +6,7 @@ import { initializeMessageStatistics } from "../messageStatistics"; import { initializePersonaSystem } from "../messageCreate/personaRandomMessage"; import { initializeConversationStarterSystem } from "../messageCreate/dailyConversationStarter"; import { initializeWelcomeSystem } from "../memberJoin"; +import { initializeReactionRoles } from "../reactionRoles"; export const handleClientReady = (client: Client) => { client.once(Events.ClientReady, async (readyClient) => { @@ -15,6 +16,7 @@ export const handleClientReady = (client: Client) => { initializePersonaSystem(readyClient); initializeConversationStarterSystem(readyClient); initializeWelcomeSystem(readyClient); + await initializeReactionRoles(readyClient); // await initializeSuperFreakChannelSystem(readyClient); await handleUmagramCatchup(readyClient); // Character claim tracker will initialize on first use diff --git a/packages/gateway/src/listeners/index.ts b/packages/gateway/src/listeners/index.ts index 0868ae0..0f74fcc 100644 --- a/packages/gateway/src/listeners/index.ts +++ b/packages/gateway/src/listeners/index.ts @@ -14,6 +14,7 @@ import { handleBotMessageLogger } from "./botMessageLogger"; import { handleRoleExclusion } from "./roleExclusion"; import { handleTextContentDeletion } from "./textContentDeletion"; import { handleImageDeletion } from "./imageDeletion"; +import { handleReactionRoles } from "./reactionRoles"; // import { handleMediaModeration } from "./mediaModeration"; export const handleListeners = (client: Client) => { @@ -32,5 +33,6 @@ export const handleListeners = (client: Client) => { handleRoleExclusion(client); handleTextContentDeletion(client); handleImageDeletion(client); + handleReactionRoles(client); // handleMediaModeration(client); }; diff --git a/packages/gateway/src/listeners/reactionRoles.ts b/packages/gateway/src/listeners/reactionRoles.ts new file mode 100644 index 0000000..2050120 --- /dev/null +++ b/packages/gateway/src/listeners/reactionRoles.ts @@ -0,0 +1,99 @@ +import { Client, Events } from "discord.js"; +import { logUnexpectedDiscordAPIError } from "../utilities"; + +const REACTION_MESSAGE_ID = "1420987176140804219"; +const TARGET_CHANNEL_ID = "1414436016520953856"; +const ART_ROLE_ID = "1410333831281643630"; +const EMOJI_ROLE_MAPPINGS = { + "🎨": ART_ROLE_ID, +} as const; +const ART_EMOJI = "🎨"; + +export const initializeReactionRoles = async (client: Client) => { + try { + const channel = client.channels.cache.get(TARGET_CHANNEL_ID); + + if (!channel || !channel.isTextBased() || channel.isDMBased()) return; + + const message = await channel.messages.fetch(REACTION_MESSAGE_ID); + const hasArtReaction = message.reactions.cache.has(ART_EMOJI); + + if (!hasArtReaction) await message.react(ART_EMOJI); + } catch (error) { + logUnexpectedDiscordAPIError(error); + } +}; + +export const handleReactionRoles = (client: Client) => { + client.on(Events.MessageReactionAdd, async (reaction, user) => { + if (user.bot) return; + + try { + const message = await reaction.message.fetch(); + + if (message.id !== REACTION_MESSAGE_ID) return; + + const emoji = reaction.emoji.name; + + if (!emoji || !(emoji in EMOJI_ROLE_MAPPINGS)) return; + + const roleId = + EMOJI_ROLE_MAPPINGS[emoji as keyof typeof EMOJI_ROLE_MAPPINGS]; + + if (!roleId) return; + + if (!message.guild) return; + + const member = await message.guild.members.fetch(user.id); + const role = message.guild.roles.cache.get(roleId); + + if (!role) { + logUnexpectedDiscordAPIError( + new Error(`Role ${roleId} not found in guild ${message.guild.id}`), + ); + + return; + } + + if (!member.roles.cache.has(roleId)) await member.roles.add(role); + } catch (error) { + logUnexpectedDiscordAPIError(error); + } + }); + + client.on(Events.MessageReactionRemove, async (reaction, user) => { + if (user.bot) return; + + try { + const message = await reaction.message.fetch(); + + if (message.id !== REACTION_MESSAGE_ID) return; + + const emoji = reaction.emoji.name; + + if (!emoji || !(emoji in EMOJI_ROLE_MAPPINGS)) return; + + const roleId = + EMOJI_ROLE_MAPPINGS[emoji as keyof typeof EMOJI_ROLE_MAPPINGS]; + + if (!roleId) return; + + if (!message.guild) return; + + const member = await message.guild.members.fetch(user.id); + const role = message.guild.roles.cache.get(roleId); + + if (!role) { + logUnexpectedDiscordAPIError( + new Error(`Role ${roleId} not found in guild ${message.guild.id}`), + ); + + return; + } + + if (member.roles.cache.has(roleId)) await member.roles.remove(role); + } catch (error) { + logUnexpectedDiscordAPIError(error); + } + }); +}; |