I’m trying to run a Telegram bot in a separate thread to keep my main thread free, but I’m running into issues. Here’s what I’ve tried:
import asyncio
from telegram.ext import Application, CommandHandler
from threading import Thread
class BotThread(Thread):
async def greet(self, update, context):
await context.bot.send_message(chat_id=update.effective_chat.id, text="Hello!")
def run(self):
async def startup(update, context):
await context.bot.send_message(chat_id=update.effective_chat.id, text="Bot is starting")
app = Application.builder().token('my_bot_token').build()
app.job_queue.run_once(startup, 60)
app.add_handler(CommandHandler('greet', self.greet))
app.run_polling()
BotThread().start()
When I run this, I get an error saying there’s no current event loop in the thread. How can I fix this and properly run the bot in a separate thread? Any help would be appreciated!
hey mate, ur issue is about asyncio loop. try this:
def run(self):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(self.run_bot())
async def run_bot(self):
app = Application.builder().token('my_bot_token').build()
# rest of ur code here
this should fix the event loop prob. good luck!
The issue you’re facing is due to the asyncio event loop not being properly set up in the new thread. To resolve this, you need to create and set an event loop for the thread. Here’s a modified version of your code that should work:
import asyncio
from telegram.ext import Application, CommandHandler
from threading import Thread
class BotThread(Thread):
async def greet(self, update, context):
await context.bot.send_message(chat_id=update.effective_chat.id, text="Hello!")
def run(self):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
async def startup(update, context):
await context.bot.send_message(chat_id=update.effective_chat.id, text="Bot is starting")
app = Application.builder().token('my_bot_token').build()
app.job_queue.run_once(startup, 60)
app.add_handler(CommandHandler('greet', self.greet))
app.run_polling()
BotThread().start()
This modification creates a new event loop and sets it for the thread before running the bot. It should resolve the ‘no current event loop’ error you were encountering. Remember to handle any exceptions that might occur in the thread and ensure proper shutdown of the bot when your main program exits.
I’ve dealt with similar issues when running async code in threads. The problem stems from how Python handles event loops in different threads. Here’s what worked for me:
Instead of creating a new event loop in the thread, I found it more reliable to use asyncio.run() to manage the event loop lifecycle. Try modifying your run method like this:
def run(self):
asyncio.run(self.bot_main())
async def bot_main(self):
app = Application.builder().token('my_bot_token').build()
app.add_handler(CommandHandler('greet', self.greet))
await app.initialize()
await app.start()
await app.updater.start_polling()
await app.updater.idle()
This approach ensures proper setup and teardown of the event loop. It also handles signals more gracefully, which is crucial for long-running bots. Just remember to implement proper shutdown logic in your main thread to stop the bot when needed.