You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

树莓派1 B+运行Telethon下载脚本时遭遇RPCError 406: UPDATE_APP_TO_LOGIN错误的解决求助

树莓派1 B+运行Telethon下载脚本时遭遇RPCError 406: UPDATE_APP_TO_LOGIN错误的解决求助

问题背景

我在树莓派1 B+(Bookworm系统)上运行下面的Telethon下载脚本时遇到了RPCError 406: UPDATE_APP_TO_LOGIN错误,而相同的脚本在Oracle服务器上已经稳定运行了好几个月,Telethon也是最新版本,请问该怎么解决这个问题?

运行的脚本代码

import asyncio
from telethon import TelegramClient, events
from telethon.errors import SessionPasswordNeededError
import logging
import json
import requests
import os
from urllib.parse import unquote
from pathlib import Path

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

class TelegramDownloader:
    def __init__(self, api_id, api_hash, phone_number):
        self.api_id = api_id
        self.api_hash = api_hash
        self.phone_number = phone_number
        self.client = TelegramClient(f'session_{phone_number}', api_id, api_hash)
        self.download_queue = asyncio.Queue()
        self.download_path = "/media/pi/MRX/Download"
        self.is_downloading = False

    async def connect(self):
        await self.client.start()
        if not await self.client.is_user_authorized():
            try:
                await self.client.send_code_request(self.phone_number)
                code = input('Enter the code: ')
                await self.client.sign_in(self.phone_number, code)
            except SessionPasswordNeededError:
                password = input('Two-step verification is enabled. Please enter your password: ')
                await self.client.sign_in(password=password)

    async def download_file(self, url, event):
        try:
            filename = unquote(url.split('/')[-1].split('?')[0])
            filepath = os.path.join(self.download_path, filename)
            
            await event.respond(f"⬇️ Downloading: {filename}")
            
            response = requests.get(url, stream=True)
            total_size = int(response.headers.get('content-length', 0))
            
            with open(filepath, 'wb') as f:
                for chunk in response.iter_content(chunk_size=8192):
                    if chunk:
                        f.write(chunk)
            
            await event.respond(f"✅ Download completed: {filename}")
            logger.info(f"Downloaded {filename}")
            
        except Exception as e:
            await event.respond(f"❌ Download failed: {filename}\nError: {str(e)}")
            logger.error(f"Error downloading {filename}: {str(e)}")

    async def process_download_queue(self):
        while True:
            url, event = await self.download_queue.get()
            self.is_downloading = True
            await self.download_file(url, event)
            self.is_downloading = False
            self.download_queue.task_done()

    async def monitor_channel(self, channel_id):
        await self.connect()
        
        # Start download queue processor
        asyncio.create_task(self.process_download_queue())

        @self.client.on(events.NewMessage(chats=[channel_id]))
        async def handler(event):
            try:
                message = event.message.text
                if message and "example.com" in message:
                    # Add download to queue
                    await self.download_queue.put((message, event))
                    if not self.is_downloading:
                        logger.info("Download added to queue")
                    else:
                        await event.respond("⏳ Download queued - will start after current download completes")
                        
            except Exception as e:
                logger.error(f"Error processing message: {str(e)}")

        logger.info(f"Started monitoring channel {channel_id} for download links")
        await self.client.run_until_disconnected()

def read_credentials():
    try:
        with open("credentials.json", "r") as file:
            creds = json.load(file)
            return creds["api_id"], creds["api_hash"], creds["phone_number"]
    except FileNotFoundError:
        logger.error("Credentials file not found.")
        return None, None, None

def write_credentials(api_id, api_hash, phone_number):
    creds = {
        "api_id": api_id,
        "api_hash": api_hash,
        "phone_number": phone_number
    }
    with open("credentials.json", "w") as file:
        json.dump(creds, file, indent=4)

async def main():
    api_id, api_hash, phone_number = read_credentials()
    if api_id is None or api_hash is None or phone_number is None:
        api_id = input("Enter your API ID: ")
        api_hash = input("Enter your API Hash: ")
        phone_number = input("Enter your phone number: ")
        write_credentials(api_id, api_hash, phone_number)
    
    downloader = TelegramDownloader(api_id, api_hash, phone_number)
    
    # Create download directory if it doesn't exist
    os.makedirs(downloader.download_path, exist_ok=True)
    
    # Monitor the specific group
    group_id = "https://t.me/+IgOxAHTrv8UzMGU9"
    await downloader.monitor_channel(group_id)

if __name__ == "__main__":
    asyncio.run(main())

错误日志

