Repository: python-discord/bot

Issue:
Repeating the reason in the confirmation message for infraction commands is redundant
When an infraction command is invoked, the bot replies with a message confirming success of the command (with the 👌). An infraction's reason is repeated in this message, but I find that to be redundant, especially when the confirmation is in the same channel as the one in which the command was sent. 

I bring this up because it stems from reasons being long. For short reasons, I think it's OK. The reason could either get truncated and have an ellipses appended, or it could just be entirely removed from the confirmation.


Discussion:
I don't think I'd miss it if it went away.
This seems like a no-brainer, we should just implement it. but it'll have to wait until after the feature freeze.

Resolving patch:
diff --git a/bot/cogs/moderation.py b/bot/cogs/moderation.py
--- a/bot/cogs/moderation.py
+++ b/bot/cogs/moderation.py
@@ -85,11 +85,7 @@ async def warn(self, ctx: Context, user: UserTypes, *, reason: str = None) -> No
 
         dm_result = ":incoming_envelope: " if notified else ""
         action = f"{dm_result}:ok_hand: warned {user.mention}"
-
-        if reason is None:
-            await ctx.send(f"{action}.")
-        else:
-            await ctx.send(f"{action} ({reason}).")
+        await ctx.send(f"{action}.")
 
         if notified:
             dm_status = "Sent"
@@ -138,11 +134,7 @@ async def kick(self, ctx: Context, user: Member, *, reason: str = None) -> None:
 
         dm_result = ":incoming_envelope: " if notified else ""
         action = f"{dm_result}:ok_hand: kicked {user.mention}"
-
-        if reason is None:
-            await ctx.send(f"{action}.")
-        else:
-            await ctx.send(f"{action} ({reason}).")
+        await ctx.send(f"{action}.")
 
         dm_status = "Sent" if notified else "**Failed**"
         title = "Member kicked" if action_result else "Member kicked (Failed)"
@@ -196,11 +188,7 @@ async def ban(self, ctx: Context, user: UserTypes, *, reason: str = None) -> Non
 
         dm_result = ":incoming_envelope: " if notified else ""
         action = f"{dm_result}:ok_hand: permanently banned {user.mention}"
-
-        if reason is None:
-            await ctx.send(f"{action}.")
-        else:
-            await ctx.send(f"{action} ({reason}).")
+        await ctx.send(f"{action}.")
 
         dm_status = "Sent" if notified else "**Failed**"
         log_content = None if all((notified, action_result)) else ctx.author.mention
@@ -223,62 +211,11 @@ async def ban(self, ctx: Context, user: UserTypes, *, reason: str = None) -> Non
             footer=f"ID {infraction['id']}"
         )
 
-    @with_role(*MODERATION_ROLES)
-    @command()
-    async def mute(self, ctx: Context, user: Member, *, reason: str = None) -> None:
-        """Create a permanent mute infraction for a user with the provided reason."""
-        if await already_has_active_infraction(ctx=ctx, user=user, type="mute"):
-            return
-
-        infraction = await post_infraction(ctx, user, type="mute", reason=reason)
-        if infraction is None:
-            return
-
-        self.mod_log.ignore(Event.member_update, user.id)
-        await user.add_roles(self._muted_role, reason=reason)
-
-        notified = await self.notify_infraction(
-            user=user,
-            infr_type="Mute",
-            expires_at="Permanent",
-            reason=reason
-        )
-
-        dm_result = ":incoming_envelope: " if notified else ""
-        action = f"{dm_result}:ok_hand: permanently muted {user.mention}"
-
-        if reason is None:
-            await ctx.send(f"{action}.")
-        else:
-            await ctx.send(f"{action} ({reason}).")
-
-        if notified:
-            dm_status = "Sent"
-            log_content = None
-        else:
-            dm_status = "**Failed**"
-            log_content = ctx.author.mention
-
-        await self.mod_log.send_log_message(
-            icon_url=Icons.user_mute,
-            colour=Colour(Colours.soft_red),
-            title="Member permanently muted",
-            thumbnail=user.avatar_url_as(static_format="png"),
-            text=textwrap.dedent(f"""
-                Member: {user.mention} (`{user.id}`)
-                Actor: {ctx.message.author}
-                DM: {dm_status}
-                Reason: {reason}
-            """),
-            content=log_content,
-            footer=f"ID {infraction['id']}"
-        )
-
     # endregion
     # region: Temporary infractions
 
     @with_role(*MODERATION_ROLES)
