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

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"]) 

问题原因

  1. 代码最后一行错误地尝试从config["TutorialBot"]读取token,但你的bot.conf配置文件中不存在名为TutorialBot的配置段(section)。
  2. 你错误地把机器人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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 22:24:53