Python でメールの送信を実装する

シェアする

Python でメールの送信を実装します。

メールの送信処理は、Web システムのアカウント発行やメールマガジン、エラーが発生したときの通知やバッチ処理の完了通知など、様々な場所で使います。

メールを送信するには、メールサーバーが必要になってきますが、自前で Postfix を用意するのは、少し大変ですので、今回は、Gmail をメールサーバーとして利用したいと思います。

Gmail の設定

安全性の低いアプリのアクセス

実装を始める前に、Python から Gmail にメールを送信できる状態になっているか確認します。

Python から Gmail にメールを送信する場合、Google アカウントのセキュリティレベルを弱くする必要があります。事前に安全性の低いアプリの許可を有効にしてください。

この設定を有効にしないと以下のエラーが出ます。

この設定はセキュリティレベルを下げる設定ということに気をつけてください。テスト目的であれば、テスト終了後に元の設定に戻しましょう。

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/satoru/.pyenv/versions/3.5.4/lib/python3.5/smtplib.py", line 730, in login
    raise last_exception
  File "/Users/satoru/.pyenv/versions/3.5.4/lib/python3.5/smtplib.py", line 721, in login
    initial_response_ok=initial_response_ok)
  File "/Users/satoru/.pyenv/versions/3.5.4/lib/python3.5/smtplib.py", line 642, in auth
    raise SMTPAuthenticationError(code, resp)
smtplib.SMTPAuthenticationError: (534, b'5.7.9 Application-specific password required. Learn more at\n5.7.9 https://support.google.com/mail/?p=InvalidSecondFactor d25sm19570259pfn.154 - gsmtp')

実装

SMTP サーバーに接続

import smtplib
smtp_obj = smtplib.SMTP('smtp.gmail.com', 587)

Gmail の SMTP サーバーに接続します。

今回はサブミッションポートの 587 に接続し、STARTTLS を使って暗号化し、メールを送信します。

別の接続方法としては、SMTPS の 465 に対して接続することもできますが、その場合は、SMTP() ではなく、SMTP_SSL() を使います。

import smtplib
smtp_obj = smtplib.SMTP_SSL('smtp.gmail.com', 465)

暗号化の開始

smtp_obj.ehlo()
smtp_obj.starttls()

暗号化の開始です。今回は、STARTTLS を使いますので、ehlo() の後に、starttls() をします。SMTPS の場合 starttls() は不要です。

これ以降の通信は暗号化しますので、安心して認証情報やメールのやりとりすることができます。

ログイン

smtp_obj.login('satoru.nakamatsu@gmail.com', 'パスワード')

次にログイン処理を実装します。

上記の安全性の低いアプリのアクセスの設定をしていないと、Application-specific password required. の SMTPAuthenticationError が出ます。

メール送信

from email.mime.text import MIMEText
from email.header import Header

charset = 'iso-2022-jp'
msg = MIMEText('日本語の本文\n2行目', 'plain', charset)
msg['Subject'] = Header('日本語の件名'.encode(charset), charset)
smtp_obj.sendmail('satoru.nakamatsu@gmail.com', '宛先のメールアドレス', msg.as_string())

sendmail() を使ってメールを送信します。件名と本文は、この関数の第三引数になりますが、日本語メールを送信する場合は、上記のように email パッケージが必要になります。

email パッケージを使わずに送信すると、UnicodeEncodeError になります。

プログラム全体

import smtplib
from email.mime.text import MIMEText
from email.header import Header

charset = 'iso-2022-jp'
msg = MIMEText('日本語の本文\n2行目', 'plain', charset)
msg['Subject'] = Header('日本語の件名'.encode(charset), charset)

smtp_obj = smtplib.SMTP('smtp.gmail.com', 587)
smtp_obj.ehlo()
smtp_obj.starttls()
smtp_obj.login('satoru.nakamatsu@gmail.com', 'パスワード')
smtp_obj.sendmail('satoru.nakamatsu@gmail.com', '宛先のメールアドレス', msg.as_string())
smtp_obj.quit()

上記で説明してきた内容を全て組み合わせて、smtp.py というファイルに保存しました。

動作確認

smtp.py の実行結果は以下の通りです。

$ python smtp.py

まとめ

Python でメールの送信を実装しました。

今回は Gmail を SMTP サーバーに利用しましたが、Gmail を SMTP サーバーとして本格的に利用する場合は、上記で説明した通りセキュリティレベルを下げてしまうということに加え、Gmail の送信数制限にも注意が必要になってきます。

逆に、これらを許容できる場合、例えば、新規で Gmail アカウントを取って、プログラム異常の通知用とかであれば、プロダクションで利用しても問題ないと思います。

シェアする

フォローする