Python Discordbot接入MongoDB后ban命令无法读取用户ID问题求助
问题修复方案
核心bug清单
- 字典成员判断逻辑错误:判断
member.id not in userdata时,userdata是键为_id、Username的字典,member.id是_id对应的值,不是字典的键,该判断永远为真,所以每次都会打印「Not in userdata」 - MongoDB集合判断逻辑错误:
member.id in bannedusers是直接判断数值是否在MongoDB集合对象中,该语法不生效,必须调用find_one查询集合内是否存在对应记录 - 数据插入格式错误:ban命令中当用户不在UserData集合时,
post = {userdata}生成的是Python集合对象,pymongo的insert_one要求传入字典,会触发插入报错 - AddDB命令逻辑冗余:判断
ctx.author.id not in userdata永远为真,该校验完全失效 - Bot初始化参数错误:
Intents参数首字母大写不符合discord.py规范,会导致意图加载失败
修复后完整代码
import pymongo import json import discord from discord.ext import commands with open("mongosetup.json") as file: setupfile = json.load(file) # ==> DISCORDBOT SETUP <== # botprefix = setupfile.get("Discordbot Prefix") token = setupfile.get("Discordbot Token") # ==> DATABASE SETUP <== # url = setupfile.get("Database url") databasename = setupfile.get("Database Name") # 修复intent参数大小写错误 bot = commands.Bot(command_prefix=botprefix, case_insensitive=True, self_bot=False, intents=discord.Intents.all()) myclient = pymongo.MongoClient(url) mydb = myclient[databasename] print(myclient.list_database_names()) dblist = myclient.list_database_names() if databasename in dblist: print("The database exists.") collection = mydb["UserData"] bannedusers = mydb["BannedUser"] @bot.command(name="AddDB") async def addtodb(ctx): try: userdata = {"_id": ctx.author.id, "Username": ctx.message.author.name} # 先查询是否已经存在,替代无效判断 if collection.find_one({"_id": ctx.author.id}) is None: collection.insert_one(userdata) await ctx.send("Your Username and your UserID where stored into our Datebase sucessfully! \n" f"Saved Data: {userdata}") else: await ctx.send("You cant add yourself twice in our Database. This User alredy exist!") except pymongo.errors.DuplicateKeyError: await ctx.send("You cant add yourself twice in our Database. This User alredy exist!") @bot.command(name="ban") @commands.has_permissions(ban_members=True) async def banuser(ctx, member: discord.Member, *, reason=None): userdata = {"_id": member.id, "Username": member.display_name} # 同步UserData集合 data = collection.find_one({"_id": member.id}) if data is None: # 修复插入格式错误,直接传入字典 collection.insert_one(userdata) print(member.id) # 先查询BannedUser集合中是否已有该用户 banned_record = bannedusers.find_one({"_id": member.id}) if banned_record is None: print("Not in banned list, adding now") bannedusers.insert_one(userdata) # 无论是否刚加入封禁列表,都执行ban操作 await ctx.send(f"Trying to ban the User {member.display_name}...") try: await member.ban(reason=reason) await ctx.send("Banned this user Sucessfully") except Exception as e: print(f"Ban error: {e}") await ctx.send("error") @bot.event async def on_command_error(ctx, error): if isinstance(error, commands.MissingRequiredArgument): await ctx.send("Please pass in all required Arguments :rolling_eyes:") if isinstance(error, commands.MissingPermissions): await ctx.send("You dont have all the required Permissions :angry:") @bot.event async def on_ready(): print(f'{bot.user} has connected to Discord!') bot.run(token)
额外说明
如果需要判断用户是否已被封禁,直接调用bannedusers.find_one({"_id": 用户id})即可,返回非None即为已封禁。
内容的提问来源于stack exchange,提问作者Pepe is Sad
相关产品推荐
相关产品推荐

