📫
email.mimeで画像を添付して送りたい
動機
- 画像(プロット)を関係者にもメールでお知らせしたい
- メールは定期的に自動送信したい
-
email.mime
パッケージを使ってメールを作成してみる
メッセージの作成
- メッセージの作成は部分は
email.mime.*
パッケージに任せる
メッセージ用オブジェクトの作成
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.utils import formatdate
from pathlib import Path
# メールに関する設定
me = "送信元のメールアドレス"
you = "Toアドレス1,Toアドレス2,..."
them = "Bccアドレス1,Bccアドレス2,..."
text = MIMEText("これは本文です\n", "plain", "utf-8")
# メッセージ用オブジェクト
msg = MIMEMultipart()
# ヘッダーセクションを追加
msg["From"] = me
msg["Date"] = formatdate(localtime=True)
msg["To"] = you
msg["Bcc"] = them
msg["Subject"] = "MIMEMultipartを使ってみる"
# 本文を追加
msg.attach(text)
# 画像を添付
fnames = sorted(Path("images/").glob("*.png"))
for fname in fnames:
with open(fname, "rb") as f:
img = f.read()
image = MIMEImage(img, name=fname.name)
msg.attach(image)
メッセージ用オブジェクトの内容
msg.items()
[('Content-Type', 'multipart/mixed'),
('MIME-Version', '1.0'),
('From', 'Fromアドレス'),
('Date', 'Wed, 05 Jan 2022 13:29:06 +0900'),
('To', 'Toアドレス1,Toアドレス2,Toアドレス3,...'),
('Bcc', 'Bccアドレス1,Bccアドレス2,Bccアドレス3...'),
('Subject', 'MIMEMultipartを使ってみる')]
print
してみる
メッセージ用オブジェクトの内容
print(msg)
出力結果
Content-Type: multipart/mixed; boundary="===============3710731288596159002=="
MIME-Version: 1.0
From: =?utf-8?b?RnJvbeOCouODieODrOOCuQ==?=
Date: Wed, 05 Jan 2022 13:29:06 +0900
To: =?utf-8?b?VG/jgqLjg4njg6zjgrkxLFRv44Ki44OJ44Os44K5MixUb+OCouODieODrOOCuTMsLi4u?=
Bcc: =?utf-8?b?QmNj44Ki44OJ44Os44K5MSxCY2PjgqLjg4njg6zjgrkyLEJjY+OCouODieODrOOCuTMuLi4=?=
Subject: =?utf-8?b?TUlNRU11bHRpcGFydOOCkuS9v+OBo+OBpuOBv+OCiw==?=
--===============3710731288596159002==
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
CuOBk+OCjOOBr+acrOaWh+OBp+OBme+8iDHooYznm67vvIkK44GT44KM44Gv5pys5paH44Gn44GZ
77yIMuihjOebru+8iQrjgZPjgozjga/mnKzmlofjgafjgZnvvIgz6KGM55uu77yJCgo=
--===============3710731288596159002==
Content-Type: image/png; name="age_address.png"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
iVBORw0KGgoAAAANSUhEUgAAAowAAAJ7CAYAAABppMB3AAAgAElEQVR4XuydB5RU1fL1S3nkoCCI
...(画像データの部分はとても長いので省略)...
Tw/BIYAAAggggAACrhcgYXT9HBABAggggAACCCBgtcD/ADLCLHirTzJQAAAAAElFTkSuQmCC
--===============3710731288596159002==
Content-Type: image/png; name="age_gender.png"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
iVBORw0KGgoAAAANSUhEUgAAAowAAAJ7CAYAAABppMB3AAAgAElEQVR4XuydC3gV1dW/V0K4RQgX
...(画像データの部分はとても長いので省略)...
LSABEiABEiABEiABpwn8P1SdUGsvHrDXAAAAAElFTkSuQmCC
--===============3710731288596159002==
Content-Type: image/png; name="age_repeat.png"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
iVBORw0KGgoAAAANSUhEUgAAArgAAAJ7CAYAAAAIvOI1AAAgAElEQVR4XuydCXQVRfb/b8IedpR9
...(画像データの部分はとても長いので省略)...
BAAAAABJRU5ErkJggg==
--===============3710731288596159002==--
確認できたこと
- メッセージが
multipart/mixed
形式で作成できている - 本文が
text/plain
形式で追加できている - 画像 3 枚を
image/png
で追加できている
さらに確認が必要なこと
- ヘッダーセクションに日本語を使ったので文字がエンコードされてる
メッセージ作成のまとめ
モジュールの役割
-
MIMEMultipart
: 画像などを添付できるメッセージ用オブジェクトの作成 -
MIMEText
: メールの本文オブジェクトの作成 -
MIMEImage
: メールに添付する画像オブジェクトの作成
メッセージ用オブジェクトの作成
- 画像などを添付するため
MIMEMultipart
オブジェクトを作成した - このオブジェクトに対して本文/画像を
attach
で追加する
ヘッダーセクションの追加
- メッセージ用オブジェクトは
msg["From"] = me
のように辞書型と同じように扱うことができる - 日付は RFC2822 準拠の形式にする必要がある。
formatdate(localtime=True)
を使うのが一番簡単だと思う
本文オブジェクトの追加
-
MIMEText
を使ってプレーンテキストを作成する - 文末に改行コード(
\n
)をつける - メッセージ用オブジェクトに
.attach
する
画像オブジェクトの追加
-
MIMEImage
を使って画像ファイルを作成する - 画像ファイルのパスは
Path
オブジェクトで作成した - 画像ファイルはバイナリ(
rb
)で開く - メッセージ用オブジェクトに
.attach
する
複数の画像を添付
- 画像ファイルを保存しているディレクトリから PNG 画像の一覧を取得する
- ファイル名の順番にならないことがあったので
sorted
する
メールの送信
- メールの送信は
smtplib
パッケージに任せる
sender.py
import smtplib
# SMTPサーバの設定
host = "SMTPサーバのアドレス
port = ポート番号
user = "SMTPサーバのログイン名"
password = "ログインパスワード"
mailer = smtplib.SMTP(host, port)
mailer.set_debuglevel(2)
mailer.starttls()
mailer.ehlo()
mailer.login(user, password)
mailer.send_message(msg)
mailer.quit()
メール送信のまとめ
- SMTP サーバに TLS を使って接続する
- ユーザ名・パスワードを使って認証する
- SMTP の拡張機能を使うことを明示する
- 作成したメッセージ用オブジェクト(
msg
)を受け取る - SMTP を使ってメールを送信する
まとめ
- メッセージ作成の部分と、メール送信の部分を一つのファイル(
sender.py
)にまとめる - 下記のコマンドを実行する
メールを送信
$ python3 sender.py
感想
-
email.mime
パッケージを使うことで、とても簡単にメール本文を作成することができた -
MIMEApplication
、MIMEAudio
など、他のモジュールもあるので、添付したいファイルの形式に応じて使い分ければよさそう -
smtplib
パッケージを使うことで、あっさりとメールを送信することができた -
crontab
やwatchdog
と組み合わせて、定期実行できそう
Discussion