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

Telethon的download_media方法在AWS Lambda中失效问题求助

问题:AWS Lambda中使用Telethon下载Telegram图片报错只读文件系统

我在Lambda的lambda_handler里用Telethon下载Telegram频道消息的图片,代码如下:

with TelegramClient(StringSession(string_session), api_id=int(telegram_id), api_hash=telegram_hash) as client:
    count = 1
    for message in client.iter_messages(name, limit=limit, reverse=False):
        news.append(message.text)
                
        file_name = f"{str(count)}"
        message.download_media(file=f"/tmp/{file_name}")
                
        path = f"/tmp/{file_name}"
        key = None
                
        s3.upload_file(Filename=path, Bucket='telebotmedia', Key=file_name)
        count += 1

运行时报错:

[Errno 30] Read-only file system: 'photo_2024-01-16_17-34-40.jpg'

已经给函数角色配置了AWSLambdaBasicExecutionRole和PowerUserAccess权限,但还是没法在/tmp目录完成下载。


原因分析

报错里的文件名是photo_2024-01-16_17-34-40.jpg,但你指定的路径是/tmp/{count},说明Telethon在下载时自动给文件追加了原始后缀,导致实际写入的路径不是你指定的/tmp/1,而是直接在Lambda的只读工作目录生成带后缀的文件,最终触发权限错误。

解决方法

方法1:明确指定完整带后缀的/tmp路径

先获取媒体文件的原始后缀,再拼接成完整的/tmp路径,确保Telethon写入到正确的可写目录:

with TelegramClient(StringSession(string_session), api_id=int(telegram_id), api_hash=telegram_hash) as client:
    count = 1
    for message in client.iter_messages(name, limit=limit, reverse=False):
        news.append(message.text)
        
        # 跳过非媒体消息
        if not message.media:
            count += 1
            continue
            
        # 获取文件后缀
        if message.photo:
            # 图片取最后一个尺寸的文件名后缀
            file_ext = message.photo.file.name.split('.')[-1]
        elif message.document:
            # 文档直接取原始文件名的后缀
            file_ext = message.document.file.name.split('.')[-1]
        else:
            count += 1
            continue
            
        # 拼接完整的可写路径
        file_name = f"{count}.{file_ext}"
        file_path = f"/tmp/{file_name}"
        
        message.download_media(file=file_path)
        s3.upload_file(Filename=file_path, Bucket='telebotmedia', Key=file_name)
        count += 1

方法2:跳过本地文件,直接上传字节流到S3

不需要写入/tmp目录,直接把Telethon下载的媒体内容转成字节流上传,彻底避免文件系统问题:

with TelegramClient(StringSession(string_session), api_id=int(telegram_id), api_hash=telegram_hash) as client:
    count = 1
    for message in client.iter_messages(name, limit=limit, reverse=False):
        news.append(message.text)
        
        if not message.media:
            count += 1
            continue
            
        # 定义S3存储的文件名
        if message.photo:
            file_name = f"{count}.jpg"
        elif message.document:
            # 优先用原始文件名,没有则自定义
            file_name = message.document.file.name or f"{count}.bin"
            
        # 直接下载字节流并上传到S3
        media_bytes = message.download_media(bytes)
        s3.put_object(Bucket='telebotmedia', Key=file_name, Body=media_bytes)
        count += 1

额外注意点

  • Lambda的/tmp目录最大容量为512MB,批量下载时要注意控制文件总大小。
  • Lambda执行结束后,/tmp目录的文件会自动清理,无需手动删除。

内容的提问来源于stack exchange,提问作者Furkan Suren

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 19:22:50