diff --git a/bot.py b/bot.py index 3d23ece..decb07f 100644 --- a/bot.py +++ b/bot.py @@ -11,6 +11,7 @@ import dns.message import shaker import re import datetime +import time load_dotenv() @@ -107,7 +108,19 @@ async def setverifiedrole(ctx,role:discord.Role): await ctx.response.send_message("Verified role set to " + role.name + " for server " + ctx.guild.name,ephemeral=True) @tree.command(name="verify", description="Verifies your ownership of a Handshake name and sets your nickname.") -async def verify(ctx, domain:str): +async def verify(ctx:discord.Interaction, domain:str): + # Verify not a DM + if ctx.guild is None: + await ctx.response.send_message("You can not verify in DMs") + return + + # Reply to user to stop timeout + await ctx.response.defer(ephemeral=True, thinking=True) + + # Sleep for 5 seconds to simulate processing + time.sleep(5) + + name_idna = domain.strip().rstrip("/").encode("idna") name_ascii = name_idna.decode("ascii") @@ -115,7 +128,7 @@ async def verify(ctx, domain:str): for part in parts: if not re.match(r'[A-Za-z0-9-_]+$', part): - return await ctx.response.send_message("Invalid domain",ephemeral=True) + return await ctx.followup.send("Invalid domain",ephemeral=True) try: @@ -125,12 +138,12 @@ async def verify(ctx, domain:str): if shaker.check_name(ctx.user.id, name_ascii): try: - await ctx.user.edit(nick=name_rendered + "/") + await ctx.user.edit(nick=name_rendered + "/") # type: ignore # Set role - await shaker.handle_role(ctx.user, True) - return await ctx.response.send_message("Your nickname has been set to " + name_rendered + "/",ephemeral=True) + await shaker.handle_role(ctx.user, True) # type: ignore + return await ctx.followup.send("Your nickname has been set to " + name_rendered + "/",ephemeral=True) except discord.errors.Forbidden: - return await ctx.response.send_message("I don't have permission to do that",ephemeral=True) + return await ctx.followup.send("I don't have permission to do that",ephemeral=True) records = [{ "type": 'TXT', @@ -150,8 +163,7 @@ async def verify(ctx, domain:str): message += f"Once the record is set (this may take a few minutes) you can run this command again or manually set your nickname to `{name_rendered}/`." message += f"\n\nAlternatively, you can set the TXT record onchain, this will take longer to propagate.\n\n" - await ctx.response.send_message(message,ephemeral=True) - + await ctx.followup.send(message,ephemeral=True) # When the bot is ready diff --git a/shaker.py b/shaker.py index 24d51a4..5882d39 100644 --- a/shaker.py +++ b/shaker.py @@ -6,6 +6,7 @@ import dns.message import discord import json import requests +import re load_dotenv() @@ -77,14 +78,37 @@ async def handle_role(member: discord.Member, shouldHaveRole: bool): async def check_member(member: discord.Member) -> bool: if member.display_name[-1] != "/": + print("No trailing /",member.display_name,flush=True) await handle_role(member, False) return False - if check_name(member.id, member.display_name[0:-1]): + domain = member.display_name[0:-1] + name_idna = domain.strip().rstrip("/").encode("idna") + name_ascii = name_idna.decode("ascii") + parts = name_ascii.split(".") + + for part in parts: + if not re.match(r'[A-Za-z0-9-_]+$', part): + try: + print("Name not verified, removing /",member.display_name,flush=True) + await member.edit(nick=member.display_name[0:-1]) + except Exception as e: + print(e) + await handle_role(member, False) + return False + + try: + name_rendered = name_idna.decode("idna") + except UnicodeError: # don't render invalid punycode + name_rendered = name_ascii + + if check_name(member.id, name_ascii): + print("Name verified",member.display_name,flush=True) await handle_role(member, True) return True try: + print("Name not verified, removing /",member.display_name,flush=True) await member.edit(nick=member.display_name[0:-1]) except Exception as e: print(e)