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 02:17:13 -04:00
from discord . ext . commands import Bot
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-11 16:40:01 -04:00
confirm = True ,
2023-08-08 00:45:21 -04:00
logging_channels = [ ] ,
2023-08-08 02:17:13 -04:00
immune_roles = [ ] ,
blacklisted_users = [ ]
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-11 16:40:01 -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 , skip_confirmation : bool = 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
2023-08-11 16:40:01 -04:00
skip_confirmation : bool = None
2023-08-08 01:44:50 -04:00
This allows you skip the confirmation prompt and immediately shortmute the user .
2023-08-08 00:02:24 -04:00
"""
2023-08-08 01:44:50 -04:00
disable_dateutil ( )
timedelta = parse ( f ' { duration } minutes ' , as_timedelta = True )
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 02:00:25 -04:00
else :
evidence = None
2023-08-11 16:40:01 -04:00
if skip_confirmation is None :
2023-08-11 16:43:05 -04:00
skip_confirmation = not bool ( await self . config . guild ( interaction . guild ) . confirm ( ) )
2023-08-08 02:05:37 -04:00
passed_info = {
" target " : target ,
" timedelta " : timedelta ,
" reason " : reason ,
" interaction " : interaction ,
" color " : await self . bot . get_embed_color ( None ) ,
" evidence " : evidence
}
2023-08-08 02:17:13 -04:00
blacklisted_users_list = await self . config . guild ( interaction . guild ) . blacklisted_users ( )
for user_id in blacklisted_users_list :
if user_id == interaction . user . id :
await interaction . response . send_message ( content = " You are blacklisted from `/shortmute`! " , ephemeral = True )
return
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 "
else :
readable_duration = f " { duration } minutes "
2023-08-08 10:10:14 -04:00
passed_info . update ( {
" readable_duration " : readable_duration
} )
2023-08-08 00:02:24 -04:00
if duration > 30 :
2023-08-08 01:37:45 -04:00
await interaction . response . send_message ( content = f " { readable_duration } is longer than the 30 minutes you are allowed to shortmute users for. " , ephemeral = True )
2023-08-08 00:02:24 -04:00
return
elif duration < 1 :
2023-08-08 01:37:45 -04:00
await interaction . response . send_message ( content = f " Please shortmute the user for longer than { readable_duration } ! The maximum duration is 30 minutes. " , ephemeral = True )
2023-08-08 00:02:24 -04:00
return
2023-08-08 01:44:50 -04:00
if skip_confirmation is False :
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 01:58:38 -04:00
embed . set_footer ( text = " /shortmute " )
2023-08-08 01:44:50 -04:00
if evidence :
embed . set_image ( url = evidence )
await interaction . response . send_message ( embed = embed , view = self . ShortmuteButtons ( timeout = 180 , passed_info = passed_info ) , ephemeral = True )
elif skip_confirmation is True :
edit_embed = discord . Embed ( title = " Shortmute confirmed! " , 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 01:58:38 -04:00
edit_embed . set_footer ( text = " /shortmute " )
2023-08-08 01:44:50 -04:00
if evidence :
edit_embed . set_image ( url = evidence )
2023-08-08 01:48:24 -04:00
message = await interaction . response . send_message ( embed = edit_embed , ephemeral = True )
2023-08-08 01:44:50 -04:00
await target . timeout ( timedelta , reason = f " User shortmuted for { readable_duration } by { interaction . user . name } ( { interaction . user . id } ) for: { reason } " )
2023-09-18 13:39:59 -04:00
shortmute_msg = await interaction . channel . send ( content = f " { target . mention } was shortmuted for { readable_duration } by { interaction . user . mention } for: ` { reason } ` " )
2023-08-08 01:44:50 -04:00
if await self . config . guild ( interaction . guild ) . dm ( ) is True :
2023-09-18 13:39:59 -04:00
dm_embed = discord . Embed ( title = f " You ' ve been shortmuted in { interaction . guild . name } ! " , description = f " **Moderator:** { interaction . user . mention } \n **Target:** { target . mention } \n **Message:** { shortmute_msg . jump_url } \n **Duration:** { readable_duration } \n **Reason:** ` { reason } ` " , color = await self . bot . get_embed_color ( None ) )
2023-08-08 01:58:38 -04:00
dm_embed . set_footer ( text = " /shortmute " )
2023-08-08 01:44:50 -04:00
if evidence :
dm_embed . set_image ( url = evidence )
try :
await target . send ( embed = dm_embed )
except discord . HTTPException as error :
await message . edit ( content = " Could not message the target, user most likely has Direct Messages disabled. " )
2023-08-11 16:31:35 -04:00
logging_channels_list = await self . config . guild ( interaction . guild ) . logging_channels ( )
if logging_channels_list :
2023-09-18 13:39:59 -04:00
logging_embed = discord . Embed ( title = " User Shortmuted " , description = f " **Moderator:** { interaction . user . mention } ( { interaction . user . id } ) \n **Target:** { target . mention } ( { target . id } ) \n **Message:** { shortmute_msg . jump_url } \n **Duration:** { readable_duration } \n **Reason:** ` { reason } ` \n **Confirmation Skipped:** True " , color = await self . bot . get_embed_color ( None ) )
2023-08-11 16:31:35 -04:00
logging_embed . set_footer ( text = " /shortmute " )
if evidence :
logging_embed . set_image ( url = evidence )
for channel_id in logging_channels_list :
channel_obj = interaction . guild . get_channel ( channel_id )
await channel_obj . send ( embed = logging_embed )
2023-08-08 00:02:24 -04:00
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 ' ]
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:44:50 -04:00
timedelta = self . passed_info [ ' timedelta ' ]
2023-08-08 02:03:44 -04:00
evidence = self . passed_info [ ' evidence ' ]
2023-08-08 01:36:22 -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 02:03:44 -04:00
if 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:32:18 -04:00
await old_interaction . channel . send ( content = f " { target . mention } was 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:36:22 -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 01:58:38 -04:00
dm_embed . set_footer ( text = " /shortmute " )
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-11 16:31:35 -04:00
logging_channels_list = await self . config . guild ( old_interaction . guild ) . logging_channels ( )
if logging_channels_list :
logging_embed = discord . Embed ( title = " User Shortmuted " , description = f " **Moderator:** { old_interaction . user . mention } ( { old_interaction . user . id } ) \n **Target:** { target . mention } ( { target . id } ) \n **Duration:** { readable_duration } \n **Reason:** ` { reason } ` \n **Confirmation Skipped:** False " , color = color )
logging_embed . set_footer ( text = " /shortmute " )
if evidence :
logging_embed . set_image ( url = evidence )
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 ) :
2023-08-08 02:33:43 -04:00
""" Used to configure the /shortmute command. """
2023-08-08 00:18:26 -04:00
2023-08-08 02:28:01 -04:00
@shortmute_config.group ( name = ' channel ' , invoke_without_command = True , aliases = [ ' channels ' ] )
2023-08-08 00:39:01 -04:00
@commands.guild_only ( )
2023-08-08 00:45:21 -04:00
@commands.admin ( )
2023-08-08 02:25:47 -04:00
async def shortmute_config_channel ( self , ctx : commands . Context ) :
2023-08-08 02:34:47 -04:00
""" Manages /shortmute logging. """
2023-08-08 02:25:47 -04:00
current_list = await self . config . guild ( ctx . guild ) . logging_channels ( )
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 ) )
else :
2023-08-08 02:38:17 -04:00
await ctx . send ( " No channels are currently in the logging list. " )
2023-08-08 02:25:47 -04:00
@shortmute_config_channel.command ( name = ' add ' )
@commands.guild_only ( )
@commands.admin ( )
async def shortmute_config_channel_add ( self , ctx : commands . Context , channel : discord . TextChannel = None ) :
2023-08-08 02:39:40 -04:00
""" Adds a channel to the 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 :
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 :
2023-08-08 02:25:47 -04:00
await ctx . send ( " Please provide a valid channel! " )
2023-08-08 00:39:01 -04:00
2023-08-08 02:25:47 -04:00
@shortmute_config_channel.command ( name = ' remove ' )
2023-08-08 00:39:01 -04:00
@commands.guild_only ( )
2023-08-08 00:45:21 -04:00
@commands.admin ( )
2023-08-08 02:25:47 -04:00
async def shortmute_config_channel_remove ( self , ctx : commands . Context , channel : discord . TextChannel = None ) :
2023-08-08 02:39:40 -04:00
""" Removes a channel from the 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 02:28:01 -04:00
@shortmute_config.group ( name = ' role ' , invoke_without_command = True , aliases = [ ' roles ' ] )
2023-08-08 02:25:47 -04:00
@commands.guild_only ( )
@commands.admin ( )
async def shortmute_config_role ( self , ctx : commands . Context ) :
2023-08-08 02:34:47 -04:00
""" Manages the immune roles list. """
2023-08-08 02:25:47 -04:00
current_list = await self . config . guild ( ctx . guild ) . immune_roles ( )
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 ) )
2023-08-08 02:38:17 -04:00
else :
await ctx . send ( " No roles are currently in the immune roles list. " )
2023-08-08 02:25:47 -04:00
@shortmute_config_role.command ( name = ' add ' )
2023-08-08 00:45:21 -04:00
@commands.guild_only ( )
@commands.admin ( )
2023-08-08 02:25:47 -04:00
async def shortmute_config_role_add ( self , ctx : commands . Context , role : discord . Role = None ) :
2023-08-08 02:40:03 -04:00
""" Adds roles to the immune roles list. """
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 :
2023-08-08 02:25:47 -04:00
await ctx . send ( " Please provide a valid role. " )
2023-08-08 00:45:21 -04:00
2023-08-08 02:25:47 -04:00
@shortmute_config_role.command ( name = ' remove ' )
2023-08-08 00:45:21 -04:00
@commands.guild_only ( )
@commands.admin ( )
2023-08-08 02:25:47 -04:00
async def shortmute_config_role_remove ( self , ctx : commands . Context , role : discord . Role = None ) :
2023-08-08 02:40:03 -04:00
""" Removes roles from the immune roles list. """
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 02:25:47 -04:00
@shortmute_config.group ( name = ' blacklist ' , invoke_without_command = True )
@commands.guild_only ( )
@commands.admin ( )
async def shortmute_config_blacklist ( self , ctx : commands . Context ) :
2023-08-08 02:34:47 -04:00
""" Manages the blacklist. """
2023-08-08 02:25:47 -04:00
current_list = await self . config . guild ( ctx . guild ) . blacklisted_users ( )
already_in_list = [ ]
for user_id in current_list :
user_obj = await Bot . fetch_user ( user_id )
if user_obj :
already_in_list . append ( user_obj . mention )
if already_in_list :
await ctx . send ( " Users already blacklisted: \n " + " \n " . join ( already_in_list ) , allowed_mentions = discord . AllowedMentions ( users = False ) )
2023-08-08 02:38:17 -04:00
else :
await ctx . send ( " No users are currently blacklisted. " )
2023-08-08 02:25:47 -04:00
@shortmute_config_blacklist.command ( name = ' add ' )
2023-08-08 02:17:13 -04:00
@commands.guild_only ( )
@commands.admin ( )
async def shortmute_config_blacklist_add ( self , ctx : commands . Context , user : discord . User = None ) :
2023-08-08 02:33:43 -04:00
""" Adds users to the /shortmute blacklist. """
2023-08-08 02:17:13 -04:00
current_list = await self . config . guild ( ctx . guild ) . blacklisted_users ( )
if user :
if user . id in current_list :
await ctx . send ( " That user is already in the blacklisted users list! " )
return
else :
current_list . append ( user . id )
await self . config . guild ( ctx . guild ) . blacklisted_users . set ( current_list )
await ctx . send ( f " { user . mention } has been blacklisted from using `/shortmute`. " , allowed_mentions = discord . AllowedMentions ( users = False ) )
else :
2023-08-08 02:25:47 -04:00
await ctx . send ( " Please provide a valid user. " )
2023-08-08 02:17:13 -04:00
2023-08-08 02:25:47 -04:00
@shortmute_config_blacklist.command ( name = ' remove ' )
2023-08-08 02:17:13 -04:00
@commands.guild_only ( )
@commands.admin ( )
async def shortmute_config_blacklist_remove ( self , ctx : commands . Context , user : discord . User = None ) :
2023-08-08 02:33:43 -04:00
""" Removes users from the /shortmute blacklist. """
2023-08-08 02:17:13 -04:00
current_list = await self . config . guild ( ctx . guild ) . blacklisted_users ( )
if user . id in current_list :
current_list . remove ( user . id )
await self . config . guild ( ctx . guild ) . blacklisted_users . set ( current_list )
await ctx . send ( f " { user . mention } has been removed from the `/shortmute` blacklist. " , allowed_mentions = discord . AllowedMentions ( users = False ) )
else :
await ctx . send ( " Please provide a valid user who is blacklisted from `/shortmute`. " )
2023-08-08 02:25:47 -04:00
@shortmute_config.command ( name = ' message ' )
2023-08-08 00:39:01 -04:00
@commands.guild_only ( )
2023-08-08 00:45:21 -04:00
@commands.admin ( )
2023-08-08 02:25:47 -04:00
async def shortmute_config_message ( self , ctx : commands . Context , enabled : bool = None ) :
2023-08-08 02:42:27 -04:00
""" Manages if /shortmute Direct Messages its target.
Parameters
- - - - - - - - - - - -
enabled : bool ( optional )
This parameter , if set , will toggle this setting to either True or False . """
2023-08-08 00:51:19 -04:00
old_value = await self . config . guild ( ctx . guild ) . dm ( )
2023-08-10 15:59:57 -04:00
if enabled is None :
await ctx . send ( content = f " Shortmute Direct Messages are currently { ' enabled ' if old_value else ' disabled ' } ! " )
else :
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 } ` " )
2023-08-11 16:40:01 -04:00
2023-08-11 16:44:42 -04:00
@shortmute_config.command ( name = ' confirmation ' , aliases = [ ' confirm ' ] )
2023-08-11 16:40:01 -04:00
@commands.guild_only ( )
@commands.admin ( )
async def shortmute_config_confirmation ( self , ctx : commands . Context , enabled : bool = None ) :
""" Manages if /shortmute has a confirmation prompt by default.
Parameters
- - - - - - - - - - - -
enabled : bool ( optional )
This parameter , if set , will toggle this setting to either True or False . """
old_value = await self . config . guild ( ctx . guild ) . confirm ( )
if enabled is None :
await ctx . send ( content = f " Shortmute Confirmations are currently { ' enabled ' if old_value else ' disabled ' } by default! " )
else :
await self . config . guild ( ctx . guild ) . confirm . set ( enabled )
await ctx . send ( content = f " Shortmute Confirmation setting changed! \n Old value: ` { old_value } ` \n New value: ` { enabled } ` " )