Discord Chess.com战绩Bot开发求助:无法获取对局数据
问题:Discord Bot调用Chess.com API获取对局结果失败
我首次开发Discord Bot,想实现一个功能:在Discord频道输入!chessresult user时,返回该用户在Chess.com上的最后一局对局结果。目前Bot已成功连接(能回复文本消息),但无法拉取数据。附上我的代码:
import discord import requests from discord.ext import commands PREFIX = '!' intents = discord.Intents.all() bot = commands.Bot(command_prefix=PREFIX, intents=intents) @bot.event async def on_ready(): print('We have logged in as {0.user}'.format(bot)) @bot.event async def on_message(message): if message.content == "hello": await message.channel.send('hello') @bot.command() async def chessresult(ctx, username: str): try: # Fetch the recent games of the user from the Chess.com API response = requests.get(f'https://api.chess.com/pub/player/{username}/games/archives') response.raise_for_status() # Raise an error for bad responses archives = response.json()['archives'] if not archives: await ctx.send(f"No games found for user {username}") return # Use the most recent archive to get the games last_month_url = archives[-1] games_response = requests.get(f"{last_month_url}/pgn") games_response.raise_for_status() # Extract games from the PGN games = games_response.text.split("\n\n\n") # Extract the result of the most recent game last_game = games[-2] # The last item is empty, so take the second last result_line = [line for line in last_game.split("\n") if "Result" in line][0] result = result_line.split('"')[1] await ctx.send(f"Last game result for {username}: {result}") except requests.RequestException as e: await ctx.send(f"Error fetching data for {username}: {str(e)}") bot.run('KEY')
我尝试了多种方法,但进展甚微。这是我第一次编写Bot。
修复方案
1. 解决命令被拦截的问题
你的on_message事件会阻止命令系统触发,需要在事件末尾添加处理命令的代码:
@bot.event async def on_message(message): if message.content == "hello": await message.channel.send('hello') await bot.process_commands(message) # 新增这行,让Bot处理命令
2. 改用更可靠的API接口
解析PGN容易出现格式兼容问题,直接调用/games/recent接口获取最近对局的JSON数据,逻辑更稳定:
修改chessresult函数如下:
@bot.command() async def chessresult(ctx, username: str): try: # 调用最近对局接口,直接获取JSON格式数据 response = requests.get(f'https://api.chess.com/pub/player/{username}/games/recent') response.raise_for_status() games_data = response.json()['games'] if not games_data: await ctx.send(f"{username} 没有找到最近的对局记录") return # 取最后一局的结果 last_game = games_data[-1] result = last_game['result'] # 补充对局类型信息,让回复更完整 game_type = last_game['time_class'] await ctx.send(f"{username} 的最近一局{game_type}对局结果:{result}") except requests.RequestException as e: await ctx.send(f"获取{username}的对局数据失败:{str(e)}")
3. 完整修改后的代码
import discord import requests from discord.ext import commands PREFIX = '!' intents = discord.Intents.all() bot = commands.Bot(command_prefix=PREFIX, intents=intents) @bot.event async def on_ready(): print('We have logged in as {0.user}'.format(bot)) @bot.event async def on_message(message): if message.content == "hello": await message.channel.send('hello') await bot.process_commands(message) # 新增处理命令 @bot.command() async def chessresult(ctx, username: str): try: response = requests.get(f'https://api.chess.com/pub/player/{username}/games/recent') response.raise_for_status() games_data = response.json()['games'] if not games_data: await ctx.send(f"{username} 没有找到最近的对局记录") return last_game = games_data[-1] result = last_game['result'] game_type = last_game['time_class'] await ctx.send(f"{username} 的最近一局{game_type}对局结果:{result}") except requests.RequestException as e: await ctx.send(f"获取{username}的对局数据失败:{str(e)}") bot.run('你的Bot密钥')
内容的提问来源于stack exchange,提问作者twellener
相关产品推荐
相关产品推荐

