代码之家  ›  专栏  ›  技术社区  ›  Alex B

Python telegram机器人的“get\u chat\u members\u count”&避免洪水限制或如何使用包装器和装饰器

  •  1
  • Alex B  · 技术社区  · 6 年前

    我正在查看大约3000个电报聊天列表,以便使用 get_chat_members_count 方法

    在某种程度上,我达到了洪水极限,并被电报机器人暂时禁止。

    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 wiki提供了关于如何避免洪水限制的详细解释和示例 here

    然而,我正在努力实现他们的解决方案,我希望这里有人比我更了解这一点。

    我确实复制并粘贴了他们的示例,但毫无疑问,我无法使其正常工作,因为我是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\u chat\u members\u count

    我添加到示例中的代码是:

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

    但什么都没发生,我也不知道有多少聊天成员。我也没有说我需要统计哪些聊天,所以毫不奇怪我什么也没有得到,但我应该把电报聊天id放在哪里?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Community Egal    4 年前

    您收到此错误是因为MQBot接收到空令牌。出于某种原因,它不会引发描述性异常,而是意外崩溃。

    那么为什么令牌是空的呢?看来你在用 os.environ.get 不正确。这个 os.environ 零件是a dictionary 及其方法 get 允许用户安全访问dict的内容。根据 docs :

    get(键[,默认])

    如果键在字典中,则返回键的值,否则为默认值。如果未给定default,则默认为None,这样该方法就不会引发KeyError。

    根据你的问题,在这一部分 token = os.environ.get('TOKEN') 您将令牌本身作为密钥传递。相反,您应该传递包含标记的环境变量的名称。

    你可以修改这部分 token = 'TOKEN' 或由 setting environmental variable correctly 并从 操作系统。包围收到 通过正确的名称。