Адаптер для 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