You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python开发Telegram Bot时遭遇RuntimeError问题求助

使用pyTelegramBotCAPTCHA时遇到RuntimeError问题

我在基于python-telegram-bot开发的项目中使用pyTelegramBotCAPTCHA时触发了RuntimeError,错误提示ExtBot is not properly initialized. Call ExtBot.initialize before accessing this property.

原代码

from telegram import Update
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes
from pyTelegramBotCAPTCHA import CaptchaManager

group_id = GROUP_ID

bot = (
    ApplicationBuilder().token("TOKEN").build()
)
job_queue = bot.job_queue

captcha_manager = CaptchaManager(bot.bot.id, default_timeout=90)
captcha_manager.initialize()


async def hello(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    await update.message.reply_text(
        f"Hi {update.effective_user.first_name}! Hope you have a good day, to the moon 🚀"
    )


async def callback_daily(context: ContextTypes.DEFAULT_TYPE):
    await context.bot.send_message(chat_id=group_id, text="One message every hour")


## * CAPTCHA START
# Message handler for new chat members
@bot.message_handler(content_types=["new_chat_members"])
def new_member(message):
    for new_user in message.new_chat_members:
        captcha_manager.restrict_chat_member(bot, message.chat.id, new_user.id)
        captcha_manager.send_new_captcha(bot, message.chat, new_user)


# Callback query handler
@bot.callback_query_handler(func=lambda callback: True)
def on_callback(callback):
    captcha_manager.update_captcha(bot, callback)


# Handler for correct solved CAPTCHAs
@captcha_manager.on_captcha_correct
def on_correct(captcha):
    bot.send_message(captcha.chat.id, "Congrats! You solved the CAPTCHA!")
    captcha_manager.unrestrict_chat_member(bot, captcha.chat.id, captcha.user.id)
    captcha_manager.delete_captcha(bot, captcha)


# Handler for wrong solved CAPTCHAs
@captcha_manager.on_captcha_not_correct
def on_not_correct(captcha):
    if captcha.incorrect_digits == 1 and captcha.previous_tries < 2:
        captcha_manager.refresh_captcha(bot, captcha)
    else:
        bot.kick_chat_member(captcha.chat.id, captcha.user.id)
        bot.send_message(
            captcha.chat.id,
            f"{captcha.user.first_name} failed solving the CAPTCHA and was banned!",
        )
        captcha_manager.delete_captcha(bot, captcha)


# Handler for timed out CAPTCHAS
@captcha_manager.on_captcha_timeout
def on_timeout(captcha):
    bot.kick_chat_member(captcha.chat.id, captcha.user.id)
    bot.send_message(
        captcha.chat.id,
        f"{captcha.user.first_name} did not solve the CAPTCHA and was banned!",
    )
    captcha_manager.delete_captcha(bot, captcha)


## * CAPTCHA END

bot.add_handler(CommandHandler("hello", hello))

job_daily = job_queue.run_repeating(
    callback_daily, interval=3600, first=0
)  ## 9 hours = 32400 secs

bot.run_polling()

错误日志

Traceback (most recent call last):
  File "c:\Users\user\Documents\GitHub\bc-project\tg-bot.py", line 17, in <module>
    captcha_manager = CaptchaManager(bot.bot.id, default_timeout=90)
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\telegram\_bot.py", line 669, in id
    return self.bot.id
  File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\telegram\_bot.py", line 658, in bot
    raise RuntimeError(
RuntimeError: ExtBot is not properly initialized. Call `ExtBot.initialize` before accessing this property.

问题原因

  1. ExtBot未初始化:python-telegram-bot v13+版本中,Application.build()创建的ExtBot实例不会自动完成初始化,必须等待run_polling()启动或手动调用initialize()后才能访问bot.id,原代码提前访问导致错误。
  2. 框架混用冲突:原代码同时使用python-telegram-bot的Application体系和pyTelegramBotCAPTCHA依赖的pyTelegramBotAPI装饰器(如@bot.message_handler),两者不兼容,会导致处理器无法正确注册。

修复后的代码

from telegram import Update
from telegram.ext import (
    ApplicationBuilder, CommandHandler, ContextTypes,
    MessageHandler, filters, CallbackQueryHandler
)
from pyTelegramBotCAPTCHA import CaptchaManager

group_id = GROUP_ID  # 替换为实际群组ID
bot_token = "TOKEN"  # 替换为实际Bot Token

captcha_manager = None

async def hello(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    await update.message.reply_text(
        f"Hi {update.effective_user.first_name}! Hope you have a good day, to the moon 🚀"
    )

async def callback_daily(context: ContextTypes.DEFAULT_TYPE):
    await context.bot.send_message(chat_id=group_id, text="One message every hour")

# 适配python-telegram-bot的新成员处理器
async def new_member(update: Update, context: ContextTypes.DEFAULT_TYPE):
    for new_user in update.message.new_chat_members:
        await captcha_manager.restrict_chat_member(context.bot, update.effective_chat.id, new_user.id)
        await captcha_manager.send_new_captcha(context.bot, update.effective_chat, new_user)

# 适配python-telegram-bot的回调查询处理器
async def on_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
    callback_query = update.callback_query
    await callback_query.answer()
    await captcha_manager.update_captcha(context.bot, callback_query)

# 异步化CaptchaManager回调
@captcha_manager.on_captcha_correct
async def on_correct(captcha):
    await captcha.bot.send_message(captcha.chat.id, "Congrats! You solved the CAPTCHA!")
    await captcha_manager.unrestrict_chat_member(captcha.bot, captcha.chat.id, captcha.user.id)
    await captcha_manager.delete_captcha(captcha.bot, captcha)

@captcha_manager.on_captcha_not_correct
async def on_not_correct(captcha):
    if captcha.incorrect_digits == 1 and captcha.previous_tries < 2:
        await captcha_manager.refresh_captcha(captcha.bot, captcha)
    else:
        await captcha.bot.kick_chat_member(captcha.chat.id, captcha.user.id)
        await captcha.bot.send_message(
            captcha.chat.id,
            f"{captcha.user.first_name} failed solving the CAPTCHA and was banned!"
        )
        await captcha_manager.delete_captcha(captcha.bot, captcha)

@captcha_manager.on_captcha_timeout
async def on_timeout(captcha):
    await captcha.bot.kick_chat_member(captcha.chat.id, captcha.user.id)
    await captcha.bot.send_message(
        captcha.chat.id,
        f"{captcha.user.first_name} did not solve the CAPTCHA and was banned!"
    )
    await captcha_manager.delete_captcha(captcha.bot, captcha)

# 延迟初始化CaptchaManager,确保ExtBot已完成初始化
async def post_init(app):
    global captcha_manager
    await app.bot.initialize()
    captcha_manager = CaptchaManager(app.bot.id, default_timeout=90)
    await captcha_manager.initialize()

if __name__ == "__main__":
    bot_app = ApplicationBuilder().token(bot_token).build()
    job_queue = bot_app.job_queue

    # 添加python-telegram-bot原生处理器
    bot_app.add_handler(CommandHandler("hello", hello))
    bot_app.add_handler(MessageHandler(filters.StatusUpdate.NEW_CHAT_MEMBERS, new_member))
    bot_app.add_handler(CallbackQueryHandler(on_callback))

    job_daily = job_queue.run_repeating(callback_daily, interval=3600, first=0)

    # 设置初始化回调
    bot_app.post_init = post_init

    bot_app.run_polling()

修复要点

  1. 延迟初始化:通过Application的post_init回调,在ExtBot初始化完成后再创建CaptchaManager,确保能正确获取bot.id。
  2. 替换处理器:使用python-telegram-bot原生的MessageHandler、CallbackQueryHandler替代pyTelegramBotAPI的装饰器,保证处理器正常注册。
  3. 异步适配:将CaptchaManager的所有回调改为异步函数,符合python-telegram-bot的异步设计,避免阻塞。

内容的提问来源于stack exchange,提问作者umut_satir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 19:17:16