如何用discord.py获取指定用户指定频道最后消息并解决相关报错?
Discord Bot 消息获取与时间格式化问题
问题详情
尝试获取用户ID 476686545034674176 在频道ID 1049386904065409054 发送的最后一条消息,调试时出现以下问题:
- 要么无任何输出
- 要么触发"找到消息"的输出后,后续调用命令时出现NoneType错误
- 调用
last_vent命令时触发时间格式化错误
原始代码
on_ready 事件代码
@client.event async def on_ready(): print('Logged in as') print(client.user.name) print(client.user.id) print('------') await tree.sync(guild=discord.Object(id=1049253865112997888)) aviv_venting_about_his_shitass_brothers = client.get_channel(1049386904065409054) global last_message async for message in aviv_venting_about_his_shitass_brothers.history(limit=1000): if message.author.id == 476686545034674176: last_message = message if last_message is None: print('no messages found') elif last_message.content == None: print('invalid message') else: print(f'found message {last_message.content}') break
命令中的时间格式化代码
await interaction.response.send_message(f'aviv last vented at {datetime.datetime.fromtimestamp(last_message.created_at).strftime("%Y-%m-%d %H:%M:%S")} <@{interaction.user.id}>')
触发的错误
discord.app_commands.errors.CommandInvokeError: Command 'last_vent' raised an exception: TypeError: 'datetime.datetime' object cannot be interpreted as an integer
问题分析与修复方案
1. 消息获取逻辑错误
- 无输出/未找到消息的问题:
原始代码中last_message未初始化,若循环1000条内无目标用户消息,变量会处于未定义状态且无提示;同时循环内判断last_message is None毫无意义——刚赋值的变量不可能为None。 - 仅显示"found message"的问题:
若消息为纯附件/嵌入内容,message.content为空,会触发elif分支但仅打印"invalid message",或者消息内容确实为空导致输出不完整。
修复后的on_ready代码:
@client.event async def on_ready(): print('Logged in as') print(client.user.name) print(client.user.id) print('------') await tree.sync(guild=discord.Object(id=1049253865112997888)) target_channel = client.get_channel(1049386904065409054) global last_message last_message = None # 初始化变量,避免未定义 # 先检查频道是否存在 if not target_channel: print('目标频道不存在,请检查频道ID') return # history默认按时间倒序(最新消息在前),找到第一条匹配的就是最后一条消息 async for message in target_channel.history(limit=1000): if message.author.id == 476686545034674176: last_message = message if not last_message.content: print('找到消息,但消息内容为空(可能是附件/嵌入消息)') else: print(f'找到消息:{last_message.content}') break # 循环结束后检查是否未找到任何消息 if not last_message: print('未找到该用户在目标频道的消息')
2. 时间格式化错误
message.created_at本身就是datetime.datetime对象,而datetime.datetime.fromtimestamp()需要传入时间戳整数,直接传入datetime对象会触发TypeError。直接调用created_at的strftime方法即可。
修复后的命令代码:
# 增加判断避免NoneType错误 if last_message: await interaction.response.send_message(f'aviv 最后发泄时间:{last_message.created_at.strftime("%Y-%m-%d %H:%M:%S")} <@{interaction.user.id}>') else: await interaction.response.send_message('未找到aviv的发泄记录')
额外建议
- 避免使用
global变量,可将last_message存储为client的属性(如client.last_vent_message),更符合编程规范。 - 增加异常捕获,处理频道历史获取时的权限不足等问题,避免bot崩溃。
内容的提问来源于stack exchange,提问作者Tauman
相关产品推荐
相关产品推荐

