diff options
| author | 2020-07-15 01:09:35 +0200 | |
|---|---|---|
| committer | 2020-07-15 01:09:35 +0200 | |
| commit | 042f472ac3207ad685a5acb659a5a69f22c72282 (patch) | |
| tree | ad7b592de78dfa15c7fca668ea93f178c99a7dd3 | |
| parent | Merge branch 'master' into dm_relay (diff) | |
Remove caching of last_dm_user.
If you're typing up a reply and the bot gets another DM while you're
typing, you might accidentally send your reply to the wrong person.
This could happen even if you're very attentive, because it might be a
matter of milliseconds. The complexity to prevent this isn't worth the
convenience of the feature, and it's nice to get rid of the caching as
well, so I've decided to just make .reply require a user for every
reply.
https://github.com/python-discord/bot/issues/1041
| -rw-r--r-- | bot/cogs/dm_relay.py | 42 | ||||
| -rw-r--r-- | bot/constants.py | 2 | ||||
| -rw-r--r-- | config-default.yml | 1 | 
3 files changed, 20 insertions, 25 deletions
diff --git a/bot/cogs/dm_relay.py b/bot/cogs/dm_relay.py index 3fce52b93..f62d6105e 100644 --- a/bot/cogs/dm_relay.py +++ b/bot/cogs/dm_relay.py @@ -1,5 +1,4 @@  import logging -from typing import Optional  import discord  from discord import Color @@ -8,9 +7,7 @@ from discord.ext.commands import Cog  from bot import constants  from bot.bot import Bot -from bot.constants import MODERATION_ROLES -from bot.utils import RedisCache -from bot.utils.checks import with_role_check +from bot.utils.checks import in_whitelist_check, with_role_check  from bot.utils.messages import send_attachments  from bot.utils.webhooks import send_webhook @@ -20,9 +17,6 @@ log = logging.getLogger(__name__)  class DMRelay(Cog):      """Relay direct messages to and from the bot.""" -    # RedisCache[str, t.Union[discord.User.id, discord.Member.id]] -    dm_cache = RedisCache() -      def __init__(self, bot: Bot):          self.bot = bot          self.webhook_id = constants.Webhooks.dm_log @@ -30,11 +24,11 @@ class DMRelay(Cog):          self.bot.loop.create_task(self.fetch_webhook())      @commands.command(aliases=("reply",)) -    async def send_dm(self, ctx: commands.Context, member: Optional[discord.Member], *, message: str) -> None: +    async def send_dm(self, ctx: commands.Context, member: discord.Member, *, message: str) -> None:          """          Allows you to send a DM to a user from the bot. -        If `member` is not provided, it will send to the last user who DM'd the bot. +        A `member` must be provided.          This feature should be used extremely sparingly. Use ModMail if you need to have a serious          conversation with a user. This is just for responding to extraordinary DMs, having a little @@ -42,21 +36,11 @@ class DMRelay(Cog):          NOTE: This feature will be removed if it is overused.          """ -        user_id = await self.dm_cache.get("last_user") -        last_dm_user = ctx.guild.get_member(user_id) if user_id else None -          try: -            if member: -                await member.send(message) -                await ctx.message.add_reaction("✅") -                return -            elif last_dm_user: -                await last_dm_user.send(message) -                await ctx.message.add_reaction("✅") -                return -            else: -                log.debug("This bot has never gotten a DM, or the RedisCache has been cleared.") -                await ctx.message.add_reaction("❌") +            await member.send(message) +            await ctx.message.add_reaction("✅") +            return +          except discord.errors.Forbidden:              log.debug("User has disabled DMs.")              await ctx.message.add_reaction("❌") @@ -84,7 +68,6 @@ class DMRelay(Cog):                  username=message.author.display_name,                  avatar_url=message.author.avatar_url              ) -            await self.dm_cache.set("last_user", message.author.id)          # Handle any attachments          if message.attachments: @@ -106,7 +89,16 @@ class DMRelay(Cog):      def cog_check(self, ctx: commands.Context) -> bool:          """Only allow moderators to invoke the commands in this cog.""" -        return with_role_check(ctx, *MODERATION_ROLES) +        checks = [ +            with_role_check(ctx, *constants.MODERATION_ROLES), +            in_whitelist_check( +                ctx, +                channels=[constants.Channels.dm_log], +                redirect=None, +                fail_silently=True, +            ) +        ] +        return all(checks)  def setup(bot: Bot) -> None: diff --git a/bot/constants.py b/bot/constants.py index 3f44003a8..778bc093c 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -395,6 +395,7 @@ class Channels(metaclass=YAMLGetter):      dev_contrib: int      dev_core: int      dev_log: int +    dm_log: int      esoteric: int      helpers: int      how_to_get_help: int @@ -461,6 +462,7 @@ class Guild(metaclass=YAMLGetter):      staff_channels: List[int]      staff_roles: List[int] +  class Keys(metaclass=YAMLGetter):      section = "keys" diff --git a/config-default.yml b/config-default.yml index d12b9be27..8061e5e16 100644 --- a/config-default.yml +++ b/config-default.yml @@ -150,6 +150,7 @@ guild:          mod_log:            &MOD_LOG        282638479504965634          user_log:                           528976905546760203          voice_log:                          640292421988646961 +        dm_log:                             653713721625018428          # Off-topic          off_topic_0:    291284109232308226  |