diff --git a/discord/ext/commands/converter.py b/discord/ext/commands/converter.py index 4ea649490..9c398a389 100644 --- a/discord/ext/commands/converter.py +++ b/discord/ext/commands/converter.py @@ -982,7 +982,7 @@ class clean_content(Converter[str]): def resolve_member(id: int) -> str: m = _utils_get(msg.mentions, id=id) or ctx.bot.get_user(id) - return f'@{m.name}' if m else '@deleted-user' + return f'@{m.display_name}' if m else '@deleted-user' def resolve_role(id: int) -> str: return '@deleted-role' @@ -990,7 +990,7 @@ class clean_content(Converter[str]): if self.fix_channel_mentions and ctx.guild: def resolve_channel(id: int) -> str: - c = ctx.guild.get_channel(id) # type: ignore + c = ctx.guild._resolve_channel(id) # type: ignore return f'#{c.name}' if c else '#deleted-channel' else: diff --git a/discord/message.py b/discord/message.py index ee6935b00..0bc9b6296 100644 --- a/discord/message.py +++ b/discord/message.py @@ -592,9 +592,9 @@ class Message(Hashable): The order of the mentions list is not in any particular order so you should not rely on it. This is a Discord limitation, not one with the library. - channel_mentions: List[:class:`abc.GuildChannel`] - A list of :class:`abc.GuildChannel` that were mentioned. If the message is in a private message - then the list is always empty. + channel_mentions: List[Union[:class:`abc.GuildChannel`, :class:`Thread`]] + A list of :class:`abc.GuildChannel` or :class:`Thread` that were mentioned. If the message is + in a private message then the list is always empty. role_mentions: List[:class:`Role`] A list of :class:`Role` that were mentioned. If the message is in a private message then the list is always empty. @@ -947,10 +947,10 @@ class Message(Hashable): return [int(x) for x in re.findall(r'<@&([0-9]{15,20})>', self.content)] @utils.cached_slot_property('_cs_channel_mentions') - def channel_mentions(self) -> List[GuildChannel]: + def channel_mentions(self) -> List[Union[GuildChannel, Thread]]: if self.guild is None: return [] - it = filter(None, map(self.guild.get_channel, self.raw_channel_mentions)) + it = filter(None, map(self.guild._resolve_channel, self.raw_channel_mentions)) return utils._unique(it) @utils.cached_slot_property('_cs_clean_content') @@ -970,40 +970,47 @@ class Message(Hashable): respectively, along with this function. """ - # fmt: off - transformations = { - re.escape(f'<#{channel.id}>'): '#' + channel.name - for channel in self.channel_mentions - } + if self.guild: - mention_transforms = { - re.escape(f'<@{member.id}>'): '@' + member.display_name - for member in self.mentions - } + def resolve_member(id: int) -> str: + m = self.guild.get_member(id) or utils.get(self.mentions, id=id) + return f'@{m.display_name}' if m else '@deleted-user' - # add the <@!user_id> cases as well.. - second_mention_transforms = { - re.escape(f'<@!{member.id}>'): '@' + member.display_name - for member in self.mentions - } + def resolve_role(id: int) -> str: + r = self.guild.get_role(id) or utils.get(self.role_mentions, id=id) + return f'@{r.name}' if r else '@deleted-role' - transformations.update(mention_transforms) - transformations.update(second_mention_transforms) + def resolve_channel(id: int) -> str: + c = self.guild._resolve_channel(id) + return f'#{c.name}' if c else '#deleted-channel' - if self.guild is not None: - role_transforms = { - re.escape(f'<@&{role.id}>'): '@' + role.name - for role in self.role_mentions - } - transformations.update(role_transforms) + else: + + def resolve_member(id: int) -> str: + m = utils.get(self.mentions, id=id) + return f'@{m.display_name}' if m else '@deleted-user' + + def resolve_role(id: int) -> str: + return '@deleted-role' + + def resolve_channel(id: int) -> str: + return f'#deleted-channel' + + transforms = { + '@': resolve_member, + '@!': resolve_member, + '#': resolve_channel, + '@&': resolve_role, + } - # fmt: on + def repl(match: re.Match) -> str: + type = match[1] + id = int(match[2]) + transformed = transforms[type](id) + return transformed - def repl(obj): - return transformations.get(re.escape(obj.group(0)), '') + result = re.sub(r'<(@[!&]?|#)([0-9]{15,20})>', repl, self.content) - pattern = re.compile('|'.join(transformations.keys())) - result = pattern.sub(repl, self.content) return escape_mentions(result) @property