Pythonのsmtplibモジュールでgmailに接続してメール送信

投稿者: | 2019-11-04

Python3からsmptlibを使ってメール送信を行う。

大分前にDjangoを使った送信を行なったことがあるが、Flaskでもメール送信したい。 Flaskのエクステンションとかあるかもしれないが、pythonのモジュール(smtplibemail.message)だけで行うことにした。 なお、gmailsmtpサーバを利用する。

他のメール プラットフォームで Gmail のメールをチェックする - Gmail ヘルプによると、SMTPの場合、

smtp.gmail.com
SSL を使用する: はい
TLS を使用する: はい(利用可能な場合)
認証を使用する: はい
SSL のポート: 465
TLS / STARTTLS のポート: 587

の設定が必要になるようだ。STARTTLSを利用するので587番ポートを指定する。 また、上のgmailの参考によると、アプリパスワードか安全性の低いアプリを許可するかが必要だ。

(アプリパスワードや許可設定なしでやろうとすると、(534, b'5.7.9 Application-specific password required. Learn more at\n5.7.9 https://support.google.com/mail/?p=InvalidSecondFactor ****** - gsmtp')というようなエラーが起こる。)

  • アプリ パスワードを使用します。2 段階認証プロセスを使用している場合は、アプリ パスワードを使ってログインしてみます。
  • 安全性の低いアプリを許可します。2 段階認証プロセスを使用していない場合は、安全性の低いアプリがアカウントにアクセスすることを許可します。

今回はアプリパスワードを利用した。作成については、上の参考ページにある。前者を選択した時は、パスワードにアプリパスワードを指定すればいい。後者を選ぶ時は、パスワードにアカウントのパスワードを指定することになると思う。

ここまで準備したら、email.messageでメッセージを構築して、smtplibで送れば良い。 EHLOSMTPインスタンスの各メソッドで暗黙的に行われるので、必要ないようだ。(starttls()後に暗黙的にやってくれてるのかよく分からん。ソースを見ると、self.ehlo_or_helo_if_needed()login()send_message()などで行われているので大丈夫。)

手順の大枠は、email: 使用例 — Python 3.8.0 ドキュメントを参考にした。

# Import smtplib for the actual sending function
import smtplib

# Import the email modules we'll need
from email.message import EmailMessage

# Create a text/plain message
msg = EmailMessage()
msg.set_content('this is a test message! hello python mail world!!')

msg['Subject'] = 'The subject!'
msg['From'] = 'from@example.com'
msg['To'] = 'to@example.com'

# Send the message via our own SMTP server.
s = smtplib.SMTP('smtp.gmail.com', 587)

s.starttls()
# 2つ目の引数に生成したアプリパスワードを指定する
s.login('<account_email_address>', '<application_password>')

# 送信
s.send_message(msg)
s.quit()

これを実行すれば、Toのアドレスへ届くはず。 未確認だが、gmailなら、SMTPクラスでなく、SMTP_SSLクラスでも行けそう。 SMTP_SSLならstarttls()が不要になる。初めからSSL(TLS)を使うはずなので。

フローはこんな感じのはず:

pythonのsmtplibでのフロー