googleフォームを利用した静的サイトでのメール自動送信機能付きフォーム作製


　本解説は[ポートフォリオサイト](https://plum-chloride.jp/contact/index.html)を作成した際の作成法を記述したものだ。静的サイト等のサーバーレス環境でのフォームを作製する際に参考にしていただけると幸いだ。

:::note alert
自動返信機能はスパムによるフォームへの投稿により、意図的に返信メールを大量のメールアドレスに送信させられる事があります。
取り扱いの際にはスパムへの対策を十分行ってください。
また本記事を閲覧の上実装したプログラムに関して不利益が生じた場合、本記事作製者は責任を負いません。そのため実装の際には自己責任でお願いします。
:::

# Google Form Apiに関して
　この記事は[Google form api](https://developers.googleblog.com/2021/10/announcing-google-forms-api_01768004272.html)に関して発表される前のモノです。そのため本記事ではこのapiを利用していません。

# Googleフォーム作製
　contact に記載して欲しいフォーム内容と同じ内容の googleフォームを作製する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640108/6504d269-7ca9-3407-8697-20c8bac8312e.png)

　必須の項目に関しては設定すべきである。また「回答の検証」機能を用いて e-mail 等の設定を行っても良いが、本解説で扱う方法では error をハンドリング出来ないため使用しないことを推奨する。

# 自分のフォーム作製
　HTML を利用したフォームに関しては様々な書き方があるが、今回は CSS の記述しない簡単な物にする。
　Googleフォームで必須の項目に設定した項目関しては **input**タグ内に required属性を追加する。

```html:hoge.html
<form action="" id="form">
  <label for="corp">貴社名</label><br>
  <input type="text" name="" placeholder="〇〇株式会社" id="corp"><br>
  <label for="name">お名前</label><span class="mandatory">＊必須</span><br>
  <input type="text" name="" placeholder="名前" id="name" required><br>
  <label for="mail">メールアドレス</label><span class="mandatory">＊必須</span><br>
  <input type="email" name="" placeholder="〇〇@〇〇.jp" id="mail" required><br>
  <label for="tell">電話番号</label><br>
  <input type="tel" name="" placeholder="00-0000-0000" id="tell"><br>
  <label for="con">お問い合わせ内容</label><span class="mandatory">＊必須</span><br>
  <textarea type="text" name="" placeholder="内容" id="con" required></textarea><br><br>
  <input type="submit" value="送信する" id="submit">
</form>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640108/ed6ed41e-06cf-810e-8301-9898fcb36cfc.png)


# googleフォームから値の取り出し
　右上送信から googleフォームの公開アドレスを取得して、そのサイトに入る。
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640108/fd0422b6-47b9-9888-db8f-c1c33e7e67f7.png)
　
　サイト内で検証から webページの HTML を閲覧する。


**1.  form タグの action を取得する**

　CONTROL + F 等で form のタグを検索する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640108/7bbf0187-560e-38b4-7207-9dd191560c93.png)

　そのタグの属性名**action** の属性値（URL）をコピー、記述する。
![hogehoge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640108/bf767fe1-ada7-0920-ab06-df36e3c5778b.png)


**2.  input タグの name を取得する**

　CONTROL + F 等で entry の属性値を検索する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640108/08120f7f-fa09-7c5b-3c22-0d06250bf8e7.png)

　そのタグの属性名**name** の属性値（entry.数値）をコピー、記述する。
![hoge2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640108/7b15475f-1ba0-c129-30fa-5403f822a041.png)

　上から順番に Googleフォームの順番と対応しているため、順番を変えないようにする

　以上の手順より Googleフォームを利用した静的サイトのフォームは完成である。しかし現状では submit ボタンを押した際に Googleフォームのページに飛ばされる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640108/6672389c-6951-3c78-38b7-7bed4e03d756.png)

# iframeを利用したページジャンプの阻止
　本解説では強引な方法だが **iframe** を利用してページジャンプを阻止する。
　まずフォームタグに属性値target を追加する

```html
<form action="https://docs.google.com/---------" id="form" target="submitComplate">
```

　また **form**タグの外に`display: none;`の iframe を記載し、そこに submit 後のページを表示させる。

```html
<iframe name="submitComplate" srcdoc="<p>_</p>" style="display: none;"></iframe>
```

　これでページジャンプは阻止できたが、この状態だと submit を押した際に表記が変わらないためフォームを送信できているか解らない。

　そのため form を送信した際のイベントを取得して、そのイベントが発生した際に submit ボタンを消し、送信完了表示をする。

```html
<input type="submit" value="送信する" id="submit">
<span id="fin_submit" class="nonvisi">送信が完了しました</span>
```

　submitの下に送信完了表示を記載。

```html
<script>
    document.getElementById("form").addEventListener('submit', (e) => {
      document.getElementById("fin_submit").classList.remove('nonvisi');
      document.getElementById("submit").classList.add("nonvisi");
    });
</script>
<style>
  .nonvisi{
    display: none;
  }
</style>
```

　フォームが送信された際に、ボタンを消しつつ送信完了と表示するように JavaScript と CSS を組む。

　これまでをまとめると下記のコードとなる。

```html:hoge.html
  <form action="" id="form">
    <label for="corp">貴社名</label><br>
    <input type="text" name="" placeholder="〇〇株式会社" id="corp"><br>
    <label for="name">お名前</label><span class="mandatory">＊必須</span><br>
    <input type="text" name="" placeholder="名前" id="name" required><br>
    <label for="mail">メールアドレス</label><span class="mandatory">＊必須</span><br>
    <input type="email" name="" placeholder="〇〇@〇〇.jp" id="mail" required><br>
    <label for="tell">電話番号</label><br>
    <input type="tel" name="" placeholder="00-0000-0000" id="tell"><br>
    <label for="con">お問い合わせ内容</label><span class="mandatory">＊必須</span><br>
    <textarea type="text" name="" placeholder="内容" id="con" required></textarea><br><br>
    <input type="submit" value="送信する" id="submit">
    <span id="fin_submit" class="nonvisi">送信が完了しました</span>
  </form>
</body>
<script>
    document.getElementById("form").addEventListener('submit', (e) => {
      document.getElementById("fin_submit").classList.remove('nonvisi');
      document.getElementById("submit").classList.add("nonvisi");
    });
</script>
<style>
  .nonvisi{
    display: none;
  }
</style>
```

# reCAPTCHA V2

　Google の CAPTCHA 認証システムである reCAPTCHA V2 を利用して機械によるフォームの送信を防ぐ。
　要らない場合は読み飛ばして問題ない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640108/cb70f711-b707-2e76-3b4d-13200f47b34d.png)

[reCAPTCHA](https://www.google.com/recaptcha/admin/create)　ここから reCAPTCHA V2 を取得する。」

　適当にラベル名を決め、reCAPTCHA V2のチェックボックスを選択し、掲載する予定のドメインを登録する（一応検証用にローカルホストも登録しておく）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640108/6e505523-a287-2010-dd04-09ace5a2a75e.png)
　gmailを入力し、同意して送信。
![hogggge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640108/4b892a69-3ff1-65fd-cd50-ee0cf34704fa.png)
　するとサイトキーが表示されるため、上のキーのみをコピーする。
![kldjfs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640108/48a22862-1bc5-7e90-82a7-412fe48fb9c7.png)



　もとの HTML に戻り以下の記述をそれぞれコメントの箇所に記述

```html
<!-- head等スクリプトを記載しているところに -->
<script src="https://www.google.com/recaptcha/api.js" async defer></script>

<!-- head等スクリプトを記載しているところに reCAPTCHAが成功した際に実行される -->
<script>
      var myAlert = (code) =>{
        if(code !== ""){
          document.getElementById("submit").removeAttribute("disabled");
        }
      }
</script>

<!-- reCAPTCHAを記載したいところに -->
<div class="g-recaptcha" data-sitekey="サイトキー" data-callback="myAlert"></div>

<!-- 内容を変更(disabledを追加) -->
<input type="submit" value="送信する" id="submit" disabled>
````

　これでreCAPTCHAが成功した際にsubmitを押せるようになった。

<details><summary>コード全文 【クリックして展開】</summary><div>

```html:hoge.html
  <form action="" id="form">
    <label for="corp">貴社名</label><br>
    <input type="text" name="" placeholder="〇〇株式会社" id="corp"><br>
    <label for="name">お名前</label><span class="mandatory">＊必須</span><br>
    <input type="text" name="" placeholder="名前" id="name" required><br>
    <label for="mail">メールアドレス</label><span class="mandatory">＊必須</span><br>
    <input type="email" name="" placeholder="〇〇@〇〇.jp" id="mail" required><br>
    <label for="tell">電話番号</label><br>
    <input type="tel" name="" placeholder="00-0000-0000" id="tell"><br>
    <label for="con">お問い合わせ内容</label><span class="mandatory">＊必須</span><br>
    <textarea type="text" name="" placeholder="内容" id="con" required></textarea><br>
    <div class="g-recaptcha" data-sitekey="サイトキー" data-callback="myAlert"></div><br>
    <input type="submit" value="送信する" id="submit" disabled>
    <span id="fin_submit" class="nonvisi">送信が完了しました</span>
  </form>
</body>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<script>
    document.getElementById("form").addEventListener('submit', (e) => {
      document.getElementById("fin_submit").classList.remove('nonvisi');
      document.getElementById("submit").classList.add("nonvisi")
    });

    var myAlert = (code) =>{
      if(code !== ""){
        document.getElementById("submit").removeAttribute("disabled");
      }
    };
</script>
<style>
  .nonvisi{
    display: none;
  }
</style>
```
</div></details>

# メール自動返信機能
　フォームに新規投稿があった際に自動で返信する機能。この機能をつけることで「5分以内に自動返信メールが届かない場合フォームの入力が失敗していますが。お手数ですが再度入力をお願いします」と記載できる。

　フォームにスクリプトエディタを記載して実装する方法が存在するが、私の環境では動かなかったためスプレッドシートにスクリプトエディタで記載する方法をとる。
　Googleフォーム回答画面右上のスプレッドシートからスプレッドシートを新規作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640108/83f9cb9c-600f-829d-c4ab-23a0d34572a3.png)
　スプレッドシートのツールからスクリプトエディタを選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640108/bd175e3a-cecb-3224-6529-f9c0c07d3045.png)
　この際「ページが見つかりません」という表示が出る人がいると思う。その場合は現在ログインしているすべての Googleアカウントからログアウトして、このフォーム作成に利用したGoogleアカウントのみログインするとこの先の操作が可能になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640108/706ad558-0833-11d0-94c9-87fc6976e315.png)

