将命令触发的循环发消息Bot改为启动自动运行的问题求助
问题:将Discord Bot从命令触发改为启动自动运行
原有命令触发实现
之前的Bot通过命令触发(比如输入+start 192839345345812312 10),就能按指定间隔向指定频道循环发送消息,代码如下:
@bot.command() async def start(ctx, channelid, time): channel_id = int(channelid) channel = bot.get_channel(channel_id) sleeptime = int(time) loopcheck = 0 while 1: if loopcheck == len(SElist): loopcheck = int(0) loopcheck = loopcheck + 1 await channel.send(random.choice(SElist)) print(f'Sent message to #{channel.name}') await asyncio.sleep(sleeptime)
当前尝试的自动启动代码(无法运行)
现在想让Bot启动时自动执行发送逻辑,从channels.json读取频道ID和间隔时间,为每个条目启动循环任务,但编写的代码无法运行:
@bot.event async def on_ready(): with open("channels.json", "r") as read_file: decodedArray = json.load(read_file) finalNumpyArrayOne = numpy.asarray(decodedArray["channels"]) for x in finalNumpyArrayOne: print(x[0]) async def start(ctx, channelid, time): channel_id = int(x[0]) channel = bot.get_channel(channel_id) sleeptime = int(x[1]) await channel.send(random.choice(SElist)) await asyncio.sleep(sleeptime)
问题分析与修复方案
存在的问题
- 循环内定义了异步函数但从未调用,任务根本不会启动
- 没必要用
numpy.asarray处理JSON数据,直接遍历原生列表即可 - 循环变量
x存在作用域陷阱,所有定义的函数会共享同一个x引用,最终全部使用最后一个频道的配置 - 丢失了原代码的无限循环逻辑,只会发送一次消息
修复后的代码
import asyncio import json import random # 请确保已导入你的bot实例和SElist变量 @bot.event async def on_ready(): print("Bot已上线,启动自动发送任务...") # 读取配置文件,无需numpy处理 with open("channels.json", "r") as read_file: config = json.load(read_file) channels_config = config.get("channels", []) # 为每个频道启动独立的异步发送任务 for channel_info in channels_config: channel_id = int(channel_info[0]) sleeptime = int(channel_info[1]) asyncio.create_task(auto_send_task(channel_id, sleeptime)) async def auto_send_task(channel_id, sleeptime): # 等待Bot缓存频道信息,避免刚上线时无法获取频道 channel = bot.get_channel(channel_id) while channel is None: await asyncio.sleep(1) channel = bot.get_channel(channel_id) loopcheck = 0 while True: # 保留原有的循环计数器逻辑(不需要可删除) if loopcheck == len(SElist): loopcheck = 0 loopcheck += 1 try: await channel.send(random.choice(SElist)) print(f'已发送消息到 #{channel.name}') except Exception as e: print(f'频道 {channel_id} 发送失败: {str(e)}') await asyncio.sleep(sleeptime)
补充说明
channels.json的标准格式示例:{ "channels": [ ["192839345345812312", 10], ["987654321098765432", 30] ] }- 使用
asyncio.create_task让多个发送任务并发运行,互不阻塞 - 增加频道对象重试逻辑,避免Bot刚上线时缓存未加载完成的报错
- 添加异常捕获,防止单个频道发送失败导致整个Bot停止运行
内容的提问来源于stack exchange,提问作者ziomek64
相关产品推荐
相关产品推荐

