如何基于条件自动调用discord.py发送消息至指定频道
解决discord.py条件触发消息发送的问题
你的问题核心在于background_task用了@client.event装饰器——discord.py的事件装饰器只认框架预定义的事件(比如on_ready),自定义函数加这个装饰器根本不会被触发。另外,要实现7×24小时的条件检测,需要在客户端的事件循环里启动一个后台任务,不能阻塞主进程。
下面是可行的修改方案:
import discord import asyncio client = discord.Client(intents=discord.Intents.default()) target_channel = None # 全局存储目标频道对象 def your_condition_check(): """替换成你的实际条件判断逻辑""" # 示例:比如检查某个数值是否达标 # return some_value >= 100 return True # 测试用,实际替换成你的条件 async def send_embed_message(): if not target_channel: return # 避免频道未初始化时出错 embed = discord.Embed(title="Testing") embed.add_field(name="Req Amount", value="100") embed.add_field(name="Return Amount", value="120") await target_channel.send(embed=embed) async def condition_monitor_loop(): await client.wait_until_ready() # 等客户端完全就绪再开始 while not client.is_closed(): if your_condition_check(): await send_embed_message() # 如果条件满足后需要暂停检测一段时间,可以加sleep # await asyncio.sleep(300) # 比如满足后5分钟再检查 await asyncio.sleep(10) # 每隔10秒检查一次,按需调整 @client.event async def on_ready(): global target_channel target_channel = client.get_channel(3534536365654654) await target_channel.send("Bot is ready") # 启动后台监测任务 client.loop.create_task(condition_monitor_loop()) client.run("YOUR_TOKEN_HERE")
关键说明:
- 移除事件装饰器:把原来的
background_task改成普通异步函数send_embed_message,去掉@client.event,让它可以被主动调用。 - 全局存储频道:在
on_ready里一次性获取频道对象并存下来,避免每次发送消息都调用get_channel,既高效又能减少API请求。 - 后台循环监测:用
condition_monitor_loop做循环检查,通过client.loop.create_task把它加入discord的事件循环,这样不会影响客户端正常运行。 - 控制检查频率:
asyncio.sleep(10)控制每次检查的间隔,根据你的需求调整(比如实时性高就缩短间隔,反之延长)。 - 条件判断隔离:把条件逻辑放到
your_condition_check函数里,便于单独维护和修改。
如果你的条件依赖同步操作(比如读取本地文件、调用同步API),不要直接在your_condition_check里执行,会阻塞事件循环,需要用await client.loop.run_in_executor(None, your_sync_condition_func)来异步处理。
内容的提问来源于stack exchange,提问作者Average Guy
相关产品推荐
相关产品推荐

