6

我正在使用 Telegram bot API 在 Python 中编写一个电报机器人。我面临管理需要用户回答的问题的问题。当程序正在等待一个用户的回答和另一个用户请求信息或在第一个用户响应之前询问另一个问题时,就会出现问题。

Telegram API 使用代码来处理请求。当您要求更新时,您会包含一个代码。如果您发送的代码高于请求代码,则将其标记为已处理,电报将其删除,不再出现在更新中。此代码是连续的,因此如果您将更新 3 标记为已处理,更新 1 和 2 也会被删除。

问题是为什么处理需要用户回答的多个请求的最佳植物/优雅方式是?

4

2 回答 2

10

没有一种最pythonic的方式来做到这一点。这是一个你必须通过编程来解决的问题。

基本上,您必须维护一些有关每个用户的状态变量。当有新消息到达时,机器人会检查用户所处的状态,并做出相应的响应。

假设您有一个函数 ,handle(msg)它会为每个到达的消息调用:

user_states = {}

def handle(msg):
    chat_id = msg['chat']['id']

    if chat_id not in user_states:
        user_states[chat_id] = some initial state ...

    state = user_states[chat_id]

    # respond according to `state`

这适用于一个简单的程序。

对于更复杂的情况,我建议使用telepot,这是我为 Telegram Bot API 创建的 Python 框架。它具有专门解决此类问题的功能。

例如,下面是一个机器人,它计算单个用户发送了多少条消息。如果 10 秒后没有收到消息,则重新开始(超时)。每次聊天都会进行计数- 这是重要的一点。

import sys
import telepot
from telepot.delegate import per_chat_id, create_open

class MessageCounter(telepot.helper.ChatHandler):
    def __init__(self, seed_tuple, timeout):
        super(MessageCounter, self).__init__(seed_tuple, timeout)
        self._count = 0

    def on_message(self, msg):
        self._count += 1
        self.sender.sendMessage(self._count)

TOKEN = sys.argv[1]  # get token from command-line

bot = telepot.DelegatorBot(TOKEN, [
    (per_chat_id(), create_open(MessageCounter, timeout=10)),
])
bot.notifyOnMessage(run_forever=True)

通过以下方式运行程序:

python messagecounter.py <token>

如果您有兴趣,请转到项目页面以了解更多信息。有很多文档和重要的例子。

于 2015-10-30T12:38:18.120 回答
1

在我的机器人中,我使用 webhook。如果你可以使用网络钩子 - 这样做,它是与电报机器人交互的更舒适的方式。

如果您无法进行 webhook(例如 ssl 问题),则有适合您的解决方法。使用ForceReply以获得先前的机器人答案并根据用户回复编写逻辑。

检查更新是否包含回复(reply_to_message 键),然后根据此回复进行机器人回答。这些操作必须是异步的才能获得高机器人性能。

如果你是 python 程序员,我推荐 Tornado 用于这些目的。

于 2015-08-22T21:10:50.280 回答