Ruby-Cogs/autoroom/waiting_room.py
Valerie 4c69cf7ab9
Some checks are pending
Run pre-commit / Run pre-commit (push) Waiting to run
Add waiting room functionality to AutoRoom cog
This update introduces a waiting room system for AutoRoom sources, allowing users to be approved before entering the main AutoRoom. New commands for enabling and disabling waiting rooms have been added, along with corresponding settings in the configuration. The README has been updated to include instructions on using the waiting room feature.
2025-06-13 19:22:53 -04:00

184 lines
No EOL
7.2 KiB
Python

"""Waiting room functionality for AutoRoom cog."""
from typing import Any, Optional
import discord
from discord import ui
from redbot.core import Config
from redbot.core.bot import Red
class WaitingRoomView(ui.View):
"""View for waiting room control buttons."""
def __init__(self, cog: Any):
super().__init__(timeout=None)
self.cog = cog
@discord.ui.button(label="Allow", style=discord.ButtonStyle.green, custom_id="waiting_room_allow")
async def allow_button(self, interaction: discord.Interaction, button: discord.ui.Button):
"""Allow a user into the AutoRoom."""
if not interaction.message:
return
# Get the waiting user from the message
waiting_user_id = int(interaction.message.content.split("User: <@")[1].split(">")[0])
waiting_user = interaction.guild.get_member(waiting_user_id)
if not waiting_user:
await interaction.response.send_message("User no longer in the server.", ephemeral=True)
return
# Get the AutoRoom info
autoroom_info = await self.cog.get_autoroom_info(interaction.channel)
if not autoroom_info:
await interaction.response.send_message("This is not an AutoRoom.", ephemeral=True)
return
# Check if the interaction user is the owner
if interaction.user.id != autoroom_info["owner"]:
await interaction.response.send_message("Only the AutoRoom owner can use these buttons.", ephemeral=True)
return
# Move the user to the AutoRoom
try:
await waiting_user.move_to(interaction.channel)
await interaction.message.delete()
await interaction.response.send_message(f"Allowed {waiting_user.mention} into the AutoRoom.", ephemeral=True)
except discord.HTTPException:
await interaction.response.send_message("Failed to move user to the AutoRoom.", ephemeral=True)
@discord.ui.button(label="Deny", style=discord.ButtonStyle.red, custom_id="waiting_room_deny")
async def deny_button(self, interaction: discord.Interaction, button: discord.ui.Button):
"""Deny a user access to the AutoRoom."""
if not interaction.message:
return
# Get the waiting user from the message
waiting_user_id = int(interaction.message.content.split("User: <@")[1].split(">")[0])
waiting_user = interaction.guild.get_member(waiting_user_id)
if not waiting_user:
await interaction.response.send_message("User no longer in the server.", ephemeral=True)
return
# Get the AutoRoom info
autoroom_info = await self.cog.get_autoroom_info(interaction.channel)
if not autoroom_info:
await interaction.response.send_message("This is not an AutoRoom.", ephemeral=True)
return
# Check if the interaction user is the owner
if interaction.user.id != autoroom_info["owner"]:
await interaction.response.send_message("Only the AutoRoom owner can use these buttons.", ephemeral=True)
return
# Add user to denied list
denied = autoroom_info.get("denied", [])
if waiting_user.id not in denied:
denied.append(waiting_user.id)
await self.cog.config.channel(interaction.channel).denied.set(denied)
# Move user back to waiting room
waiting_room = interaction.guild.get_channel(autoroom_info["waiting_room_channel_id"])
if waiting_room:
try:
await waiting_user.move_to(waiting_room)
except discord.HTTPException:
pass
await interaction.message.delete()
await interaction.response.send_message(f"Denied {waiting_user.mention} access to the AutoRoom.", ephemeral=True)
class WaitingRoom:
"""Handles waiting room functionality."""
def __init__(self, cog: Any):
self.cog = cog
self.bot: Red = cog.bot
self.config: Config = cog.config
async def setup_waiting_room(self, autoroom_source: discord.VoiceChannel, text_channel: discord.TextChannel) -> bool:
"""Set up the waiting room for an AutoRoom source."""
try:
# Create waiting room channel
waiting_room = await autoroom_source.guild.create_voice_channel(
name="Waiting Room",
category=autoroom_source.category,
reason="AutoRoom: Setting up waiting room."
)
# Set up permissions
perms = discord.PermissionOverwrite(
view_channel=True,
connect=True,
speak=True,
stream=True,
use_voice_activation=True
)
await waiting_room.set_permissions(autoroom_source.guild.default_role, overwrite=perms)
# Save waiting room channel ID
await self.config.custom(
"AUTOROOM_SOURCE",
str(autoroom_source.guild.id),
str(autoroom_source.id)
).waiting_room_channel_id.set(waiting_room.id)
# Enable waiting room
await self.config.custom(
"AUTOROOM_SOURCE",
str(autoroom_source.guild.id),
str(autoroom_source.id)
).waiting_room_enabled.set(True)
return True
except discord.HTTPException:
return False
async def handle_waiting_user(self, member: discord.Member, autoroom: discord.VoiceChannel) -> None:
"""Handle a user joining the waiting room."""
autoroom_info = await self.cog.get_autoroom_info(autoroom)
if not autoroom_info:
return
# Get the text channel
text_channel = await self.cog.get_autoroom_legacy_text_channel(autoroom)
if not text_channel:
return
# Create waiting message with buttons
view = WaitingRoomView(self.cog)
message = await text_channel.send(
f"User: {member.mention} is waiting to join the AutoRoom.",
view=view
)
# Save message ID
await self.config.channel(autoroom).waiting_room_message_id.set(message.id)
async def cleanup_waiting_room(self, autoroom_source: discord.VoiceChannel) -> None:
"""Clean up the waiting room when disabling it."""
config = await self.config.custom(
"AUTOROOM_SOURCE",
str(autoroom_source.guild.id),
str(autoroom_source.id)
).all()
if config["waiting_room_channel_id"]:
waiting_room = autoroom_source.guild.get_channel(config["waiting_room_channel_id"])
if waiting_room:
try:
await waiting_room.delete(reason="AutoRoom: Disabling waiting room.")
except discord.HTTPException:
pass
await self.config.custom(
"AUTOROOM_SOURCE",
str(autoroom_source.guild.id),
str(autoroom_source.id)
).waiting_room_enabled.set(False)
await self.config.custom(
"AUTOROOM_SOURCE",
str(autoroom_source.guild.id),
str(autoroom_source.id)
).waiting_room_channel_id.set(None)