在 python 中使用 Gmail API 下载 google 封电子邮件的驱动器附件

Download google drive attachments of an email using Gmail API in python

我目前使用 this solution 通过 python 使用 Gmail API 从 Gmail 下载附件。 但是,每次附件超过 25MB 时,附件都会自动上传到 Google 驱动器,并且文件会在邮件中链接。在这种情况下,消息中没有 attachmentId。 我只能在消息文件的 'snippet' 部分看到文件名。

有什么方法可以从邮件中下载 Google 潜水附件吗?

有人发布了类似的问题here,但还没有提供解决方案

如何下载驱动器“附件”

所指的“附件”实际上只是一个 link 到云端硬盘文件,所以令人困惑的是它根本不是附件,而只是文本或 HTML。

这里的问题是,由于它本身不是附件,因此您无法通过 Gmail API 单独获取它。您需要使用驱动器 API.

要使用驱动器 API,您需要获取文件 ID。这将在 HTML 内容部分等中。

您可以使用 re 模块对 HTML 内容执行 findall,我使用以下正则表达式模式来识别驱动器 links:

(?<=https:\/\/drive\.google\.com\/file\/d\/).+(?=\/view\?usp=drive_web)

这里是获取文件 ID 的示例 python 函数。它将 return 一个列表。

def get_file_ids(service, user_id, msg_id):
    message = service.users().messages().get(userId=user_id, id=msg_id).execute()
    for part in message['payload']['parts']:
        if part["mimeType"] == "text/html":
            b64 = part["body"]["data"].encode('UTF-8')
            unencoded_data = str(base64.urlsafe_b64decode(b64))
            results = re.findall(
                '(?<=https:\/\/drive\.google\.com\/file\/d\/).+(?=\/view\?usp=drive_web)',
                unencoded_data
            )
            return results

获得 ID 后,您需要调用云端硬盘 API。

您可以按照 docs 中的示例进行操作:

file_ids = get_file_ids(service, "me", "[YOUR_MSG_ID]"

for id in file_ids:
    request = service.files().get_media(fileId=id)
    fh = io.BytesIO()
    downloader = MediaIoBaseDownload(fh, request)
    done = False
    while done is False:
        status, done = downloader.next_chunk()
        print "Download %d%%." % int(status.progress() * 100)

请记住,鉴于您现在要使用云端硬盘 API 以及 Gmail API,您需要更改项目中的范围。还记得在开发人员控制台中激活驱动器 API,更新您的 OAuth 同意屏幕、凭据并删除本地 token.pickle 文件。

参考资料