From 56161c0a88e6ec31ae2bd0b0d284ca8f54cad496 Mon Sep 17 00:00:00 2001 From: DiscordLiz <47602820+DiscordLiz@users.noreply.github.com> Date: Tue, 28 May 2019 12:37:02 -0400 Subject: [PATCH] Send to owners (#2738) * Add bot.send_to_owner resolves #2665 Adds some basic methods and config entries. Does not add commands for modifying this yet. * Use send_to_owners in events * handle feedback --- redbot/core/bot.py | 45 +++++++++++++++++++++++++++++++++++++++++++ redbot/core/events.py | 24 ++++++----------------- 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/redbot/core/bot.py b/redbot/core/bot.py index 877c54eb7..23f1b6ddd 100644 --- a/redbot/core/bot.py +++ b/redbot/core/bot.py @@ -20,6 +20,8 @@ from .utils import common_filters CUSTOM_GROUPS = "CUSTOM_GROUPS" +log = logging.getLogger("redbot") + def _is_submodule(parent, child): return parent == child or child.startswith(parent + ".") @@ -60,6 +62,8 @@ class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin): disabled_commands=[], disabled_command_msg="That command is disabled.", api_tokens={}, + extra_owner_destinations=[], + owner_opt_out_list=[], ) self.db.register_guild( @@ -464,6 +468,47 @@ class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin): ctx.permission_state = commands.PermState.DENIED_BY_HOOK return False + async def get_owner_notification_destinations(self) -> List[discord.abc.Messageable]: + """ + Gets the users and channels to send to + """ + destinations = [] + opt_outs = await self.db.owner_opt_out_list() + for user_id in (self.owner_id, *self._co_owners): + if user_id not in opt_outs: + user = self.get_user(user_id) + if user: + destinations.append(user) + + channel_ids = await self.db.extra_owner_destinations() + for channel_id in channel_ids: + channel = self.get_channel(channel_id) + if channel: + destinations.append(channel) + + return destinations + + async def send_to_owners(self, content=None, **kwargs): + """ + This sends something to all owners and their configured extra destinations. + + This takes the same arguments as discord.abc.Messageable.send + + This logs failing sends + """ + destinations = await self.get_owner_notification_destinations() + + async def wrapped_send(location, content=None, **kwargs): + try: + await location.send(content, **kwargs) + except Exception as _exc: + log.exception( + f"I could not send an owner notification to ({location.id}){location}" + ) + + sends = [wrapped_send(d, content, **kwargs) for d in destinations] + await asyncio.gather(*sends) + class Red(RedBase, discord.AutoShardedClient): """ diff --git a/redbot/core/events.py b/redbot/core/events.py index aacc88017..bd0bff3cd 100644 --- a/redbot/core/events.py +++ b/redbot/core/events.py @@ -120,24 +120,12 @@ def init_events(bot, cli_flags): "but you're using {}".format(data["info"]["version"], red_version) ) - owners = [] - owner = bot.get_user(bot.owner_id) - if owner is not None: - owners.append(owner) - - for co_owner in bot._co_owners: - co_owner = bot.get_user(co_owner) - if co_owner is not None: - owners.append(co_owner) - - for owner in owners: - with contextlib.suppress(discord.HTTPException): - await owner.send( - "Your Red instance is out of date! {} is the current " - "version, however you are using {}!".format( - data["info"]["version"], red_version - ) - ) + await bot.send_to_owners( + "Your Red instance is out of date! {} is the current " + "version, however you are using {}!".format( + data["info"]["version"], red_version + ) + ) INFO2 = [] mongo_enabled = storage_type() != "JSON"