我已经使用 Telepot 12.7 实现了很多电报机器人,并且从未遇到过任何问题。现在,突然间,将我的机器人添加到群组后,它开始发送垃圾邮件:
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'}}}"
问题似乎是这样的:https://github.com/nickoala/telepot/issues/184 但这是一个2016年解决的老问题。 我尝试将“new_chat_member”添加到键盘映射中,通过此修复,机器人启动但没有响应,没有任何内容传递到“handle(msg)”方法。如果您在私人聊天中写信,但在群组中写信,它不会回复。
这是我初始化机器人的代码:
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:])
当我通过 Bot 添加到群组时,我遇到了同样的问题。为了解决这个问题,我在模块“loop.py”第 102 行的 _extract_message(update) 函数内的键列表中添加了“update_id”。
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]
我再次运行机器人,它不再引发异常。然后我删除了更改,现在一切正常。
(我知道,这是一个丑陋的解决方法,但至少可以阻止这个问题)
面临同样的问题:
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))
)
环境:
Python 3.7.7
远程遥控==12.7
尝试:
使用@Carlog 建议为我提出了例外:
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
这是我们机器人的修补程序,直到我们有更好的解决方案。
在文件 Lib\site-packages elepot\loop.py 更改函数 _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')
我遇到了同样的问题,并修复了将 init.py 中的 _find_first_key 函数替换为以下内容:
def _find_first_key(d, keys):
for k in keys:
if k in d:
return k
return 'update_id'
如果似乎没有修补程序适合您,请检查错误的确切输出,获取字典中的任何有效密钥并将其用作 _find_first_key 的返回值。
我只需使用这些更改运行我的机器人一次,然后它就会处理队列中的所有消息并恢复正常行为。
我发现的最快修复是代码中的 RUN bot.getUpdates(offset=-1) (就在 While 循环之前 - 不在 while 循环中)。这需要在删除或添加组后重新启动程序。 我决定修改 Telepot 库文件:init.py 第 1191 行(添加 self.getUpdates(offset=-1)),如下所示。这似乎是自动工作的,但需要对所有人进行评估......(我现在可以随意添加和删除组)
`def get_from_telegram_server(): offset = None # 运行偏移量 允许的更新 = 允许的更新 而1: 尝试: 结果 = self.getUpdates(offset=offset, 超时=超时, allowed_updates=allowed_upd)
# Once passed, this parameter is no longer needed.
allowed_upd = None
if len(result) > 0:
# William Test for Group Add Error
self.getUpdates(offset=-1)
# No sort. Trust server to give messages in correct order.
# Update offset to max(update_id) + 1
offset = max([relay_to_collector(update) for update in result]) + 1
`