-    @command()
+    @command(aliases=('mute',))
     async def tempmute(self, ctx: Context, user: Member, duration: Duration, *, reason: str = None) -> None:
         """
         Create a temporary mute infraction for a user with the provided expiration and reason.
@@ -314,11 +251,7 @@ async def tempmute(self, ctx: Context, user: Member, duration: Duration, *, reas
 
         dm_result = ":incoming_envelope: " if notified else ""
         action = f"{dm_result}:ok_hand: muted {user.mention} until {infraction_expiration}"
-
-        if reason is None:
-            await ctx.send(f"{action}.")
-        else:
-            await ctx.send(f"{action} ({reason}).")
+        await ctx.send(f"{action}.")
 
         if notified:
             dm_status = "Sent"
@@ -391,11 +324,7 @@ async def tempban(self, ctx: Context, user: UserTypes, duration: Duration, *, re
 
         dm_result = ":incoming_envelope: " if notified else ""
         action = f"{dm_result}:ok_hand: banned {user.mention} until {infraction_expiration}"
-
-        if reason is None:
-            await ctx.send(f"{action}.")
-        else:
-            await ctx.send(f"{action} ({reason}).")
+        await ctx.send(f"{action}.")
 
         dm_status = "Sent" if notified else "**Failed**"
         log_content = None if all((notified, action_result)) else ctx.author.mention
@@ -423,7 +352,7 @@ async def tempban(self, ctx: Context, user: UserTypes, duration: Duration, *, re
     # region: Permanent shadow infractions
 
     @with_role(*MODERATION_ROLES)
-    @command(hidden=True, aliases=['shadowwarn', 'swarn', 'shadow_warn'])
+    @command(hidden=True)
     async def note(self, ctx: Context, user: UserTypes, *, reason: str = None) -> None:
         """
         Create a private infraction note in the database for a user with the provided reason.
@@ -434,10 +363,7 @@ async def note(self, ctx: Context, user: UserTypes, *, reason: str = None) -> No
         if infraction is None:
             return
 
-        if reason is None:
-            await ctx.send(f":ok_hand: note added for {user.mention}.")
-        else:
-            await ctx.send(f":ok_hand: note added for {user.mention} ({reason}).")
+        await ctx.send(f":ok_hand: note added for {user.mention}.")
 
         await self.mod_log.send_log_message(
             icon_url=Icons.user_warn,
@@ -477,10 +403,7 @@ async def shadow_kick(self, ctx: Context, user: Member, *, reason: str = None) -
         except Forbidden:
             action_result = False
 
-        if reason is None:
-            await ctx.send(f":ok_hand: kicked {user.mention}.")
-        else:
-            await ctx.send(f":ok_hand: kicked {user.mention} ({reason}).")
+        await ctx.send(f":ok_hand: kicked {user.mention}.")
 
         title = "Member shadow kicked"
         if action_result:
@@ -532,10 +455,7 @@ async def shadow_ban(self, ctx: Context, user: UserTypes, *, reason: str = None)
         except Forbidden:
             action_result = False
 
-        if reason is None:
-            await ctx.send(f":ok_hand: permanently banned {user.mention}.")
-        else:
-            await ctx.send(f":ok_hand: permanently banned {user.mention} ({reason}).")
+        await ctx.send(f":ok_hand: permanently banned {user.mention}.")
 
         title = "Member permanently banned"
         if action_result:
@@ -558,47 +478,11 @@ async def shadow_ban(self, ctx: Context, user: UserTypes, *, reason: str = None)
             footer=f"ID {infraction['id']}"
         )
 
