skip to Main Content

My program is supposed to reply Telegram messages the user’s account receives with a user-defined text. This text can be changed by sending a message to a telegram bot.
For the bot, I’ve been using PyTelegramBotAPI, and for sending messages from the user’s account I’ve been using Telethon.
I can run the bot by calling bot.polling() and it works fine.
The Telethon Client also works fine separately, It has methods like:

async def run():
    self.add_event_handler(self.message_handler, events.NewMessage)

    while True:
        #(Every Second the while is supposed to be checked)
        if(condition):
            do_something()

async def message_handler(self, event):
     do_another_thing()

and to start running the client I would just:

loop = asyncio.get_event_loop()

loop.run_until_complete(client.run())

But I can’t make them run simultaneously.

I’ve tried:

asyncio.get_event_loop().run_until_complete(asyncio.gather(
    bot.bot.polling(none_stop=True, interval=0.1, timeout=15),
    client.run()
))

to run both of them simultaneously, but this only runs the bot.

I’ve also tried:

executor = ProcessPoolExecutor(2)
loop = asyncio.get_event_loop()
boo = asyncio.create_task(loop.run_in_executor(executor, bot.bot.polling(none_stop=True, interval=0.5, timeout=15)))
baa = asyncio.create_task(loop.run_in_executor(executor, client.run()))

but it doesn’t work either.

could you please tell me how to run the bot and client at the same time?

3

Answers


  1. Chosen as BEST ANSWER

    The problem, as mentioned in comments by Lonami, was that the PyTelegramBotAPI is not an asynchronous library, therefor when adding it to asyncio event loop, it never gave control back to other tasks, (client.run() method in my case). I switched to aiogram, which is an asynchronous library, and the problem was solved.

    P.S. PyTelegramBotAPI offers an asynchronous module, but I was't able to make it work. Openning an issue on its GitHub page didn't help either.


  2. You should put this code at the end of your script.

    loop = asyncio.get_event_loop()
    loop.create_task(function1())
    loop.create_task(function2())
    loop.run_forever()
    
    Login or Signup to reply.
  3. This worked for me using the asyncronous mode for python-telegram-bot’2 handlers:

    from telegram import Bot, Chat
    from telegram.ext import Updater, CommandHandler
    
    telegram_bot = Bot(token=token)
    telegram_chat = Chat(id=test_group_chat_id, type='group', bot=telegram_bot)
    updater = Updater(bot=telegram_bot, use_context=True)
    dp = updater.dispatcher
    
    async def main_loop():
        while condition_1:
            # Do stuff
            if condition_2:
                telegram_chat.send_message('Something happened')
            pass
    
    def callback_function(update, context):
        telegram_chat.send_message('Test')
    
    async def main_telegram():
        dp.add_handler(CommandHandler("command", callback_function, run_async=True))
        updater.start_polling()
    
    if __name__ == '__main__':
        
       
        loop = asyncio.get_event_loop()
        try:
            loop.create_task(main_loop(), name="Main loop")
            loop.create_task(main_telegram(), name="Telegram listen task")
            loop.run_forever()
        finally:
            log.info("Shutting down ...")
            log.info("Updater running " + str(updater.running))
            updater.stop()
    
            pending = asyncio.all_tasks(loop=loop)
            for task in pending:
                task.cancel()
        
            loop.stop()
            loop.close()
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search