diff --git a/discord/abc.py b/discord/abc.py index 656a38659..d9dc1a14c 100644 --- a/discord/abc.py +++ b/discord/abc.py @@ -699,6 +699,7 @@ class GuildChannel: - Member overrides - Implicit permissions - Member timeout + - User installed app If a :class:`~discord.Role` is passed, then it checks the permissions someone with that role would have, which is essentially: @@ -714,6 +715,12 @@ class GuildChannel: .. versionchanged:: 2.0 ``obj`` parameter is now positional-only. + .. versionchanged:: 2.4 + User installed apps are now taken into account. + The permissions returned for a user installed app mirrors the + permissions Discord returns in :attr:`~discord.Interaction.app_permissions`, + though it is recommended to use that attribute instead. + Parameters ---------- obj: Union[:class:`~discord.Member`, :class:`~discord.Role`] @@ -745,6 +752,13 @@ class GuildChannel: return Permissions.all() default = self.guild.default_role + if default is None: + + if self._state.self_id == obj.id: + return Permissions._user_installed_permissions(in_guild=True) + else: + return Permissions.none() + base = Permissions(default.permissions.value) # Handle the role case first diff --git a/discord/permissions.py b/discord/permissions.py index 9fb46bcba..17c7b38c9 100644 --- a/discord/permissions.py +++ b/discord/permissions.py @@ -208,6 +208,22 @@ class Permissions(BaseFlags): base.send_messages_in_threads = False return base + @classmethod + def _user_installed_permissions(cls, *, in_guild: bool) -> Self: + base = cls.none() + base.send_messages = True + base.attach_files = True + base.embed_links = True + base.external_emojis = True + base.send_voice_messages = True + if in_guild: + # Logically this is False but if not set to True, + # permissions just become 0. + base.read_messages = True + base.send_tts_messages = True + base.send_messages_in_threads = True + return base + @classmethod def all_channel(cls) -> Self: """A :class:`Permissions` with all channel-specific permissions set to