为什么我的Discord机器人无法发送每日定时消息?
问题根因
你遇到的AttributeError: 'NoneType' object has no attribute 'send'报错,核心原因是后台任务执行时Discord客户端还没有完成登录初始化,内部的频道缓存还未加载完成,所以client.get_channel(channel_id)调用返回了None,后续调用send方法自然触发空对象属性错误。
你把对应代码放到on_ready()中可以正常运行,也能佐证这个判断:on_ready()是Discord客户端完全登录、资源加载完毕后才会触发的事件,这时候调用get_channel()可以正常获取到频道对象。
修复方案
核心调整点
- 调整后台任务的启动时机,不要在
client.run()之前创建任务,改为在on_ready()事件中启动,保证客户端初始化完成后再执行逻辑 - 增加空值校验作为兜底容错,避免因为频道ID错误、机器人未加入对应频道等其他异常场景导致崩溃
- 将
background_task()的递归调用改为无限循环,避免长时间运行出现栈溢出风险
修复后完整代码示例
import os import discord import requests import json import asyncio channel_id = 791884298810163200 # 补全客户端初始化逻辑,注意根据你的需求调整intents权限 client = discord.Client(intents=discord.Intents.default()) def get_quote(): response = requests.get("https://zenquotes.io/api/random") json_data = json.loads(response.text) quote = json_data[0]["q"] + " -" + json_data[0]["a"] return quote async def sendQuote(): channel = client.get_channel(channel_id) # 增加空值判断兜底 if not channel: print(f"无法获取ID为{channel_id}的频道,请检查ID是否正确、机器人是否拥有该频道访问权限") return await channel.send(get_quote()) async def background_task(): # 替换递归为无限循环,避免栈溢出 while True: # 后续可在此处添加上午8点判断逻辑 await sendQuote() # 测试阶段用5秒,上线后替换为86400(24小时对应的秒数) await asyncio.sleep(5) @client.event async def on_ready(): print(f"登录成功,当前账号为:{client.user}") # 客户端初始化完成后再启动后台任务 client.loop.create_task(background_task()) if __name__ == "__main__": # 补全你的机器人token获取逻辑 my_secret = os.getenv("DISCORD_BOT_TOKEN") keep_alive() client.run(my_secret)
内容的提问来源于stack exchange,提问作者Joseph Spielman
相关产品推荐
相关产品推荐

