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-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-08 01:44:50 -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 = False ) :
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-08 01:44:50 -04:00
skip_confirmation : bool = False
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-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 "
passed_info . update ( {
" readable_duration " : readable_duration
} )
else :
readable_duration = f " { duration } minutes "
passed_info . update ( {
" readable_duration " : readable_duration
} )
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 } " )
await interaction . channel . send ( content = f " { target . mention } was shortmuted for { readable_duration } by { interaction . user . mention } for: ` { reason } ` " )
if await self . config . guild ( interaction . guild ) . dm ( ) is True :
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 **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. " )
logging_channels_list = await self . config . guild ( interaction . guild ) . logging_channels ( )
if logging_channels_list :
2023-08-08 02:01:17 -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 **Duration:** { readable_duration } \n **Reason:** ` { reason } ` \n **Confirmation Skipped:** True " , color = await self . bot . get_embed_color ( None ) )
2023-08-08 01:44:50 -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-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:58:38 -04:00
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 )
2023-08-08 01:33:34 -04:00
logging_embed . set_footer ( text = " /shortmute " )
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 ) :
2023-08-08 02:17:13 -04:00
""" This command adds roles to the immune roles list for immunity from 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 ) :
2023-08-08 02:17:13 -04:00
""" This command removes roles from the immune roles list to remove immunity from 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 02:17:13 -04:00
@shortmute_config.command ( name = ' blacklist add ' )
@commands.guild_only ( )
@commands.admin ( )
async def shortmute_config_blacklist_add ( self , ctx : commands . Context , user : discord . User = None ) :
""" This command adds users to the blacklist for the `/shortmute` slash command. """
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 :
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 ) )
else :
await ctx . send ( " Please provide a valid user. " )
@shortmute_config.command ( name = ' blacklist remove ' )
@commands.guild_only ( )
@commands.admin ( )
async def shortmute_config_blacklist_remove ( self , ctx : commands . Context , user : discord . User = None ) :
""" This command adds users to the blacklist for the `/shortmute` slash command. """
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 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! " )