Адаптер для bot.send_message в telebot на python для ограничения отправки сообщений по лимитам телеграм

Пишу бота на python и pyTelegramBotAPI

Для того чтобы не превысить лимиты телеграм (не больше 30 сообщений в секунду разным пользователям и не больше 1 сообщения в секунду одному и тому же пользователю) написал функцию (точнее прототип)

Получилось вот такое ниже. По плану функция работала бы в отдельном потоке, msgslst был бы доступен глобально и в него бы добавлялись сообщения от бота (объекты с полями userid и text)

Потом только понял что в таком виде это будет работать только если просто делать рассылку сообщений на которые не ожидается ответ, а как использовать это с next_step_handler не могу сообразить.

То есть нужен адаптер который будет возвращать message (когда придет время его отправки) так же как при msg=bot.send_message чтобы потом передать его в некст стэп хэндлер. Видимо нужно передавать в функцию userid и text когда это нужно, но что дальше, как вернуть именно то сообщение которое нужно, ведь порядок сообщений в списке меняется.

Помогите пожалуйста. Или подскажите другие решения по ограничению отправки по лимитам телеграм, уверен такие существуют, но я не смог найти, пришлось изобретать велосипед. Спасибо.

import time

# значения в списке - будущие userid из объектов которыми бот будет дополнять список. второе будущее поле 
# объекта - text собственно сообщения
msgslst = [1, 2, 3, 4, 1, 1, 2, 5, 6, 7, 8, 9, 9, 8, 10, 11, 12, 13, 14, 15, 16, 17]
# ключ - значение элемента(в будущем userid), значение - разрешенное время отправки
blcldct = dict()


def sender():
    timer = time.monotonic() + 0.033333
    while len(msgslst) > 0:
        # действия в этом блоке выполняются раз в 1/30 секунды
        if time.monotonic() > timer:
            # извлекаем и удаляем из списка первый элемент
            item = msgslst.pop(0)
            # извлекаем разрешенное время отправки этого элемента
            item_timer = blcldct.get(item)
            # если в списке нет элемента или наступило разрешенное время отправки
            if item_timer == None or time.monotonic() > item_timer:
                # обновляем или добавляем разрешенное время отправки элемента(через 1 секунду)
                blcldct[item] = time.monotonic() + 1
                # тут должен быть bot.send_message(chat_id=userid, text=text)
                print(f'{item}: {time.monotonic()}')
            # если разрешенное время для вывода элемента не наступило
            else:
                # то если после извлечения и удаления элемента список оказался пуст, опять возвращаем элемент на 
                # первую позицию, и так до тех пор пока не наступит разрешенное время для его вывода
                if len(msgslst) == 0:
                    msgslst.insert(0, item)
                # если в сумме с удаленным первым элементом в списке хотя бы два элемента
                else:
                    count = 0
                    # начинаем искать в оставшихся элементах те, для которых разрешенное время вывода уже наступило
                    for i in msgslst:
                        # пытаемся получить из словаря разрешенное время отправки элемента
                        moving_item_time = blcldct.get(i)
                        # как только находится элемент который уже можно отправлять
                        # (или если словарь вернул None, т.е. таких элементов еще не отправлялось)
                        if moving_item_time == None \
                                or (moving_item_time != None and moving_item_time > time.monotonic()):
                            # удаляем этот элемент из списка и присваиваем его временной переменной
                            item_to_move = msgslst.pop(count)  
                            # вставляем элемент на первую позицию списка
                            msgslst.insert(0, item_to_move)  
                            # вставляем на вторую позицию элемент время которого еще не наступило
                            msgslst.insert(1, item)  
                            # прерываем поиск
                            break  
                        count = +1
            timer = time.monotonic() + 0.033333

Ответы (0 шт):