disnake机器人如何通过JSON存储的用户ID向目标用户发送私信?
问题原因
报错的核心原因是你从JSON文件中读取到的user是字符串格式的用户ID,并非disnake库中拥有send方法的User类实例,自然无法直接调用发送消息的方法。
修复步骤
- 第一步:将字符串格式的用户ID转换为整数类型(disnake的用户ID要求为整数)
- 第二步:通过机器人实例的
fetch_user方法请求API获取对应的User实例 - 第三步:对获取到的
User实例调用send方法发送消息,同时增加异常处理兼容用户不存在、无发送权限等异常场景
修正后的核心代码示例
import disnake import json import datetime as dt import asyncio @commands.Cog.listener() async def on_ready(self): period = 10 # 实际使用可改回86400.0 while True: # 等价于原写法while 3,可读性更强 with open('work_data/statues.json') as j: u_data = json.load(j) for user_id_str in list(u_data.keys()): if dt.datetime.now().timestamp() - u_data[user_id_str][0]['last_seen'] >= period: # 转换ID格式并获取用户对象 try: user_id = int(user_id_str) user_obj = await self.bot.fetch_user(user_id) await user_obj.send(f"{user_obj.mention},你已经24小时没上班,被解雇了。") await asyncio.sleep(2) u_data.pop(user_id_str) write_json(u_data) except ValueError: # ID格式非法无法转整数,直接删除无效记录 u_data.pop(user_id_str) write_json(u_data) except disnake.NotFound: # 对应用户不存在,删除无效记录 u_data.pop(user_id_str) write_json(u_data) except disnake.Forbidden: # 机器人无权限向该用户发送消息,可根据需求选择是否删除记录 pass await asyncio.sleep(0.1)
额外注意点
- 如果你的机器人已经开启了成员缓存,也可以用
self.bot.get_user(user_id)替代fetch_user,性能更高但如果用户不在缓存中会返回None,需要额外判空 - 更规范的做法是使用disnake的任务扩展
tasks来实现定时轮询逻辑,避免在on_ready事件中写长时间运行的死循环阻塞其他事件响应
内容的提问来源于stack exchange,提问作者Dominik
相关产品推荐
相关产品推荐

