如何获取Discord机器人上次离线时间?遇AttributeError问题求助
解决Discord Bot获取上次离线时间的问题
先修复当前报错
你遇到的AttributeError是因为visabot.activity为None,而且timestamps是字典类型(并非异步可迭代对象),不能用async for遍历。就算activity存在,正确的访问方式也是直接取visabot.activity.timestamps.get('start')这类键值,而非异步遍历。
但核心问题是:Discord不会主动记录机器人的上次离线时间,activity的timestamps只对应当前活动(比如你设置的"Watching"状态的开始时间),和离线时间完全无关。
无需数据库的解决方案
既然没法依赖Discord提供数据,我们可以在机器人运行时用内存变量结合事件监听来记录离线时间:
步骤1:在客户端类中添加状态记录变量
在你的MyClient类里初始化两个变量,用于记录离线时间和在线状态:
class MyClient(discord.Client): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.last_offline_time = None # 存储上次离线时间 self.is_online = True # 标记当前是否在线
步骤2:监听断开连接事件记录离线时间
当机器人断开连接时(无论主动退出还是被动断网),触发on_disconnect事件记录当前时间:
import datetime async def on_disconnect(self): self.is_online = False self.last_offline_time = datetime.datetime.now(datetime.timezone.utc) print(f"机器人已离线,时间:{self.last_offline_time}")
步骤3:在就绪事件中处理离线后逻辑
当机器人重新上线触发on_ready时,就可以调用last_offline_time执行你需要的操作:
async def on_ready(self): print(f'已登录为 {self.user}') # 若存在上次离线记录且之前处于离线状态,执行对应逻辑 if self.last_offline_time is not None and not self.is_online: await self.add_visa_after_offline() self.is_online = True async def add_visa_after_offline(self) -> bool: # 这里可以使用self.last_offline_time处理业务逻辑 print(f"上次离线时间:{self.last_offline_time}") # 你的业务代码写在这里 return True
补充说明
- 这种内存记录方式的局限是:如果机器人进程完全退出(比如崩溃重启),
last_offline_time会丢失。如果需要轻量持久化又不想用数据库,可以把时间写入本地文本文件(比如offline_record.txt),在on_disconnect时写入,在__init__时读取。 - 你已经开启了全部intents,这满足功能所需的权限要求。
on_disconnect事件会在各种断开场景下触发,能准确捕捉离线时间。
内容的提问来源于stack exchange,提问作者Bernoulli
相关产品推荐
相关产品推荐

