使用Telethon开发的Telegram Bot输入验证码后无响应
解决Telethon脚本输入验证码后挂起的问题
针对你遇到的输入验证码后脚本无限挂起的情况,以下是几个可行的排查和解决方向:
1. 替换同步客户端导入为纯异步版本
你当前使用的from telethon.sync import TelegramClient是Telethon为同步代码提供的封装,在纯异步环境(依赖asyncio.run)中混用会导致事件循环阻塞。修改导入语句:
from telethon import TelegramClient # 替换原同步导入
2. 检查并调整代理配置
确认SOCKS5代理参数是否符合Telethon要求:
- 代理参数格式为
(socks.SOCKS5, host, port, rdns, username, password),其中rdns控制是否远程解析域名,部分代理需设置为False才能正常工作 - 临时注释代理参数,直接连接测试,排除代理导致的阻塞
- 验证代理服务器的连通性、端口及账号密码正确性
3. 处理两步验证(若账号开启)
如果账号开启了两步验证,client.start()会静默等待密码输入,导致脚本挂起。添加密码处理逻辑:
import getpass # 动态获取两步验证密码(无则直接回车) password = getpass.getpass("请输入两步验证密码:") await client.start(phone_number, password=password if password else None)
4. 增加连接确认步骤
在client.start()后添加账号信息获取请求,确保客户端完全建立连接:
await client.start(phone_number, password=password) # 确认登录状态 me = await client.get_me() print(f"已登录账号:{me.phone}")
5. 开启调试日志定位阻塞点
添加日志输出,查看脚本内部执行细节:
import logging logging.basicConfig(level=logging.DEBUG) # 开启DEBUG级日志
日志会输出Telethon的网络请求、内部操作等信息,帮助你精准定位阻塞环节。
6. 调整事件循环运行方式
部分环境下asyncio.run()存在兼容性问题,改用以下方式运行:
if __name__ == "__main__": loop = asyncio.get_event_loop() loop.run_until_complete(main())
修改后的完整示例代码
import asyncio import getpass import logging from telethon import TelegramClient from telethon.sessions import StringSession import socks logging.basicConfig(level=logging.INFO) api_id = 'YOUR_API_ID' api_hash = 'YOUR_API_HASH' phone_number = 'YOUR_PHONE_NUMBER' source_channel = '@source_channel_username' target_channel = '@target_channel_username' proxy_host = 'YOUR_SOCKS5_HOST' proxy_port = YOUR_SOCKS5_PORT proxy_username = 'PROXY_USERNAME' proxy_password = 'PROXY_PASSWORD' session_string = '' async def main(): async with TelegramClient(StringSession(session_string), api_id, api_hash, proxy=(socks.SOCKS5, proxy_host, proxy_port, False, proxy_username, proxy_password)) as client: print("Connecting to account...") # 处理两步验证 password = getpass.getpass("请输入两步验证密码(无则直接回车):") await client.start(phone_number, password=password if password else None) # 确认登录成功 me = await client.get_me() print(f"Successfully connected to account: {me.phone}") print("Fetching the last message...") last_message = await client.get_messages(source_channel, limit=1) print("Last message fetched.") await asyncio.sleep(1) if last_message: message_text = last_message[0].text message_media = last_message[0].media print("Sending message...") if message_media is not None: await client.send_message(target_channel, message_text, file=message_media) else: await client.send_message(target_channel, message_text) print("Successfully copied and sent the last message.") else: print("No messages found in the source channel.") saved_session_string = client.session.save() print("Session saved. Copy this string and use it on the next launch:") print(saved_session_string) if __name__ == "__main__": asyncio.run(main())
内容的提问来源于stack exchange,提问作者Foertsch
相关产品推荐
相关产品推荐

