gmail API 插入 - 如何将 gmail 可以读取的图像数据写入现有电子邮件

问题描述 投票:0回答:0

我正在尝试编写一个脚本来调整我们 gmail 帐户中现有电子邮件(作为内联附件)中图像的大小。但是被写回以替换原始照片的图像数据随后不会被 gmail 显示。

使用下面的 attempt == 1 和 attempt == 2 代码,我可以从三点菜单手动下载生成的电子邮件作为 .eml 文件,在 python 中打开该 .eml 文件并获取 PIL 的 Image.open 函数以毫无怨言地读取图像数据(使用 base64.urlsafe_decode),PIL 还可以将该数据保存到一个文件中,我的系统上的图像查看器可以毫无问题地读取该文件。

使用 attempt == 1 代码,在使用 set_payload 之后,我无法使用 get_payload 获取 PIL 将以当前形式读回的内容(大概是因为此时它不是 base64 编码)。

使用 attempt == 2 代码,我可以使用 get_payload 获取 PIL 可以读取、保存等内容

但无论哪种方式,gmail 都不会识别/显示网络界面中的图像,只会显示原始电子邮件中图像前后出现的文本。

from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from google.auth.transport.requests import Request
import base64
import email
from PIL import Image
import io

SCOPES = ['https://mail.google.com/']
query = "123456 before:2020-05-30 after:2020-05-20" 
# query that finds one specific email containing two images (both having width > 400 pixels)

flow = InstalledAppFlow.from_client_secrets_file(OURSECRETSJSONFILE, SCOPES)
creds = flow.run_local_server(port=0)
service = build('gmail', 'v1', credentials=creds)


res1 = service.users().messages().list(userId='me', q=query).execute() # or any other q= string
fullmsg = service.users().messages().get(userId='me', id=res1['messages'][0]['id'], format='raw').execute()

unencoded = base64.urlsafe_b64decode(fullmsg['raw']).decode('utf-8')
mmsg = email.message_from_string(unencoded)

for part in mmsg.walk():
    if part.get_content_maintype() != 'multipart' and part.get('Content-Disposition') is not None and 'image' in part.get_content_type(): # image
        image = Image.open(io.BytesIO(part.get_payload(decode=True)))
        if image.size[0] > 400:

            image.thumbnail((400,400))
            resizedIO = io.BytesIO()
            image.save(resizedIO, format='png')
            resizedIO.seek(0)
           
            if attempt == 1:
                part.set_payload(resizedIO.read())
                # attempting to read this back with the Image.open line above fails with
                #
                # PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x04B3D320>
                #
                # using the same line without the decode parameter yields
                #
                # TypeError: a bytes-like object is required, not 'str'
                #
                # and adding a .encode() on to the end of get_payload() again gives PIL.UnidentifiedImageError

            elif attempt == 2:
                part.set_payload(base64.urlsafe_b64encode(resizedIO.read()))
                # attempting to read this back with the Image.open line above works,
                # and the image data can be saved, viewed in an image viewer and confirmed
                # as non-corrupted. But when viewing this email in gmail's web interface,
                # the image is not displayed.

encmsg = base64.urlsafe_b64encode(mmsg.as_string().encode('utf-8'))
temp2 = { 'raw' : encmsg.decode(), 'labelIds' : fullmsg['labelIds'], 'threadId' : fullmsg['threadId']}
resp2 = service.users().messages().insert(userId='me', body=temp2, internalDateSource='dateHeader').execute()
#service.users().messages().delete(userId='me', id=res1['messages'][0]['id']).execute()
# Don't enable the line deleting the original email until everything is working.
python gmail python-imaging-library gmail-api email-attachments
© www.soinside.com 2019 - 2024. All rights reserved.