diff options
author | 2021-10-07 12:34:50 -0700 | |
---|---|---|
committer | 2021-10-07 12:34:50 -0700 | |
commit | e8e6067666b6b2b0f3d4ff07906942860c2baaf4 (patch) | |
tree | 788588c5a0dc1de78804c7addfa2522fb566fd91 | |
parent | Added Anagrams command (#874) (diff) | |
parent | Allow topics to be refreshed (diff) |
Merge pull request #880 from python-discord/topic-command-cooldown
Add a 2 minute cooldown to the topic command
-rw-r--r-- | bot/exts/utilities/conversationstarters.py | 77 |
1 files changed, 60 insertions, 17 deletions
diff --git a/bot/exts/utilities/conversationstarters.py b/bot/exts/utilities/conversationstarters.py index dd537022..5d62fa83 100644 --- a/bot/exts/utilities/conversationstarters.py +++ b/bot/exts/utilities/conversationstarters.py @@ -1,11 +1,14 @@ +import asyncio +from contextlib import suppress +from functools import partial from pathlib import Path +import discord import yaml -from discord import Color, Embed from discord.ext import commands from bot.bot import Bot -from bot.constants import WHITELISTED_CHANNELS +from bot.constants import MODERATION_ROLES, WHITELISTED_CHANNELS from bot.utils.decorators import whitelist_override from bot.utils.randomization import RandomCycle @@ -35,35 +38,75 @@ TOPICS = { class ConvoStarters(commands.Cog): """General conversation topics.""" - @commands.command() - @whitelist_override(channels=ALL_ALLOWED_CHANNELS) - async def topic(self, ctx: commands.Context) -> None: + def __init__(self, bot: Bot): + self.bot = bot + + @staticmethod + def _build_topic_embed(channel_id: int) -> discord.Embed: """ - Responds with a random topic to start a conversation. + Build an embed containing a conversation topic. If in a Python channel, a python-related topic will be given. - Otherwise, a random conversation topic will be received by the user. """ # No matter what, the form will be shown. - embed = Embed(description=f"Suggest more topics [here]({SUGGESTION_FORM})!", color=Color.blurple()) + embed = discord.Embed( + description=f"Suggest more topics [here]({SUGGESTION_FORM})!", + color=discord.Color.blurple() + ) try: - # Fetching topics. - channel_topics = TOPICS[ctx.channel.id] - - # If the channel isn't Python-related. + channel_topics = TOPICS[channel_id] except KeyError: + # Channel doesn't have any topics. embed.title = f"**{next(TOPICS['default'])}**" - - # If the channel ID doesn't have any topics. else: embed.title = f"**{next(channel_topics)}**" + return embed + + def _predicate(self, message: discord.Message, reaction: discord.Reaction, user: discord.User) -> bool: + right_reaction = ( + user != self.bot.user + and reaction.message.id == message.id + and str(reaction.emoji) == "🔄" + ) + if not right_reaction: + return False + + is_moderator = any(role.id in MODERATION_ROLES for role in getattr(user, "roles", [])) + if is_moderator or user.id == message.author.id: + return True + + return False + + async def _listen_for_refresh(self, message: discord.Message) -> None: + await message.add_reaction("🔄") + while True: + try: + reaction, user = await self.bot.wait_for( + "reaction_add", + check=partial(self._predicate, message), + timeout=60.0 + ) + except asyncio.TimeoutError: + with suppress(discord.NotFound): + await message.clear_reaction("🔄") + else: + await message.edit(embed=self._build_topic_embed(message.channel.id)) - finally: - await ctx.send(embed=embed) + @commands.command() + @commands.cooldown(1, 60*2, commands.BucketType.channel) + @whitelist_override(channels=ALL_ALLOWED_CHANNELS) + async def topic(self, ctx: commands.Context) -> None: + """ + Responds with a random topic to start a conversation. + + Allows the refresh of a topic by pressing an emoji. + """ + message = await ctx.send(embed=self._build_topic_embed(ctx.channel.id)) + self.bot.loop.create_task(self._listen_for_refresh(message)) def setup(bot: Bot) -> None: """Load the ConvoStarters cog.""" - bot.add_cog(ConvoStarters()) + bot.add_cog(ConvoStarters(bot)) |