diff --git a/bot.py b/bot.py index 6c15dd8..9018bcf 100644 --- a/bot.py +++ b/bot.py @@ -3255,8 +3255,8 @@ async def modhelp(ctx): embed.add_field( name="šŸ‘® Moderator Commands (Level 5+)", value=( - "`/warn [message_id]` - Warn a user (with optional message reference)\n" - "`/mute [reason] [message_id]` - Mute a user temporarily\n" + "`/warn [message_id] [silent:True]` - Warn a user (with optional silent mode)\n" + "`/mute [reason] [message_id] [silent:True]` - Mute a user temporarily (with optional silent mode)\n" "`/unmute ` - Manually unmute a user (deactivates all active mutes)\n" "`/viewmute ` - View detailed mute information by ID or UUID\n" "`/listmutes [status]` - List mutes (active, completed, expired, cancelled, all)\n" @@ -3316,7 +3316,22 @@ async def modhelp(ctx): "• **Mute IDs**: Easy-to-use numeric IDs for tracking (e.g. `/viewmute 123`)\n" "• **Multiple Mutes**: Can handle multiple active mutes per user\n" "• **Smart Notifications**: Auto-unmute alerts sent to mod log channel\n" - "• **Role Restoration**: Automatically restores previous roles after mute" + "• **Role Restoration**: Automatically restores previous roles after mute\n" + "• **Silent Mode**: Optional discrete moderation (ephemeral responses only)" + ), + inline=False + ) + + # Silent Mode Features + embed.add_field( + name="šŸ”‡ Silent Mode Features", + value=( + "• **Discrete Moderation**: Use `silent:True` parameter with warn/mute commands\n" + "• **Ephemeral Responses**: Only moderator sees the action confirmation\n" + "• **User Notifications**: Target user still receives DM about action\n" + "• **Full Logging**: Mod log channel records all actions normally\n" + "• **No Public Messages**: Regular users don't see moderation announcements\n" + "• **Perfect for**: Handling sensitive issues without public drama" ), inline=False ) @@ -4723,19 +4738,21 @@ async def restore_user_roles(user, guild): close_database_connection(connection) @client.hybrid_command() -async def warn(ctx, user: discord.User, reason: str = "No reason provided", message_id: str = None, context_range: int = 3): +async def warn(ctx, user: discord.User, reason: str = "No reason provided", message_id: str = None, context_range: int = 3, silent: bool = False): """Warns a user (Requires Permission Level 5 or higher) Usage: /warn @user "Inappropriate behavior" /warn @user "Bad language" 1407754702564884622 /warn @user "Spam" 1407754702564884622 15 + /warn @user "Bad behavior" silent:True (silent mode - no public announcement) Parameters: - user: The user to warn - reason: Reason for the warning - message_id: Optional message ID to reference (required for context_range) - context_range: Number of messages before/after to archive (only works with message_id) + - silent: If True, only send ephemeral response to mod (no public message) Note: context_range parameter only works when message_id is also provided! """ @@ -4991,7 +5008,30 @@ async def warn(ctx, user: discord.User, reason: str = "No reason provided", mess inline=False ) - await send_response(embed=embed) + # Send response based on silent mode + if silent: + # Silent mode: only ephemeral response to moderator + silent_embed = discord.Embed( + title="šŸ”‡ Silent Warning Issued", + description=f"{user.mention} has been warned silently.", + color=0xff9500, + timestamp=datetime.now() + ) + silent_embed.add_field(name="šŸ“ Reason", value=reason, inline=False) + silent_embed.add_field(name="āš ļø Warning Count", value=f"{target_data['warns']}/{warn_threshold}", inline=True) + if warning_id: + silent_embed.add_field(name="šŸ†” Warning ID", value=str(warning_id), inline=True) + + silent_embed.add_field(name="šŸ”” Actions Taken", + value="• User received DM notification\n• Mod log entry created\n• No public announcement", + inline=False) + silent_embed.set_footer(text=f"Silent Mode • User ID: {user.id}") + silent_embed.set_thumbnail(url=user.display_avatar.url) + + await send_response(embed=silent_embed, ephemeral=True) + else: + # Normal mode: public response + await send_response(embed=embed) # Log the warning action log_additional_info = { @@ -6232,13 +6272,14 @@ async def restorewarn(ctx, warning_id: int): close_database_connection(connection) @client.hybrid_command() -async def mute(ctx, user: discord.User, duration: str, reason: str = "No reason provided", message_id: str = None, context_range: int = 3): +async def mute(ctx, user: discord.User, duration: str, reason: str = "No reason provided", message_id: str = None, context_range: int = 3, silent: bool = False): """Mutes a user for a specified duration (Requires Permission Level 5 or higher) Usage: /mute @user 10m "Inappropriate behavior" /mute @user 1h "Bad language" 1407754702564884622 /mute @user 1h "Bad language" 1407754702564884622 15 + /mute @user 30m "Spamming" silent:True (silent mode - no public announcement) Parameters: - user: The user to mute @@ -6246,6 +6287,7 @@ async def mute(ctx, user: discord.User, duration: str, reason: str = "No reason - reason: Reason for the mute (can include message ID and context range) - message_id: Optional message ID to reference (required for context_range) - context_range: Number of context messages to archive (only works with message_id) + - silent: If True, only send ephemeral response to mod (no public message) Duration examples: - 10m = 10 minutes @@ -6524,7 +6566,31 @@ async def mute(ctx, user: discord.User, duration: str, reason: str = "No reason embed.set_footer(text=f"User ID: {user.id} | Process ID: {str(process_uuid)[:8]} | Use /viewmute {mute_id} for details") embed.set_thumbnail(url=user.display_avatar.url) - await send_response(embed=embed) + # Send response based on silent mode + if silent: + # Silent mode: only ephemeral response to moderator + silent_embed = discord.Embed( + title="šŸ”‡ Silent Mute Applied", + description=f"{user.mention} has been muted silently.", + color=0xff0000, + timestamp=datetime.now() + ) + silent_embed.add_field(name="ā±ļø Duration", value=duration, inline=True) + silent_embed.add_field(name="ā° Ends At", value=f"", inline=True) + silent_embed.add_field(name="šŸ“ Reason", value=reason, inline=False) + silent_embed.add_field(name="šŸ”‡ Mute Count", value=f"{user_data['mutes']}", inline=True) + silent_embed.add_field(name="šŸ†” Mute Record ID", value=f"`{mute_id}`", inline=True) + + silent_embed.add_field(name="šŸ”” Actions Taken", + value="• User muted with timeout role\n• User received DM notification\n• Mod log entry created\n• No public announcement", + inline=False) + silent_embed.set_footer(text=f"Silent Mode • User ID: {user.id} | Use /viewmute {mute_id} for details") + silent_embed.set_thumbnail(url=user.display_avatar.url) + + await send_response(embed=silent_embed, ephemeral=True) + else: + # Normal mode: public response + await send_response(embed=embed) # Log the mute action log_additional_info = {