Телеграмма бота Python `get_chat_members_count` и избегание лимитов затопления или как использовать обертки и декораторы - PullRequest
0 голосов
/ 06 мая 2018

Я проверяю список из примерно 3000 телеграммных чатов, чтобы узнать и узнать количество участников чата в каждом чате, используя метод get_chat_members_count.

В какой-то момент я достигаю предела паводков и временно блокируюсь Telegram BOT.

Traceback (most recent call last):
  File "C:\Users\alexa\Desktop\ico_icobench_2.py", line 194, in <module>
    ico_tel_memb = bot.get_chat_members_count('@' + ico_tel_trim, timeout=60)
  File "C:\Python36\lib\site-packages\telegram\bot.py", line 60, in decorator
    result = func(self, *args, **kwargs)
  File "C:\Python36\lib\site-packages\telegram\bot.py", line 2006, in get_chat_members_count
    result = self._request.post(url, data, timeout=timeout)
  File "C:\Python36\lib\site-packages\telegram\utils\request.py", line 278, in post
    **urlopen_kwargs)
  File "C:\Python36\lib\site-packages\telegram\utils\request.py", line 208, in _request_wrapper
    message = self._parse(resp.data)
  File "C:\Python36\lib\site-packages\telegram\utils\request.py", line 168, in _parse
    raise RetryAfter(retry_after)
telegram.error.RetryAfter: Flood control exceeded. Retry in 85988 seconds

Вики python-telegram-bot дают подробное объяснение и пример того, как избежать ограничения наводнений здесь .

Однако я изо всех сил пытаюсь реализовать их решение и надеюсь, что кто-то здесь знает об этом больше, чем я.

Я буквально сделал копию и вставил их пример и не могу заставить его работать, без сомнения, потому что я новичок в python. Я предполагаю, что мне не хватает некоторых определений, но я не уверен, какое. Вот код ниже и после этого первая ошибка, которую я получаю. Очевидно, токен необходимо заменить на ваш токен.

import telegram.bot
from telegram.ext import messagequeue as mq

class MQBot(telegram.bot.Bot):
    '''A subclass of Bot which delegates send method handling to MQ'''
    def __init__(self, *args, is_queued_def=True, mqueue=None, **kwargs):
        super(MQBot, self).__init__(*args, **kwargs)
        # below 2 attributes should be provided for decorator usage
        self._is_messages_queued_default = is_queued_def
        self._msg_queue = mqueue or mq.MessageQueue()

    def __del__(self):
        try:
            self._msg_queue.stop()
        except:
            pass
        super(MQBot, self).__del__()

    @mq.queuedmessage
    def send_message(self, *args, **kwargs):
        '''Wrapped method would accept new `queued` and `isgroup`
        OPTIONAL arguments'''
        return super(MQBot, self).send_message(*args, **kwargs)


if __name__ == '__main__':
    from telegram.ext import MessageHandler, Filters
    import os
    token = os.environ.get('TOKEN')
    # for test purposes limit global throughput to 3 messages per 3 seconds
    q = mq.MessageQueue(all_burst_limit=3, all_time_limit_ms=3000)
    testbot = MQBot(token, mqueue=q)
    upd = telegram.ext.updater.Updater(bot=testbot)

    def reply(bot, update):
        # tries to echo 10 msgs at once
        chatid = update.message.chat_id
        msgt = update.message.text
        print(msgt, chatid)
        for ix in range(10):
            bot.send_message(chat_id=chatid, text='%s) %s' % (ix + 1, msgt))

    hdl = MessageHandler(Filters.text, reply)
    upd.dispatcher.add_handler(hdl)
    upd.start_polling()

Первая ошибка, которую я получаю:

Traceback (most recent call last):
  File "C:\Users\alexa\Desktop\z test.py", line 34, in <module>
    testbot = MQBot(token, mqueue=q)
  File "C:\Users\alexa\Desktop\z test.py", line 9, in __init__
    super(MQBot, self).__init__(*args, **kwargs)
  File "C:\Python36\lib\site-packages\telegram\bot.py", line 108, in __init__
    self.token = self._validate_token(token)
  File "C:\Python36\lib\site-packages\telegram\bot.py", line 129, in _validate_token
    if any(x.isspace() for x in token):
TypeError: 'NoneType' object is not iterable

Второй вопрос, который у меня есть, - как использовать обертки и декораторы с get_chat_members_count.

Код, который я добавил к примеру:

@mq.queuedmessage
def get_chat_members_count(self, *args, **kwargs):
    return super(MQBot, self).get_chat_members_count(*args, **kwargs)

Но ничего не происходит, и я не могу подсчитать количество участников чата. Я также не говорю, какой чат мне нужно сосчитать, поэтому неудивительно, что я ничего не получаю, но куда мне добавить идентификатор чата в телеграмме?

1 Ответ

0 голосов
/ 11 мая 2018

Вы получаете эту ошибку, потому что MQBot получает пустой токен. По какой-то причине он не вызывает описательное исключение, а неожиданно завершает работу.

Так почему же токен пуст? Кажется, вы используете os.environ.get неправильно. Часть os.environ представляет собой словарь , а его метод get позволяет безопасно получать доступ к содержимому dict. Согласно документам :

get (ключ [, по умолчанию])

Возвращает значение для ключа, если ключ находится в словаре, иначе по умолчанию. Если значение по умолчанию не указано, по умолчанию используется значение Нет, поэтому этот метод никогда не вызывает ошибку KeyError.

Согласно вашему вопросу, в этой части token = os.environ.get('TOKEN') вы передаете токен как ключ. Вместо этого вы должны были передать имя переменной среды, содержащей ваш токен.

Это можно исправить, переписав эту часть, например, token = 'TOKEN' или , установив переменную среды правильно и получив доступ к os.environ.get через правильное имя.

...