python-telegram-bot初始化时向指定ID发消息报错解决咨询
python-telegram-bot初始化时发送消息失败的解决办法
问题描述
我希望在python-telegram-bot初始化时,向机器人维护者的指定ID发送消息。我的脚本全部基于handler构建,但无法实现该功能:
def main() -> None: """Start the bot.""" # Create the Application and pass it your bot's token. application = Application.builder().token("TOKEN").build() application.bot.send_message("SOME ID","Hello! I am working.") # Problematic line # Handlers application.add_handler(CommandHandler("command", command_function)) ... # on non command i.e message - echo the message on Telegram application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, default_command)) # Run the bot until the user presses Ctrl-C application.run_polling()
运行脚本时出现如下警告:
RuntimeWarning: coroutine 'ExtBot.send_message' was never awaited application.bot.send_message("SOME ID","Hello! I am working.") # Problematic line
我猜测问题出在消息发送方式的冲突上,请问能否同时使用两种方式?或者至少实现初始化时发送一次消息?
解决方案
警告原因
ExtBot.send_message是异步协程函数,你直接调用但没有用await等待执行,才会触发这个警告。但不能直接在main(普通函数)里加await,可以用下面两种方式解决:
方法一:用asyncio.run执行发送消息协程
在同步的main函数里,用asyncio.run包裹异步的发送消息操作:
import asyncio def main() -> None: """Start the bot.""" application = Application.builder().token("TOKEN").build() # 用asyncio.run执行异步发送消息 asyncio.run(application.bot.send_message(chat_id="SOME ID", text="Hello! I am working.")) # 后续handler配置不变 application.add_handler(CommandHandler("command", command_function)) ... application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, default_command)) application.run_polling()
方法二:利用启动钩子(推荐)
这种方式更贴合python-telegram-bot的异步架构,注册一个机器人启动时自动执行的回调函数:
async def send_startup_notification(bot): await bot.send_message(chat_id="SOME ID", text="Hello! I am working.") def main() -> None: """Start the bot.""" application = Application.builder().token("TOKEN").build() # 注册启动回调,机器人启动时触发 application.add_startup_callback(lambda: send_startup_notification(application.bot)) # Handlers配置 application.add_handler(CommandHandler("command", command_function)) ... application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, default_command)) application.run_polling()
关于你的疑问
完全可以同时使用handler架构和初始化发送消息的功能,两者没有任何冲突。上面两种方法都能实现初始化时发送一次消息,其中方法二更符合库的设计逻辑,也不会出现同步异步混用的潜在问题。
内容的提问来源于stack exchange,提问作者PepitoGrillo
相关产品推荐
相关产品推荐

