このページで解説している内容は、以下の YouTube 動画の解説で見ることができます。

【Python入門】管理者にメールを送信する

管理者にメールを送信する

 サーバーやシステムの状態を監視していると、何らかの異常が発生した際に管理者へ通知する仕組みが必要になることがあります。Pythonには標準ライブラリだけでメール送信が可能な機能が搭載されており、これを使って自動的に警告メールやレポートメールを送り出せるようになります。ここでは、その仕組みや注意点、実装例について順を追って解説します。

プログラムのダウンロード

 「ダウンロード」から、JupyterLab で実行できるサンプルプログラムがダウンロードできます。ファイルは、ESET Endpoint Securityでウイルスチェックをしておりますが、ダウンロードとプログラムの実行は自己責任でお願いいたします。

1.メール送信の基本原理

 プログラムによるメール送信は、SMTP(Simple Mail Transfer Protocol)サーバーを経由して行われます。SMTPサーバーのホスト名やポート番号、ログイン情報をプログラム側で指定することで、テキスト形式のメールを送信できるようになります。

1.1.準備と設定

  • SMTPサーバーの情報:Gmailなどの外部サービスを使う場合、事前にアプリパスワードの生成などが必要です。自前のメールサーバーがある場合は、そのホスト名やポート番号、認証情報を把握しておきます。
  • ポート番号:通常は587番を使用し、TLS接続を開始して安全に通信することが推奨されています。
  • メールの作成:本文や件名、送信元、送信先は「ヘッダ情報」と呼ばれ、指定しないとメールクライアントで正しく表示されません。

2.SMTPサーバーへ接続する方法

 Pythonの標準ライブラリsmtplibを使えば、数行のコードでSMTPサーバーへ接続し、ログインしてメールを送信できます。

メソッド名役割
ehlo()EHLOコマンドをサーバーに送ってクライアント名を伝える。
starttls()TLS(暗号化)接続を開始する。
login(ユーザー, パスワード)SMTPサーバーに対して認証を行い、メール送信の権限を得る。
sendmail(From, To, 本文)送信元アドレス・送信先アドレス・メール本文を指定し、メールを送信する。

3.メールの作成方法

 Pythonの標準ライブラリemail.mime.textからMIMETextクラスを利用すると、テキストメールの本文とヘッダ(Subject, From, Toなど)を手軽に指定できます。

from email.mime.text import MIMEText

msg = MIMEText("メール本文をここに書きます。")
msg["Subject"] = "任意の件名"
msg["From"] = "送信元メールアドレス"
msg["To"] = "送信先メールアドレス"

 これによって、メール本文のテキストと各種ヘッダが設定されたオブジェクトが生成されます。あとはsmtplib.SMTPオブジェクトに渡して送信するだけです。

4.サンプルコード(JupyterLabで実行可能)

 以下に、JupyterLabのセルで実行できるサンプルプログラムを示します。実際に試す際は、SMTP_SERVERやメールアドレス、パスワードなどをご自身の環境に合わせて修正してください。テストとして自分自身にメールを送信すると、届いたことをすぐに確認できます。

import smtplib
from email.mime.text import MIMEText

# SMTPサーバーの情報と認証情報を設定してください
SMTP_SERVER = "smtp.example.com"     # 例: "smtp.gmail.com"
SMTP_PORT = 587
FROM_ADDRESS = "sender@example.com"  # 例: "user@gmail.com"
TO_ADDRESS = "receiver@example.com"  # 例: 同じメールにして自分へ送信でもOK
SMTP_USER = FROM_ADDRESS            # Gmailの場合はFROM_ADDRESSと同じ
SMTP_PASS = "app_password_here"     # アプリパスワードやSMTPサーバー用のパスワード
                                    # Gmailの場合 2段階認証プロセスを有効にしてアプリパスワードを作成する
def send_alert_mail():
    """
    SMTPサーバーに接続し、メールを送信するサンプル関数。
    """
    # メール本文(複数行にわたる場合、三重クォートが便利)
    body = """\
このメールはPythonスクリプトから送信されています。
システムに異常が検出されました。

詳細:
 - CPU使用率が高い可能性があります。
 - ディスク残容量が少なくなっています。

至急、確認をお願いします。
"""
    # MIMETextオブジェクトの生成
    msg = MIMEText(body)
    msg["Subject"] = "Server Alert"
    msg["From"] = FROM_ADDRESS
    msg["To"] = TO_ADDRESS

    try:
        # SMTPサーバーへ接続
        with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as smtp:
            smtp.ehlo()          # サーバーへの挨拶
            try:
                smtp.starttls()  # TLS暗号化開始
                smtp.ehlo()      # 再度EHLOで暗号化後の状態を確立
            except smtplib.SMTPNotSupportedError:
                # サーバーがTLS非対応の場合はスキップ
                pass

            # SMTPサーバーへログイン
            smtp.login(SMTP_USER, SMTP_PASS)

            # メールを送信 (ヘッダを参照しつつ、送信元・送信先・本文を指定)
            smtp.sendmail(FROM_ADDRESS, TO_ADDRESS, msg.as_string())

        print("メールの送信が完了しました。")
    except smtplib.SMTPException as e:
        print("メール送信中にエラーが発生しました:", e)

# メイン処理
send_alert_mail()

【送信されるメールの内容】

Server Alert

xxxxxxxx@gmail.com To 自分

このメールはPythonスクリプトから送信されています。 システムに異常が検出されました。

詳細:

CPU使用率が高い可能性があります。
ディスク残容量が少なくなっています。
至急、確認をお願いします。

プログラムの解説

  • smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
    指定したSMTPサーバーとポート番号に接続します。withブロックを使うことで、自動的に接続がクローズされます。
  • smtp.starttls()
    TLS(暗号化通信)を開始し、認証情報やメール内容が平文で流れないようにします。
  • smtp.login(SMTP_USER, SMTP_PASS)
    SMTPサーバー側で認証を行い、メール送信が許可される状態にするステップです。
  • msg.as_string()
    MIMETextオブジェクトをSMTPで送るための文字列形式に変換します。ヘッダや本文など、メールの構造がすべてテキストとしてまとめられます。
  • smtplib.SMTPException
    メール送信中に起こり得る一般的な例外をキャッチするためのクラスです。サーバー接続の問題や認証エラーなど、メール送信が失敗するケースをハンドリングできます。

まとめ

 このようにPythonの標準ライブラリを活用すれば、SMTPサーバーへの接続とメール送信は非常に短いコードで実現できます。システム監視の一環として活用する場合、サーバーの状態(CPUやメモリ、ディスク情報など)を本文に含めてリアルタイムに管理者へ報告できるようにすると、障害対応がスムーズになるでしょう。さらに、複数の宛先への送信や、HTMLメールの送付、添付ファイルの送信なども拡張可能ですので、要件に合わせて機能を追加してみてください。