Disnake.py私人语音频道开发:如何实现撤销删除功能?
实现私人语音频道的自动删除与撤销功能
核心问题分析
现有代码仅在检测到频道为空后固定等待10秒删除,无法中断倒计时处理用户返回的情况。要实现撤销删除,需要用异步任务+状态跟踪的方式,允许在用户返回时终止删除流程。
解决方案代码
import disnake from disnake.ext import commands import asyncio bot = commands.Bot(command_prefix=commands.when_mentioned_or('!'), help_command=None, intents=disnake.Intents.all()) # 存储私人频道的删除任务:频道ID -> 异步任务对象 delete_tasks = {} @bot.event async def on_voice_state_update(member, before, after): # 替换为你的主语音频道ID MAIN_CHANNEL_ID = 123456789012345678 # 私人频道名称前缀,用于识别我们创建的频道 PRIVATE_CHANNEL_PREFIX = '𝙰𝚁𝙴𝙽𝙰 ' # 1. 处理用户进入主频道,创建私人语音频道 if after.channel and after.channel.id == MAIN_CHANNEL_ID: category = after.channel.category guild = member.guild # 创建私人频道 private_channel = await guild.create_voice_channel( name=f'{PRIVATE_CHANNEL_PREFIX}{member.display_name}', category=category ) # 给用户分配频道管理权限 await private_channel.set_permissions( member, connect=True, mute_members=True, move_members=True, manage_channels=True ) await member.move_to(private_channel) # 2. 处理私人频道的成员变动,管理删除逻辑 # 情况A:用户离开私人频道,检查是否需要启动删除倒计时 if before.channel and before.channel.name.startswith(PRIVATE_CHANNEL_PREFIX): target_channel = before.channel # 频道为空时启动删除任务 if len(target_channel.members) == 0: async def delete_countdown(): await asyncio.sleep(10) # 再次确认频道为空,避免竞态问题 if len(target_channel.members) == 0: await target_channel.delete() del delete_tasks[target_channel.id] task = asyncio.create_task(delete_countdown()) delete_tasks[target_channel.id] = task # 情况B:用户返回私人频道,取消删除倒计时 if after.channel and after.channel.name.startswith(PRIVATE_CHANNEL_PREFIX): target_channel = after.channel if target_channel.id in delete_tasks: # 取消删除任务并清理记录 delete_tasks[target_channel.id].cancel() del delete_tasks[target_channel.id] bot.run('YOUR_BOT_TOKEN')
关键实现说明
delete_tasks字典:跟踪每个私人频道的删除倒计时任务,确保能精准定位并取消对应频道的删除流程。- 异步倒计时任务:用
asyncio.create_task创建独立的倒计时任务,不阻塞主事件循环,允许同时处理其他用户操作。 - 双重状态校验:在执行删除前再次检查频道成员数,避免因用户快速进出导致误删。
- 前缀识别私人频道:通过名称前缀判断是否为机器人创建的私人频道,无需额外存储频道ID列表,简化逻辑。
内容的提问来源于stack exchange,提问作者Mars
相关产品推荐
相关产品推荐

