定時にメールを自動送信するPythonスクリプト

プログラミング

Pythonによる定時メール自動送信スクリプト

はじめに

本ドキュメントでは、Pythonを使用して定時にメールを自動送信するスクリプトの作成方法について、詳細に解説します。このスクリプトは、日々の業務報告、定期的な通知、リマインダーなど、様々な場面で活用できます。Pythonの標準ライブラリを活用し、外部ライブラリの導入なしで実現できるため、環境構築も容易です。

スクリプトの概要

このスクリプトは、指定した時間に、指定した宛先に、指定した件名と本文のメールを送信します。メール送信には、Pythonのsmtplib(SMTPクライアントモジュール)とemail.mime.text(MIMEテキストメッセージ作成モジュール)を使用します。スケジューリング機能は、Pythonのscheduleライブラリ(またはAPSchedulerなどのより高機能なライブラリ)を利用します。ここでは、シンプルさを重視し、scheduleライブラリを使用します。

必要なライブラリ

  • smtplib: SMTPプロトコルを使用してメールを送信するための標準ライブラリ。
  • email.mime.text: テキスト形式のメールメッセージを作成するための標準ライブラリ。
  • datetime: 日付と時刻を扱うための標準ライブラリ。
  • schedule: ジョブを定期的に実行するための外部ライブラリ。pipでインストールする必要があります(pip install schedule)。

スクリプト作成手順

1. 必要なモジュールのインポート

まず、スクリプトの冒頭で必要なモジュールをインポートします。

import smtplib
from email.mime.text import MIMEText
import datetime
import schedule
import time

2. メール送信関数の定義

メール送信処理をまとめた関数を作成します。この関数は、送信元メールアドレス、送信先メールアドレス、件名、本文を引数として受け取ります。

def send_email(sender_email, sender_password, receiver_email, subject, body):
    try:
        # メールの作成
        msg = MIMEText(body, 'plain', 'utf-8') # 本文をUTF-8でエンコード
        msg['Subject'] = subject
        msg['From'] = sender_email
        msg['To'] = receiver_email

        # SMTPサーバーへの接続
        # Gmailを使用する場合の例。他のメールプロバイダの場合は、サーバーアドレスとポート番号を変更してください。
        smtp_server = "smtp.gmail.com"
        smtp_port = 587 # SSL/TLSを使用する場合は465の場合もあります

        server = smtplib.SMTP(smtp_server, smtp_port)
        server.starttls()  # TLSで暗号化
        server.login(sender_email, sender_password)

        # メール送信
        server.sendmail(sender_email, receiver_email, msg.as_string())
        print(f"メールが正常に送信されました: {receiver_email}")

    except Exception as e:
        print(f"メール送信中にエラーが発生しました: {e}")
    finally:
        if 'server' in locals() and server:
            server.quit()

注記:

  • sender_emailsender_passwordreceiver_emailsubjectbodyは、実際の内容に置き換える必要があります。
  • Gmailを使用する場合、「安全性の低いアプリのアクセス」を有効にするか、「アプリパスワード」を発行して使用する必要があります。セキュリティ上の理由から、アプリパスワードの使用が推奨されます。
  • SMTPサーバーアドレスとポート番号は、利用するメールプロバイダによって異なります。一般的なプロバイダの設定を確認してください。

3. 定時実行の設定

scheduleライブラリを使用して、メール送信関数を定期的に実行するように設定します。

def job():
    # ここでメール送信に必要な情報を定義または取得します
    sender_email = "your_email@example.com" # 送信元メールアドレス
    sender_password = "your_app_password" # 送信元メールパスワード(アプリパスワード推奨)
    receiver_email = "recipient_email@example.com" # 送信先メールアドレス
    subject = "定時メール送信テスト"
    body = f"これは自動送信されたメールです。n送信日時: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"

    send_email(sender_email, sender_password, receiver_email, subject, body)

# 例: 毎日午前9時に実行
schedule.every().day.at("09:00").do(job)

# 例: 毎週月曜日の午後3時に実行
# schedule.every().monday.at("15:00").do(job)

