discord.py中fetch_member获取Member语音状态返回None问题求助
问题原因与解决办法
这问题我之前排查过,核心是Discord API的数据返回规则和discord.py的缓存机制差异导致的:
为什么会出现这个差异?
await a.fetch_member(ctx.author.id)是直接调用Discord官方API获取成员数据,但API默认返回的成员信息里不包含语音状态这类实时动态字段——毕竟语音状态变化频繁,API不会主动把这类数据塞进基础成员请求里,所以你拿到的b.voice自然是None。- 而
ctx.author是discord.py客户端已经在本地缓存好的成员对象,客户端会实时同步服务器里成员的语音状态变化,所以缓存里的对象包含完整的语音状态数据,能正常返回VoiceStateObject。
怎么解决?
推荐两种实用方案:
方案一:优先使用本地缓存获取成员
直接用服务器对象的get_member()方法从本地缓存取成员,既快又能拿到完整状态:
@client.command() async def test(ctx): # 从本地缓存获取成员,包含语音状态 b = ctx.guild.get_member(ctx.author.id) print(b.voice) # 正常返回VoiceStateObject print(ctx.author.voice)
如果缓存里没有目标成员(比如成员刚加入不久),可以先用await ctx.guild.fetch_members(limit=None)预加载所有成员到缓存,再用get_member()。
方案二:底层API请求(仅特殊场景用)
如果必须从API直接拉取带语音状态的成员数据,可以手动调用API并指定要包含的字段,但这种写法比较繁琐:
import discord from discord.http import Route @client.command() async def test(ctx): route = Route("GET", "/guilds/{guild_id}/members/{user_id}", guild_id=ctx.guild.id, user_id=ctx.author.id) # 请求时指定包含语音状态字段 data = await client.http.request(route, params={"include": "voice"}) # 手动构造成员对象 member = discord.Member(data=data, guild=ctx.guild, state=client._connection) print(member.voice)
这种写法需要自己处理数据解析,一般没必要,优先用方案一就够了。
内容的提问来源于stack exchange,提问作者enesd
相关产品推荐
相关产品推荐

