Is it possible to asynchronously send telegram bot images?

Question:

I want to quickly send images to users of my bot. I don’t want to be able to do it with a big delay. Now it takes (the same for all) 0.2 seconds to send one image. Those. for 200 users the delay will be ~40 sec. This is a lot for my program. How to make sending an image faster? Use asynchrony, multithreading, etc.?

import time
import telebot

bot = telebot.TeleBot('xxx')
@bot.message_handler(content_types=["text"])
def echo_message(message):

      time_start = time.time()
      text = 'blablal'
      path_to_screen = 'https://wallpapercave.com/wp/5PzmvMv.jpg'
      tg_ids = [12345, 6789, 7777] # about 200-300ids
      for tg_user_id in tg_ids:
            bot.send_photo(tg_user_id, f'{path_to_screen}', caption=f"{text})
      time_end = time.time()
      total_time = time_end - time_start
      print(t)


bot.infinity_polling()

total_time = +-40 sec

Also I tried to do it via aiogram:


from telebot.async_telebot import AsyncTeleBot

import time

bot = AsyncTeleBot('xxxx')
@bot.message_handler(func=lambda message: True)
async def echo_message(message):

      time_start = time.time()
      text = 'blablal'
      path_to_screen = 'https://wallpapercave.com/wp/5PzmvMv.jpg'
      tg_ids = [12345, 6789, 7777] # about 200-300ids
      for tg_user_id in tg_ids:
            await bot.send_photo(tg_user_id, f'{path_to_screen}', caption=f"{text})
      time_end = time.time()
      total_time = time_end - time_start
      print(t)

asyncio.run(bot.polling())

total_time = +-38 sec

I know that you can’t send more than 30 messages per second, but I’m not even close to these values. Please advise the optimal solution.

I want to add one more solution from me, but in my opinion it is worse than yours, but it might suit those who don’t use asynchronous library:

import threading
...
    def fast_sender():
          bot.send_photo(tg_user_id, f'{path_to_screen}', caption=f"{text})
    thr = threading.Thread(target=fast_sender)
    thr.start()
Asked By: random debagger

||

Answers:

You can try using asyncio.create_task() like this below:

from telebot.async_telebot import AsyncTelebot

import time

bot = AsyncTelebot('xxxx')
@bot.message_handler(func=lambda message: True)
async def echo_message(message):
    start = time.perf_counter()
    text = 'blablal'
    path_to_screen = 'https://wallpapercave.com/wp/5PzmvMv.jpg'
    tg_ids = [12345, 6789, 7777]

    tasks = []
    for tg_user_id in tg_ids:
        tasks.append(asyncio.create_task(bot.send_photo(tg_user_id, f'{path_to_screen}', caption=f"{text}")))
    await asyncio.gather(*tasks)
    end = time.perf_counter()
    print(f"Echo Message took: {end - start}")
Answered By: Roy
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.