HTMLメールに添付ファイルの画像を埋め込む

HTMLメールに画像ファイルを添付して、メール文面にその画像を表示させるには、次の2点に気を付ければよいようです。

  • HTMLのimg要素には src="cid:image.jpg" のように指定
  • 添付の画像ファイルに Content-ID ヘッダを付与

img要素

メールのHTMLパートのソースには <img src="cid:image.png"> のようにファイル名に cid: を付けます。

画像の添付ファイルのヘッダ

以下のようにファイル名を指定します。 Content-ID: <image.png> というのが必要のようです。他の2行も必要なのかはわかりませんが、いちおう付けました。 Content-ID に指定するファイル名は <> で囲む必要があります。

Content-Disposition: attachment; filename="image.png"
Content-Type: image/png; name="image.png"
Content-ID: <image.png>

Pythonでメール送信する例

from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import formatdate

import boto3

profile = "default"
region = "ap-northeast-1"

email_from = "sample_from@example.com"
email_to = "sample_to@example.com"

session = boto3.session.Session(profile_name = profile, region_name = region)
ses_client = session.client("ses")

charset = "UTF-8"

body_text = "画像を添付\n"
body_html  = "<!DOCTYPE html><html><head><meta charset=\"utf-8\"/></head><body>"
body_html += "<p>画像を添付</p>\n"
body_html += "<p><img src=\"cid:image.png\"></p>" # `cid:` を付けないとGmailは画像を参照してくれなかった
body_html += "</body></html>"

subject = "Sample email"
date = formatdate()

file_binary = open("image.png", 'rb').read()

msg = MIMEMultipart("mixed")
msg['Subject'] = subject
msg['From'] = email_from
msg['To'] = email_to
msg['Date'] = date

msg_body = MIMEMultipart('alternative')
msg_body.attach(MIMEText(body_text.encode(charset), 'plain', charset))
msg_body.attach(MIMEText(body_html.encode(charset), 'html', charset))
msg.attach(msg_body)

attachment = MIMEApplication(file_binary)
attachment.add_header('Content-Disposition', 'attachment', filename = "image.png")
attachment.add_header('Content-Type', 'image/png', name = "image.png")
attachment.add_header('Content-ID', "<image.png>")
msg.attach(attachment)

# AWS SESでメール送信する例
ses_client.send_raw_email(
    Source = email_from,
    Destinations = [email_to],
    RawMessage = {
        "Data": msg.as_string(),
    },
)

# SMTPサーバでメール送信する例
#import smtplib
#smtp = smtplib.SMTP(SMTP_HOST, SMTP_PORT)
#smtp.starttls()
#smtp.sendmail(email_from, email_to, msg.as_string())

メール受信例

GmailOutlookで確認しました。添付ファイルとしてではなく、文中に差し込みができています。

Gmailでの受信 f:id:suzuki-navi:20210607233057p:plain

Outlookでの受信 f:id:suzuki-navi:20210607233120p:plain