1

I'm building a telegram bot and for the start I used the structure from an example of the api wrapper. In the py script there is an infinite loop which is polling the telegram api to get new messages for the bot. And processes each new message one by one.

 while True:
    for update in bot.getUpdates(offset=LAST_UPDATE_ID, timeout=10):
        chat_id = update.message.chat.id
        update_id = update.update_id
        if update.message.text:
            #do things with the message \ start other functions and so on

What I foresee already now, is that with some messages\requests - i'll have a longer processing time and other messages, if the even came at the same time - will wait. For the user it will look like a delay in answering. Which boils down to a simple dependency: more user chatting = more delay.

I was thinking this: Can I have this main script bot.py run and check for new messages and each time a message arrived - this script will kickstart another script answer.py to do the processing of the message and reply.

And to start as many as needed those answer.py scripts in parallel.

I can also use bot.py to log all incoming things into DB with reference data about the user who is sending a message and then have another process processing all newly logged data and marking it as answered - but also then it should process each new entry parallel to each other.

I'm not a guru in python and is asking for some ideas and guidance on how to approach this? Thank you!

Charles Okwuagwu
  • 10,538
  • 16
  • 87
  • 157
GeekSince1982
  • 732
  • 10
  • 25

1 Answers1

2

What you need are threads, or some frameworks that can handle many requests asynchronously, e.g. Twisted, Tornado, or asyncio in Python 3.4.

Here is an implementation using threads:

import threading

def handle(message):
    ##### do your response here

offset = None

while True:
    for update in bot.getUpdates(offset=offset, timeout=10):
        if update.message.text:
            t = threading.Thread(target=handle, args=(update.message,))
            t.start()

        offset = update.update_id + 1

        ##### log the message if you want

This way, the call to handle() would not block, and the loop can go on handling the next message.

For more complicated situations, for example if you have to maintain states across messages from the same chat_id, I recommend taking a look at telepot, and this answer:

Handle multiple questions for Telegram bot in python

In short, telepot spawns threads for you, freeing you from worrying about the low-level details and letting you focus on the problem at hand.

Community
  • 1
  • 1
Nick Lee
  • 5,639
  • 3
  • 27
  • 35
  • Thank you! Your library seems like a great tool! I'm about to create another bot and for this one I'll use your library! The one I already have - I will have to restructure the code a bit to use teleport, but I've read through your project and find it very useful!:) Thanks! And about the threads - I did try to do threads in my main bot, but things kept crashing... Not sure what was wrong.. I'll just switch to teleport:) – GeekSince1982 Nov 12 '15 at 08:49
  • You have to be very careful using threads; things can get flaky when two threads try to change the same data, and these kinds of bugs may be hard to track down (because they may not happen all the time). If you really need to handle many requests at the same time, I recommend using the asynchronous way. Async programming is a little different from the classical, but it's worth the effort. – Nick Lee Nov 12 '15 at 09:19
  • thank you! I'm pretty new to Python and these kinda of tasks, so I'll have to read up on things more, but you gave me a good kickstart here!:) thanks! – GeekSince1982 Nov 12 '15 at 10:06