Discord机器人检测用户加入语音频道方法及on_voice_state_update报错修复
问题原因与修复方案
1. 报错根源
你遇到的AttributeError是两个错误共同导致的:
on_voice_state_update事件的官方参数顺序完全错误,正确的参数顺序是(member, before, after),你把第一个member对象误当成了message传入get_context方法get_context是用于解析消息指令的方法,只能接收消息对象作为入参,而语音状态更新事件根本没有关联的消息对象,在这里调用这个方法完全多余
2. 正确的用户加入语音检测逻辑
你不需要遍历所有语音频道排查,直接通过事件自带的before和after状态对比就能判断用户是不是刚加入语音频道:
- 当
before.channel is None且after.channel is not None时,说明用户刚加入了某个语音频道 - 再匹配
member.id是否等于你要监控的指定用户ID,就能精准触发提示音逻辑
3. 修正后的代码示例
import asyncio import discord from gtts import gTTS from discord.ext import commands # 注意要开启服务器成员和语音状态相关的网关意图,Discord开发者后台也要开启对应权限 bot = commands.Bot(command_prefix="!", intents=discord.Intents.all()) # 你要监控的目标用户ID TARGET_USER_ID = 428938023057620994 @bot.event async def on_voice_state_update(member, before, after): # 过滤非目标用户的事件 if member.id != TARGET_USER_ID: return # 过滤不是刚加入语音频道的情况 if before.channel is not None or after.channel is None: return target_channel = after.channel # 生成提示音 tts = gTTS(text=f"{member.display_name}已加入聊天", lang='zh-cn') tts.save("join_notice.mp3") try: # 检查机器人是否已经在目标频道,避免重复连接 existing_vc = discord.utils.get(bot.voice_clients, guild=target_channel.guild) if existing_vc: await existing_vc.move_to(target_channel) vc = existing_vc else: vc = await target_channel.connect() # 播放提示音,play是异步非阻塞,需要等播放完再断开 vc.play(discord.FFmpegPCMAudio('join_notice.mp3')) while vc.is_playing(): await asyncio.sleep(0.5) await vc.disconnect() except Exception as e: # 如需发送错误通知,可以找服务器内的文字频道推送 notice_channel = target_channel.guild.text_channels[0] await notice_channel.send("Scusate ho la 104 e non funziono.")
额外注意事项
- 记得开启机器人的
语音状态 intent和服务器成员 intent,代码初始化Bot时要配置intents参数,同时Discord开发者后台的机器人设置页也要打开对应开关 - 播放音频前要确认运行环境已经正确安装配置了FFmpeg
内容的提问来源于stack exchange,提问作者Diego Gaglione
相关产品推荐
相关产品推荐

