Handle multiple questions for Telegram bot in python

2024/9/20 22:46:34

I'm programming a telegram bot in Python using the Telegram bot API. I'm facing the problem of managing questions that need an answer of the user. The problem arises when the program is waiting for an answer of one user and another user request information or ask another question before the first user responds.

The Telegram API uses a code to handle the request. When you ask for updates you include a code. If the code you send is higher than a request code, it is mark as handled and telegram delete it and no longer appears in the updates. This code is sequential, so if you mark update 3 as handled, updates 1 and 2 are erased as well.

The question is why is the best phytonic/elegant way to handle multiple requests that needs an answer for the users?

Answer

There is not a most pythonic way of doing this. It is a problem you have to program to solve.

Basically, you have to maintain some state variables concerning each user. When a new message arrives, the bot checks what state that user is in, and responds accordingly.

Suppose you have a function, handle(msg), that gets called for each arriving message:

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`

This will do for a simple program.

For more complicated situations, I recommend using telepot, a Python framework I have created for Telegram Bot API. It has features that specifically solve this kind of problems.

For example, below is a bot that counts how many messages have been sent by an individual user. If no message is received after 10 seconds, it starts over (timeout). The counting is done per chat - that's the important point.

import sys
import telepot
from telepot.delegate import per_chat_id, create_openclass MessageCounter(telepot.helper.ChatHandler):def __init__(self, seed_tuple, timeout):super(MessageCounter, self).__init__(seed_tuple, timeout)self._count = 0def on_message(self, msg):self._count += 1self.sender.sendMessage(self._count)TOKEN = sys.argv[1]  # get token from command-linebot = telepot.DelegatorBot(TOKEN, [(per_chat_id(), create_open(MessageCounter, timeout=10)),
])
bot.notifyOnMessage(run_forever=True)

Run the program by:

python messagecounter.py <token>

Go to the project page to learn more if you are interested. There are a lot of documentations and non-trivial examples.

https://en.xdnf.cn/q/72065.html

Related Q&A

Which GTK+ elements support which CSS properties?

While applying my own CSS to my GTK+ application, I noticed, that some elements ignore some CSS properties and others ignore others or dont ignore them, which leads me to search for an overview of whic…

Self import of subpackages or not?

Suppose you have the following b b/__init__.py b/c b/c/__init__.py b/c/d b/c/d/__init__.pyIn some python packages, if you import b, you only get the symbols defined in b. To access b.c, you have to exp…

why is my text not aligning properly in wxPython?

Im using wxPython to build a GUI and Im trying to align some text but its not working at all. Im trying align three different static text items in three places (right aligned, center aligned, and left …

Python subprocess check_output decoding specials characters

Im having some issues with python encoding. When I try to execute this:subprocess.check_output("ipconfig", shell=True)it gives me an output with special characters in it, like:"Statut du…

Python - SystemError: NULL result without error in PyObject call

The story: Im trying to interface from C to Python in order to use the faster computational speed of C for an existing Python code. I already had some success, also with passing NumPy arrays - but now …

Fix jumping of multiple progress bars (tqdm) in python multiprocessing

I want to parallelize a task (progresser()) for a range of input parameters (L). The progress of each task should be monitored by an individual progress bar in the terminal. Im using the tqdm package f…

How to access data stored in QModelIndex

The code below create a single QListView with the data and proxy models "attached". Clicking one of the radio buttons calls for buttonClicked() function. This function calls models .data(inde…

Pythons read and write add \x00 to the file

I have come across a weird problem when working with files in python. Lets say I have a text file and a simple piece of code that reads the contents of the file and then rewrites it with unaltered cont…

NetworkX remove attributes from a specific node

I am having a problem with networkX library in python. I build a graph that initialises some nodes, edges with attributes. I also developed a method that will dynamic add a specific attribute with a sp…

How to use Python left outer join using FOR/LIST/DICTIONARY comprehensions (not SQL)?

I have two tuples, details below:t1 = [ [aa], [ff], [er] ]t2 = [ [aa, 11,], [er, 99,] ]and I would like to get results like these below using python method similar to SQLs LEFT OUTER JOIN:res = [ [aa, …