为了账号安全,请及时绑定邮箱和手机立即绑定

如何仅在 Telethon 对话中处理 NewMessage

如何仅在 Telethon 对话中处理 NewMessage

临摹微笑 2023-10-11 20:05:36
我的机器人代码中有两个处理程序:my_conversation - 捕获“/start”消息并开始新对话,其中等待来自用户的消息数字 - 按模式捕获消息 - 仅数字    import asyncio    import logging    import re        from telethon import TelegramClient    from telethon.events import StopPropagation, NewMessage    me = TelegramClient('bot', 'API_ID_BOT', 'API_HASH_BOT').start(bot_token='BOT_TOKEN')            async def my_conversation(event):        async with me.conversation(event.sender_id) as conv:            await conv.send_message('I\'m waiting for message')            response = conv.get_response()            response = await response            await conv.send_message(f'conversation: {response.text}')        raise StopPropagation            async def digits(event):        await me.send_message(event.sender_id, f'catches digits: {event.text}')        raise StopPropagation            async def main():        me.add_event_handler(my_conversation, NewMessage(incoming=True, pattern=r'^\/start$'))        me.add_event_handler(digits, NewMessage(incoming=True, pattern=re.compile(r'[0-9]+')))        await me.run_until_disconnected()            if __name__ == '__main__':        logging.basicConfig(level=logging.INFO)        loop = asyncio.get_event_loop()        loop.run_until_complete(main())我的期望:我发送“/start”机器人开始对话并回复“我正在等待消息”我发送“123”机器人发送消息“对话:123”,因为对话已开始。其他处理程序必须忽略消息,因为对话已经开始。我有什么:机器人发送消息“捕获数字:123”机器人发送消息“对话:123”所以 Bot 也在对话之外捕获了处理程序的消息,太出乎意料了。我必须在脚本中更改哪些内容才能使其正常工作?
查看完整描述

1 回答

?
慕标5832272

TA贡献1966条经验 获得超4个赞

我计划conversation在该库的未来版本中删除该方法,因为正如您所看到的,很快就会遇到很大的限制,因为将基于回调的事件方法与命令式对话风格混合起来很困难。我建议您改用FSM 风格的对话。您应该能够轻松地调整该答案的代码以“等待数字”:


from enum import Enum, auto


class State(Enum):

    WAIT_DIGITS = auto()


conversation_state = {}


@client.on(events.NewMessage)

async def handler(event):

    who = event.sender_id

    state = conversation_state.get(who)

    

    if state is None:

        await event.respond('Please send digits!')

        conversation_state[who] = State.WAIT_DIGITS


    elif state == State.WAIT_DIGITS:

        if event.text.isdigit():

            digits = event.text

            await event.respond(f'Thanks for your digits! {digits}')

            del conversation_state[who]

        else:

            await event.respond('Please only send digits, not letters')

您可以轻松地为此添加更多抽象(根据状态为其他函数构建自己的装饰器,或者只是将每个状态的代码分离到另一个函数,使用它们的返回值作为下一个状态等)。


查看完整回答
反对 回复 2023-10-11
  • 1 回答
  • 0 关注
  • 128 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信