# 例: 毎時間実行
# schedule.every().hour.do(job)

# 例: 5分ごとに実行
# schedule.every(5).minutes.do(job)

print("スケジューラを開始しました。Ctrl+Cで終了します。")

# スケジューラを実行し続けるループ
while True:
    schedule.run_pending()
    time.sleep(1) # CPU負荷を軽減するために1秒待機

schedule.every().day.at("09:00").do(job) の部分で、実行頻度と時刻を指定します。job() 関数は、メール送信に必要な全ての情報(送信元、宛先、件名、本文)を準備し、send_email 関数を呼び出します。

スクリプトの実行と管理

1. 実行方法

作成したPythonスクリプト(例: send_scheduled_email.py)を、ターミナルやコマンドプロンプトから以下のコマンドで実行します。

python send_scheduled_email.py

スクリプトはバックグラウンドで実行され、指定された時間にメールを送信します。スクリプトを終了するには、ターミナルで Ctrl + C を押します。

2. 永続的な実行

サーバーなどでスクリプトを常時実行させたい場合は、nohup コマンドや systemd サービス、screentmux などのターミナルマルチプレクサを使用することを検討してください。

  • nohup コマンド: ターミナルを閉じてもスクリプトが実行され続けます。
  • nohup python send_scheduled_email.py &
        
  • systemd: Linuxシステムでサービスとして管理する場合に最適です。スクリプトをサービス化することで、システムの起動時に自動実行させたり、異常終了時に自動再起動させたりできます。
  • screen/tmux: 一時的にセッションを維持したい場合に便利です。

3. エラーハンドリングとロギング

実際の運用では、メール送信の失敗やスクリプトの異常終了に備えて、エラーハンドリングとロギングを強化することが重要です。

  • エラーハンドリング: try-except ブロックを適切に使用し、例外が発生した場合に何が起こったのかを把握できるようにします。
  • ロギング: Pythonのloggingモジュールを使用して、メール送信の成功・失敗、エラーメッセージなどをファイルに記録することで、後から状況を分析しやすくなります。
# loggingモジュールの追加例
import logging

logging.basicConfig(filename='email_log.txt', level=logging.INFO,
                    format='%(asctime)s - %(levelname)s - %(message)s')

def send_email(...):
    try:
        ...
        logging.info(f"メールが正常に送信されました: {receiver_email}")
    except Exception as e:
        logging.error(f"メール送信中にエラーが発生しました: {e}", exc_info=True) # exc_info=Trueでトレースバックも記録
    finally:
        ...

def job():
    logging.info("ジョブが開始されました。")
    # ... (メール送信処理) ...
    logging.info("ジョブが終了しました。")

応用・発展

1. 複数宛先への送信

receiver_email をリスト形式にし、ループ処理で各宛先に送信することも可能です。

receiver_emails = ["recipient1@example.com", "recipient2@example.com"]
for receiver in receiver_emails:
    send_email(sender_email, sender_password, receiver, subject, body)

2. HTML形式のメール送信

MIMEText の第一引数にHTMLコードを記述し、第二引数を `’html’` にすることで、HTML形式のメールを送信できます。

msg = MIMEText(html_body, 'html', 'utf-8')

3. ファイル添付

email.mime.multipart.MIMEMultipartemail.mime.base.MIMEBase を使用することで、ファイル添付機能を追加できます。これはより高度な処理になります。

4. 外部設定ファイルの使用

メールアドレスやパスワード、送信時刻などの設定情報を、スクリプト内に直接記述するのではなく、外部の.iniファイルや.jsonファイル、環境変数などから読み込むようにすると、設定の変更や管理が容易になります。

まとめ

本スクリプトは、Pythonの標準ライブラリとscheduleライブラリを組み合わせることで、定時メール自動送信を実現する基本的な構成を示しました。このスクリプトをベースに、必要に応じてエラーハンドリングの強化、ロギング機能の追加、設定の外部化などを行うことで、より堅牢で管理しやすいシステムを構築できます。業務効率化や情報伝達の自動化に、ぜひご活用ください。