summaryrefslogtreecommitdiff
path: root/packages/gateway/src/commands
diff options
context:
space:
mode:
authorFuwn <[email protected]>2025-10-03 14:10:42 -0700
committerFuwn <[email protected]>2025-10-03 14:10:42 -0700
commit369310e9f9455d2acb7e24ab60391c3efcc36574 (patch)
treea5003ae4fec143b56e915129787d086ef223e2a4 /packages/gateway/src/commands
parentfeat(nsfw-apply): Add discord and server join date fields (diff)
downloadumabotdiscord-369310e9f9455d2acb7e24ab60391c3efcc36574.tar.xz
umabotdiscord-369310e9f9455d2acb7e24ab60391c3efcc36574.zip
feat(gateway:commands): Add role command
Diffstat (limited to 'packages/gateway/src/commands')
-rw-r--r--packages/gateway/src/commands/commandHandler.ts2
-rw-r--r--packages/gateway/src/commands/role.ts138
2 files changed, 140 insertions, 0 deletions
diff --git a/packages/gateway/src/commands/commandHandler.ts b/packages/gateway/src/commands/commandHandler.ts
index c9b4ee9..a684339 100644
--- a/packages/gateway/src/commands/commandHandler.ts
+++ b/packages/gateway/src/commands/commandHandler.ts
@@ -5,6 +5,7 @@ import { handleCrpCommand } from "./crp";
import { handleReactCommand } from "./react";
import { handleDeleteCommand } from "./delete";
import { handlePinCommand } from "./pin";
+import { handleRoleCommand } from "./role";
export const handleCommandHandler = (client: Client) => {
client.on(Events.MessageCreate, async (message: Message) => {
@@ -17,6 +18,7 @@ export const handleCommandHandler = (client: Client) => {
handleReactCommand(message),
handleDeleteCommand(message),
handlePinCommand(message),
+ handleRoleCommand(message),
]);
});
};
diff --git a/packages/gateway/src/commands/role.ts b/packages/gateway/src/commands/role.ts
new file mode 100644
index 0000000..b29cdea
--- /dev/null
+++ b/packages/gateway/src/commands/role.ts
@@ -0,0 +1,138 @@
+import { Message } from "discord.js";
+import { replyWithCleanup } from "../utilities";
+
+export const handleRoleCommand = async (message: Message) => {
+ if (message.author.bot) return;
+
+ if (message.content.toLowerCase().startsWith("uma!role")) {
+ const application = await message.client.application?.fetch();
+ const botOwnerId = application?.owner?.id;
+ const guildOwnerId = message.guild?.ownerId;
+
+ if (message.author.id !== botOwnerId && message.author.id !== guildOwnerId)
+ return;
+
+ const parameters = message.content.split(" ").slice(1);
+
+ if (parameters.length < 3) {
+ await replyWithCleanup(
+ message,
+ "❌ Usage: `uma!role <server_id> <user_id_or_mention> <role_id_or_mention> [role_id_or_mention...]`\nExamples:\n- `uma!role 1234567890123456789 @user @role`\n- `uma!role 1234567890123456789 @user @role1 @role2 @role3`\n- `uma!role 1234567890123456789 9876543210987654321 1111111111111111111`",
+ );
+
+ return;
+ }
+
+ const serverInput = parameters[0];
+ const userInput = parameters[1];
+ const roleInputs = parameters.slice(2);
+
+ try {
+ let serverId: string;
+
+ if (/^\d{17,19}$/.test(serverInput)) {
+ serverId = serverInput;
+ } else {
+ await replyWithCleanup(
+ message,
+ "❌ Invalid server ID format. Use a valid Discord server ID.",
+ );
+
+ return;
+ }
+
+ let targetUserId: string;
+
+ if (userInput.startsWith("<@") && userInput.endsWith(">")) {
+ targetUserId = userInput.slice(2, -1).replace("!", "");
+ } else if (/^\d{17,19}$/.test(userInput)) {
+ targetUserId = userInput;
+ } else {
+ await replyWithCleanup(
+ message,
+ "❌ Invalid user format. Use a user mention (@user) or user ID.",
+ );
+
+ return;
+ }
+
+ const targetRoleIds: string[] = [];
+
+ for (const roleInput of roleInputs)
+ if (roleInput.startsWith("<@&") && roleInput.endsWith(">")) {
+ targetRoleIds.push(roleInput.slice(3, -1));
+ } else if (/^\d{17,19}$/.test(roleInput)) {
+ targetRoleIds.push(roleInput);
+ } else {
+ await replyWithCleanup(
+ message,
+ `❌ Invalid role format: ${roleInput}. Use a role mention (@role) or role ID.`,
+ );
+
+ return;
+ }
+
+ const targetUser = await message.client.users.fetch(targetUserId);
+
+ if (!targetUser) {
+ await replyWithCleanup(message, "❌ User not found.");
+
+ return;
+ }
+
+ const guild = message.client.guilds.cache.get(serverId);
+
+ if (!guild) {
+ await replyWithCleanup(
+ message,
+ `❌ Server with ID ${serverId} not found or bot is not in that server.`,
+ );
+
+ return;
+ }
+
+ const targetMember = await guild.members.fetch(targetUserId);
+
+ if (!targetMember) {
+ await replyWithCleanup(message, `❌ User is not a member of ${guild.name}.`);
+
+ return;
+ }
+
+ const results: string[] = [];
+
+ for (const targetRoleId of targetRoleIds) {
+ const role = guild.roles.cache.get(targetRoleId);
+
+ if (!role) {
+ await replyWithCleanup(message, `❌ Role with ID ${targetRoleId} not found in ${guild.name}.`);
+
+ return;
+ }
+
+ const hasRole = targetMember.roles.cache.has(targetRoleId);
+
+ if (hasRole) {
+ await targetMember.roles.remove(role);
+ results.push(`Removed **${role.name}**`);
+ } else {
+ await targetMember.roles.add(role);
+ results.push(`Added **${role.name}**`);
+ }
+ }
+
+ const actionText = results.join(", ");
+
+ await replyWithCleanup(
+ message,
+ `✅ ${actionText} for **${targetUser.username}** in **${guild.name}**.`,
+ );
+ } catch (error) {
+ console.error("Error in role command:", error);
+ await replyWithCleanup(
+ message,
+ "❌ Failed to manage role. Check bot permissions and try again.",
+ );
+ }
+ }
+};