async def send_basics(self) -> None: """ Send the message containing the captcha code. """ if self.messages.get("bot_challenge"): raise OverflowError("Use 'Challenge.reload' to create another code.") embed_and_file = await self.captcha.generate_embed( guild_name=self.guild.name, author={"name": f"Captcha for {self.member.name}", "url": self.member.avatar_url}, footer={"text": f"Tries: {self.trynum} / Limit: {self.limit}"}, title=f"{self.guild.name} Verification System", description=( "Please return me the code on the following image. The code is made of 8 " "characters." ), ) try: await asyncio.sleep(1) bot_message: discord.Message = await self.channel.send( content=self.member.mention, embed=embed_and_file["embed"], file=embed_and_file["image"], delete_after=900, # Delete after 15 minutes. ) except discord.Forbidden: raise MissingPermissions("Cannot send message in verification channel.") self.messages["bot_challenge"] = bot_message try: await bot_message.add_reaction("🔁") except discord.Forbidden: raise MissingPermissions("Cannot react in verification channel.")
async def remove_temprole(self, challenge: Challenge) -> None: if temprole := challenge.config["temprole"]: try: await challenge.member.remove_roles( challenge.guild.get_role(temprole), reason="Finishing Captcha challenge.") except discord.Forbidden: raise MissingPermissions( 'Bot miss the "manage_roles" permission.')
async def reload(self) -> None: """ Resend another message with another code. """ if not self.messages.get("bot_challenge", None): raise AttributeError( "There is not message to reload. Use 'Challenge.send_basics' first." ) old_message: discord.Message = self.messages["bot_challenge"] try: await old_message.delete() except (discord.Forbidden, discord.HTTPException): log.warning( "Bot was unable to delete previous message in {guild}, ignoring.".format( guild=self.guild.name ) ) self.captcha.code = discapty.discapty.random_code() embed_and_file = await self.captcha.generate_embed( guild_name=self.guild.name, title="{guild} Verification System".format(guild=self.guild.name), footer={"text": f"Tries: {self.trynum} / Limit: {self.limit}"}, description=( "Please return me the code on the following image. The code is made of 8 " "characters." ), ) try: bot_message: discord.Message = await self.channel.send( embed=embed_and_file["embed"], file=embed_and_file["image"], delete_after=900, # Delete after 15 minutes. ) except discord.Forbidden: raise MissingPermissions("Cannot send message in verification channel.") self.messages["bot_challenge"] = bot_message try: await bot_message.add_reaction("🔁") except discord.Forbidden: raise MissingPermissions("Cannot react in verification channel.")
async def nicely_kick_user_from_challenge(self, challenge: Challenge, reason: str) -> bool: # We're gonna check our permission first, to avoid DMing the user for nothing. # Admin may have set channel to be DM, checking for kick_members is useless since # it always return False, instead, we're taking a random text channel of the guild # to check our permission for kicking. channel = (challenge.guild.text_channels[0] if isinstance( challenge.channel, discord.DMChannel) else challenge.channel) if not channel.permissions_for( self.bot.get_guild(challenge.guild.id).me).kick_members: raise MissingPermissions('Bot miss the "kick_members" permission.') with suppress(discord.Forbidden, discord.HTTPException): await challenge.member.send( embed=build_kick_embed(challenge.guild, reason)) try: await challenge.guild.kick(challenge.member, reason=reason) except discord.Forbidden: raise MissingPermissions("Unable to kick member.") return True
async def congratulation(self, challenge: Challenge, roles: list) -> None: """ Congrats to a member! He finished the captcha! """ # Admin may have set channel to be DM, checking for manage_roles is useless since # it always return False, instead, we're taking a random text channel of the guild # to check our permission for kicking. channel = (challenge.guild.text_channels[0] if isinstance( challenge.channel, discord.DMChannel) else challenge.channel) if not channel.permissions_for( self.bot.get_guild(challenge.guild.id).me).manage_roles: raise MissingPermissions('Bot miss the "manage_roles" permission.') await challenge.member.add_roles(*roles, reason="Passed Captcha successfully.")
async def cleanup_messages(self) -> bool: """ Remove every stocked messages. Return a boolean, if the deletion was successful. """ errored = False for message in self.messages.items(): if message[0] == "bot_challenge": self.cancel_tasks() if message[0] == "logs": # We don't want to delete logs. continue try: await message[1].delete() del message except discord.Forbidden: if not isinstance(self.channel, discord.DMChannel): # We're fine with not deleting user's message if it's in DM. raise MissingPermissions("Cannot delete message.") except discord.HTTPException: errored = True return not errored # Return if deleted, contrary of erroring, big brain