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

如何实现discord.py机器人存储用户信息并支持资料修改

嘿,我来帮你搞定这个个人资料修改的功能!用JSON存储用户数据确实是个简单又实用的方案,下面我一步步给你拆解具体操作:

第一步:初始化JSON数据文件

首先你需要创建一个用来存储所有用户资料的JSON文件,比如命名为users.json。初始内容可以是空对象:

{}

这个文件会以用户的Discord ID(字符串格式,因为JSON不支持整数键)作为唯一标识,存储每个用户的资料字段,比如昵称、简介、年龄这些。

第二步:编写数据读写工具函数

为了方便后续调用,我们先写两个工具函数:一个用来读取用户数据,一个用来保存用户数据。这样能避免重复代码,也让逻辑更清晰。

import json
import os
from discord import Member

# 读取用户数据
def get_user_data(user_id: int) -> dict:
    # 检查文件是否存在,不存在就创建空文件
    if not os.path.exists("users.json"):
        with open("users.json", "w", encoding="utf-8") as f:
            json.dump({}, f, ensure_ascii=False)
    
    # 读取文件内容
    with open("users.json", "r", encoding="utf-8") as f:
        all_data = json.load(f)
    
    # 返回当前用户的数据,没有的话返回空字典
    return all_data.get(str(user_id), {})

# 保存用户数据
def save_user_data(user_id: int, new_info: dict):
    # 先获取用户现有数据,避免覆盖未修改的字段
    current_data = get_user_data(user_id)
    # 合并现有数据和新数据(新数据会覆盖旧的同名字段)
    updated_data = {**current_data, **new_info}
    
    # 读取所有用户数据并更新
    with open("users.json", "r", encoding="utf-8") as f:
        all_data = json.load(f)
    
    all_data[str(user_id)] = updated_data
    
    # 写回文件,indent=4让JSON格式更易读
    with open("users.json", "w", encoding="utf-8") as f:
        json.dump(all_data, f, indent=4, ensure_ascii=False)
第三步:实现~switchcode修改命令

根据你说的“用户输入代码修改资料”,我假设代码对应不同的资料字段(比如1=修改简介,2=修改昵称)。下面是命令的具体实现:

@bot.command(name="switchcode")
async def switch_code(ctx, code: int, *, content: str):
    # 定义代码和对应字段的映射,你可以根据自己的embed字段调整
    code_field_map = {
        1: "bio",      # 简介
        2: "nickname", # 自定义昵称
        3: "age",      # 年龄
        4: "hobby"     # 爱好
    }
    
    # 检查输入的代码是否有效
    if code not in code_field_map:
        valid_codes = "\n".join([f"{k} = 修改{v}" for k, v in code_field_map.items()])
        await ctx.send(f"无效的代码!可用代码如下:\n{valid_codes}")
        return
    
    # 获取要修改的字段名
    target_field = code_field_map[code]
    
    # 保存修改后的资料
    save_user_data(ctx.author.id, {target_field: content})
    
    # 给用户反馈,并发送更新后的个人资料embed
    await ctx.send(f"已成功更新你的{target_field}字段!")
    
    # 生成更新后的个人资料embed(这里用你已有的embed逻辑调整即可)
    user_data = get_user_data(ctx.author.id)
    profile_embed = discord.Embed(
        title=f"{ctx.author.display_name}的个人资料",
        color=discord.Color.blue()
    )
    profile_embed.add_field(name="自定义昵称", value=user_data.get("nickname", "未设置"), inline=False)
    profile_embed.add_field(name="个人简介", value=user_data.get("bio", "未设置"), inline=False)
    profile_embed.add_field(name="年龄", value=user_data.get("age", "未设置"), inline=False)
    profile_embed.add_field(name="爱好", value=user_data.get("hobby", "未设置"), inline=False)
    profile_embed.set_thumbnail(url=ctx.author.avatar.url)
    
    await ctx.send(embed=profile_embed)
第四步:同步查看资料命令的逻辑

之前你写的查看资料embed,现在要改成从JSON读取最新数据,比如:

@bot.command(name="profile")
async def view_profile(ctx, member: Member = None):
    # 默认查看自己的资料,也可以@别人查看对方的
    target_member = member or ctx.author
    user_data = get_user_data(target_member.id)
    
    # 生成embed(和你之前的代码逻辑一致,只是数据来源换成JSON)
    profile_embed = discord.Embed(
        title=f"{target_member.display_name}的个人资料",
        color=discord.Color.green()
    )
    profile_embed.add_field(name="自定义昵称", value=user_data.get("nickname", "未设置"), inline=False)
    profile_embed.add_field(name="个人简介", value=user_data.get("bio", "未设置"), inline=False)
    profile_embed.add_field(name="年龄", value=user_data.get("age", "未设置"), inline=False)
    profile_embed.add_field(name="爱好", value=user_data.get("hobby", "未设置"), inline=False)
    profile_embed.set_thumbnail(url=target_member.avatar.url)
    
    await ctx.send(embed=profile_embed)
一些注意事项
  • 异常处理:可以给文件读写部分加上try-except块,防止文件被占用或者格式错误导致机器人崩溃。
  • 字段扩展:如果以后要加新的资料字段,只需要修改code_field_map和embed的字段即可,非常灵活。
  • 数据持久化:JSON文件会一直保存在本地,重启机器人后数据也不会丢失,完全满足你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 17:17:38