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

求助:基于Python disnake实现Discord自动语音频道机器人

基于disnake实现自动语音频道创建/销毁功能

需求说明

  • 设置一个名为「Create voice chat」的触发语音频道,用户加入该频道时,机器人自动创建新的专属语音频道,并将用户移入新频道
  • 当自动创建的语音频道内无成员时,自动销毁该频道

参考的JavaScript实现(来自autocode)

const lib = require('lib')({token: process.env.STDLIB_SECRET_TOKEN});
const event = context.params.event;
const { guild_id, channel_id, user_id } = event

// The 'central' voice channel users must join first
const voiceChannelId = process.env.VOICE_CHANNEL_ID

// The voice channel name to create for the user
const voiceChannelName = `vc_${user_id}`

// Create a new voice channel when the user joins the specifc voice channel
const joinedChannel = channel_id === voiceChannelId
if (joinedChannel) {
  const channel = await lib.discord.guilds['@0.1.0'].channels.create({
    guild_id,
    name: voiceChannelName,
    type: 2, // vc
  })
  await lib.discord.guilds['@0.1.0'].members.update({
    guild_id, user_id,
    channel_id: channel.id,
  });
  return
}

// Delete the user's voice channel when the user disconnects
const leftChannel = !channel_id
if (leftChannel) {
  const channels = await lib.discord.guilds['@0.1.0'].channels.list({ guild_id });
  const channel = channels.find(c => c.name === voiceChannelName)
  if (channel)
    await lib.discord.channels['@0.2.0'].destroy({ channel_id: channel.id });
  return
}

自行编写的无法运行的Python代码

def _get_channel(self) -> disnake.abc.GuildChannel:
    return self.channel


def __init__(self):
    self.auto_channel = 1030505142820282408
    self.auto_channel = self.guild.get_channel(self.auto_channel)


@bot.event
async def on_voice_state_update(self, member = disnake.Member, before = disnake.VoiceState, after = disnake.VoiceState) -> None:
    if after.channel is not None and after.channel == auto_channel:
        ch = await self.auto_channel.category.create_voice_channel(name=member.display_name, overwrites={**self.auto_channel.category.overwrites, member: disnake.PermissionOverwrite(connect=True, move_members=True, manage_channels=True, manage_roles=True)})
        try:
            await member.move_to(ch, reason='autochannel')
        except disnake.HTTPException:
            pass
    if before.channel is not None and before.channel.id != auto_channel and before.channel.category.id == auto_channel and len(before.channel.members) == 0:
        try:
            await before.channel.delete()
        except disnake.NotFound:
            pass

修正后的代码及说明

问题分析

原代码存在以下关键问题:

  1. 事件处理函数on_voice_state_update定义错误:非Cog写法下不需要self参数;若用Cog则需用@commands.Cog.listener()装饰器而非@bot.event
  2. 变量引用错误:auto_channel未正确通过self引用,且初始化时self.guild未提前获取,导致无法拿到有效频道对象
  3. 判断条件错误:before.channel.category.id == auto_channel应与auto_channel.category.id比较,而非直接和频道对象对比

修正后的代码(非Cog写法)

import disnake
from disnake.ext import commands

bot = commands.Bot(command_prefix="!", intents=disnake.Intents.all())

# 替换为你的触发频道ID
TRIGGER_CHANNEL_ID = 1030505142820282408

@bot.event
async def on_voice_state_update(member: disnake.Member, before: disnake.VoiceState, after: disnake.VoiceState):
    # 获取触发频道对象
    trigger_channel = member.guild.get_channel(TRIGGER_CHANNEL_ID)
    if not trigger_channel:
        return

    # 情况1:用户加入触发频道,创建新语音频道并移动用户
    if after.channel == trigger_channel:
        # 在触发频道的分类下创建新频道
        new_channel = await trigger_channel.category.create_voice_channel(
            name=f"VC - {member.display_name}",
            # 继承分类权限,给用户额外管理权限
            overwrites={
                **trigger_channel.category.overwrites,
                member: disnake.PermissionOverwrite(
                    connect=True,
                    move_members=True,
                    manage_channels=True
                )
            }
        )
        try:
            await member.move_to(new_channel, reason="自动创建专属语音频道")
        except disnake.HTTPException as e:
            print(f"移动用户失败: {e}")
            # 移动失败则清理已创建的频道
            await new_channel.delete()

    # 情况2:用户离开频道,检查是否需要自动销毁
    if before.channel and before.channel != trigger_channel:
        # 仅处理触发频道分类下的自动创建频道
        if before.channel.category == trigger_channel.category:
            # 频道无成员时自动删除
            if len(before.channel.members) == 0:
                try:
                    await before.channel.delete(reason="频道无成员,自动销毁")
                except disnake.NotFound:
                    pass

bot.run("你的机器人Token")

代码逻辑说明

  1. 触发频道检测:用户加入指定的「Create voice chat」频道时,在同一分类下创建以用户昵称命名的新语音频道
  2. 用户移动:创建频道后立即将用户移入新频道,若移动失败则删除已创建的频道
  3. 自动销毁:用户离开频道时,检查该频道是否属于触发频道的分类且不是触发频道本身,若频道内无成员则自动删除

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 19:45:43