You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Telethon对话中收到特定消息(如bye)时终止对话

如何在Telethon对话中检测“bye”消息并终止对话

刚好我之前也处理过类似的需求,给你两种可行的实现方案,都能解决你要在用户发“bye”时终止对话的问题:

方案一:在对话流程内部监听“bye”消息

这种方式是在活跃的对话循环里,同时监听用户的按钮点击和普通消息,一旦检测到“bye”就立即终止对话。我们需要用一个全局字典来跟踪所有正在进行的对话实例:

from telethon import events, Button
from telethon.errors import ConversationCancelledError

# 全局字典,用聊天ID作为键保存活跃的对话实例
active_conversations = {}

@bot.on(events.NewMessage(incoming=True, pattern='Hi'))
async def main(event):
    chat_id = event.chat_id
    async with bot.conversation(chat_id) as conv:
        # 将当前对话实例存入字典,方便后续调用
        active_conversations[chat_id] = conv
        try:
            # 发送初始消息和按钮
            await conv.send_message('choose', buttons=[[Button.inline('Yes'), Button.inline('No')]])
            await conv.send_message('<b> Want More ? </b>', parse_mode='html', buttons=[
                [Button.text('Yes', resize=True,single_use=True), Button.text('No', resize=True,single_use=True)],
                [Button.text('More', resize=True,single_use=True)]
            ])
            
            # 循环等待用户响应,同时监听消息和按钮事件
            while True:
                # 等待用户的消息或者按钮点击
                response = await conv.wait_event(
                    events.NewMessage(chats=chat_id) | events.CallbackQuery(chats=chat_id)
                )
                
                # 处理普通消息
                if isinstance(response, events.NewMessage):
                    user_msg = response.raw_text.lower()
                    if user_msg == 'bye':
                        await conv.send_message('对话已结束!')
                        conv.cancel()  # 终止当前对话
                        break
                    else:
                        # 这里可以处理用户发送的其他消息
                        await conv.send_message(f'你输入了:{response.raw_text}')
                
                # 处理按钮点击
                elif isinstance(response, events.CallbackQuery):
                    await response.answer()  # 先回复按钮点击的确认
                    await conv.send_message(f'你点击了:{response.data.decode()}')
                    
        except ConversationCancelledError:
            # 捕获对话被取消的异常,做收尾处理
            await bot.send_message(chat_id, '对话已终止')
        finally:
            # 无论对话正常结束还是被取消,都从字典中移除实例,避免内存泄漏
            if chat_id in active_conversations:
                del active_conversations[chat_id]

方案二:单独监听“bye”消息并终止对应对话

这种方式是写一个独立的事件处理器,专门监听用户发送的“bye”消息,然后找到对应的活跃对话实例并终止:

# 先定义和方案一一样的active_conversations字典
active_conversations = {}

# 原有的Hi对话处理器和方案一一致,这里省略...

# 单独的bye消息处理器
@bot.on(events.NewMessage(incoming=True, pattern='^bye$', case_sensitive=False))
async def handle_bye(event):
    chat_id = event.chat_id
    # 检查当前聊天是否有活跃的对话
    if chat_id in active_conversations:
        conv = active_conversations[chat_id]
        conv.cancel()  # 终止对话
        await event.respond('对话已结束!')
        # 清理对话实例
        del active_conversations[chat_id]
    else:
        await event.respond('当前没有正在进行的对话哦')

关键知识点说明

  • conv.cancel():这个方法会终止当前的对话,让所有等待中的conv.wait()或conv.wait_event()抛出ConversationCancelledError,我们可以捕获这个异常来做收尾操作。
  • conv.cancel_all():这个方法会终止机器人所有的活跃对话,一般只在需要全局终止对话的时候使用,大部分场景用cancel()就足够了。
  • 全局字典active_conversations:用来跟踪每个聊天的活跃对话,确保我们能准确找到要终止的对话实例,处理完后记得删除,避免内存占用。

内容的提问来源于stack exchange,提问作者jonny789

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 11:52:46