feat: Add timeout and interaction control to captcha modal
Set a 10-minute timeout for the `CaptchaModal` to prevent it from hanging indefinitely. Implemented a `wait()` method within the modal, allowing the calling function to asynchronously wait for submission or timeout. This enables proper flow control for the upload process. Restricted the "Solve Captcha" button in `CaptchaView` to only be clickable by the user who initiated the command, preventing unauthorized interaction.
This commit is contained in:
parent
04c2dd75b9
commit
bfd0d606ab
@ -12,7 +12,8 @@ import discord.ui
|
||||
|
||||
class CaptchaModal(discord.ui.Modal, title="Solve Image Captcha"):
|
||||
def __init__(self, captcha_id: str):
|
||||
super().__init__()
|
||||
# Set the modal timeout to 10 minutes to match the view's timeout for consistency
|
||||
super().__init__(timeout=600)
|
||||
self.captcha_id = captcha_id
|
||||
self.solution = discord.ui.TextInput(
|
||||
label="Captcha Solution",
|
||||
@ -22,20 +23,43 @@ class CaptchaModal(discord.ui.Modal, title="Solve Image Captcha"):
|
||||
max_length=100
|
||||
)
|
||||
self.add_item(self.solution)
|
||||
self.interaction = None
|
||||
self.is_submitted = asyncio.Event()
|
||||
|
||||
async def on_submit(self, interaction: discord.Interaction):
|
||||
# This method will be called when the user submits the modal
|
||||
# The actual file upload logic will be handled by the calling function
|
||||
await interaction.response.defer(ephemeral=True) # Defer the response to prevent interaction timeout
|
||||
# Store the interaction for later use
|
||||
self.interaction = interaction
|
||||
await interaction.response.defer(ephemeral=True) # Defer the response to prevent interaction timeout
|
||||
# Set the event to signal that the modal has been submitted
|
||||
self.is_submitted.set()
|
||||
|
||||
async def wait(self) -> bool:
|
||||
"""Wait for the modal to be submitted or time out.
|
||||
|
||||
Returns:
|
||||
bool: True if the modal timed out, False if it was submitted.
|
||||
"""
|
||||
try:
|
||||
await asyncio.wait_for(self.is_submitted.wait(), timeout=self.timeout)
|
||||
return False # Modal was submitted
|
||||
except asyncio.TimeoutError:
|
||||
return True # Modal timed out
|
||||
|
||||
|
||||
class CaptchaView(discord.ui.View):
|
||||
def __init__(self, modal: CaptchaModal):
|
||||
def __init__(self, modal: CaptchaModal, original_interactor_id: int):
|
||||
super().__init__(timeout=600) # 10 minutes timeout
|
||||
self.modal = modal
|
||||
self.original_interactor_id = original_interactor_id
|
||||
|
||||
@discord.ui.button(label="Solve Captcha", style=discord.ButtonStyle.primary)
|
||||
async def solve_button(self, interaction: discord.Interaction, button: discord.ui.Button):
|
||||
# Check if the user interacting is the original user who initiated the command
|
||||
if interaction.user.id != self.original_interactor_id:
|
||||
await interaction.response.send_message("Only the user who initiated this command can solve the captcha.", ephemeral=True)
|
||||
return
|
||||
|
||||
await interaction.response.send_modal(self.modal)
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user