2023-03-17 02:12:53 -04:00
import discord
2023-08-08 00:02:24 -04:00
from pytimeparse2 import disable_dateutil , parse
from discord import ui
2023-08-08 00:37:31 -04:00
from redbot . core import Config , commands , app_commands
2023-03-17 02:12:53 -04:00
class Shortmute ( commands . Cog ) :
2023-08-08 00:02:24 -04:00
""" Allows staff members to shortmute individuals for up to 30 minutes, using Discord ' s Timeouts feature. """
2023-03-17 02:12:53 -04:00
2023-08-08 00:02:24 -04:00
def __init__ ( self , bot ) - > None :
2023-03-17 02:12:53 -04:00
self . bot = bot
2023-08-08 00:02:24 -04:00
self . config = Config . get_conf ( self , identifier = 25781647388294 , force_registration = True )
2023-03-17 02:12:53 -04:00
self . config . register_guild (
2023-08-08 00:18:26 -04:00
dm = True ,
2023-08-08 00:45:21 -04:00
logging_channels = [ ] ,
immune_roles = [ ]
2023-03-17 02:12:53 -04:00
)
2023-08-08 00:02:24 -04:00
@app_commands.command ( )
@app_commands.rename ( target = ' member ' )
2023-08-08 00:33:53 -04:00
async def shortmute ( self , interaction : discord . Interaction , target : discord . Member , duration : int , reason : str , evidence_link : str = None , evidence_image : discord . Attachment = None ) :
2023-08-08 00:02:24 -04:00
""" Shortmute someone for up to 30m.
Parameters
- - - - - - - - - - -
target : discord . Member
The member to shortmute
duration : int
The duration of the shortmute
reason : str
The reason for the shortmute
evidence_link : str = None
An image link to evidence for the shortmute , do not use with evidence_image
2023-08-08 00:33:53 -04:00
evidence_image : discord . Attachment = None
2023-08-08 00:02:24 -04:00
An image file used as evidence for the shortmute , do not use with evidence_link
"""
passed_info = {
" target " : target ,
" duration " : duration ,
" reason " : reason ,
2023-08-08 01:26:43 -04:00
" interaction " : interaction ,
" color " : await self . bot . get_embed_color ( None )
2023-03-17 02:12:53 -04:00
}
2023-08-08 00:02:24 -04:00
if evidence_image and evidence_link :
2023-08-08 00:51:07 -04:00
await interaction . response . send_message ( content = " You ' ve provided both the `evidence_image` and the `evidence_link` arguments! Please only use one or the other. " , ephemeral = True )
2023-08-08 00:02:24 -04:00
return
elif evidence_link :
evidence = evidence_link
elif evidence_image :
evidence = str ( evidence_image )
2023-08-08 00:51:07 -04:00
immune_roles_list = await self . config . guild ( interaction . guild ) . immune_roles ( )
for role_id in immune_roles_list :
role = interaction . guild . get_role ( role_id )
if role in target . roles :
await interaction . response . send_message ( content = " You ' re trying to shortmute someone who is immune from shortmuting. " , ephemeral = True )
return
2023-08-08 00:02:24 -04:00
if duration == 1 or duration == - 1 :
readable_duration = f " { duration } minute "
passed_info . update ( {
" readable_duration " : readable_duration
} )
else :
readable_duration = f " { duration } minutes "
passed_info . update ( {
" readable_duration " : readable_duration
} )
if duration > 30 :
await interaction . response ( content = f " { readable_duration } is longer than the 30 minutes you are allowed to shortmute users for. " , ephemeral = True )
return
elif duration < 1 :
await interaction . response ( content = f " Please shortmute the user for longer than { readable_duration } ! The maximum duration is 30 minutes. " , ephemeral = True )
return
2023-08-08 01:23:32 -04:00
embed = discord . Embed ( title = " Are you sure? " , description = f " Moderator: { interaction . user . mention } \n Target: { target . mention } \n Duration: { readable_duration } \n Reason: ` { reason } ` " , color = await self . bot . get_embed_color ( None ) )
2023-08-08 00:02:24 -04:00
if evidence :
2023-08-08 00:58:00 -04:00
embed . set_image ( url = evidence )
2023-08-08 00:02:24 -04:00
passed_info . update ( {
" evidence " : evidence
} )
await interaction . response . send_message ( embed = embed , view = self . ShortmuteButtons ( timeout = 180 , passed_info = passed_info ) , ephemeral = True )
class ShortmuteButtons ( ui . View ) :
def __init__ ( self , timeout , passed_info : dict ) :
super ( ) . __init__ ( )
self . timeout = timeout
self . passed_info = passed_info
self . config = Config . get_conf ( None , cog_name = ' Shortmute ' , identifier = 25781647388294 )
@ui.button ( label = " Yes " , style = discord . ButtonStyle . success )
async def shortmute_button_yes ( self , button : ui . Button , interaction : discord . Interaction ) :
disable_dateutil ( )
target = self . passed_info [ ' target ' ]
duration = self . passed_info [ ' duration ' ]
readable_duration = self . passed_info [ ' readable_duration ' ]
reason = self . passed_info [ ' reason ' ]
old_interaction = self . passed_info [ ' interaction ' ]
2023-08-08 01:26:43 -04:00
color = self . passed_info [ ' color ' ]
2023-08-08 01:29:01 -04:00
timedelta = parse ( f ' { duration } minutes ' , as_timedelta = True )
2023-08-08 01:26:43 -04:00
edit_embed = discord . Embed ( title = " Shortmute confirmed! " , description = f " Moderator: { old_interaction . user . mention } \n Target: { target . mention } \n Duration: { readable_duration } \n Reason: ` { reason } ` " , color = color )
2023-08-08 00:02:24 -04:00
if self . passed_info . get ( ' evidence ' ) :
evidence = self . passed_info [ ' evidence ' ]
2023-08-08 00:58:00 -04:00
edit_embed . set_image ( url = evidence )
2023-08-08 01:26:43 -04:00
old_message = await old_interaction . edit_original_response ( embed = edit_embed , view = None )
2023-08-08 01:27:43 -04:00
await target . timeout ( timedelta , reason = f " User shortmuted for { readable_duration } by { old_interaction . user . name } ( { old_interaction . user . id } ) for: { reason } " )
2023-08-08 01:07:20 -04:00
await interaction . channel . send ( content = f " { target . mention } shortmuted for { readable_duration } by { old_interaction . user . mention } for: ` { reason } ` " )
2023-08-08 00:51:19 -04:00
if await self . config . guild ( old_interaction . guild ) . dm ( ) is True :
2023-08-08 01:26:43 -04:00
dm_embed = discord . Embed ( title = f " You ' ve been shortmuted in { old_interaction . guild . name } ! " , description = f " Moderator: { old_interaction . user . mention } \n Target: { target . mention } \n Duration: { readable_duration } \n Reason: ` { reason } ` " , color = color )
2023-08-08 00:02:24 -04:00
if evidence :
2023-08-08 00:58:00 -04:00
dm_embed . set_image ( url = evidence )
2023-08-08 00:02:24 -04:00
try :
await target . send ( embed = dm_embed )
except discord . HTTPException as error :
await old_message . edit ( content = " Could not message the target, user most likely has Direct Messages disabled. " )
2023-08-08 00:51:19 -04:00
logging_channels_list = await self . config . guild ( old_interaction . guild ) . logging_channels ( )
2023-08-08 00:24:15 -04:00
if logging_channels_list :
2023-08-08 01:26:43 -04:00
logging_embed = discord . Embed ( title = " Shortmute " , description = f " Moderator: { old_interaction . user . mention } ( { old_interaction . user . id } ) \n Target: { target . mention } ( { target . id } ) \n Duration: { readable_duration } \n Reason: ` { reason } ` " , color = color )
2023-08-08 00:24:15 -04:00
if evidence :
2023-08-08 00:58:00 -04:00
logging_embed . set_image ( url = evidence )
2023-08-08 00:24:15 -04:00
for channel_id in logging_channels_list :
channel_obj = old_interaction . guild . get_channel ( channel_id )
await channel_obj . send ( embed = logging_embed )
2023-08-08 00:02:24 -04:00
@ui.button ( label = " No " , style = discord . ButtonStyle . danger )
async def shortmute_button_no ( self , button : ui . Button , interaction : discord . Interaction ) :
message = await self . passed_info [ ' interaction ' ] . edit_original_response ( content = " Command cancelled. " , view = None , embed = None )
await message . delete ( delay = 3 )
2023-08-08 00:39:01 -04:00
@commands.group ( name = ' shortmuteset ' , autohelp = True )
@commands.guild_only ( )
2023-08-08 00:45:21 -04:00
@commands.admin ( )
2023-08-08 00:39:01 -04:00
async def shortmute_config ( self , ctx : commands . Context ) :
""" This command group is used to configure the `/shortmute` slash command. """
2023-08-08 00:18:26 -04:00
2023-08-08 00:39:01 -04:00
@shortmute_config.command ( name = ' addchannel ' )
@commands.guild_only ( )
2023-08-08 00:45:21 -04:00
@commands.admin ( )
2023-08-08 00:39:01 -04:00
async def shortmute_config_addchannel ( self , ctx : commands . Context , channel : discord . TextChannel = None ) :
""" This command changes where the `/shortmute` slash command will log shortmutes. You can set multiple channels as well! """
2023-08-08 00:51:19 -04:00
current_list = await self . config . guild ( ctx . guild ) . logging_channels ( )
2023-08-08 00:39:01 -04:00
if channel :
2023-08-08 00:18:26 -04:00
if channel . id in current_list :
2023-08-08 00:39:01 -04:00
await ctx . send ( " This channel is already in the logging channel list! " )
return
else :
current_list . append ( channel . id )
2023-08-08 00:51:19 -04:00
await self . config . guild ( ctx . guild ) . logging_channels . set ( current_list )
2023-08-08 00:39:01 -04:00
await ctx . send ( f " { channel . mention } has been added to the logging channels list. " )
else :
already_in_list = [ ]
for channel_id in current_list :
channel_obj = ctx . guild . get_channel ( channel_id )
if channel_obj :
already_in_list . append ( channel_obj . mention )
if already_in_list :
await ctx . send ( " Channels already in the list: \n " + " \n " . join ( already_in_list ) )
2023-08-08 00:18:26 -04:00
else :
2023-08-08 00:39:01 -04:00
await ctx . send ( " Please provide a valid channel. " )
@shortmute_config.command ( name = ' removechannel ' )
@commands.guild_only ( )
2023-08-08 00:45:21 -04:00
@commands.admin ( )
2023-08-08 00:39:01 -04:00
async def shortmute_config_removechannel ( self , ctx : commands . Context , channel : discord . TextChannel = None ) :
""" This command removes a channel from the `/shortmute`slash command ' s logging channels list. """
2023-08-08 00:51:19 -04:00
current_list = await self . config . guild ( ctx . guild ) . logging_channels ( )
2023-08-08 00:39:01 -04:00
if channel . id in current_list :
current_list . remove ( channel . id )
2023-08-08 00:51:19 -04:00
await self . config . guild ( ctx . guild ) . logging_channels . set ( current_list )
2023-08-08 00:39:01 -04:00
await ctx . send ( f " { channel . mention } has been removed from the logging channels list. " )
else :
await ctx . send ( " Please provide a valid channel that exists in the logging channels list. " )
2023-08-08 00:18:26 -04:00
2023-08-08 00:45:21 -04:00
@shortmute_config.command ( name = ' addrole ' )
@commands.guild_only ( )
@commands.admin ( )
async def shortmute_config_addrole ( self , ctx : commands . Context , role : discord . Role = None ) :
""" This command adds roles to the immune roles list for immunity from the the `/shortmute` slash command. """
2023-08-08 00:51:19 -04:00
current_list = await self . config . guild ( ctx . guild ) . immune_roles ( )
2023-08-08 00:45:21 -04:00
if role :
if role . id in current_list :
await ctx . send ( " This role is already in the immune roles list! " )
return
else :
current_list . append ( role . id )
2023-08-08 00:51:19 -04:00
await self . config . guild ( ctx . guild ) . immune_roles . set ( current_list )
2023-08-08 00:54:00 -04:00
await ctx . send ( f " { role . mention } has been added to the immune roles list. " , allowed_mentions = discord . AllowedMentions ( roles = False ) )
2023-08-08 00:45:21 -04:00
else :
already_in_list = [ ]
for role_id in current_list :
role_obj = ctx . guild . get_role ( role_id )
if role_obj :
already_in_list . append ( role_obj . mention )
if already_in_list :
await ctx . send ( " Roles already in the immune roles list: \n " + " \n " . join ( already_in_list ) , allowed_mentions = discord . AllowedMentions ( roles = False ) )
else :
await ctx . send ( " Please provide a valid role. " )
@shortmute_config.command ( name = ' removerole ' )
@commands.guild_only ( )
@commands.admin ( )
async def shortmute_config_removerole ( self , ctx : commands . Context , role : discord . Role = None ) :
""" This command removes roles from the immune roles list to remove immunity from the the `/shortmute` slash command. """
2023-08-08 00:51:19 -04:00
current_list = await self . config . guild ( ctx . guild ) . immune_roles ( )
2023-08-08 00:45:21 -04:00
if role . id in current_list :
current_list . remove ( role . id )
2023-08-08 00:51:19 -04:00
await self . config . guild ( ctx . guild ) . immune_roles . set ( current_list )
2023-08-08 00:45:21 -04:00
await ctx . send ( f " { role . mention } has been removed from the immune roles list. " , allowed_mentions = discord . AllowedMentions ( roles = False ) )
else :
await ctx . send ( " Please provide a valid role that exists in the immune roles list. " )
2023-08-08 00:39:01 -04:00
@shortmute_config.command ( name = ' dm ' )
@commands.guild_only ( )
2023-08-08 00:45:21 -04:00
@commands.admin ( )
2023-08-08 00:39:01 -04:00
async def shortmute_config_dm ( self , ctx : commands . Context , enabled : bool = None ) :
""" This command changes if the `/shortmute` slash command Direct Messages its target. """
2023-08-08 00:51:19 -04:00
old_value = await self . config . guild ( ctx . guild ) . dm ( )
2023-08-08 00:39:01 -04:00
if enabled :
2023-08-08 00:51:19 -04:00
await self . config . guild ( ctx . guild ) . dm . set ( enabled )
2023-08-08 00:39:01 -04:00
await ctx . send ( content = f " Shortmute Direct Message setting changed! \n Old value: ` { old_value } ` \n New value: ` { enabled } ` " )
elif old_value is True :
await ctx . send ( content = " Shortmute Direct Messages are currently enabled! " )
elif old_value is False :
await ctx . send ( content = " Shortmute Direct Messages are currently disabled! " )