使用 boto3 将 SVG 图像内容作为 HTML 发送到电子邮件

Send SVG image content to email as HTML using boto3

我想将 SVG 内容(没有保存的文件)作为 HTML 发送到 Outlook 电子邮件地址。 此 SVG 内容在显示圆形图像的浏览器中运行良好,但通过 boto3.client 将其发送到 Outlook 电子邮件会导致邮件为空。为什么?任何建议表示赞赏。

import io
import json
import boto3
from botocore.exceptions import ClientError

SENDER = "Name1 LastName1 <Name1.LastName1@mail.com>"
RECIPIENT = "Name2 LastName2 <Name2.LastName2@mail.com>"
AWS_REGION = "us-east-1"
SUBJECT = "something"

svg = """
<svg width="100" height="100">
<circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
</svg> 
"""

BODY_HTML = f"""<html>
<body>
{svg}
</body>
</html>
            """ 

CHARSET = "UTF-8"

client = boto3.client('ses',region_name=AWS_REGION)

try:
    response = client.send_email(
        Destination={
            'ToAddresses': [
                RECIPIENT
            ],
        },
        Message={
            'Body': {
                'Html': {
                    'Charset': CHARSET,
                    'Data': BODY_HTML
                }
            },
            'Subject': {
                'Charset': CHARSET,
                'Data': SUBJECT
            },
        },
        Source=SENDER
    )   
except ClientError as e:
    print(e.response['Error']['Message'])
else:
    print("Email sent! Message ID:"),
    print(response['MessageId'])

SVG 图形在 Web 浏览器中得到广泛支持,但并非所有电子邮件程序都知道如何处理这些新图像。如果是 Outlook,您需要将文件导出为任何图像文件格式,如 PNG 或 JPEG,然后将其附加到邮件项目。然后在消息正文中,您可以参考使用带有 cid: 前缀的特殊语法。您还需要使用 Attachment.PropertyAccessor.SetProperty 方法设置 PR_ATTACH_CONTENT_ID MAPI 属性(DASL 名称“http://schemas.microsoft.com/mapi/proptag/0x3712001F”)并参考该附件通过与附件上设置的 PR_ATTACH_CONTENT_ID 值相匹配的 src 属性。 PR_ATTACH_CONTENT_ID 对应邮件发送时的 Content-ID MIME 头。

attachment = MailItem.Attachments.Add("c:\temp\MyPicture.jpg")
attachment.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001F", "YourImageId")
MailItem.HTMLBody = "<html><body>Test image <img src=""cid:YourImageId""></body></html>"

我找到了解决办法。使用 send_raw_emailMIMEImageMIMEImage 中的 cid 用于在 html 正文中插入图像数据。更新代码如下:

from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import json
import boto3
from botocore.exceptions import ClientError

SENDER = "Name1 LastName1 <Name1.LastName1@mail.com>"
RECIPIENT = "Name2 LastName2 <Name2.LastName2@mail.com>"
AWS_REGION = "us-east-1"
SUBJECT = "something"

png_data = image_bytes()

CHARSET = "utf-8"

client = boto3.client('ses',region_name=AWS_REGION)

msg = MIMEMultipart('mixed')

msg['Subject'] = SUBJECT 
msg['From'] = SENDER 
msg['To'] = RECIPIENT

img = MIMEImage(png_data, 'png')
img.add_header("Content-Type", "image/png", name="some_name.png")
img.add_header("Content-Disposition", "inline", filename="some_name.png")
img.add_header('Content-Id', 'some_cid_name')
img.add_header('Content-Transfer-Encoding', 'base64')

BODY_HTML = '<img src="cid:some_cid_name"/>'

email_body= MIMEText(BODY_HTML.encode(CHARSET), 'html', CHARSET)
msg.attach(email_body)

try:
    #Provide the contents of the email.
    response = client.send_raw_email(
        Source=SENDER,
        Destinations=[
            RECIPIENT
        ],
        RawMessage={
            'Data':msg.as_string(),
        },
    )
# Display an error if something goes wrong. 
except ClientError as e:
    print(e.response['Error']['Message'])
else:
    print("Email sent! Message ID:"),
    print(response['MessageId'])