From a5f94df5499f9ea19c4413b2534489cba1f0023e Mon Sep 17 00:00:00 2001 From: neoarz Date: Mon, 20 Oct 2025 12:21:43 -0400 Subject: [PATCH] chore: add permission checks --- cogs/idevice/idevice.py | 70 +++++++++++++++++++---- cogs/media/download.py | 110 ++++++++++++++++++++++++++++-------- cogs/media/mcquote.py | 38 ++++++++++--- cogs/media/tts.py | 38 ++++++++++--- cogs/melonx/melonx.py | 71 +++++++++++++++++++++-- cogs/sidestore/sidestore.py | 49 ++++++++++++++-- 6 files changed, 309 insertions(+), 67 deletions(-) diff --git a/cogs/idevice/idevice.py b/cogs/idevice/idevice.py index 44caa79..560a1f4 100644 --- a/cogs/idevice/idevice.py +++ b/cogs/idevice/idevice.py @@ -186,12 +186,21 @@ class ideviceSelect(discord.ui.Select): await interaction.followup.send(embed=embed, view=view, ephemeral=True) except discord.Forbidden: - self.bot.logger.warning(f"Bot missing permissions in server {interaction.guild.name} (ID: {interaction.guild.id}) - cannot execute errorcodes command") - embed = discord.Embed( - title="Permission Error", - description="The bot doesn't have the required permissions in this server to execute this command. Use the slash command `/errorcodes` instead.", - color=0xFF0000 - ) + guild_info = f"server {interaction.guild.name} (ID: {interaction.guild.id})" if interaction.guild else "DM or private channel" + self.bot.logger.warning(f"Bot missing permissions in {guild_info} - cannot execute errorcodes command") + + if interaction.guild is None: + embed = discord.Embed( + title="Error", + description="This command cannot be executed in DMs.", + color=0xFF0000 + ) + else: + embed = discord.Embed( + title="Permission Error", + description="The bot needs the `send messages` permission to execute this command.", + color=0xFF0000 + ) embed.set_author(name="idevice", icon_url="https://yes.nighty.works/raw/snLMuO.png") await interaction.response.edit_message(embed=embed, view=None) except Exception as e: @@ -220,12 +229,21 @@ class ideviceSelect(discord.ui.Select): embed.set_author(name="idevice", icon_url="https://yes.nighty.works/raw/snLMuO.png") await interaction.response.edit_message(embed=embed, view=None) except discord.Forbidden: - self.bot.logger.warning(f"Bot missing permissions in server {interaction.guild.name} (ID: {interaction.guild.id}) - cannot execute {command_name} command") - embed = discord.Embed( - title="Permission Error", - description=f"The bot doesn't have the required permissions in this server to execute this command. Use the slash command `/{command_name}` instead.", - color=0xFF0000 - ) + guild_info = f"server {interaction.guild.name} (ID: {interaction.guild.id})" if interaction.guild else "DM or private channel" + self.bot.logger.warning(f"Bot missing permissions in {guild_info} - cannot execute {command_name} command") + + if interaction.guild is None: + embed = discord.Embed( + title="Error", + description="This command cannot be executed in DMs.", + color=0xFF0000 + ) + else: + embed = discord.Embed( + title="Permission Error", + description="The bot needs the `send messages` permission to execute this command.", + color=0xFF0000 + ) embed.set_author(name="idevice", icon_url="https://yes.nighty.works/raw/snLMuO.png") await interaction.response.edit_message(embed=embed, view=None) except Exception as e: @@ -258,6 +276,34 @@ def idevice_command(): name="idevice", description="idevice troubleshooting and help" ) async def idevice(self, context): + if isinstance(context.channel, discord.DMChannel): + embed = discord.Embed( + title="Error", + description="This command can only be used in servers.", + color=0xE02B2B, + ) + embed.set_author(name="idevice", icon_url="https://yes.nighty.works/raw/snLMuO.png") + + if context.interaction: + await context.interaction.response.send_message(embed=embed, ephemeral=True) + else: + await context.send(embed=embed, ephemeral=True) + return + + if isinstance(context.channel, discord.PartialMessageable): + embed = discord.Embed( + title="Error", + description="The bot needs send messages permissions in this channel.", + color=0xE02B2B, + ) + embed.set_author(name="idevice", icon_url="https://yes.nighty.works/raw/snLMuO.png") + + if context.interaction: + await context.interaction.response.send_message(embed=embed, ephemeral=True) + else: + await context.send(embed=embed, ephemeral=True) + return + embed = discord.Embed( title="idevice Commands", description="Choose a command from the dropdown below to get help with specific issues:", diff --git a/cogs/media/download.py b/cogs/media/download.py index f7fa090..5165d53 100644 --- a/cogs/media/download.py +++ b/cogs/media/download.py @@ -38,7 +38,7 @@ def download_command(): if isinstance(context.channel, discord.PartialMessageable): embed = discord.Embed( title="Error", - description="The bot needs send messages permissions in this channel.", + description="The bot needs the `send messages` permission in this channel.", color=0xE02B2B, ) embed.set_author(name="Media", icon_url="https://yes.nighty.works/raw/y5SEZ9.webp") @@ -208,16 +208,36 @@ def download_command(): embed.set_footer(text=f"Requested by {context.author.name}", icon_url=context.author.display_avatar.url) if interaction is not None: - await context.channel.send(embed=embed) - await context.channel.send(link) try: - await interaction.delete_original_response() - except: - pass + await context.channel.send(embed=embed) + await context.channel.send(link) + try: + await interaction.delete_original_response() + except: + pass + except discord.Forbidden: + embed = discord.Embed( + title="Permission Error", + description="The bot needs the `send messages` permission to execute this command.", + color=0xE02B2B, + ) + embed.set_author(name="Media", icon_url="https://yes.nighty.works/raw/y5SEZ9.webp") + await interaction.followup.send(embed=embed, ephemeral=True) + return else: - await processing_msg.delete() - await context.channel.send(embed=embed) - await context.channel.send(link) + try: + await processing_msg.delete() + await context.channel.send(embed=embed) + await context.channel.send(link) + except discord.Forbidden: + embed = discord.Embed( + title="Permission Error", + description="The bot needs the `send messages` permission to execute this command.", + color=0xE02B2B, + ) + embed.set_author(name="Media", icon_url="https://yes.nighty.works/raw/y5SEZ9.webp") + await context.send(embed=embed, ephemeral=True) + return return except Exception as upload_error: logger.exception(f"Catbox upload exception: {upload_error}") @@ -265,16 +285,36 @@ def download_command(): file = discord.File(f, filename=files[0]) if interaction is not None: - await context.channel.send(embed=embed) - await context.channel.send(file=file) try: - await interaction.delete_original_response() - except: - pass + await context.channel.send(embed=embed) + await context.channel.send(file=file) + try: + await interaction.delete_original_response() + except: + pass + except discord.Forbidden: + embed = discord.Embed( + title="Permission Error", + description="The bot needs the `send messages` permission to execute this command.", + color=0xE02B2B, + ) + embed.set_author(name="Media", icon_url="https://yes.nighty.works/raw/y5SEZ9.webp") + await interaction.followup.send(embed=embed, ephemeral=True) + return else: - await processing_msg.delete() - await context.channel.send(embed=embed) - await context.channel.send(file=file) + try: + await processing_msg.delete() + await context.channel.send(embed=embed) + await context.channel.send(file=file) + except discord.Forbidden: + embed = discord.Embed( + title="Permission Error", + description="The bot needs the `send messages` permission to execute this command.", + color=0xE02B2B, + ) + embed.set_author(name="Media", icon_url="https://yes.nighty.works/raw/y5SEZ9.webp") + await context.send(embed=embed, ephemeral=True) + return except discord.HTTPException as e: if e.status == 413: logger.info("Discord rejected file (413), falling back to Catbox upload") @@ -313,16 +353,36 @@ def download_command(): embed.set_footer(text=f"Requested by {context.author.name}", icon_url=context.author.display_avatar.url) if interaction is not None: - await context.channel.send(embed=embed) - await context.channel.send(link) try: - await interaction.delete_original_response() - except: - pass + await context.channel.send(embed=embed) + await context.channel.send(link) + try: + await interaction.delete_original_response() + except: + pass + except discord.Forbidden: + embed = discord.Embed( + title="Permission Error", + description="The bot needs the `send messages` permission to execute this command.", + color=0xE02B2B, + ) + embed.set_author(name="Media", icon_url="https://yes.nighty.works/raw/y5SEZ9.webp") + await interaction.followup.send(embed=embed, ephemeral=True) + return else: - await processing_msg.delete() - await context.channel.send(embed=embed) - await context.channel.send(link) + try: + await processing_msg.delete() + await context.channel.send(embed=embed) + await context.channel.send(link) + except discord.Forbidden: + embed = discord.Embed( + title="Permission Error", + description="The bot needs the `send messages` permission to execute this command.", + color=0xE02B2B, + ) + embed.set_author(name="Media", icon_url="https://yes.nighty.works/raw/y5SEZ9.webp") + await context.send(embed=embed, ephemeral=True) + return except Exception as upload_error: logger.exception(f"Catbox upload exception: {upload_error}") embed = discord.Embed( diff --git a/cogs/media/mcquote.py b/cogs/media/mcquote.py index b1a7886..a6333f7 100644 --- a/cogs/media/mcquote.py +++ b/cogs/media/mcquote.py @@ -34,7 +34,7 @@ def mcquote_command(): if isinstance(context.channel, discord.PartialMessageable): embed = discord.Embed( title="Error", - description="The bot needs send messages permissions in this channel.", + description="The bot needs the `send messages` permission in this channel.", color=0xE02B2B, ) embed.set_author(name="Media", icon_url="https://yes.nighty.works/raw/y5SEZ9.webp") @@ -127,16 +127,36 @@ def mcquote_command(): interaction = getattr(context, "interaction", None) if interaction is not None: - await context.channel.send(embed=embed) - await context.channel.send(file=file) try: - await interaction.delete_original_response() - except: - pass + await context.channel.send(embed=embed) + await context.channel.send(file=file) + try: + await interaction.delete_original_response() + except: + pass + except discord.Forbidden: + embed = discord.Embed( + title="Permission Error", + description="The bot needs the `send messages` permission to execute this command.", + color=0xE02B2B, + ) + embed.set_author(name="Media", icon_url="https://yes.nighty.works/raw/y5SEZ9.webp") + await interaction.followup.send(embed=embed, ephemeral=True) + return else: - await processing_msg.delete() - await context.channel.send(embed=embed) - await context.channel.send(file=file) + try: + await processing_msg.delete() + await context.channel.send(embed=embed) + await context.channel.send(file=file) + except discord.Forbidden: + embed = discord.Embed( + title="Permission Error", + description="The bot needs the `send messages` permission to execute this command.", + color=0xE02B2B, + ) + embed.set_author(name="Media", icon_url="https://yes.nighty.works/raw/y5SEZ9.webp") + await context.send(embed=embed, ephemeral=True) + return os.remove(temp_file_path) except aiohttp.ClientError: diff --git a/cogs/media/tts.py b/cogs/media/tts.py index 6d62295..b670b3d 100644 --- a/cogs/media/tts.py +++ b/cogs/media/tts.py @@ -85,7 +85,7 @@ def tts_command(): if isinstance(context.channel, discord.PartialMessageable): embed = discord.Embed( title="Error", - description="The bot needs send messages permissions in this channel.", + description="The bot needs the `send messages` permission in this channel.", color=0xE02B2B, ) embed.set_author(name="Media", icon_url="https://yes.nighty.works/raw/y5SEZ9.webp") @@ -198,15 +198,35 @@ def tts_command(): ) if interaction is not None: - await context.channel.send(embed=embed) - await context.channel.send(file=audio_file) try: - await interaction.delete_original_response() - except: - pass + await context.channel.send(embed=embed) + await context.channel.send(file=audio_file) + try: + await interaction.delete_original_response() + except: + pass + except discord.Forbidden: + embed = discord.Embed( + title="Permission Error", + description="The bot needs the `send messages` permission to execute this command.", + color=0xE02B2B, + ) + embed.set_author(name="Media", icon_url="https://yes.nighty.works/raw/y5SEZ9.webp") + await interaction.followup.send(embed=embed, ephemeral=True) + return else: - await processing_message.delete() - await context.channel.send(embed=embed) - await context.channel.send(file=audio_file) + try: + await processing_message.delete() + await context.channel.send(embed=embed) + await context.channel.send(file=audio_file) + except discord.Forbidden: + embed = discord.Embed( + title="Permission Error", + description="The bot needs the `send messages` permission to execute this command.", + color=0xE02B2B, + ) + embed.set_author(name="Media", icon_url="https://yes.nighty.works/raw/y5SEZ9.webp") + await context.send(embed=embed, ephemeral=True) + return return tts \ No newline at end of file diff --git a/cogs/melonx/melonx.py b/cogs/melonx/melonx.py index 545b2a5..b2c4d98 100644 --- a/cogs/melonx/melonx.py +++ b/cogs/melonx/melonx.py @@ -63,12 +63,21 @@ class MelonxSelect(discord.ui.Select): embed.set_author(name="MeloNX", icon_url="https://yes.nighty.works/raw/TLGaVa.png") await interaction.response.edit_message(embed=embed, view=None) except discord.Forbidden: - self.bot.logger.warning(f"Bot missing permissions in server {interaction.guild.name} (ID: {interaction.guild.id}) - cannot execute {command_name} command") - embed = discord.Embed( - title="Permission Error", - description="The bot doesn't have the required permissions in this server to execute this command. Use the slash command `/{command_name}` instead.", - color=0x963155 - ) + guild_info = f"server {interaction.guild.name} (ID: {interaction.guild.id})" if interaction.guild else "DM or private channel" + self.bot.logger.warning(f"Bot missing permissions in {guild_info} - cannot execute {command_name} command") + + if interaction.guild is None: + embed = discord.Embed( + title="Error", + description="This command cannot be executed in DMs.", + color=0xFF0000 + ) + else: + embed = discord.Embed( + title="Permission Error", + description="The bot needs the `send messages` permission to execute this command.", + color=0xFF0000 + ) embed.set_author(name="MeloNX", icon_url="https://yes.nighty.works/raw/TLGaVa.png") await interaction.response.edit_message(embed=embed, view=None) except Exception as e: @@ -94,3 +103,53 @@ class MelonxView(discord.ui.View): def __init__(self, bot): super().__init__() self.add_item(MelonxSelect(bot)) + + +def melonx_command(): + @commands.hybrid_command( + name="melonx", description="MeloNX troubleshooting and help" + ) + async def melonx(self, context): + if isinstance(context.channel, discord.DMChannel): + embed = discord.Embed( + title="Error", + description="This command can only be used in servers.", + color=0xE02B2B, + ) + embed.set_author(name="MeloNX", icon_url="https://yes.nighty.works/raw/TLGaVa.png") + + if context.interaction: + await context.interaction.response.send_message(embed=embed, ephemeral=True) + else: + await context.send(embed=embed, ephemeral=True) + return + + if isinstance(context.channel, discord.PartialMessageable): + embed = discord.Embed( + title="Error", + description="The bot needs send messages permissions in this channel.", + color=0xE02B2B, + ) + embed.set_author(name="MeloNX", icon_url="https://yes.nighty.works/raw/TLGaVa.png") + + if context.interaction: + await context.interaction.response.send_message(embed=embed, ephemeral=True) + else: + await context.send(embed=embed, ephemeral=True) + return + + embed = discord.Embed( + title="MeloNX Commands", + description="Choose a command from the dropdown below to get help with specific issues:", + color=0x963155 + ) + embed.set_author(name="MeloNX", icon_url="https://yes.nighty.works/raw/TLGaVa.png") + + view = MelonxView(self.bot) + + if context.interaction: + await context.interaction.response.send_message(embed=embed, view=view, ephemeral=True) + else: + await context.send(embed=embed, view=view) + + return melonx diff --git a/cogs/sidestore/sidestore.py b/cogs/sidestore/sidestore.py index 09f6ea1..078bc5d 100644 --- a/cogs/sidestore/sidestore.py +++ b/cogs/sidestore/sidestore.py @@ -74,12 +74,21 @@ class SidestoreSelect(discord.ui.Select): embed.set_author(name="SideStore", icon_url="https://github.com/SideStore/assets/blob/main/icons/classic/Default.png?raw=true") await interaction.response.edit_message(embed=embed, view=None) except discord.Forbidden: - self.bot.logger.warning(f"Bot missing permissions in server {interaction.guild.name} (ID: {interaction.guild.id}) - cannot execute {command_name} command") - embed = discord.Embed( - title="Permission Error", - description="The bot doesn't have the required permissions in this server to execute this command. Use the slash command `/{command_name}` instead.", - color=0xFF0000 - ) + guild_info = f"server {interaction.guild.name} (ID: {interaction.guild.id})" if interaction.guild else "DM or private channel" + self.bot.logger.warning(f"Bot missing permissions in {guild_info} - cannot execute {command_name} command") + + if interaction.guild is None: + embed = discord.Embed( + title="Error", + description="This command cannot be executed in DMs.", + color=0xFF0000 + ) + else: + embed = discord.Embed( + title="Permission Error", + description="The bot needs the `send messages` permission to execute this command.", + color=0xFF0000 + ) embed.set_author(name="SideStore", icon_url="https://github.com/SideStore/assets/blob/main/icons/classic/Default.png?raw=true") await interaction.response.edit_message(embed=embed, view=None) except Exception as e: @@ -112,6 +121,34 @@ def sidestore_command(): name="help", description="SideStore troubleshooting and help" ) async def sidestore(self, context): + if isinstance(context.channel, discord.DMChannel): + embed = discord.Embed( + title="Error", + description="This command can only be used in servers.", + color=0xE02B2B, + ) + embed.set_author(name="SideStore", icon_url="https://github.com/SideStore/assets/blob/main/icons/classic/Default.png?raw=true") + + if context.interaction: + await context.interaction.response.send_message(embed=embed, ephemeral=True) + else: + await context.send(embed=embed, ephemeral=True) + return + + if isinstance(context.channel, discord.PartialMessageable): + embed = discord.Embed( + title="Error", + description="The bot needs send messages permissions in this channel.", + color=0xE02B2B, + ) + embed.set_author(name="SideStore", icon_url="https://github.com/SideStore/assets/blob/main/icons/classic/Default.png?raw=true") + + if context.interaction: + await context.interaction.response.send_message(embed=embed, ephemeral=True) + else: + await context.send(embed=embed, ephemeral=True) + return + embed = discord.Embed( title="SideStore Commands", description="Choose a command from the dropdown below to get help with specific issues:",