3

I have already implemented a lot of telegram bots with Telepot 12.7 and never had a single problem. Now, suddenly, after adding my bot to a group it started spamming this error message:

    raise KeyError('No suggested keys %s in %s' % (str(keys), str(d)))
KeyError: "No suggested keys ['message', 'edited_message', 'channel_post', 'edited_channel_post', 'callback_query', 'inline_query', 'chosen_inline_result', 'shipping_query', 'pre_checkout_query'] in {'update_id': 676740400, 'my_chat_member': {'chat': {'id': -500413139, 'title': 'NazTestGroup', 'type': 'group', 'all_members_are_administrators': True}, 'from': {'id': 172579176, 'is_bot': False, 'first_name': 'Nazareno Descanso', 'username': 'Descanso7', 'language_code': 'en'}, 'date': 1616661428, 'old_chat_member': {'user': {'id': 1684936782, 'is_bot': True, 'first_name': 'telegram-reputation', 'username': 'reputationhmci_bot'}, 'status': 'member'}, 'new_chat_member': {'user': {'id': 1684936782, 'is_bot': True, 'first_name': 'telegram-reputation', 'username': 'reputationhmci_bot'}, 'status': 'left'}}}"

The issue seems this one: https://github.com/nickoala/telepot/issues/184 but it is an old issue solved in 2016. I tried adding 'new_chat_member' to the keymap and, with this fix, the bot starts but it is unresponsive, nothing passes to the "handle(msg)" method. It responds if you write to it in a private chat, but not in the group.

Here is the code with which I initialize the bot:


def handle(msg):
    global users_manager

    content_type, chat_type, chat_id = telepot.glance(msg)
    print(content_type, chat_type, chat_id, msg)

    try:
        userid = get_userid(chat_id, msg)
        users_manager.add_user(userid)

        if content_type == "text" and msg["text"] == "/start":
            bot.sendMessage(chat_id, f"Ciao! Sono reputation_bot, vi darò punti per ogni messaggio scritto "
                                     f"potendo guadagnare così livelli esclusivi!")
        else:
                users_manager.get_user(userid).add_points(1)
                check_if_lucky_message(userid, chat_id, msg)
                check_current_level(userid, chat_id, msg)
                print(users_manager.get_user(userid))
                pickle.dump(users_manager, open("score_dict.pkl", mode="wb"))
    except Exception as e:
        print(f"Error:: {e}")
      

def main(argv):

    global bot
    global users_manager
    global levels_manager

    print(f"Bot started, token {TOKEN}")
    bot = telepot.Bot(TOKEN)

    levels_manager = LevelManager()
    users_manager = pickle.load(open("score_dict.pkl", mode="rb")) \
        if os.path.exists("score_dict.pkl") else UsersManager()

    print(levels_manager)
    print(users_manager)

    bot.message_loop(handle, run_forever=True)


if __name__ == "__main__":
    main(sys.argv[1:])
Descanso7
  • 55
  • 1
  • 7

3 Answers3

2

I had the same problem when I have added by Bot into a group. To solve it, I have added 'update_id' in the list of keys inside _extract_message(update) function of the module 'loop.py', line 102.

def _extract_message(update):
    key = _find_first_key(update, ['update_id',
                                   'message',
                                   'edited_message',
                                   'channel_post',
                                   'edited_channel_post',
                                   'callback_query',
                                   'inline_query',
                                   'chosen_inline_result',
                                   'shipping_query',
                                   'pre_checkout_query'])
    return key, update[key]

I ran the bot again and it stops raising the exception. Then I remove my change and now everything works OK.

(I know, it's an ugly workaround but at least stop the issue)

Carlog
  • 21
  • 1
  • I think the OP had already found the solution to the issue. See the comments. – gofvonx Apr 17 '21 at 16:06
  • This prevents the issue, however, there is another error popping up now: `argument of type int is not iteratable` - it's possible that telepot is broken with the new update – skjerns Jun 27 '21 at 16:18
  • You can fix this by putting the `'update_id'` at the end of the list and not the beginning. – skjerns Jun 27 '21 at 16:29
2

Faced with the same problem:

Traceback (most recent call last):
  File "C:\Program Files\Python37\lib\site-packages\telepot\aio\loop.py", line 38, in run_forever
    self._update_handler(update)
  File "C:\Program Files\Python37\lib\site-packages\telepot\aio\loop.py", line 82, in <lambda>
    self._handle(_extract_message(update)[1]))
  File "C:\Program Files\Python37\lib\site-packages\telepot\loop.py", line 111, in _extract_message
    'pre_checkout_query'])
  File "C:\Program Files\Python37\lib\site-packages\telepot\__init__.py", line 68, in _find_first_key
    raise KeyError('No suggested keys %s in %s' % (str(keys), str(d))

)

Environment:

Python 3.7.7

telepot==12.7

Attempts:

Using @Carlog suggestion raised for me the exception:

Traceback (most recent call last):
  File "C:\Program Files\Python37\lib\site-packages\telepot\aio\loop.py", line 38, in run_forever
    self._update_handler(update)
  File "C:\Program Files\Python37\lib\site-packages\telepot\aio\loop.py", line 82, in <lambda>
    self._handle(_extract_message(update)[1]))
  File "C:\Program Files\Python37\lib\site-packages\telepot\aio\__init__.py", line 912, in handle
    id = calculate_seed(msg)
  File "C:\Program Files\Python37\lib\site-packages\telepot\delegate.py", line 303, in f
    seed = fn(msg)
  File "C:\Program Files\Python37\lib\site-packages\telepot\delegate.py", line 9, in w
    return fn(*args, **kwargs)
  File "C:\Program Files\Python37\lib\site-packages\telepot\delegate.py", line 24, in <lambda>
    if types == 'all' or msg['chat']['type'] in types
TypeError: 'int' object is not subscriptable

This is hotfix below for our bots until we have a better solution.

In the file Lib\site-packages\telepot\loop.py change the function _extract_message.

def _extract_message(update):

    key = _find_first_key(update, ['update_id',
                                   'message',
                                   'edited_message',
                                   'channel_post',
                                   'edited_channel_post',
                                   'callback_query',
                                   'inline_query',
                                   'chosen_inline_result',
                                   'shipping_query',
                                   'pre_checkout_query'])

    if key != 'update_id':
        return key, update[key]

    if 'message' in update.keys():
        return 'message', update['message']

    if 'my_chat_member' in update.keys():
        return 'message', {'message_id': update['update_id'], 
                            'from': update['my_chat_member']['from'], 
                            'chat': update['my_chat_member']['chat'], 
                            'date': update['my_chat_member']['date'], 
                            'text': f"It's update_id {update['update_id']}"
                        }
    raise Exception('The hotfix for update_id bug needs to upgrade')
0

I faced the same problem and fixed replacing _find_first_key function in init.py to the following:

def _find_first_key(d, keys):
for k in keys:
    if k in d:
        return k
return 'update_id'

If no hotfix seems to work for you, check the exact output of your error, get any valid key in your dictionary and use it as a return value for _find_first_key.
I only had to run my bot with these changes once, then it handled all the messages in the queue and got back to normal behavior.