-    @with_role(*MODERATION_ROLES)
-    @command(hidden=True, aliases=['shadowmute', 'smute'])
-    async def shadow_mute(self, ctx: Context, user: Member, *, reason: str = None) -> None:
-        """
-        Create a permanent mute infraction for a user with the provided reason.
-
-        This does not send the user a notification.
-        """
-        if await already_has_active_infraction(ctx=ctx, user=user, type="mute"):
-            return
-
-        infraction = await post_infraction(ctx, user, type="mute", reason=reason, hidden=True)
-        if infraction is None:
-            return
-
-        self.mod_log.ignore(Event.member_update, user.id)
-        await user.add_roles(self._muted_role, reason=reason)
-
-        if reason is None:
-            await ctx.send(f":ok_hand: permanently muted {user.mention}.")
-        else:
-            await ctx.send(f":ok_hand: permanently muted {user.mention} ({reason}).")
-
-        await self.mod_log.send_log_message(
-            icon_url=Icons.user_mute,
-            colour=Colour(Colours.soft_red),
-            title="Member permanently muted",
-            thumbnail=user.avatar_url_as(static_format="png"),
-            text=textwrap.dedent(f"""
-                Member: {user.mention} (`{user.id}`)
-                Actor: {ctx.message.author}
-                Reason: {reason}
-            """),
-            footer=f"ID {infraction['id']}"
-        )
-
     # endregion
     # region: Temporary shadow infractions
 
     @with_role(*MODERATION_ROLES)
-    @command(hidden=True, aliases=["shadowtempmute, stempmute"])
+    @command(hidden=True, aliases=["shadowtempmute, stempmute", "shadowmute", "smute"])
     async def shadow_tempmute(
         self, ctx: Context, user: Member, duration: Duration, *, reason: str = None
     ) -> None:
@@ -626,15 +510,8 @@ async def shadow_tempmute(
             .fromisoformat(infraction["expires_at"][:-1])
             .strftime('%c')
         )
-
         self.schedule_task(ctx.bot.loop, infraction["id"], infraction)
-
-        if reason is None:
-            await ctx.send(f":ok_hand: muted {user.mention} until {infraction_expiration}.")
-        else:
-            await ctx.send(
-                f":ok_hand: muted {user.mention} until {infraction_expiration} ({reason})."
-            )
+        await ctx.send(f":ok_hand: muted {user.mention} until {infraction_expiration}.")
 
         await self.mod_log.send_log_message(
             icon_url=Icons.user_mute,
@@ -690,15 +567,8 @@ async def shadow_tempban(
             .fromisoformat(infraction["expires_at"][:-1])
             .strftime('%c')
         )
-
         self.schedule_task(ctx.bot.loop, infraction["id"], infraction)
-
-        if reason is None:
-            await ctx.send(f":ok_hand: banned {user.mention} until {infraction_expiration}.")
-        else:
-            await ctx.send(
-                f":ok_hand: banned {user.mention} until {infraction_expiration} ({reason})."
-            )
+        await ctx.send(f":ok_hand: banned {user.mention} until {infraction_expiration}.")
 
         title = "Member temporarily banned"
         if action_result:
diff --git a/bot/cogs/tags.py b/bot/cogs/tags.py
--- a/bot/cogs/tags.py
+++ b/bot/cogs/tags.py
@@ -26,7 +26,7 @@ def __init__(self, bot: Bot):
         self.bot = bot
         self.tag_cooldowns = {}
 
-    @group(name='tags', aliases=('tag', 't'), hidden=True, invoke_without_command=True)
+    @group(name='tags', aliases=('tag', 't'), invoke_without_command=True)
     async def tags_group(self, ctx: Context, *, tag_name: TagNameConverter = None) -> None:
         """Show all known tags, a single tag, or run a subcommand."""
         await ctx.invoke(self.get_command, tag_name=tag_name)


Test patch: