diff --git a/CHANGELOG.md b/CHANGELOG.md index 688462f439..4ec54e0f8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/modmail-dev/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v4.1.2 + +### Fixed +- Members not caching correctly for large servers. ([PR #3365](https://github.com/modmail-dev/Modmail/pull/3365)) + # v4.1.1 ### Fixed diff --git a/README.md b/README.md index eef9e3f940..2e3d32e344 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
- +
diff --git a/bot.py b/bot.py index 3c6ebe7911..3f13ef7ced 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.1.1" +__version__ = "4.1.2" import asyncio @@ -640,6 +640,16 @@ async def get_or_fetch_user(self, id: int) -> discord.User: """ return self.get_user(id) or await self.fetch_user(id) + @staticmethod + async def get_or_fetch_member(guild: discord.Guild, member_id: int) -> typing.Optional[discord.Member]: + """ + Attempt to get a member from cache; on failure fetch from the API. + + Returns: + The :obj:`discord.Member` or :obj:`None` to indicate the member could not be found. + """ + return guild.get_member(member_id) or await guild.fetch_member(member_id) + async def retrieve_emoji(self) -> typing.Tuple[str, str]: sent_emoji = self.config["sent_emoji"] blocked_emoji = self.config["blocked_emoji"] diff --git a/core/thread.py b/core/thread.py index 81dc03f44d..00060ab7f5 100644 --- a/core/thread.py +++ b/core/thread.py @@ -823,7 +823,13 @@ async def reply( """Returns List[user_dm_msg] and thread_channel_msg""" if not message.content and not message.attachments and not message.stickers: raise MissingRequiredArgument(DummyParam("msg")) - if not any(g.get_member(self.id) for g in self.bot.guilds): + for guild in self.bot.guilds: + try: + if await self.bot.get_or_fetch_member(guild, self.id): + break + except discord.NotFound: + pass + else: return await message.channel.send( embed=discord.Embed( color=self.bot.error_color, @@ -995,7 +1001,7 @@ async def send( attachments.append(attachment) image_urls = re.findall( - r"http[s]?:\/\/(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", + r"http[s]?:\/\/(?:[a-zA-Z]|[0-9]|[$\-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", message.content, ) diff --git a/pyproject.toml b/pyproject.toml index 1a5ed16a3b..7e29a4d4ef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.1.1' +version = '4.1.2' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [