【Streamlit v1.46.1】お問い合わせ機能の追加とMailHogで受信確認

前回の記事「Streamlit v1.46.1で簡易的なログイン機能を実装」に、Pythonの標準ライブラリであるsmptlibを使ってお問い合わせ機能を追加しましたのでそのメモ書きです。メール受信動作にはMailHogを使用。MailHogは開発・テスト向けのSMTPサーバーで簡単にメール送信/受信動作が確認できて、とても便利です。

MailHogの準備

Dockerを使うのが最も簡単です。Docker用のフォルダを作り、そのフォルダに下記『docker-compose.yml』を作成します。そのフォルダでsudo docker compose up -d を実行し起動してください。

docker-compose.yml

services:
  mailhog:
    image: mailhog/mailhog:latest 
    restart: always
    container_name: mail-hog
    ports:
      - 1026:1025  # smtp
      - 8026:8025  # web ui

MailHogの初期起動画面

お問い合わせページ追加

Pythonの標準ライブラリであるsmptlibを使って、MailHogにメール送信します。

また、ユーザーが入力するメールアドレス検証用にemail-validatorをインストール(pip install email-validator)しておいてください。

Streamlitのapp.py抜粋

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# ↓pip install email-validator
from email_validator import validate_email, EmailNotValidError

# メールアドレスの検証
def   is_valid_email(email):
    try:
        validate_email(email, check_deliverability=False)
        return True
    except EmailNotValidError as e:
        return False

# お問い合わせ関数
def inquiry():
    st.header('お問い合わせ')
    with st.form(key='form-inquiry',clear_on_submit=True):
        from_name = st.text_input('お名前', placeholder="氏名をご記入")
        from_address = st.text_input('メールアドレス', placeholder="メールアドレス記入")
        body = st.text_area("お問い合わせ内容", placeholder="自由にご記入ください")
        subject = "お問い合わせの件"
        submit_button = st.form_submit_button(label='送信')
    
        if submit_button:
            # 検証
            if from_name == "":
                st.markdown("<span style='color:red;'>お名前をご記入ください</span>", unsafe_allow_html=True) 
            elif from_address == "":
                st.markdown("<span style='color:red;'>メールアドレスをご記入ください</span>", unsafe_allow_html=True) 
            elif not is_valid_email(from_address):
                st.markdown("<span style='color:red;'>" f"{from_address} は無効なメールアドレスです。"
                "</span>", unsafe_allow_html=True) 
            elif body == "":
                st.markdown("<span style='color:red;'>お問い合わせ内容をご記入ください</span>", unsafe_allow_html=True) 

            else:
                # メール構築
                msg = MIMEMultipart()  # クラスインスタンス
                msg["From"] = from_address
                msg["To"] = "info.sample.com"
                msg["Subject"] = subject
                msg.attach(MIMEText(body, "plain"))  # MIMEオブジェクトを生成

                # MailHogのSMTPサーバーに送信
                smtp = smtplib.SMTP("localhost", 1026)  # ← docker-compose.ymlを参照
                smtp.send_message(msg)
                smtp.quit()  # smtpセッションを切る

                # 後処理
                st.markdown("<span style='color:blue;'>送信ありがとうございました。</span>", unsafe_allow_html=True) 
# メイン画面の設計
if st.session_state["page"] == "dashboard":
    # st.header('ダッシュボード')
    # 画面遷移
    if st.session_state["mypage"] == "Home":
        Home()
    elif st.session_state["mypage"] == "お知らせ":
        info()
    elif st.session_state["mypage"] == "お問い合わせ":
        inquiry()

因みに、SMTPサーバーにMailHogでなく、Gmailに変更すると外部にメール送信できました。変更箇所を参考までに載せておきます。

SMTPサーバーの設定箇所

MailHogの場合

 # メール構築
msg = MIMEMultipart()  # クラスインスタンス
msg["From"] = from_address
# ↓架空のメール送信先
msg["To"] = "info.sample.com"
msg["Subject"] = subject
# ↓MIMEオブジェクトを生成 
msg.attach(MIMEText(body, "plain"))  


smtp = smtplib.SMTP("localhost", 1026)


 smtp.send_message(msg)
 smtp.quit()  # smtpセッションを切る

Gmailの場合

# メール構築
msg = MIMEMultipart()  # クラスインスタンス
msg["From"] = from_address
# ↓Googleの場合
msg["To"] = "実際の送信先@gmail.com" 
msg["Subject"] = subject
# ↓MIMEオブジェクトを生成 
msg.attach(MIMEText(body, "plain"))  

app_pasword= 'アプリパスワード'
smtp = smtplib.SMTP("smtp.gmail.com", 587)
smtp.starttls()
smtp.login("*****@gmail.com", app_pasword)
smtp.send_message(msg)
smtp.quit() 

動作確認

このような動作になります。

以上です。😀

Follow me!