　その後のスクリプトエディタ、コード.gsの表記を以下の様に変える

<details><summary>コード全文 【クリックして展開】</summary><div>

```js:コード.gs
function onFormSubmit(e) {
  // フォームの回答を取得
  var corp = e.namedValues['貴社名'][0];
  var name = e.namedValues['お名前'][0];
  var tell = e.namedValues['電話番号'][0];
  var email = e.namedValues['メールアドレス'][0];
  var message = e.namedValues['お問い合わせ内容'][0];
  
  // 自動返信メール件名
  var subject = 'お問い合わせいただきありがとうございました。';
      
  // 自動返信メール本文
  if(!corp){
    if(!tell){
      var body = name + '様\n' +
      '\n' +
      'この度はお問い合わせいただき、誠にありがとうございます。' +
      '\n' +
      '後日あらためてご連絡させていただきますので\n' +
      'よろしくお願い申し上げます。\n' + 
      '\n' +
      '─────────────────────────\n' +
      'ご送信内容の確認\n' +
      '─────────────────────────\n' +
      '\n' +
      '【氏名】\n' +
      name + '\n' + 
      '\n' +
      '【メールアドレス】\n' +
      email + '\n' + 
      '\n' +
      '【お問い合わせ内容】\n' +
      message+'\n'+'\n'
      + '\n※このメールはGoogleフォームからの自動送信メールです。';
    }else{
      var body = name + '様\n' +
      '\n' +
      'この度はお問い合わせいただき、誠にありがとうございます。' +
      '\n' +
      '後日あらためてご連絡させていただきますので\n' +
      'よろしくお願い申し上げます。\n' + 
      '\n' +
      '─────────────────────────\n' +
      'ご送信内容の確認\n' +
      '─────────────────────────\n' +
      '\n' +
      '【氏名】\n' +
      name + '\n' + 
      '\n' +
      '【メールアドレス】\n' +
      email + '\n' + 
      '\n' +
      '【電話番号】\n' +
      tell + '\n' + 
      '\n' +
      '【お問い合わせ内容】\n' +
      message+'\n'+'\n'
      + '\n※このメールはGoogleフォームからの自動送信メールです。';
    }
  }else{
    if(!tell){
      var body = corp +" "+name + '様\n' +
      '\n' +
      'この度はお問い合わせいただき、誠にありがとうございます。' +
      '\n' +
      '後日あらためてご連絡させていただきますので\n' +
      'よろしくお願い申し上げます。\n' + 
      '\n' +
      '─────────────────────────\n' +
      'ご送信内容の確認\n' +
      '─────────────────────────\n' +
      '\n' +
      '【氏名】\n' +
      name + '\n' + 
      '\n' +
      '【メールアドレス】\n' +
      email + '\n' + 
      '\n' +
      '【お問い合わせ内容】\n' +
      message+'\n'+'\n'
      + '\n※このメールはGoogleフォームからの自動送信メールです。';
    }else{
      var body = corp +" "+name + '様\n' +
      '\n' +
      'この度はお問い合わせいただき、誠にありがとうございます。' +
      '\n' +
      '後日あらためてご連絡させていただきますので\n' +
      'よろしくお願い申し上げます。\n' + 
      '\n' +
      '─────────────────────────\n' +
      'ご送信内容の確認\n' +
      '─────────────────────────\n' +
      '\n' +
      '【氏名】\n' +
      name + '\n' + 
      '\n' +
      '【メールアドレス】\n' +
      email + '\n' + 
      '\n' +
      '【電話番号】\n' +
      tell + '\n' + 
      '\n' +
      '【お問い合わせ内容】\n' +
      message+'\n'+'\n'
      + '\n※このメールはGoogleフォームからの自動送信メールです。';
    }
  }
  
  // メール送信
  MailApp.sendEmail({
    to: email,
    subject: subject,
    body: body
  });
}
```

