如何确保通过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!")
问题
- 如何修改Telethon脚本以确保接收SMS验证码而非语音电话?
- 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
相关产品推荐
相关产品推荐

