15 Aug 2016, 14-minute piece by Dev Mukherjee
Most Internet services requires to send email to their users.Pythonでメール送信のためのマルチパートメモリメッセージを構築する。 メッセージを構築することは、電子メールを送信することとは別の作業です。 この投稿では、Python で Multipurpose Internet Mail Extensions (MIME) メッセージを適切に構築する方法を説明します。
MIME メッセージには、さまざまな種類のコンテンツをカプセル化するために多くのサブタイプがあります。 Python の電子メール MIME ライブラリは、それらを扱うためのラッパーを提供します。
-
mixed
異なるタイプのコンテンツを、インラインまたは添付ファイルとして送信するために使用されます -
alternative
同じコンテンツの代替バージョンを送信するために使用します。 HTML コンテンツで使用される画像
この投稿で作成する電子メール メッセージには、以下が含まれる予定です。
- 本文の HTML およびプレーン テキスト バージョン
- 添付ファイル (この例では、生成された
ICS
ファイル) - オプションで HTML コンテンツに画像を表示
では、メッセージの各種コンポーネント (メール本文、インライン表示画像、ダウンロードできる添付ファイル) が含まれる mixed
MIME マルチパート メッセージを作成することから始めてみましょう。
from email.mime.multipart import MIMEMultipart# By default the type is set to mixedmessage = MIMEMultipart()message = "Hello World"message = "Anomaly Support <[email protected]>"message = "Anomaly Reception <[email protected]>"# If a Reply-To is explicitly provided then the email client will# use this address when the user hit the reply button message = "Anomaly Support <[email protected]>"
HTML およびプレーン テキストのボディ コンテンツ
2 つの添付ファイルを持つ alternative
メッセージを作成し、最初は電子メール メッセージのプレーン テキスト バージョン、次に HTML バージョンが含まれるようにします。
HTML およびテキスト コンテンツは、通常、テンプレート エンジンの支援を受けて作成されます。
alternative
メッセージは MIMEMultipart
オブジェクトをインスタンス化することで作成され、今回は alternative
サブタイプを使用するようにコンストラクタに依頼します。
textual_message = MIMEMultipart('alternative')
MIMEText
ヘルパーを使って、平文と HTML 添付ファイルを生成してください。
from email.mime.text import MIMEText# I assume that you have a variable called txt_content# with the textual rendition of the message, this could# have been generated via a templating engineplaintext_part = MIMEText(txt_content, 'plain')textual_message.attach(plaintext_part)# likewise a variable called html_content with the HTMLhtml_part = MIMEText(html_content, 'html')textual_message.attach(html_part)
親の mixed
メッセージに alternative
メッセージを添付して、メール メッセージのテキスト本文を作成します。
# Attach this to the mixed type messagemessage.attach(textual_message)
Downloadable attachment
MIMEApplication
ヘルパーを使ってテキストファイルまたはバイナリファイルをメールに添付することが可能です。 これは、添付ファイルのコンテンツに続いて、添付ファイルの MIME タイプ、つまり、application/pdf
の場合は pdf
部分を指定してインスタンス化されます。 これを添付ファイルにするには、MIMEApplication
インスタンスの add_header
メソッドを使用して、添付ファイルであることを宣言します。 添付ファイルのコンテンツはエンコードされたメッセージの一部になったので、ファイル名のようなメタ情報を明示的に提供する必要があります。
from email.mime.application import MIMEApplicationpdf_file = MIMEApplication(pdf_file_data, "pdf")pdf_file.add_header('Content-Disposition', 'attachment', filename='report.pdf')
MIMEApplication
ヘルパーは、コンテンツがメッセージに添付されると自動的に Base64
エンコードします:
message.attach(pdf_file)
HTML 本文で使用するオプション画像
メール本文で表示するが受信者にダウンロードしてほしくない画像はないか考えてみてください。
また、画像が適切にエンコードされるように、MIMEImage
サブクラスを使用する必要があります。
related_message = MIMEMultipart('related')
画像コンテンツを含む MIMEImage
のインスタンスを作成します。
from email.MIMEImage import MIMEImage# Content of an image that relates to the HTML messageimage = MIMEImage(image_binary_contents)# Lets you reference the image locally in HTMLimage.add_header('Content-ID', '<image1>')
Content-ID
ヘッダーを追加すると、<img src="cid:image1">
として HTML コンテンツで画像を参照できます。 もともと作成したalternate
メッセージをrelated
メッセージに添付し、その後にMIMEImage
インスタンスを添付します:
# Attach the alternative textural message to the # related messagerelated_message.attach(textual_message)# Attach the image to the related messagerelated_message.attach(image)
最後にrelated
メッセージをmixed
メッセージに添付してください。
# Attach the related message to our parent messagemessage.attach(related_message)
Encoding and sending the email
MIME
タイプとサブタイプを組み合わせたら、as_string
関数をコールしてメッセージをエンコードできます。 これは、順番に、すべてのサブメッセージと添付ファイルを1つのまとまったメッセージとしてレンダリングするように要求します。
encoded_email = message.as_string()
smtplib
は、このメッセージを配信する SMTP
クライアントを提供しています。 とてもわかりやすいですね。 アプリケーションとサーバーのセットアップによっては、ローカルリレーを使用するか、利用可能なSMTPサーバーに直接リレーすることを選択することができます。
from smtplib import SMTPsmtp = SMTP("localhost", 25)smtp.sendmail(message, message, encoded_email)smtp.quit()
Note: Reply-To
ディレクティブは SMTP ペイロードの一部ではなく、MIME
メッセージの一部として扱われます。