I use async version of pyTelegramBotApi for a Telegram bot part. I use vk-api for a VK part (not sure if that matters).
I have a bot that monitors other social network (Vkontakte) and, on some occasions, calls a method that should make Telegram bot send me a message. Here is this method:
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())
When I try it, it gives me this error: ERROR: RequestTimeout::Request timeout. Request: method=get url=sendMessage params=<aiohttp.formdata.FormData object at 0x0000022B66B1F5D0> files=None request_timeout=300
I get this error only when I call send_post from the loop of receiving events from VK. When I use same tg_bot.send_message() method, for example, in response to command - it works perfectly. It's not connected to the markup or message text also, I tried changing these out of despair. Here's the VK loop in vkontakte.py, just in case:
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()
I've also read that it's important how you start the bot, so here's my setup:
async def main():
vk_thread = threading.Thread(target=run_vk_loop)
vk_thread.start()
await tg_bot.init()
Then, in tg_bot.py, I have this:
async def init():
print("Connecting to TG...")
await tg_bot.infinity_polling()
I've also tried to set timeout parameter in infinity_polling
to 30, 40, 50. No effect.
The fun thing is - it worked before, for several days, and then crashed. Now it doesn't work from the beginning. I'm bad with both vkontakte and telegram bots, so my code is a mess, sorry. I would be very thankful if we can solve this together.
This is not a good answer, but it works. It seems that vk_api and pyTelegramBotApi use some common resource that's shared within a thread. Simply switching from threading to multiprocessing solves the problem.
So, instead of this:
async def main():
vk_thread = threading.Thread(target=run_vk_loop)
vk_thread.start()
await tg_bot.init()
I now use this:
def main():
vk_process = Process(target=run_vk_loop)
vk_process.start()
tg_process = Process(target=run_tg_loop)
tg_process.start()