HTMLでPythonを呼び出しメールを送信する

# PythonをHTMLで実行
HTMLでPythonを呼び出しメールを送信できるようにしたい、というのが今回の目的です。もっと簡単な方法やいい方法があるというのは受け付けません。
というわけで、古の魔術であるPythonでCGIプログラミングの詠唱をしましょう。

# 実施したい内容
HTMLのお問い合わせフォームから名前やメールアドレスを記入させます。送信を押すとその内容がPythonに送られ、Pythonから自分宛にメールが送信されてくるというのが実施したい内容です。
■HTMLの内容
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340199/3069ac0a-dc6c-b362-a55c-f43be129b502.png">
■受信したメール
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340199/b1b11d7e-ebb2-7e29-fe37-9e6da46feba1.png">



# 実行環境
CentOS Stream 8にApachをインストールしています。
ディレクトリ構成はデフォルトです。
www
　L cgi-bin
　　L smtp.py
　L html
　　L contact.html

# メールについて
Gmailは「安全性の低いアプリのアクセス」を許可にしないとメールの送信が出来ない仕様になっているのですが、許可できないように最近仕様変更されたらしく、今回はyahooを利用しました。

YahooのWEBメールを開き設定の項目より「Yahoo! JAPAN公式サービス以外からのアクセスも有効にする」を選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340199/d491d9a3-335d-d54c-510d-5557482c559c.png)

yahooはパスワードレスで認証ができますが、パスワードレスだとsmtpでパスワード認証させることができないのでパスワードを設定してください。

古いWEBサイトだとyahooのSMTPのポートが記載されていることがあります。最新のを参照してください。
https://whatsnewmail.yahoo.co.jp/yahoo/20200824a.html

# コード内容
htmlのformタグにてPythonのスクリプトを呼び出してきています。cssのコードは記載しません。またhtmlの内容も今回の主な内容ではないので参考までの記載になります。コードはほぼパクリなので、元を参照してください。
https://yuyauver98.me/contactform-coding-capok/
https://python-work.com/mail-auto/


```python:smtp.py
#!/usr/bin/python3
import smtplib
from email.mime.text import MIMEText
import cgi
 
form = cgi.FieldStorage()
# PRG2: メール情報の設定
name = form.getvalue("name")
email = form.getvalue("email")
tell = form.getvalue("tell")
text = form.getvalue("text")

from_email ='送信元メールアドレス' 
to_email = '送信先メールアドレス' 
cc_mail = 'CCに入れるメールアドレス'
mail_title = '【お問い合わせ】{}様からのお問い合わせ'.format(name)
message = ('''
　ご担当者
　
　お問い合わせフォームからの問い合わせです。
　以下内容について転送しますのでご対応ください。
　　
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
【問い合わせ者】
　　{}
　
【Email】
　　{}
　
【tell】
　　{}
　
【お問い合わせ内容】
　　{}
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
''').format(name,email,tell,text)

# PRG3: MIMEオブジェクトでメールを作成
msg = MIMEText(message, 'plain')
msg['Subject'] = mail_title
msg['To'] = to_email
msg['From'] = from_email
msg['cc'] = cc_mail
 
# PRG4: サーバを指定してメールを送信する
smtp_host = 'smtp.mail.yahoo.co.jp'
smtp_port = '465'
smtp_password = 'パスワードを記述'
 
server = smtplib.SMTP_SSL(smtp_host, smtp_port)
server.login(from_email, smtp_password)
server.send_message(msg)
server.quit()

print("Content-Type: text/html")
print()
print("""
<html>
<head>
  <title>送信完了</title>
</head>
<body>
  <p>送信しました。</p>
  <form>
    <input type="button" value="戻る" onClick="history.back()">
  </form>
</body>
</html>
""")
```

```html:contact.html
<!DOCTYPE html>
<html>
  <head>
    <title>My Website</title>
    <link rel="stylesheet" href="style.css">
    <link rel="stylesheet" href="contactstyle.css">
    <link rel="icon" href="./pict/uniicon.jpg" type="image/x-icon">
  </head>
  <body>
    <div class="contact-content">
    <form method="post" action="/cgi-bin/smtp.py">    
    <div class="Form">
      <h4 class="contact-ttl">お問い合わせ(工事中)
      </h4>
      <div class="Form-Item">
        <p class="Form-Item-Label"><span class="Form-Item-Label-Required">必須</span>お名前</p>
        <input type="text" name="name" class="Form-Item-Input" placeholder="例）田中　太郎">
      </div>
      <div class="Form-Item">
        <p class="Form-Item-Label"><span class="Form-Item-Label-Required">必須</span>電話番号</p>
        <input type="text" name="tell"  class="Form-Item-Input" placeholder="例）000-0000-0000">
      </div>
      <div class="Form-Item">
        <p class="Form-Item-Label"><span class="Form-Item-Label-Required">必須</span>メールアドレス</p>
        <input type="email" name="email" class="Form-Item-Input" placeholder="例）unikura@gmail.com">
      </div>
      <div class="Form-Item">
        <p class="Form-Item-Label isMsg"><span class="Form-Item-Label-Required">必須</span>お問い合わせ内容</p>
        <textarea class="Form-Item-Textarea"  name="text" ></textarea>
      </div>
      <input type="submit" class="Form-Btn" value="送信する">
    </div>
    </form>

  </div>
  </body>
</html>
```

# 実行してみる
私はそのままでも動くと思っていたのですが、エラーが出て結論動かないです。実施しないと行けない作業がいくつかあったのでまとめておきます。
・httpd.confの書き換え
・パーミッションの許可
・文字コードの確認
これらを実施しないと下記エラーが出ます。私はこれでまるまる２日溶かしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340199/379655a6-4764-4901-58af-790a45c00582.png)

### httpd.confの書き換え
/etc/httpd/conf/httpd.confを下記のように書き換えてください。

```conf:httpd.conf
<Directory "/var/www/cgi-bin">
    AllowOverride None
    Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
    Require all granted
</Directory>
AddHandler cgi-script .py
```
### パーミッションの許可
pyrhonのスクリプトに実行権限を与えます。

```terminal:
$chmod 755 smtp.py
```
### 文字コードの確認
sudo tail -f /var/log/httpd/error_logでログを見てみると、一生パスが正しくないですというエラーが出続けて、いやあってるんだがというのを繰り返していました。そしてたどり着いた無人島でこのブログを発見。
https://zenn.dev/zgw426/articles/63c9116df599a458af91

自分のエディタを見てみると確かに「CRLF」になっていた。右下の「CRLF」をクリックして、「LF」におしたところ無事に実行できるようになりました。

文字コードに関しては普通にバリデーションエラーとかでマジではじいてくれ！！！！
# おわりに
無事に自分宛にメールを送ることが出来ました。ちょびっと気になっているのはこのソースコードだと送信を連打しまくることでメールのDOS攻撃ができるので、セキュリティ的によろしくないと思っています。今後の課題ですね。

また、上記内容実施中にエラーを相談した友達にはフレームワークって知ってる？って言われました。勉強がてら古の魔法を使ってみたかっただけです。許してほしい。
次ステップでDjangoを触ってみようと思います。