Discord.py机器人运行触发KeyError: 'TutorialBot'问题求助
解决Discord机器人启动时的KeyError: 'TutorialBot'问题
问题背景
我是Python零基础新手,正在开发一款用于Discord和Minetest互通消息的机器人,启动程序时遇到KeyError: 'TutorialBot'错误。
错误信息
Traceback (most recent call last): File "/home/<user>/Downloads/discordmt_bot-main/Main.py", line 154, in <module> bot.run(config["TutorialBot"]["<discord account key combination here"]) File "/usr/lib/python3.9/configparser.py", line 960, in __getitem__ raise KeyError(key) KeyError: 'TutorialBot'
相关代码(Main.py)
import configparser import os import discord from discord.ext import commands, tasks from discord.ext.commands import bot import asyncio #array to send messages to minetest from discord minetest_messages = [] config = configparser.ConfigParser() #you may need to path to bot.conf config.read('bot.conf') #settings bot = commands.Bot( command_prefix=config["BOT"]["command_prefix"], help_command=None, intents=discord.Intents(messages=True, message_content=True) ) lua_file = config["RELAY"]["lua_file_path"] python_file = config["RELAY"]["python_file_path"] python_report_file = config["RELAY"]["report_file_path"] relay_channel = config["RELAY"]["relay_channel"] report_channel = config["RELAY"]["report_channel"] cooldown = config["RELAY"]["cooldown"] debug_channel = config["RELAY"]["debug_channel"] debug_file = config["RELAY"]["debug_action_file_path"] def get_reports_msg(): if os.path.getsize(python_report_file) != 0: messages = [] with open(python_report_file, 'r') as filehandle: for message in filehandle: messages.append(message) #once readed empty file's input file = open(python_report_file, 'w') file.write("") file.close() return messages def get_messages(): #check if file has input or is empty if os.path.getsize(lua_file) != 0: messages = [] with open(lua_file, 'r') as filehandle: for message in filehandle: messages.append(message) #once readed empty file's input file = open(lua_file, 'w') file.write("") file.close() return messages def get_debug_message(): #check if file has input or is empty if os.path.getsize(debug_file) != 0: messages = [] with open(debug_file, 'r') as filehandle: for message in filehandle: messages.append(message) #once readed empty file's input file = open(debug_file, 'w') file.write("") file.close() return messages def write_messages(): #check if discord has messages to send and if so empty the array and send if os.path.getsize(python_file) == 0: #once readed empty file's input file = open(python_file, 'a') for dmsg in (minetest_messages): file.write("{} \n".format(dmsg)) file.close() minetest_messages.clear() @bot.event async def on_ready(): print('Connected!') #start the loop task_loop.start() #fetch messages in the channel @bot.event async def on_message(message): #make sure the channel is the right one and the bot messages getting ignored if (message.channel.id == int(relay_channel)) and (message.author.id != bot.user.id): author = message.author.name if config["RELAY"]["use_nicknames"] == True: author = message.author.display_name msg = "[Discord] <{}> {}".format(author, message.content) minetest_messages.append(msg) #loop to check if file has input or not @tasks.loop(seconds=int(cooldown)) async def task_loop(): #incase of an timeout try: channel = await bot.fetch_channel(relay_channel) rep_channel = await bot.fetch_channel(report_channel) deb_channel = await bot.fetch_channel(debug_channel) except discord.HTTPException as e: print(f'Error: {e}') await asyncio.sleep(60) #check if channel exists if channel is None: print("Error: Channel id {}, dosn't exists".format(channel)) elif rep_channel is None: print("Error: Channel id {}, dosn't exists".format(rep_channel)) elif debug_channel is None: print("Error: Channel id {}, dosn't exists".format(debug_channel)) #get messages from lua.txt messages = get_messages() report_msg = get_reports_msg() debug_msg = get_debug_message() #Read / send messages if messages != None: for msg in (messages): await channel.send(msg) if report_msg != None: for rmsg in (report_msg): await rep_channel.send(rmsg) if debug_msg != None: for dmsg in (debug_msg): await deb_channel.send(dmsg) #only write if array isn't emtpy if len(minetest_messages) != 0: write_messages() #bot token to run bot.run(config["TutorialBot"]["MTEyOTM4MDQ2OTU3ODkyNDEwMw.GL2azN.BI1Q54MHF8HnCdf-y5D3cVyEo-l-4vTRCQNvqs"])
问题原因
- 代码最后一行错误地尝试从
config["TutorialBot"]读取token,但你的bot.conf配置文件中不存在名为TutorialBot的配置段(section)。 - 你错误地把机器人token字符串当成了配置项的key来使用,这不符合
configparser的使用逻辑(正确逻辑是config[配置段][配置项名])。
解决方案
步骤1:修正bot.conf配置文件
在你的bot.conf文件中,添加token的配置项(如果已有[BOT]段,直接追加即可):
[BOT] command_prefix=! token=MTEyOTM4MDQ2OTU3ODkyNDEwMw.GL2azN.BI1Q54MHF8HnCdf-y5D3cVyEo-l-4vTRCQNvqs [RELAY] # 保留你原来的RELAY段配置 lua_file_path=... python_file_path=... # ...其他配置项
步骤2:修正代码中的token读取逻辑
把代码最后一行的错误代码替换为:
bot.run(config["BOT"]["token"])
额外优化建议
- 避免硬编码敏感信息:始终通过配置文件读取token,不要直接写在代码里,防止泄露。
- 验证配置文件读取结果:可以在
config.read('bot.conf')后添加判断,确保配置文件被正确读取:if not config.sections(): print("错误:未成功读取bot.conf,请检查文件路径是否正确") exit(1) - 修复布尔值判断问题:
on_message事件中,config["RELAY"]["use_nicknames"]读取的是字符串,直接和True比较会出错,改成:
因为if config["RELAY"].getboolean("use_nicknames"):configparser默认将所有配置值存储为字符串,getboolean方法可以正确转换布尔类型的配置项。
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