　記述不要なフォーム項目に関して条件分岐させて、値がある場合はその結果を出力するといったことをしている。変数を賢く使えば短くなるが、面倒くさいため実行していない。

</div></details>

　その後コードを保存して関数が onFormSubmit になっていることを確認する。
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640108/eba3cd0b-3630-bfbd-0059-9ef131d1a9f6.png)

　左のトリガーを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640108/69c216a5-8734-1b2c-62a4-fe318c7fc506.png)

　トリガーを追加から追加する。`イベントの種類を選択`をフォーム送信時に変更し保存する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640108/97b6ba46-cf07-f35e-af82-11b81876fa21.png)

　保存の際にこのようなポップアップが出るが、左下詳細をクリックし安全ではないサイトに進み、要求されたアプリケーションを承認する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640108/2c9cc8ba-2425-2d23-5070-fde8c7427c42.png)


　以上でメールの自動返信機能の搭載は完了だ。

# まとめ

　大分長くなったが以上で「googleフォームを利用した静的サイトでのメール自動送信機能付きフォーム」の作製が完了した。ポートフォリオ等のフォームを搭載したいときに役立てて欲しい。

# 参考文献

- Googleフォームを利用した静的サイトでのフォーム　https://qiita.com/samuraibrass/items/d6afda6bd8f3306cee4f
- reCAPTCHA　https://www.webdesignleaves.com/pr/plugins/google_recaptcha.php
- メール自動返信機能　https://valmore.work/auto-response-from-google-form/