From d69ebeb1c90c7c133664ca866684ba4c4571d7c9 Mon Sep 17 00:00:00 2001 From: Ali Hammoud Date: Wed, 5 Nov 2025 05:59:56 +0200 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=8C=9F=20feat:=20add=20auto=20role=20?= =?UTF-8?q?assignment=20based=20on=20other=20roels?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/env.ts | 3 +++ src/events/auto-roles.ts | 24 ++++++++++++++++++++++++ src/events/index.ts | 2 ++ src/util/member.ts | 5 +++++ 4 files changed, 34 insertions(+) create mode 100644 src/events/auto-roles.ts create mode 100644 src/util/member.ts diff --git a/src/env.ts b/src/env.ts index cc90dea..c4be473 100644 --- a/src/env.ts +++ b/src/env.ts @@ -33,6 +33,9 @@ export const config = { channelId: requireEnv('GUIDES_CHANNEL_ID'), trackerPath: optionalEnv('GUIDES_TRACKER_PATH'), }, + roleA: requireEnv('ROLE_A_ID'), + roleB: requireEnv('ROLE_B_ID'), + roleC: requireEnv('ROLE_C_ID'), // Add more config sections as needed: // database: { // url: requireEnv('DATABASE_URL'), diff --git a/src/events/auto-roles.ts b/src/events/auto-roles.ts new file mode 100644 index 0000000..37c445e --- /dev/null +++ b/src/events/auto-roles.ts @@ -0,0 +1,24 @@ +import { Events } from 'discord.js'; +import { config } from '../env.js'; +import { createEvent } from '../util/events.js'; +import { memberHasRoles } from '../util/member.js'; + +export const autoRoleEvent = createEvent( + { + name: Events.GuildMemberUpdate, + }, + async (_, newMember) => { + const hasRoleC = memberHasRoles(newMember, config.roleC); + if (hasRoleC) { + return; + } + const hasRequiredRoles = memberHasRoles(newMember, config.roleA, config.roleB); + if (hasRequiredRoles) { + try { + await newMember.roles.add(config.roleC); + } catch (error) { + console.error(`Failed to add roleC to ${newMember.user.tag}:`, error); + } + } + } +); diff --git a/src/events/index.ts b/src/events/index.ts index 86d64fa..c524685 100644 --- a/src/events/index.ts +++ b/src/events/index.ts @@ -1,3 +1,4 @@ +import { autoRoleEvent } from './auto-roles.js'; import { guildCreateEvent } from './guild-create.js'; import { hasVarEvent } from './has-var.js'; import { interactionCreateEvent } from './interaction-create.js'; @@ -11,4 +12,5 @@ export const events = [ justAskEvent, hasVarEvent, interactionCreateEvent, + autoRoleEvent, ] as DiscordEvent[]; diff --git a/src/util/member.ts b/src/util/member.ts new file mode 100644 index 0000000..4ea47f4 --- /dev/null +++ b/src/util/member.ts @@ -0,0 +1,5 @@ +import type { GuildMember } from 'discord.js'; + +export const memberHasRoles = (member: GuildMember, ...roles: string[]): boolean => { + return roles.every((roleId) => member.roles.cache.has(roleId)); +}; From f08b0f316ae104d8f7bf869d0b1ad9b035ffbb8a Mon Sep 17 00:00:00 2001 From: Ali Hammoud Date: Wed, 5 Nov 2025 20:11:24 +0200 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=94=A8=20refactor:=20rename=20memberH?= =?UTF-8?q?asRoles=20to=20hasRoles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/util/member.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/member.ts b/src/util/member.ts index 4ea47f4..33adab7 100644 --- a/src/util/member.ts +++ b/src/util/member.ts @@ -1,5 +1,5 @@ import type { GuildMember } from 'discord.js'; -export const memberHasRoles = (member: GuildMember, ...roles: string[]): boolean => { +export const hasRoles = (member: GuildMember, ...roles: string[]): boolean => { return roles.every((roleId) => member.roles.cache.has(roleId)); }; From 3de135649cd3b489cb74755247609a991957427a Mon Sep 17 00:00:00 2001 From: Ali Hammoud Date: Wed, 5 Nov 2025 20:13:09 +0200 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=94=A8=20refactor:=20remove=20unecess?= =?UTF-8?q?ary=20return=20by=20switching=20the=20condition=20'hasRoleC`=20?= =?UTF-8?q?->=20`!hasRoleC`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/events/auto-roles.ts | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/events/auto-roles.ts b/src/events/auto-roles.ts index 37c445e..dabb624 100644 --- a/src/events/auto-roles.ts +++ b/src/events/auto-roles.ts @@ -1,23 +1,22 @@ import { Events } from 'discord.js'; import { config } from '../env.js'; import { createEvent } from '../util/events.js'; -import { memberHasRoles } from '../util/member.js'; +import { hasRoles } from '../util/member.js'; export const autoRoleEvent = createEvent( { name: Events.GuildMemberUpdate, }, async (_, newMember) => { - const hasRoleC = memberHasRoles(newMember, config.roleC); - if (hasRoleC) { - return; - } - const hasRequiredRoles = memberHasRoles(newMember, config.roleA, config.roleB); - if (hasRequiredRoles) { - try { - await newMember.roles.add(config.roleC); - } catch (error) { - console.error(`Failed to add roleC to ${newMember.user.tag}:`, error); + const hasRoleC = hasRoles(newMember, config.roleC); + if (!hasRoleC) { + const hasRequiredRoles = hasRoles(newMember, config.roleA, config.roleB); + if (hasRequiredRoles) { + try { + await newMember.roles.add(config.roleC); + } catch (error) { + console.error(`Failed to add roleC to ${newMember.user.tag}:`, error); + } } } } From 947c2d5fc4548bca69e57b8cd91b69591d279b03 Mon Sep 17 00:00:00 2001 From: Ali Hammoud Date: Wed, 5 Nov 2025 21:16:20 +0200 Subject: [PATCH 4/4] feat: remove auto-role assignment from events for later setup --- src/events/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/events/index.ts b/src/events/index.ts index c524685..86d64fa 100644 --- a/src/events/index.ts +++ b/src/events/index.ts @@ -1,4 +1,3 @@ -import { autoRoleEvent } from './auto-roles.js'; import { guildCreateEvent } from './guild-create.js'; import { hasVarEvent } from './has-var.js'; import { interactionCreateEvent } from './interaction-create.js'; @@ -12,5 +11,4 @@ export const events = [ justAskEvent, hasVarEvent, interactionCreateEvent, - autoRoleEvent, ] as DiscordEvent[];