diff --git a/redbot/cogs/audio/core/abc.py b/redbot/cogs/audio/core/abc.py index 9c423127b..2ad4f36ba 100644 --- a/redbot/cogs/audio/core/abc.py +++ b/redbot/cogs/audio/core/abc.py @@ -231,6 +231,10 @@ class MixinMeta(ABC): ) -> discord.Message: raise NotImplementedError() + @abstractmethod + def _has_notify_perms(self, channel: discord.TextChannel) -> bool: + raise NotImplementedError() + @abstractmethod async def update_external_status(self) -> bool: raise NotImplementedError() diff --git a/redbot/cogs/audio/core/events/cog.py b/redbot/cogs/audio/core/events/cog.py index dc487343b..879f1f318 100644 --- a/redbot/cogs/audio/core/events/cog.py +++ b/redbot/cogs/audio/core/events/cog.py @@ -195,6 +195,7 @@ class AudioEvents(MixinMeta, metaclass=CompositeMetaClass): player: lavalink.Player, ): notify_channel = self.bot.get_channel(player.fetch("channel")) + has_perms = self._has_notify_perms(notify_channel) tries = 0 while not player._is_playing: await asyncio.sleep(0.1) @@ -202,7 +203,7 @@ class AudioEvents(MixinMeta, metaclass=CompositeMetaClass): return tries += 1 - if notify_channel and not player.fetch("autoplay_notified", False): + if notify_channel and has_perms and not player.fetch("autoplay_notified", False): if ( len(player.manager.players) < 10 or not player._last_resume diff --git a/redbot/cogs/audio/core/events/lavalink.py b/redbot/cogs/audio/core/events/lavalink.py index bd623f946..f1285ad1a 100644 --- a/redbot/cogs/audio/core/events/lavalink.py +++ b/redbot/cogs/audio/core/events/lavalink.py @@ -137,19 +137,19 @@ class LavalinkEvents(MixinMeta, metaclass=CompositeMetaClass): and self.playlist_api is not None and self.api_interface is not None ): - notify_channel = player.fetch("channel") + notify_channel_id = player.fetch("channel") try: await self.api_interface.autoplay(player, self.playlist_api) except DatabaseError: - notify_channel = self.bot.get_channel(notify_channel) - if notify_channel: + notify_channel = self.bot.get_channel(notify_channel_id) + if notify_channel and self._has_notify_perms(notify_channel): await self.send_embed_msg( notify_channel, title=_("Couldn't get a valid track.") ) return except TrackEnqueueError: - notify_channel = self.bot.get_channel(notify_channel) - if notify_channel: + notify_channel = self.bot.get_channel(notify_channel_id) + if notify_channel and self._has_notify_perms(notify_channel): await self.send_embed_msg( notify_channel, title=_("Unable to Get Track"), @@ -160,9 +160,9 @@ class LavalinkEvents(MixinMeta, metaclass=CompositeMetaClass): ) return if event_type == lavalink.LavalinkEvents.TRACK_START and notify: - notify_channel = player.fetch("channel") - if notify_channel: - notify_channel = self.bot.get_channel(notify_channel) + notify_channel_id = player.fetch("channel") + notify_channel = self.bot.get_channel(notify_channel_id) + if notify_channel and self._has_notify_perms(notify_channel): if player.fetch("notify_message") is not None: with contextlib.suppress(discord.HTTPException): await player.fetch("notify_message").delete() @@ -199,9 +199,9 @@ class LavalinkEvents(MixinMeta, metaclass=CompositeMetaClass): if event_type == lavalink.LavalinkEvents.QUEUE_END: if not autoplay: - notify_channel = player.fetch("channel") - if notify_channel and notify: - notify_channel = self.bot.get_channel(notify_channel) + notify_channel_id = player.fetch("channel") + notify_channel = self.bot.get_channel(notify_channel_id) + if notify_channel and notify and self._has_notify_perms(notify_channel): await self.send_embed_msg(notify_channel, title=_("Queue ended.")) if disconnect: self.bot.dispatch("red_audio_audio_disconnect", guild) diff --git a/redbot/cogs/audio/core/utilities/miscellaneous.py b/redbot/cogs/audio/core/utilities/miscellaneous.py index beb561f15..cd50b6a26 100644 --- a/redbot/cogs/audio/core/utilities/miscellaneous.py +++ b/redbot/cogs/audio/core/utilities/miscellaneous.py @@ -100,6 +100,10 @@ class MiscellaneousUtilities(MixinMeta, metaclass=CompositeMetaClass): embed.set_author(name=name) return await ctx.send(embed=embed) + def _has_notify_perms(self, channel: discord.TextChannel) -> bool: + perms = channel.permissions_for(channel.guild.me) + return all((perms.send_messages, perms.embed_links)) + async def maybe_run_pending_db_tasks(self, ctx: commands.Context) -> None: if self.api_interface is not None: await self.api_interface.run_tasks(ctx)