Raspberry Pi で メール送信(添付ファイル指定可能版)

前回に引き続き、Rapsberry Pi にてPythonを使用してコーディング、メールを送信します。

今回は、添付ファイルの指定有無を選択できます。

オプショナルな引数に添付ファイル名を指定すれば添付できます。

これと人感センサー、カメラを組み合わせれば、

「人が通ったら写真を撮り、それを添付したメールを送信」

する、簡易的な監視カメラが作れます。

写真ではなく、動画でもできるでしょうが、ファイルサイズが大きいと制限がありますのでお気をつけて。

 

Pythonプログラミング

# -*- coding: utf-8 -*-
# 日本語コメントをエラーとしないように、UTF-8で保存

# 使用するライブラリのインポート
import smtplib
from email import encoders
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.utils import formatdate
from email.mime.base import MIMEBase

# 定数の定義
SELF_MAIL_ADDRESS = '****@*****'      # 自分のメールアドレス
SELF_MAIL_PASSWORD = '*****'          # 自分のメールサーバーへのパスワード
SELF_SMTP_SERVER = '******'           # 自分のメールアドレスのSMTPサーバー名
SELF_SMTP_PORT = 587                  # SMTPサーバーのポート番号

def create_mail(mail_subject, mail_body, mail_from, mail_to, attach_filename = None):
    """
    送信メールを生成、返却
    """

    # 添付ファイル名の指定有無により切り分け
    if attach_filename == None:
        # 添付ファイルを指定していない場合
        mail_message = MIMEText(mail_body)
    else:
        # 添付ファイルを指定した場合
        mail_message = MIMEMultipart()

        # 本文(添付ファイルより先に指定する必要がある)
        mail_message.attach(MIMEText(mail_body, "plain"))

        # 添付ファイルを読み込んで添付
        try:
            # 添付ファイル名が指定されている場合、ファイルを読み込む
            with open(attach_filename, 'rb') as attach_File:
                att = MIMEBase('application', 'octet-stream')
                att.set_payload(attach_File.read())
        except Exception as e:
            # 指定された添付ファイルが読み込めなかった場合は、ログを吐いて終了
            print(f'Error:{e}')
            exit(0)        

        # 添付ファイルをbase64エンコードして添付
        encoders.encode_base64(att)
        att.add_header('Content-Disposition', f'attachment; filename={attach_filename}')
        mail_message.attach(att)

    # 送信メールを編集
    mail_message['Subject'] = mail_subject              # 件名
    mail_message['From'] = mail_from                    # 送信元メールアドレス
    mail_message['To'] = mail_to                        # 送信先メールアドレス
    mail_message['Date'] = formatdate(localtime=True)   # 送信時間。OSのタイムゾーン依存
           
    # デバッグ用に送信メールの内容を出力
    print(mail_message)

    return mail_message

def send_mail(mail_message):
    """
    メールを送信する
    """

    try:
        smtp = smtplib.SMTP(SELF_SMTP_SERVER, SELF_SMTP_PORT)
        smtp.ehlo()
        smtp.starttls()
        smtp.ehlo()
        smtp.login(SELF_MAIL_ADDRESS, SELF_MAIL_PASSWORD)
    
        smtp.sendmail(SELF_MAIL_ADDRESS, mail_to, mail_message.as_string())
    except Exception as e:
        print(f'Error:{e}')
    finally:
        smtp.quit()


# 継承した場合など、実行されないようにする(現状、意味は特にない)
if __name__ == '__main__':
    # メールの内容
    # 送信先メールアドレス
    mail_to = '***@***'
    # メールの件名
    mail_subject = '件名テスト'
    # メールの本文
    mail_body = '本文テスト'
    # 添付ファイル名
    mail_att = '***.jpg'

    # 送信メールを作成する(添付ファイル付き)
    mail_message = create_mail(mail_subject, mail_body, SELF_MAIL_ADDRESS, mail_to, mail_att)
    #  送信メールを作成する(添付ファイルなし)
    # mail_message = create_mail(mail_subject, mail_body, SELF_MAIL_ADDRESS, mail_to)

    # メールを送信する
    send_mail(mail_message)