Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add UnVerified role removal after verification #3

Merged
merged 3 commits into from
Nov 5, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 36 additions & 10 deletions bot/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,15 @@ async def on_submit(self, interaction: discord.Interaction):
if not email_input.is_valid_bits_email:
raise ValueError("Enter a valid BITS Pilani student email.")

verification_code = "".join(
OTP = "".join(
random.choices("0123456789", k=OTP_LENGTH)
)

email_params = {
"from": f"BITS Discord Bot <{BOT_EMAIL}>",
"to": [email_input.email],
"subject": "Discord Email Verification OTP",
"html": f"Your OTP is: <strong>{verification_code}</strong>",
"html": f"Your OTP is: <strong>{OTP}</strong>",
}

if not resend.Emails.send(email_params):
Expand All @@ -110,12 +110,12 @@ async def on_submit(self, interaction: discord.Interaction):

await redis_client.set(
f"verify:{interaction.user.id}",
f"{verification_code}:{email_input.email}",
f"{OTP}:{email_input.email}",
ex=OTP_EXPIRY,
)

await interaction.followup.send(
f"An OTP has been sent to **{email_input.email}**. \nNOTE: The code will expire in **10 minutes**. \nIf Enter Code Button doesn't appear use `/verify` again",
f"An OTP has been sent to **{email_input.email}**. \nNOTE: The code will expire in **10 minutes**. \nIf Enter OTP Button doesn't appear use `/verify` again",
ephemeral=True,
)

Expand All @@ -136,9 +136,13 @@ async def on_submit(self, interaction: discord.Interaction):
logger.error(f"Unexpected error in EmailModal: {str(e)}")


class CodeModal(Modal):
class OTPModal(Modal):
"""
Modal dialog for OTP entry.
Handles the verification process including role management and Redis operations.
"""
def __init__(self):
super().__init__(title="Code Verification")
super().__init__(title="OTP Verification")
self.code = TextInput(
label="Enter the OTP",
placeholder="xxxxxx",
Expand All @@ -152,13 +156,15 @@ async def on_submit(self, interaction: discord.Interaction):
await interaction.response.defer(ephemeral=True)

try:
# Check if user is already verified
verified_role = discord.utils.get(interaction.guild.roles, name="Verified")
if verified_role in interaction.user.roles:
await interaction.followup.send(
"You are already verified!", ephemeral=True
)
return


# Validate OTP from Redis
stored_data = await redis_client.get(f"verify:{interaction.user.id}")
if not stored_data:
raise ValueError("OTP expired or not found")
Expand All @@ -167,26 +173,46 @@ async def on_submit(self, interaction: discord.Interaction):
if self.code.value != correct_code:
raise ValueError("Incorrect OTP")

# Remove UnVerified Role
unverified_role = discord.utils.get(interaction.guild.roles, name="UnVerified")

if not unverified_role:
raise ValueError("@UnVerified role not found")

await interaction.user.remove_roles(unverified_role)

# Add Verified Role
verified_role = discord.utils.get(interaction.guild.roles, name="Verified")
sattwyk marked this conversation as resolved.
Show resolved Hide resolved
if not verified_role:
raise ValueError("@Verified role not found")

await interaction.user.add_roles(verified_role)
await redis_client.delete(f"verify:{interaction.user.id}")

# Remove UnVerified Role
unverified_role = discord.utils.get(interaction.guild.roles, name="UnVerified")

if not unverified_role:
raise ValueError("@UnVerified role not found")

await interaction.user.remove_roles(unverified_role)

# Cleanup and Success Message
await redis_client.delete(f"verify:{interaction.user.id}")
await interaction.followup.send(
"Verification successful! You have been given the Verified role.",
ephemeral=True,
)

except ValueError as e:
# Handle validation errors
await interaction.followup.send(str(e), ephemeral=True)
logger.error(f"OTP verification error: {str(e)}")
except Exception as e:
# Handle unexpected errors
await interaction.followup.send(
"An unexpected error occurred. Please try again later.", ephemeral=True
)
logger.error(f"Unexpected error in CodeModal: {str(e)}")
logger.error(f"Unexpected error in OTPModal: {str(e)}")


class VerifyBot(discord.Client):
Expand Down Expand Up @@ -259,7 +285,7 @@ async def on_interaction(interaction: discord.Interaction):
if interaction.data["custom_id"] == "email_button":
await interaction.response.send_modal(EmailModal())
elif interaction.data["custom_id"] == "otp_button":
await interaction.response.send_modal(CodeModal())
await interaction.response.send_modal(OTPModal())


@discord_client.event
Expand Down
Loading