113 lines
4.5 KiB
Python
113 lines
4.5 KiB
Python
"""JARVIS Verify Cog."""
|
|
import asyncio
|
|
import logging
|
|
from random import randint
|
|
|
|
from jarvis_core.db import q
|
|
from jarvis_core.db.models import Setting
|
|
from naff import Client, Extension, InteractionContext
|
|
from naff.models.discord.components import Button, ButtonStyles, spread_to_rows
|
|
from naff.models.naff.application_commands import slash_command
|
|
from naff.models.naff.command import cooldown
|
|
from naff.models.naff.cooldowns import Buckets
|
|
|
|
|
|
def create_layout() -> list:
|
|
"""Create verify component layout."""
|
|
buttons = []
|
|
yes = randint(0, 2) # noqa: S311
|
|
for i in range(3):
|
|
label = "YES" if i == yes else "NO"
|
|
id = f"no_{i}" if not i == yes else "yes"
|
|
color = ButtonStyles.GREEN if i == yes else ButtonStyles.RED
|
|
buttons.append(
|
|
Button(
|
|
style=color,
|
|
label=label,
|
|
custom_id=f"verify_button||{id}",
|
|
)
|
|
)
|
|
return spread_to_rows(*buttons, max_in_row=3)
|
|
|
|
|
|
class VerifyCog(Extension):
|
|
"""JARVIS Verify Cog."""
|
|
|
|
def __init__(self, bot: Client):
|
|
self.bot = bot
|
|
self.logger = logging.getLogger(__name__)
|
|
|
|
@slash_command(name="verify", description="Verify that you've read the rules")
|
|
@cooldown(bucket=Buckets.USER, rate=1, interval=30)
|
|
async def _verify(self, ctx: InteractionContext) -> None:
|
|
await ctx.defer()
|
|
role = await Setting.find_one(q(guild=ctx.guild.id, setting="verified"))
|
|
if not role:
|
|
message = await ctx.send("This guild has not enabled verification", ephemeral=True)
|
|
return
|
|
verified_role = await ctx.guild.fetch_role(role.value)
|
|
if not verified_role:
|
|
await ctx.send("This guild has not enabled verification", ephemeral=True)
|
|
await role.delete()
|
|
return
|
|
|
|
if verified_role in ctx.author.roles:
|
|
await ctx.send("You are already verified.", ephemeral=True)
|
|
return
|
|
components = create_layout()
|
|
message = await ctx.send(
|
|
content=f"{ctx.author.mention}, please press the button that says `YES`.",
|
|
components=components,
|
|
)
|
|
|
|
try:
|
|
verified = False
|
|
while not verified:
|
|
response = await self.bot.wait_for_component(
|
|
messages=message,
|
|
check=lambda x: ctx.author.id == x.context.author.id,
|
|
timeout=30,
|
|
)
|
|
|
|
correct = response.context.custom_id.split("||")[-1] == "yes"
|
|
if correct:
|
|
for row in components:
|
|
for component in row.components:
|
|
component.disabled = True
|
|
setting = await Setting.find_one(q(guild=ctx.guild.id, setting="verified"))
|
|
try:
|
|
role = await ctx.guild.fetch_role(setting.value)
|
|
await ctx.author.add_role(role, reason="Verification passed")
|
|
except AttributeError:
|
|
self.logger.warning("Verified role deleted before verification finished")
|
|
setting = await Setting.find_one(q(guild=ctx.guild.id, setting="unverified"))
|
|
if setting:
|
|
try:
|
|
role = await ctx.guild.fetch_role(setting.value)
|
|
await ctx.author.remove_role(role, reason="Verification passed")
|
|
except AttributeError:
|
|
self.logger.warning(
|
|
"Unverified role deleted before verification finished"
|
|
)
|
|
|
|
await response.context.edit_origin(
|
|
content=f"Welcome, {ctx.author.mention}. Please enjoy your stay.",
|
|
components=components,
|
|
)
|
|
await response.context.message.delete(delay=5)
|
|
self.logger.debug(f"User {ctx.author.id} verified successfully")
|
|
else:
|
|
await response.context.edit_origin(
|
|
content=(
|
|
f"{ctx.author.mention}, incorrect. "
|
|
"Please press the button that says `YES`"
|
|
)
|
|
)
|
|
except asyncio.TimeoutError:
|
|
await message.delete(delay=2)
|
|
self.logger.debug(f"User {ctx.author.id} failed to verify before timeout")
|
|
|
|
|
|
def setup(bot: Client) -> None:
|
|
"""Add VerifyCog to JARVIS"""
|
|
VerifyCog(bot)
|