pi@raspberrypi:~/telegram_forwarder $ sudo python3 linkdownloader.py
2025-02-04 23:02:03,276 - telethon.network.mtprotosender - INFO -
Connecting to 149.154.167.51:443/TcpFull... 2025-02-04 23:02:08,398 -
telethon.network.mtprotosender - INFO - Connection to
149.154.167.51:443/TcpFull complete! Please enter your phone (or bot token): ********** 2025-02-04 23:03:21,912 - telethon.client.users
- INFO - Phone migrated to 5 2025-02-04 23:03:22,181 - telethon.client.telegrambaseclient - INFO - Reconnecting to new data
center 5 2025-02-04 23:03:22,494 - telethon.network.mtprotosender -
INFO - Disconnecting from 149.154.167.51:443/TcpFull... 2025-02-04
23:03:22,508 - telethon.network.mtprotosender - INFO - Disconnection
from 149.154.167.51:443/TcpFull complete! 2025-02-04 23:03:22,518 -
telethon.network.mtprotosender - INFO - Connecting to
91.108.56.128:443/TcpFull... 2025-02-04 23:03:26,847 - telethon.network.mtprotosender - INFO - Connection to
91.108.56.128:443/TcpFull complete! Traceback (most recent call last):   File "/home/pi/telegram_forwarder/linkdownloader.py", line 125, in

asyncio.run(main())   File "/usr/lib/python3.11/asyncio/runners.py", line 190, in run
return runner.run(main)
^^^^^^^^^^^^^^^^   File "/usr/lib/python3.11/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   File "/usr/lib/python3.11/asyncio/base_events.py", line 653, in
run_until_complete
return future.result()
^^^^^^^^^^^^^^^   File "/home/pi/telegram_forwarder/linkdownloader.py", line 122, in main
await downloader.monitor_channel(group_id)   File "/home/pi/telegram_forwarder/linkdownloader.py", line 66, in
monitor_channel
await self.connect()   File "/home/pi/telegram_forwarder/linkdownloader.py", line 25, in connect
await self.client.start()   File "/usr/lib/python3/dist-packages/telethon/client/auth.py", line 190, in
_start
await self.send_code_request(phone, force_sms=force_sms)   File "/usr/lib/python3/dist-packages/telethon/client/auth.py", line 519, in
send_code_request
result = await self(functions.auth.SendCodeRequest(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   File "/usr/lib/python3/dist-packages/telethon/client/users.py", line 30, in
__call__
return await self._call(self._sender, request, ordered=ordered)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   File "/usr/lib/python3/dist-packages/telethon/client/users.py", line
84, in _call
result = await future
^^^^^^^^^^^^ telethon.errors.rpcbaseerrors.AuthKeyError: RPCError 406: UPDATE_APP_TO_LOGIN (caused by SendCodeRequest)
pi@raspberrypi:~/telegram_forwarder $

可能的解决方法

这个错误是Telegram服务器认定当前客户端版本过时,要求更新后才能登录,结合树莓派的硬件特性,试试下面几个方案:

  • 自定义客户端标识参数
    修改TelegramClient的初始化代码,添加更贴近官方APP的设备和版本信息,避免被判定为过时客户端:

    self.client = TelegramClient(
        f'session_{phone_number}', 
        api_id, 
        api_hash,
        device_model='Raspberry Pi 1 B+',
        system_version='Debian Bookworm',
        app_version='4.16.0'  # 可以参考Telegram官方APP的最新版本号填写
    )
    
  • 删除旧会话文件重新登录
    树莓派上可能存在损坏或过期的会话文件,删除当前目录下的session_你的手机号.session文件,然后重新运行脚本,从头完成登录流程。

  • 更新系统和依赖库
    树莓派1硬件较老,部分依赖库版本可能过低,执行以下命令更新系统和Python包:

    sudo apt update && sudo apt upgrade -y
    pip3 install --upgrade telethon requests
    
  • 尝试使用代理连接
    如果树莓派的公网IP被Telegram服务器限制,可以尝试添加MTProxy代理(需要有可用的代理服务),修改客户端初始化代码:

    from telethon import connection
    # 替换成你的代理信息
    self.client = TelegramClient(
        f'session_{phone_number}', 
        api_id, 
        api_hash,
        connection=connection.ConnectionTcpMTProxyRandomizedIntermediate,
        proxy=('你的代理地址', 代理端口, '代理密钥')
    )
    
  • 确认账号状态
    先在手机端登录你的Telegram账号,检查是否有异常提示(比如账号验证、登录限制等),确保账号处于正常状态后再尝试运行脚本。

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

火山引擎 最新活动