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

discord.py构造embed发送日志报Member不可JSON序列化错误

报错原因

discord.Embed.from_dict() 内部会对传入的字典做JSON序列化校验,要求字典内所有值都必须是可JSON序列化的原生类型(字符串、数字、布尔值、嵌套字典/列表等)。
你的代码中直接将discord.Member/discord.User类型的实例对象赋值给了embed字段的value属性:

{
  'name' : 'Name:',
  'value' : target  # 直接传入Member对象,不是原生可序列化类型
},
{
  'name' : 'Moderator:',
  'value' : mod  # 直接传入Member对象,不是原生可序列化类型
}

Discord的成员对象不属于JSON可序列化的原生类型,因此触发TypeError: Object of type Member is not JSON serializable报错。

修复方案
  • 将embed字典中直接传入的成员对象转为字符串类型的合法值:需要@用户就用对象.mention,需要显示用户名+鉴别号就用str(对象),需要显示用户ID就用str(对象.id)
  • 补全原代码里的遗漏问题:给Reason字段补全默认inline属性、提前定义embed用的颜色值、增加target为空时的错误提示、将参数类型改为discord.Member(discord.User是跨公会的用户抽象,没有加角色的权限)、给reason参数加*前缀以接收带空格的完整禁言理由

修复后的完整可运行代码:

import discord
from discord import Embed
from discord.ext import commands

# 定义mod日志嵌入条的颜色,禁言操作可使用红色
MUTE_LOG_COLOR = 0xff0000

def log_embed(target : discord.Member, mod : discord.Member, action : str, reason : str = None):
  embed = {
    'title' : f'{target.mention} has been {action}',
    'type' : 'rich',
    'color' : MUTE_LOG_COLOR,
    'fields' : [
      {
        'name' : 'Name:',
        'value' : str(target),  # 转为「用户名#鉴别号」格式的字符串
        'inline': True
      },
      {
        'name' : 'Moderator:',
        'value' : str(mod),  # 转为字符串
        'inline': True
      },
      {
        'name' : 'Reason:',
        'value' : reason.capitalize() if reason else 'No reason given',
        'inline' : True
      }
    ]
  }
  return embed

@bot.command()
@commands.has_role('Staff')
async def mute(ctx, target : discord.Member = None, *, reason : str = None):
  # 未指定禁言目标时返回提示
  if not target:
    await ctx.send("请指定需要禁言的目标用户")
    return
  # 获取公会内的muted角色
  muted_role = discord.utils.get(ctx.guild.roles, name='muted')
  await target.add_roles(muted_role, reason=reason)
  # 发送日志到mod-log频道
  channel = discord.utils.get(ctx.guild.channels, name='mod-log')
  if channel:
    await channel.send(embed = Embed.from_dict(log_embed(target=target, mod=ctx.author, action='muted', reason=reason)))
  await ctx.send(f"已对 {target.mention} 完成禁言操作")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 20:03:39