I'm trying to build a bot that basically has two threads. One thread is doing something, generating data and another thread is managing telegram bot. User can subscribe on telegram to receive updates from the first thread. This first thread calls the second one when it generates data and that data is sent out to all the users who subscribed.
import threading
import asyncio
from config import cfg
from telegram import Update
from telegram.ext import filters, ApplicationBuilder, ContextTypes, CommandHandler, MessageHandler
import os
subscribed = set()
async def subscribe(update: Update, context: ContextTypes.DEFAULT_TYPE):
subscribed.add(update.effective_chat.id)
await context.bot.send_message(
chat_id=update.effective_chat.id,
text="You have subscribed"
)
class TelegramService():
def __init__(self, control) -> None:
self.control = control
#asyncio.run(self.main())
self.thread = threading.Thread(target=self.mainM)
self.thread.start()
def mainM(self):
self.loop = asyncio.new_event_loop()
asyncio.set_event_loop(self.loop)
self.application = ApplicationBuilder().token(cfg.telegram_TOKEN).build()
self.application.add_handler(CommandHandler('subscribe', subscribe))
self.application.run_polling()
def sendOut(self, msg):
asyncio.ensure_future(self.sendAsync(msg), loop=self.loop)
async def sendAsync(self, msg):
async with self.application.bot:
for chat_id in subscribed:
await self.application.bot.send_message(text = msg, chat_id=chat_id)
This works more-or-less, I receive updates in Telegram and can also send stuff (like mentioned /subscribe
, but I receive an erorr in the output:
It is just too big to mention here, but it start with this:
Error while getting Updates: httpx.ReadError:
Task exception was never retrieved
future: <Task finished coro=<TelegramService.sendAsync() done, defined at .\communication\telegramService.py:83> exception=NetworkError('httpx.ReadError: ')>
Traceback (most recent call last):
File "d:\Development\.Projects.Chast\ViGrabber2\.venv\lib\site-packages\httpcore\_exceptions.py", line 10, in map_exceptions
yield
File "d:\Development\.Projects.Chast\ViGrabber2\.venv\lib\site-packages\httpcore\backends\asyncio.py", line 34, in read
return await self._stream.receive(max_bytes=max_bytes)
File "d:\Development\.Projects.Chast\ViGrabber2\.venv\lib\site-packages\anyio\streams\tls.py", line 195, in receive
data = await self._call_sslobject_method(self._ssl_object.read, max_bytes)
File "d:\Development\.Projects.Chast\ViGrabber2\.venv\lib\site-packages\anyio\streams\tls.py", line 137, in _call_sslobject_method
data = await self.transport_stream.receive()
File "d:\Development\.Projects.Chast\ViGrabber2\.venv\lib\site-packages\anyio\_backends\_asyncio.py", line 1272, in receive
raise ClosedResourceError from None
anyio.ClosedResourceError
During handling of the above exception, another exception occurred:
....
There goes two more httpcore.ReadError
, two httpx.ReadError
, one anyio.ClosedResourceError
, two httpcore.ReadError
and ends with RuntimeError: This HTTPXRequest is not initialized!
followed by telegram.error.NetworkError: Unknown error in HTTP implementation: RuntimeError('This HTTPXRequest is not initialized!')
all of these are connected by The above exception was the direct cause of the following exception:
I've tried to increase timeouts but I think it is not the problem. I guess I am doing something very wrong with asyncio
The problem was in sendAsync
method. The line
async with self.application.bot:
Should be removed as this closes the context of the service that is currently running