@@ -282,3 +282,85 @@ def after_callback(error):
282282 await message .channel .send (f"Error joining voice channel: { str (e )} " )
283283 else :
284284 await message .channel .send ("You need to be in a voice channel first!" )
285+
286+ class RoleHandlerClient (discord .Client ):
287+ def __init__ (self , * , intents : discord .Intents , unique : bool = False , ** kwargs ):
288+ super ().__init__ (intents = intents , ** kwargs )
289+ self .unique = unique
290+ self .tree = discord .app_commands .CommandTree (self )
291+
292+ async def setup_hook (self ):
293+ @self .tree .command (name = "claim" , description = "Claim a role by its name" )
294+ async def claim (interaction : discord .Interaction , identifier : str ):
295+ await self ._handle_claim (interaction , identifier )
296+
297+ @self .tree .command (name = "unclaim" , description = "Drop a role you have claimed" )
298+ async def unclaim (interaction : discord .Interaction , identifier : str ):
299+ await self ._handle_unclaim (interaction , identifier )
300+
301+ await self .tree .sync ()
302+
303+ async def on_ready (self ):
304+ if (self .user is not None ):
305+ print (f"Logged in as { self .user } (ID: { self .user .id } )" )
306+ print ("------" )
307+
308+ async def _handle_claim (self , interaction : discord .Interaction , identifier : str ):
309+ if not isinstance (interaction .user , discord .Member ):
310+ await interaction .response .send_message ("This command can only be used in a server." , ephemeral = True )
311+ return
312+ if interaction .guild is not None :
313+ role = discord .utils .get (interaction .guild .roles , name = identifier )
314+ if not role :
315+ await interaction .response .send_message (f"Role '{ identifier } ' not found." , ephemeral = True )
316+ return
317+ else :
318+ await interaction .response .send_message ("This command can only be used in a server." , ephemeral = True )
319+ return
320+
321+ if self .unique and len (interaction .user .roles ) > 1 :
322+ for user_role in interaction .user .roles :
323+ if user_role .name != "@everyone" and user_role != role :
324+ await interaction .response .send_message (
325+ f"You already have the role '{ user_role .name } '. "
326+ f"Use `/unclaim { user_role .name } ` to remove it first." ,
327+ ephemeral = True
328+ )
329+ return
330+ if role in interaction .user .roles :
331+ await interaction .response .send_message (f"You already have the '{ identifier } ' role." , ephemeral = True )
332+ return
333+
334+ try :
335+ await interaction .user .add_roles (role )
336+ await interaction .response .send_message (f"Successfully claimed the '{ identifier } ' role!" , ephemeral = True )
337+ except discord .Forbidden :
338+ await interaction .response .send_message ("I don't have permission to assign that role." , ephemeral = True )
339+ except Exception as e :
340+ await interaction .response .send_message (f"An error occurred: { str (e )} " , ephemeral = True )
341+
342+ async def _handle_unclaim (self , interaction : discord .Interaction , identifier : str ):
343+ if not isinstance (interaction .user , discord .Member ):
344+ await interaction .response .send_message ("This command can only be used in a server." , ephemeral = True )
345+ return
346+
347+ if interaction .guild is None :
348+ await interaction .response .send_message ("This command can only be used in a server." , ephemeral = True )
349+ return
350+
351+ role = discord .utils .get (interaction .guild .roles , name = identifier )
352+ if not role :
353+ await interaction .response .send_message (f"Role '{ identifier } ' not found." , ephemeral = True )
354+ return
355+
356+ if role not in interaction .user .roles :
357+ await interaction .response .send_message (f"You don't have the '{ identifier } ' role." , ephemeral = True )
358+ return
359+
360+ try :
361+ await interaction .user .remove_roles (role )
362+ await interaction .response .send_message (f"Successfully removed the '{ identifier } ' role!" , ephemeral = True )
363+ except discord .Forbidden :
364+ await interaction .response .send_message ("I don't have permission to remove that role." , ephemeral = True )
365+ except Exception as e :
366+ await interaction .response .send_message (f"An error occurred: { str (e )} " , ephemeral = True )
0 commit comments