概要
Pythonの標準ライブラリであるsmtplibを使用してメールを送信するコードの例です。今回使用する私のメールサーバーがTLS通信(SSL)をサポートしたものであるため、TLS通信で、かつ認証を行う場合の例となっています。
なお、Pythonのバージョンは3.9を使用しています。
コード
import smtplib
from email.mime.text import MIMEText
# 送受信先
to_addr = "送信先アドレス"
from_addr = "送信元アドレス"
msg = MIMEText('本文', "plain", 'utf-8')
msg['Subject'] = "メールのタイトル"
msg['From'] = from_addr
msg['To'] = to_addr
with smtplib.SMTP_SSL(host="host name", port=465) as smtp:
smtp.login('user', 'pass')
smtp.send_message(msg)
smtp.quit()
コードの解説
方法としては、
- MIMETextクラスでMessageオブジェクトを作成
- SMTP_SSLオブジェクトを作成
-
.login()
でログイン -
.send_message()
で送付 -
.quit()
で終了
という流れです。
クラスの関数の使い方さえ分かれば、それほど難しくはないですね。
ちなみに、.sendmail()も送信用の関数ですが、こちらは若干手間で、メールのヘッダーフィールドを文字列で直に書く必要があります。emailのメッセージに関する規約であるRFC 5322に準拠した形式で書かないといけません。
ただ、公式マニュアルの.send_message()
の箇所を見ると、”This is a convenience method for calling sendmail()
with the message. . .”と書いてあり、.send_message()
が便利な方法だと書かれています。こちらを使用したほうが楽でしょう。
ちなみに、SMTP_SSL
のコンストラクタとしてport
を指定しない場合、自動的に465が使用されるようです(今回は明示的に示している)。
EmailMessage, MIMETextどちらを使用するか
.send_message()
では、引数にMessage
オブジェクトを渡します。作成方法は、色んなサイトを見るとMIMEText
が使用されていますが、ところが、Python公式ドキュメントによるとEmailMessage
もあるようです。どちらでもMessageオブジェクトは作成可能のようですが、どう違うのでしょうね?
試しに確認してみましょう。
from email.message import EmailMessage
from email.mime.text import MIMEText
# 送受信先
to_email = "送信先"
from_email = "送信元"
msg = EmailMessage()
msg['Subject'] = "タイトル行"
msg['From'] = from_email
msg['To'] = to_email
msg.set_content('本文')
msg_mime = MIMEText('本文', "plain", 'utf-8')
msg_mime['Subject'] = "タイトル行"
msg_mime['From'] = from_email
msg_mime['To'] = to_email
[print('{0}: {1}'.format(k,v)) for k,v in msg.items()]
[print('{0}: {1}'.format(k,v)) for k,v in msg_mime.items()]
最後の行で、生成されたヘッダを出力しています。
EmailMessage
を使用した場合、Content-Transfer-Encoding
が8bit
になっていますね。
Subject: タイトル行
From: 送信元
To: 送信先
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
MIME-Version: 1.0
それに対し、MIMEText
は次のようでした。Content-Transfer-Encoding
がbase64
です。
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Subject: タイトル行
From: 送信元
To: 送信先
メールのエンコードには、通常、base64が使用されますね。
エンコードは設定で変更できると思うのですが、今回はそこまでは調べていません。
基底クラスを確認してみる
EmailMessage
クラス、MIMEText
クラスの基底クラスを確認してみましょう。継承元のクラスを調べるにはinspect
モジュールの.getmro()
が使えます。
import inspect
inspect.getmro(EmailMessage)
inspect.getmro(MIMEText)
EmailMessage
です。
[print(r) for r in inspect.getmro(EmailMessage)]
<class 'email.message.EmailMessage'>
<class 'email.message.MIMEPart'>
<class 'email.message.Message'>
<class 'object'>
MIMEText
はこちら。どちらも、基底クラスにMessage
クラスがあります(当たり前だけど)。
<class 'email.mime.text.MIMEText'>
<class 'email.mime.nonmultipart.MIMENonMultipart'>
<class 'email.mime.base.MIMEBase'>
<class 'email.message.Message'>
<class 'object'>
以上です。