我将异步版本的 pyTelegramBotApi 用于 Telegram 机器人部分。我使用 vk-api 作为 VK 部分(不确定这是否重要)。
我有一个机器人可以监控其他社交网络(Vkontakte),并且在某些情况下会调用一个方法,让 Telegram 机器人向我发送消息。这是这个方法:
async def send_post(text, post_id) -> None:
print("tg_bot.py.send_post()")
msg_text = f"{text}\n\n[id={post_id}]"
"""Send the post."""
await tg_bot.send_message(my_chat_id, text=msg_text, reply_markup=gen_markup())
当我尝试时,它给了我这个错误:
ERROR: RequestTimeout::Request timeout. Request: method=get url=sendMessage params=<aiohttp.formdata.FormData object at 0x0000022B66B1F5D0> files=None request_timeout=300
仅当我从 VK 接收事件的循环中调用 send_post 时,才会出现此错误。例如,当我使用相同的 tg_bot.send_message() 方法来响应命令时 - 它工作得很好。它也没有连接到标记或消息文本,我出于绝望而尝试更改这些。这是 vkontakte.py 中的 VK 循环,以防万一:
def init():
print("Starting VK Cycle")
try:
for event in longpoll.listen():
print("There's a VK event")
event_received = False
while not event_received:
print("Trying to receive it...")
try:
if event.type == VkBotEventType.WALL_POST_NEW:
print("It's a new post on the wall")
post = event.object
if post.post_type == 'suggest':
print("The new post is a suggested post")
asyncio.run(tg_bot.send_post(text=post.text, post_id=post.id))
event_received = True
except requests.exceptions.ReadTimeout as e:
print("ERROR: ReadTimeout. Waiting for 3 seconds and trying to reconnect")
log_file = open("cogparty.log", "a")
log_file.write(
f"\n\nvkontakte.py init() INNER try-catch error:\n\n{str(e)}\n\nTrying again in 3 seconds...")
log_file.close()
time.sleep(3)
except Exception as e:
print(f"ERROR: {type(e).__name__}::{str(e)}")
log_file = open("cogparty.log", "a")
log_file.write(f"\n\nvkontakte.py init() OUTER try-catch error:\n\n{str(e)}")
log_file.close()
我还了解到如何启动机器人很重要,所以这是我的设置:
async def main():
vk_thread = threading.Thread(target=run_vk_loop)
vk_thread.start()
await tg_bot.init()
然后,在 tg_bot.py 中,我有这个:
async def init():
print("Connecting to TG...")
await tg_bot.infinity_polling()
我还尝试将
infinity_polling
中的超时参数设置为30、40、50。没有效果。
有趣的是 - 它之前工作了几天,然后就崩溃了。现在从一开始就行不通了。我对 vkontakte 和 telegram 机器人都很不好,所以我的代码很乱,抱歉。如果我们能一起解决这个问题,我将非常感激。
这不是一个好的答案,但它有效。 似乎 vk_api 和 pyTelegramBotApi 使用一些在线程内共享的公共资源。只需从线程切换到多处理即可解决问题。
所以,而不是这个:
async def main():
vk_thread = threading.Thread(target=run_vk_loop)
vk_thread.start()
await tg_bot.init()
我现在用这个:
def main():
vk_process = Process(target=run_vk_loop)
vk_process.start()
tg_process = Process(target=run_tg_loop)
tg_process.start()