微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何仅在Telethon对话中处理NewMessage

如何解决如何仅在Telethon对话中处理NewMessage

我的机器人代码中有两个处理程序:

  1. my_conversation-捕获“ /开始”消息并开始新的对话,其中来自用户的等待消息
  2. 数字-按模式捕获邮件-仅数字
    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,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())

我期望的是

  1. 我发送“ /开始”
  2. 开始对话并回复“我正在等待消息”
  3. 我发送“ 123”
  4. 因为对话已开始,所以发送消息“对话:123”。其他处理者必须忽略消息,因为对话已经开始。

我所拥有的:

  1. 发送邮件“捕获位数:123”
  2. 发送邮件“对话:123”

因此Bot还在对话外捕获了处理程序的消息,这是意外的。 我必须更改脚本才能使其正常工作吗?

解决方法

我计划在库的未来版本中删除conversation方法,因为如您所见,由于将基于回调的事件处理方法与会话的强制性样式混合在一起,您很快就会遇到很大的限制。很难。我建议您改用FSM-style conversation。您应该能够轻松地将该答案的代码修改为“等待数字”:

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')

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。