Python开发Midjourney Discord Bot故障排查求助
Midjourney自动化脚本问题排查与修复
一、生成脚本:心跳阻塞(heartbeat blocked)问题
问题根源
discord.gateway Shard ID None heartbeat blocked for more than 60 seconds 报错核心原因是:Discord网关的心跳线程被长时间阻塞。你的on_message事件回调里的while循环是同步执行逻辑,完全占满了异步事件循环,导致客户端无法按时向Discord服务器发送心跳包,最终触发网关断开、脚本冻结。
修复方案
Discord.py是异步框架,必须避免在事件回调中写阻塞式同步逻辑,把耗时操作转为异步任务,不占用主事件循环:
原始问题代码示例(典型错误):
@client.event async def on_message(message): if message.content == "!start_gen": while True: # 同步发送指令、等待结果的逻辑 time.sleep(5) # 同步sleep直接卡死事件循环
修改后代码:
用异步API替代同步操作,把循环逻辑放到独立异步任务中:
import asyncio @client.event async def on_message(message): if message.content == "!start_gen": # 启动独立异步任务,不阻塞on_message回调 asyncio.create_task(run_gen_loop(message)) async def run_gen_loop(message): midjourney_bot_id = 936929561302675456 # Midjourney Bot的ID while True: # 异步发送生成指令 await message.channel.send("/imagine prompt:你的提示词") # 用异步sleep替代同步sleep await asyncio.sleep(10) # 异步等待Midjourney的回复,避免轮询阻塞 def check_reply(m): return m.author.id == midjourney_bot_id and m.channel == message.channel try: reply_msg = await client.wait_for('message', check=check_reply, timeout=60) # 处理生成完成的图片逻辑 except asyncio.TimeoutError: await message.channel.send("生成超时,重试中...")
关键修复点:
- 用
asyncio.sleep替代time.sleep,不阻塞事件循环 - 把长时间循环逻辑放到独立异步任务,避免占用事件回调线程
- 使用
client.wait_for异步等待消息,替代同步轮询
二、下载脚本:仅下载少量图片后停止
可能原因及对应修复
Discord API限流:频繁请求图片触发Discord速率限制,后续请求被静默拒绝,无报错但停止下载
- 修复:每次下载后添加异步延迟,控制请求频率:
await asyncio.sleep(1.5) # 每次下载后等待1.5秒
- 修复:每次下载后添加异步延迟,控制请求频率:
历史消息分页未处理:脚本仅获取了第一页历史消息,没有遍历所有分页内容
- 修复:循环获取所有历史消息分页,直到无更多内容:
async def download_all_images(channel_id): channel = client.get_channel(channel_id) last_msg = None while True: # 分页获取历史消息,每次取100条 messages = await channel.history(limit=100, after=last_msg).flatten() if not messages: break last_msg = messages[-1] for msg in messages: for att in msg.attachments: if att.content_type.startswith('image/'): try: await att.save(f"./output/{att.filename}") await asyncio.sleep(1) except Exception as e: print(f"保存失败 {att.filename}: {str(e)}")
- 修复:循环获取所有历史消息分页,直到无更多内容:
文件系统异常未捕获:
output文件夹无写入权限、空间不足或文件名冲突,导致保存失败但脚本未报错- 修复:添加异常捕获,打印错误信息定位问题:
try: await att.save(f"./output/{att.filename}") except PermissionError: print(f"无写入权限:./output/{att.filename}") except FileExistsError: print(f"文件已存在:./output/{att.filename}") except Exception as e: print(f"保存失败:{str(e)}")
- 修复:添加异常捕获,打印错误信息定位问题:
通用注意事项
- 确保使用最新版discord.py(v2.x),旧版本存在异步事件循环bug:
pip install --upgrade discord.py - 所有网络请求需用异步库(如
aiohttp),禁止在异步函数中调用同步阻塞操作(如requests.get)
内容的提问来源于stack exchange,提问作者d3d
相关产品推荐
相关产品推荐

