如何使用discord.py实现Discord bot的线性分支持续对话流程
Discord.py 分支会话流程实现方案
你需要的限定作用域的会话响应可以通过discord.py内置的client.wait_for()方法实现,无需额外修改全局on_message事件的逻辑。
核心实现逻辑
你原来的写法问题在于:全局on_message事件是全量监听所有频道消息,新的用户回复不会自动传入stepOne的作用域,用asyncio.sleep也无法主动捕获用户发送的内容。
使用wait_for方法可以指定监听规则,仅捕获符合条件的消息,且仅在当前函数范围内生效,逻辑和控制台input阻塞等待输入的效果完全一致。
可直接运行的修正代码
import asyncio import discord # 配置机器人权限,必须开启消息内容意图才能读取用户消息内容 intents = discord.Intents.default() intents.message_content = True client = discord.Client(intents=intents) async def stepOne(trigger_msg): await trigger_msg.channel.send("你最近怎么样?") # 定义消息过滤规则:仅接收触发对话的同一用户、同一频道的消息 def check(msg): return msg.author == trigger_msg.author and msg.channel == trigger_msg.channel try: # 等待60秒内符合规则的用户回复,超时触发异常 user_reply = await client.wait_for('message', check=check, timeout=60) if user_reply.content == "挺好的": await trigger_msg.channel.send("很高兴听到这个消息") # 可在此添加更多分支逻辑,也可嵌套调用stepTwo、stepThree实现树状对话 # elif user_reply.content == "不太好": # await stepTwo(trigger_msg) except asyncio.TimeoutError: await trigger_msg.channel.send("长时间未收到回复,本次对话已结束") @client.event async def on_message(message): # 忽略机器人自身发送的消息,避免触发死循环 if message.author.bot: return if message.content == "你好": await message.channel.send("哈喽~") # 把当前触发对话的消息对象传入stepOne await stepOne(message) client.run("你的机器人Token")
方案优势
- 作用域完全隔离:
wait_for捕获的消息只会在当前调用的步骤函数内处理,不会和全局on_message的其他逻辑冲突 - 分支扩展灵活:可以在任意步骤的条件判断中继续调用其他步骤函数,完全按照你想要的树状分支逻辑编写,和普通控制台线性流程的编写体验一致
- 自带资源回收:超时机制可以自动结束无人响应的对话,不会占用后台资源
注意事项
- 必须在Discord开发者后台的机器人设置页开启
Message Content Intent权限,否则机器人无法读取用户发送的消息内容 - 过滤规则可根据需求调整,比如允许指定角色用户回复、支持多用户参与对话等
内容的提问来源于stack exchange,提问作者KEYS
相关产品推荐
相关产品推荐

