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

Pyrogram输入OTP及时却提示过期的问题修复请求

Pyrogram输入OTP及时却提示过期的问题修复请求

问题描述

我现在碰到一个特别棘手的问题:明明在收到Telegram的OTP后几秒内就输入提交了,系统却一直弹出错误提示**"The confirmation code has expired. Request a new one."**。我怀疑是Pyrogram库存在bug,或者我代码里有没注意到的细节问题,试了好几种验证OTP的方式都没解决,麻烦帮忙看看怎么修复,谢谢!

核心实现代码

下面是我实现Telegram认证流程的核心代码:

class TelegramWorker(QThread):
    otp_sent = pyqtSignal(object)
    auth_complete = pyqtSignal(bool, str)

    def __init__(self, action, phone_number=None, otp=None, phone_code_hash=None, password=None):
        super().__init__()
        self.action = action
        self.phone_number = phone_number
        self.otp = otp
        self.phone_code_hash = phone_code_hash
        self.password = password
        self.client = None

    def run(self):
        asyncio.run(self.perform_action())

    async def perform_action(self):
        try:
            self.client = Client(TELEGRAM_SESSION, api_id=API_ID, api_hash=API_HASH)
            await self.client.connect()

            if self.action == "send_code":
                sent_code_info = await self.client.send_code(self.phone_number)
                self.otp_sent.emit(sent_code_info)
            elif self.action == "auth_with_otp":
                try:
                    await self.client.sign_in(
                        self.phone_number, self.phone_code_hash, self.otp
                    )
                    self.auth_complete.emit(True, "Authentication successful!")
                except errors.PhoneCodeInvalid:
                    self.auth_complete.emit(False, "Invalid confirmation code. Please try again.")
                except errors.PhoneCodeExpired:
                    self.auth_complete.emit(False, "The confirmation code has expired. Request a new one.")
            elif self.action == "auth_with_password":
                await self.client.check_password(self.password)
                self.auth_complete.emit(True, "Authentication successful!")
            await self.client.disconnect()
        except errors.SessionPasswordNeeded:
            self.auth_complete.emit(False, "Password is required for authentication.")
        except Exception as e:
            self.auth_complete.emit(False, str(e))

class TelegramAuthenticationDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("Telegram Authentication")
        self.setFixedSize(400, 300)
        self.phone_number = None
        self.sent_code = None
        self.worker = None
        self.resend_timer = QTimer(self)  # Add a QTimer for resending OTP
        self.resend_timer.timeout.connect(self.update_resend_timer)
        self.resend_countdown = 60

        self.init_ui()

    def init_ui(self):
        --- relevant UI code---

    def authenticate(self):
        otp = self.otp_input.text().strip()
        if not otp:
            QMessageBox.information(self, "Error", "Enter the OTP.")
            return

        self.worker = TelegramWorker(action="auth_with_otp", phone_number=self.phone_number, otp=otp, phone_code_hash=self.sent_code.phone_code_hash)
        self.worker.auth_complete.connect(self.handle_auth_result)
        self.worker.start()

    def handle_auth_result(self, success, message):
        if success:
            QMessageBox.information(self, "Success", message)
            self.accept()
        else:
            QMessageBox.warning(self, "Error", message)
            if "password" in message.lower():
                self.password_input.setVisible(True)
                self.otp_input.setVisible(False)
                self.action_button.setText("Authenticate with Password")
                self.action_button.clicked.disconnect()
                self.action_button.clicked.connect(self.authenticate_with_password)
            elif "expired" in message.lower() or "invalid" in message.lower():
                self.otp_input.clear()
                self.action_button.setText("Send OTP on Telegram")
                self.action_button.clicked.disconnect()
                self.action_button.clicked.connect(self.send_otp)
                self.otp_input.setVisible(False)
                self.resend_label.setVisible(False)

    def authenticate_with_password(self):
        password = self.password_input.text().strip()
        if not password:
            QMessageBox.information(self, "Error", "Enter your Telegram password.")
            return

        self.worker = TelegramWorker(action="auth_with_password", password=password)
        self.worker.auth_complete.connect(self.handle_auth_result)
        self.worker.start()

    def start_resend_timer(self):
        self.resend_countdown = 180
        self.resend_label.setText(f"Didn't receive OTP? Resend in {self.resend_countdown} seconds")
        self.resend_timer.start(1000)

    def update_resend_timer(self):
        self.resend_countdown -= 1
        if self.resend_countdown <= 0:
            self.resend_timer.stop()
            self.resend_label.setText("Didn't receive OTP? Resend")
            self.action_button.setText("Resend OTP")
            self.action_button.clicked.disconnect()
            self.action_button.clicked.connect(self.resend_otp)
        else:
            self.resend_label.setText(f"Didn't receive OTP? Resend in {self.resend_countdown} seconds")

    def resend_otp(self):
        self.resend_label.setVisible(False)
        self.otp_input.clear()
        self.otp_input.setVisible(False)
        self.send_otp()

排查与修复建议

我梳理了几个高概率的问题点,你可以逐一尝试:

  1. 会话文件冲突问题
    你当前的TELEGRAM_SESSION是固定文件名,可能存在不同手机号会话残留的干扰。试试把会话文件名和手机号绑定,比如改成f"telegram_session_{self.phone_number}",确保每个手机号的会话独立。

  2. OTP格式处理问题
    Telegram发送的OTP可能带有空格(比如123 456),如果直接传递带空格的字符串给sign_in就会触发错误。在authenticate方法里加一行格式处理:

    otp = otp.replace(" ", "").strip()
    
  3. Pyrogram版本兼容问题
    旧版本Pyrogram可能存在OTP验证的bug,试试升级到最新稳定版:

    pip install --upgrade pyrogram tgcrypto
    
  4. 参数传递准确性验证
    确认self.sent_code确实完整保存了send_code返回的sent_code_info对象,没有在传递过程中丢失phone_code_hash的正确值。可以在auth_with_otp分支里打印参数,确认phone_code_hash和OTP都是正确的。

  5. 异步线程调度问题
    用QThread跑异步任务时,可能存在调度延迟导致请求发送不及时。可以在perform_action的auth_with_otp块里添加时间戳打印,确认请求是在OTP有效期内发送的。

先从这几个方向排查,尤其是会话文件和OTP格式的问题,大概率能解决你的问题!

备注:内容来源于stack exchange,提问作者Madhusudan Mishra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 18:29:32