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

如何确保通过Telethon获取Telegram的SMS验证码而非语音电话?

Telegram API(Telethon)强制接收SMS验证码问题

问题背景

开发Python项目时,使用Telethon库调用Telegram API完成用户认证,期望接收SMS验证码,但始终收到语音电话。已在代码中设置force_sms=True,仍无法获取SMS验证码,且已确认手机号正确、Telegram的SMS通知已启用。

相关代码:

from telethon.sync import TelegramClient
from telethon.errors import SessionPasswordNeededError, FloodWaitError

api_id = 'your_api_id'  # Replace with your actual API ID
api_hash = 'your_api_hash'  # Replace with your actual API hash
phone_number = '+1234567890'  # Replace with the phone number you're using

client = TelegramClient('anon', api_id, api_hash)

async def send_code_via_sms():
    await client.connect()
    if not await client.is_user_authorized():
        try:
            # Explicitly request the code via SMS
            result = await client.send_code_request(phone=phone_number, force_sms=True)
            print("Code request sent via SMS. Please check your messages.")
            # Proceed with handling the code
            code = input("Enter the code: ")
            await client.sign_in(phone=phone_number, code=code, phone_code_hash=result.phone_code_hash)
            print("Signed in successfully!")
        except FloodWaitError as e:
            print(f"Need to wait for {e.seconds} seconds before trying again.")
        except Exception as e:
            print(f"Failed to sign in: {e}")
    else:
        print("Already authorized!")

问题

  1. 如何修改Telethon脚本以确保接收SMS验证码而非语音电话?
  2. Telegram选择发送语音电话而非SMS的特定条件是什么,能否通过编程方式干预?

解答

1. 脚本修改方案

你可以通过以下几点调整脚本,提升获取SMS验证码的概率:

  • 删除旧会话文件:如果之前运行过脚本生成了anon.session文件,先删除它。残留的会话状态可能干扰新的验证码请求逻辑。
  • 明确指定允许的验证码类型:在send_code_request中添加allowed_types=['sms']参数,强制Telegram仅尝试SMS渠道,结合force_sms=True进一步强化要求。
  • 补充错误捕获:增加对Telegram特定错误的捕获,比如PhoneNumberFloodError(手机号请求过于频繁)、PhoneCodeInvalidError(验证码无效)等,方便排查问题。

修改后的代码示例:

from telethon.sync import TelegramClient
from telethon.errors import (
    SessionPasswordNeededError, 
    FloodWaitError,
    PhoneNumberFloodError,
    PhoneCodeInvalidError
)

api_id = 'your_api_id'  # Replace with your actual API ID
api_hash = 'your_api_hash'  # Replace with your actual API hash
phone_number = '+1234567890'  # Replace with the phone number you're using

client = TelegramClient('anon', api_id, api_hash)

async def send_code_via_sms():
    await client.connect()
    if not await client.is_user_authorized():
        try:
            # 强制指定仅使用SMS发送验证码
            result = await client.send_code_request(
                phone=phone_number, 
                force_sms=True,
                allowed_types=['sms']
            )
            print("已请求发送SMS验证码,请查看短信。")
            code = input("输入验证码:")
            await client.sign_in(
                phone=phone_number, 
                code=code, 
                phone_code_hash=result.phone_code_hash
            )
            print("登录成功!")
        except FloodWaitError as e:
            print(f"请求过于频繁,请等待{e.seconds}秒后重试。")
        except PhoneNumberFloodError:
            print("该手机号请求验证码次数过多,请稍后再试或更换手机号。")
        except PhoneCodeInvalidError:
            print("输入的验证码无效,请重新获取。")
        except Exception as e:
            print(f"登录失败:{str(e)}")
    else:
        print("已处于登录状态!")

2. Telegram发送语音验证码的触发条件及干预可能性

Telegram优先发送语音而非SMS的常见条件:

  • 地区/运营商限制:部分地区的SMS服务不稳定、成本过高,或运营商拦截Telegram的SMS消息,Telegram会自动切换到语音渠道。
  • 反滥用机制触发:短时间内多次请求验证码,或账号存在异常登录记录,Telegram会限制SMS发送,改用语音验证以降低滥用风险。
  • 账号安全策略:如果账号之前有过被盗、异地登录等安全事件,Telegram会默认使用语音验证码提升安全性。

编程干预的局限性:

  • 无法完全绕过Telegram的后台策略,force_sms=True和allowed_types=['sms']是仅有的能传递给API的干预参数,但如果Telegram后台判定无法发送SMS,这些参数会被忽略,仍会发送语音或返回错误。
  • 可间接优化的方向:
    • 避免短时间内重复请求验证码,触发FloodWaitError后严格等待指定时长。
    • 确保账号处于正常状态,无异地登录、违规记录。
    • 更换在Telegram SMS服务稳定地区注册的手机号。

内容的提问来源于stack exchange,提问作者or.cohenadiv

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 17:13:31