You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

discord.py中on_voice_state_update触发NoneType错误,无法删除临时语音频道

Discord.py 语音频道克隆与自动删除问题修复

需求

  • 用户连接到ID为1191737629281107978的特定语音频道时,自动克隆临时频道并将用户移入
  • 临时频道无成员时自动删除

问题现象

当前代码可成功创建临时频道,但无法自动删除,且触发两个AttributeError错误:

错误1

line 58, in on_voice_state_update
    if after.channel.id == 1191737629281107978:
       ^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'id'

错误2

line 61, in on_voice_state_update
    if before.channel.name == possible_channel_name and len(before.channel.members) == 0:
       ^^^^^^^^^^^^^^^^^^^

当前代码

依赖库

import discord
from discord.ext import commands
from datetime import datetime
from PIL import Image, ImageDraw
import asyncio
import configure
import sqlite3
import requests
import io

Intents配置

intents = discord.Intents.all()
intents.members = True

client = commands.Bot(intents=intents, command_prefix="/")

事件函数

@client.event
async def on_voice_state_update(member, before, after):
    possible_channel_name = f'new {member}`s channel'
    if after.channel.id == 1191737629281107978:
        temp_channel = await after.channel.clone(name=possible_channel_name)
        await member.move_to(temp_channel)
    if before.channel.name == possible_channel_name and len(before.channel.members) == 0:
        await before.channel.delete()

问题原因与修复方案

错误根源

  1. 未处理channel为None的场景:
    • 用户退出所有语音频道时,after.channel为None,直接访问id属性会报错
    • 用户首次进入语音频道时,before.channel为None,直接访问name属性会报错
  2. 频道名称字符串语法错误:原代码中f'new {member}s channel'`的单引号冲突,会导致字符串解析异常

修复后的代码

@client.event
async def on_voice_state_update(member, before, after):
    target_channel_id = 1191737629281107978
    # 修正单引号转义问题,避免语法错误
    temp_channel_name = f"new {member}'s channel"

    # 处理用户进入目标频道逻辑:先判断after.channel是否存在
    if after.channel and after.channel.id == target_channel_id:
        temp_channel = await after.channel.clone(name=temp_channel_name)
        await member.move_to(temp_channel)
    
    # 处理临时频道自动删除逻辑:先判断before.channel是否存在
    if before.channel:
        # 验证是否为创建的临时频道,且频道内无成员
        if before.channel.name == temp_channel_name and len(before.channel.members) == 0:
            await before.channel.delete()

额外优化建议

如果需要支持多用户创建临时频道,建议用频道分类或自定义前缀(比如temp-)来标识临时频道,避免因用户名重复导致误删其他频道。

内容的提问来源于stack exchange,提问作者RayanUtka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 23:10:18