Skip to content

Commit 487968a

Browse files
feat: Add EventRoleManager for managing event notification roles (#112)
1 parent 538e299 commit 487968a

File tree

2 files changed

+103
-0
lines changed

2 files changed

+103
-0
lines changed

src/main.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from commands import admin_commands, gemini, help_menu, skullboard
2222
from constants.colours import LIGHT_YELLOW
2323
from utils import spam_detection, time
24+
from utils.event_roles import EventRoleManager
2425

2526
# Load environment variables from .env file
2627
load_dotenv()
@@ -44,12 +45,25 @@
4445

4546

4647
class DuckBot(commands.Bot):
48+
async def on_scheduled_event_user_add(self, event, user):
49+
"""Delegate to EventRoleManager."""
50+
await self.event_role_manager.on_scheduled_event_user_add(event, user)
51+
52+
async def on_scheduled_event_user_remove(self, event, user):
53+
"""Delegate to EventRoleManager."""
54+
await self.event_role_manager.on_scheduled_event_user_remove(event, user)
55+
56+
async def on_scheduled_event_update(self, before, after):
57+
"""Delegate to EventRoleManager."""
58+
await self.event_role_manager.on_scheduled_event_update(before, after)
59+
4760
def __init__(self):
4861
super().__init__(command_prefix="", intents=intents)
4962
self.synced = False # Make sure that the command tree will be synced only once
5063
self.skullboard_manager = skullboard.SkullboardManager(
5164
self
5265
) # Initialise SkullboardManager
66+
self.event_role_manager = EventRoleManager(self) # Initialise EventRoleManager
5367
self.prev_day = None
5468
self.expiry_loop = None
5569

src/utils/event_roles.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import logging
2+
3+
from discord.enums import EventStatus
4+
5+
6+
def get_event_role_name(event_name: str) -> str:
7+
"""Return the role name for a given event."""
8+
return f"Event: {event_name}"
9+
10+
11+
class EventRoleManager:
12+
"""Manages auto-assignment and deletion of event notification roles."""
13+
14+
def __init__(self, bot):
15+
self.bot = bot
16+
17+
async def on_scheduled_event_user_add(self, event, user):
18+
"""Auto-assigns a notification role (per event) when a user is interested in an event."""
19+
guild = self.bot.get_guild(event.guild_id)
20+
if not guild:
21+
return
22+
member = guild.get_member(user.id)
23+
if not member:
24+
member = await guild.fetch_member(user.id)
25+
role_name = get_event_role_name(event.name)
26+
role = next((r for r in guild.roles if r.name == role_name), None)
27+
if not role:
28+
try:
29+
role = await guild.create_role(
30+
name=role_name, reason=f"Auto-created for event: {event.name}"
31+
)
32+
logging.info(f"Created new event notification role: {role_name}")
33+
except Exception as e:
34+
logging.error(f"Failed to create event notification role: {e}")
35+
return
36+
if role and member:
37+
try:
38+
await member.add_roles(
39+
role, reason=f"Interested in event: {event.name}"
40+
)
41+
logging.info(
42+
f"Added event notification role '{role_name}' to {member.display_name} for event {event.name}"
43+
)
44+
except Exception as e:
45+
logging.error(f"Failed to add event notification role: {e}")
46+
47+
async def on_scheduled_event_user_remove(self, event, user):
48+
"""Removes the notification role (per event) if user is no longer interested in the event."""
49+
guild = self.bot.get_guild(event.guild_id)
50+
if not guild:
51+
return
52+
member = guild.get_member(user.id)
53+
if not member:
54+
member = await guild.fetch_member(user.id)
55+
role_name = get_event_role_name(event.name)
56+
role = next((r for r in guild.roles if r.name == role_name), None)
57+
if role and member:
58+
try:
59+
await member.remove_roles(
60+
role, reason=f"No longer interested in event: {event.name}"
61+
)
62+
logging.info(
63+
f"Removed event notification role '{role_name}' from {member.display_name} for event {event.name}"
64+
)
65+
except Exception as e:
66+
logging.error(f"Failed to remove event notification role: {e}")
67+
68+
async def on_scheduled_event_update(self, before, after):
69+
"""Deletes the notification role (per event) after the event ends or is cancelled."""
70+
if before.status != after.status and after.status in (
71+
EventStatus.completed,
72+
EventStatus.cancelled,
73+
):
74+
guild = self.bot.get_guild(after.guild_id)
75+
if not guild:
76+
return
77+
role_name = get_event_role_name(after.name)
78+
role = next((r for r in guild.roles if r.name == role_name), None)
79+
if not role:
80+
return
81+
try:
82+
await role.delete(
83+
reason=f"Event {after.name} ended or was cancelled; auto-deleted notification role."
84+
)
85+
logging.info(
86+
f"Deleted event notification role '{role_name}' after event {after.name} ended or was cancelled."
87+
)
88+
except Exception as e:
89+
logging.error(f"Failed to delete event notification role: {e}")

0 commit comments

Comments
 (0)