251 lines
15 KiB
Python
251 lines
15 KiB
Python
import discord
|
|
from pytimeparse2 import disable_dateutil, parse
|
|
from discord import ui
|
|
from redbot.core import Config, commands, app_commands
|
|
|
|
class Shortmute(commands.Cog):
|
|
"""Allows staff members to shortmute individuals for up to 30 minutes, using Discord's Timeouts feature."""
|
|
|
|
def __init__(self, bot) -> None:
|
|
self.bot = bot
|
|
self.config = Config.get_conf(self, identifier=25781647388294, force_registration=True)
|
|
self.config.register_guild(
|
|
dm = True,
|
|
logging_channels = [],
|
|
immune_roles = []
|
|
)
|
|
|
|
@app_commands.command()
|
|
@app_commands.rename(target='member')
|
|
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):
|
|
"""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
|
|
evidence_image: discord.Attachment = None
|
|
An image file used as evidence for the shortmute, do not use with evidence_link
|
|
skip_confirmation: bool = False
|
|
This allows you skip the confirmation prompt and immediately shortmute the user.
|
|
"""
|
|
disable_dateutil()
|
|
timedelta = parse(f'{duration} minutes', as_timedelta=True)
|
|
passed_info = {
|
|
"target": target,
|
|
"duration": duration,
|
|
"timedelta": timedelta,
|
|
"reason": reason,
|
|
"interaction": interaction,
|
|
"color": await self.bot.get_embed_color(None)
|
|
}
|
|
if evidence_image and evidence_link:
|
|
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)
|
|
return
|
|
elif evidence_link:
|
|
evidence = evidence_link
|
|
elif evidence_image:
|
|
evidence = str(evidence_image)
|
|
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
|
|
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.send_message(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.send_message(content=f"Please shortmute the user for longer than {readable_duration}! The maximum duration is 30 minutes.", ephemeral=True)
|
|
return
|
|
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))
|
|
if evidence:
|
|
embed.set_image(url=evidence)
|
|
passed_info.update({
|
|
"evidence": 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))
|
|
if evidence:
|
|
edit_embed.set_image(url=evidence)
|
|
message = await interaction.response.send_message(embed=edit_embed, ephemeral=True)
|
|
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))
|
|
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:
|
|
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}`", color=await self.bot.get_embed_color(None))
|
|
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)
|
|
|
|
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']
|
|
color = self.passed_info['color']
|
|
timedelta = self.passed_info['timedelta']
|
|
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)
|
|
if self.passed_info.get('evidence'):
|
|
evidence = self.passed_info['evidence']
|
|
edit_embed.set_image(url=evidence)
|
|
old_message = await old_interaction.edit_original_response(embed=edit_embed, view=None)
|
|
await target.timeout(timedelta, reason=f"User shortmuted for {readable_duration} by {old_interaction.user.name} ({old_interaction.user.id}) for: {reason}")
|
|
await old_interaction.channel.send(content=f"{target.mention} was shortmuted for {readable_duration} by {old_interaction.user.mention} for: `{reason}`")
|
|
if await self.config.guild(old_interaction.guild).dm() is True:
|
|
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)
|
|
if evidence:
|
|
dm_embed.set_image(url=evidence)
|
|
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.")
|
|
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}`", 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)
|
|
|
|
@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)
|
|
|
|
@commands.group(name='shortmuteset', autohelp=True)
|
|
@commands.guild_only()
|
|
@commands.admin()
|
|
async def shortmute_config(self, ctx: commands.Context):
|
|
"""This command group is used to configure the `/shortmute` slash command."""
|
|
|
|
@shortmute_config.command(name='addchannel')
|
|
@commands.guild_only()
|
|
@commands.admin()
|
|
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!"""
|
|
current_list = await self.config.guild(ctx.guild).logging_channels()
|
|
if channel:
|
|
if channel.id in current_list:
|
|
await ctx.send("This channel is already in the logging channel list!")
|
|
return
|
|
else:
|
|
current_list.append(channel.id)
|
|
await self.config.guild(ctx.guild).logging_channels.set(current_list)
|
|
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))
|
|
else:
|
|
await ctx.send("Please provide a valid channel.")
|
|
|
|
@shortmute_config.command(name='removechannel')
|
|
@commands.guild_only()
|
|
@commands.admin()
|
|
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."""
|
|
current_list = await self.config.guild(ctx.guild).logging_channels()
|
|
if channel.id in current_list:
|
|
current_list.remove(channel.id)
|
|
await self.config.guild(ctx.guild).logging_channels.set(current_list)
|
|
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.")
|
|
|
|
@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."""
|
|
current_list = await self.config.guild(ctx.guild).immune_roles()
|
|
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)
|
|
await self.config.guild(ctx.guild).immune_roles.set(current_list)
|
|
await ctx.send(f"{role.mention} has been added to the immune roles list.", allowed_mentions = discord.AllowedMentions(roles=False))
|
|
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."""
|
|
current_list = await self.config.guild(ctx.guild).immune_roles()
|
|
if role.id in current_list:
|
|
current_list.remove(role.id)
|
|
await self.config.guild(ctx.guild).immune_roles.set(current_list)
|
|
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.")
|
|
|
|
@shortmute_config.command(name='dm')
|
|
@commands.guild_only()
|
|
@commands.admin()
|
|
async def shortmute_config_dm(self, ctx: commands.Context, enabled: bool = None):
|
|
"""This command changes if the `/shortmute` slash command Direct Messages its target."""
|
|
old_value = await self.config.guild(ctx.guild).dm()
|
|
if enabled:
|
|
await self.config.guild(ctx.guild).dm.set(enabled)
|
|
await ctx.send(content=f"Shortmute Direct Message setting changed!\nOld value: `{old_value}`\nNew 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!")
|