diff options
| author | 2021-06-07 16:35:34 -0400 | |
|---|---|---|
| committer | 2021-06-07 16:35:34 -0400 | |
| commit | c808ca0e069d97d0a9aba97d7332fe9e1ed15d75 (patch) | |
| tree | 08e39309994bce8a26cef8b699957dce7f5acb09 | |
| parent | Merge pull request #1623 from python-discord/new_zapped_formats (diff) | |
| parent | Add help dm feature (diff) | |
Merge pull request #1 from JakeM0001/griff/helpdm
Griff/helpdm
| -rw-r--r-- | bot/exts/help_channels/_caches.py | 9 | ||||
| -rw-r--r-- | bot/exts/help_channels/_cog.py | 91 |
2 files changed, 100 insertions, 0 deletions
diff --git a/bot/exts/help_channels/_caches.py b/bot/exts/help_channels/_caches.py index c5e4ee917..8d45c2466 100644 --- a/bot/exts/help_channels/_caches.py +++ b/bot/exts/help_channels/_caches.py @@ -24,3 +24,12 @@ question_messages = RedisCache(namespace="HelpChannels.question_messages") # This cache keeps track of the dynamic message ID for # the continuously updated message in the #How-to-get-help channel. dynamic_message = RedisCache(namespace="HelpChannels.dynamic_message") + +# This cache keeps track of who has help-dms on. +# RedisCache[discord.User.id, bool] +help_dm = RedisCache(namespace="HelpChannels.help_dm") + +# This cache tracks member who are participating and opted in to help channel dms. +# serialise the set as a comma separated string to allow usage with redis +# RedisCache[discord.TextChannel.id, str[set[discord.User.id]]] +session_participants = RedisCache(namespace="HelpChannels.session_participants") diff --git a/bot/exts/help_channels/_cog.py b/bot/exts/help_channels/_cog.py index 5c410a0a1..919115e95 100644 --- a/bot/exts/help_channels/_cog.py +++ b/bot/exts/help_channels/_cog.py @@ -424,6 +424,7 @@ class HelpChannels(commands.Cog): ) -> None: """Actual implementation of `unclaim_channel`. See that for full documentation.""" await _caches.claimants.delete(channel.id) + await _caches.session_participants.delete(channel.id) claimant = self.bot.get_guild(constants.Guild.id).get_member(claimant_id) if claimant is None: @@ -466,9 +467,14 @@ class HelpChannels(commands.Cog): if channel_utils.is_in_category(message.channel, constants.Categories.help_available): if not _channel.is_excluded_channel(message.channel): await self.claim_channel(message) + + elif channel_utils.is_in_category(message.channel, constants.Categories.help_in_use): + await self.notify_session_participants(message) + else: await _message.update_message_caches(message) + @commands.Cog.listener() async def on_message_delete(self, msg: discord.Message) -> None: """ @@ -535,3 +541,88 @@ class HelpChannels(commands.Cog): ) self.dynamic_message = new_dynamic_message["id"] await _caches.dynamic_message.set("message_id", self.dynamic_message) + + @staticmethod + def _serialise_session_participants(participants: set[int]) -> str: + """Convert a set to a comma separated string.""" + return ','.join(str(p) for p in participants) + + @staticmethod + def _deserialise_session_participants(s: str) -> set[int]: + """Convert a comma separated string into a set.""" + return set(int(user_id) for user_id in s.split(",") if user_id != "") + + @lock.lock_arg(NAMESPACE, "message", attrgetter("channel.id")) + @lock.lock_arg(NAMESPACE, "message", attrgetter("author.id")) + async def notify_session_participants(self, message: discord.Message) -> None: + """ + Check if the message author meets the requirements to be notified. + If they meet the requirements they are notified. + """ + if await _caches.claimants.get(message.channel.id) == message.author.id: + return # Ignore messages sent by claimants + + if not await _caches.help_dm.get(message.author.id): + return # Ignore message if user is opted out of help dms + + if message.content == f"{self.bot.command_prefix}close": + return # Ignore messages that are closing the channel + + session_participants = self._deserialise_session_participants( + await _caches.session_participants.get(message.channel.id) or "" + ) + + if not message.author.id in session_participants: + session_participants.add(message.author.id) + await message.author.send("Purple") + await _caches.session_participants.set( + message.channel.id, + self._serialise_session_participants(session_participants) + ) + + @commands.group(name="helpdm") + async def help_dm_group(self, ctx: commands.Context) -> None: + if ctx.invoked_subcommand is None: + await ctx.send_help(ctx.command) + + @help_dm_group.command(name="on") + async def on_command(self, ctx: commands.Context) -> None: + if await _caches.help_dm.get(ctx.author.id): + await ctx.send(f"{constants.Emojis.cross_mark}{ctx.author.mention} Help DMs are already ON!") + + log.trace(f"{ctx.author.id} Attempted to turn Help DMs on but they are already ON") + return + + await _caches.help_dm.set(ctx.author.id, True) + + await ctx.send(f"{constants.Emojis.ok_hand} {ctx.author.mention} Help DMs ON!") + + log.trace(f"{ctx.author.id} Help DMs OFF") + + @help_dm_group.command(name="off") + async def off_command(self, ctx: commands.Context) -> None: + if not await _caches.help_dm.get(ctx.author.id): + await ctx.send(f"{constants.Emojis.cross_mark} {ctx.author.mention} Help DMs are already OFF!") + + log.trace(f"{ctx.author.id} Attempted to turn Help DMs on but they are already OFF") + return + + await _caches.help_dm.set(ctx.author.id, False) + + await ctx.send(f"{constants.Emojis.ok_hand} {ctx.author.mention} Help DMs OFF!") + + log.trace(f"{ctx.author.id} Help DMs OFF") + + # TODO: REMOVE BEFORE COMMIT + @help_dm_group.command() + async def embed_test(self, ctx): + user = self.bot.get_user(ctx.author.id) + + embed = discord.Embed( + title="Currently Helping", + description=f"You're currently helping in <#{ctx.channel.id}>", + color=discord.Colour.green(), + timestamp=ctx.message.created_at + ) + embed.add_field(name="Conversation", value=f"[Jump to message]({ctx.message.jump_url})") + await user.send(embed=embed) |