当サイトには Googleフォームを利用したフォームメールを設置していますが、最近スパムメールが多くなってきましたので何か対策が必要になってきました。
- はてなブログに Googleフォームを設置
- Google reCaptcha
- フォームに reCaptcha ウィジェットをレンダリング
- クライアントサイトでバリデーション
- サーバー側(Google Apps Script)
01はてなブログに Googleフォームを設置
Googleフォームのテーマではなく、はてなブログで使用しているテーマ内にフォームを設置する方法の記事です。
- Google Form を自前のフォームで実装(はてなブログで完全カスタマイズ可)
- Google Form ブログ実装のためのバリデーションを考える
- Google Form に自動返信スクリプト実装 Google Apps Script
- はてなブログのお問い合わせフォームに hidden 型追加
02Google reCaptcha
「私はロボットではありません」にチェックするように促されるアレです。
reCAPTCHA: Easy on Humans, Hard on Bots
上のは v2 ですが、現在は v3 になっているようです。v3 がどういうものかわかっていませんので v2 でやってみます。
reCaptcha の考え方は、事前に発行されたサイトキーを使ったトークンをサーバーに送り、サーバーでは事前に発行されたシークレットキーを使ってトークンをチェックするということになります。
ですので、サーバー側の実装が必須になり、はてななどブログサービスでは実質的には使うことができません。ただ、クライアント(ブログ)側でトークンが発行されたかどうか、つまりボットかどうかをチェックすることだけは可能です。
効果があるかどうかはわかりませんが、一度やってみましょう。
まず、サイトキーとシークレットキーを取得します。
reCAPTCHA: Easy on Humans, Hard on Bots に行き、右上の+アイコンをクリックしサイトを登録します。
03フォームに reCaptcha ウィジェットをレンダリング
reCaptcha のサイトにドキュメントがあります。
reCAPTCHA v2 | Google Developers
<html> <head> <title>reCAPTCHA demo: Simple page</title> <script src="https://www.google.com/recaptcha/api.js" async defer></script> </head> <body> <form action="?" method="POST"> <div class="g-recaptcha" data-sitekey="your_site_key"></div> <br/> <input type="submit" value="Submit"> </form> </body> </html>
https://www.google.com/recaptcha/api.js
を読み込み、フォーム内に <div class="g-recaptcha" data-sitekey="your_site_key"></div>
の htmlコードを入れるだけです。ただし、はてなの場合はデフォルトで api.js
が読み込まれていますので htmlコードを挿入すればそれだけで reCaptcha ウィジェットがレンダリングされます。
04クライアントサイトでバリデーション
reCaptcha ウィジェットが作成したトークンはクライアント側でも grecaptcha.getResponse()
で取得することができます。この値は reCaptcha の認証を通っていない場合は空になりますので、送信ボタンをクリックした時にこの値をチェックすればいいことになります。
reCaptcha を導入した Googleフォームのコードはこうなります。もちろん、name属性、action属性、サイトキーはご自身のものに差し替えてください。
<script> function showThxMessage(){ var email = document.myForm.elements['entry.94116415'].value; if(email !== ''){ var thxDiv = document.getElementById('thxMessage'); thxDiv.getElementsByTagName('span')[0].innerHTML = email; document.myForm.reset(); document.getElementById('formWrapper').style.display = 'none'; thxDiv.style.display = 'block'; } } function checkRecaptcha() { var response = grecaptcha.getResponse(); if(response.length == 0) { //reCaptcha 未認証 document.getElementById('recaptcha-error').innerHTML = "reCaptchaにチェックを入れてください"; return false; } else { //reCaptch 認証済み document.myForm.submit(); } } </script> <div id="formWrapper">、 <form action="https://docs.google.com/forms/d/e/1FAIpQLSf34P577G_wSnWra6sfde0xGEirpor-Opk_EsDs4Z5CSYa6ng/formResponse" method="post" name="myForm" target="dummyIframe" onsubmit="return checkRecaptcha();"> <label>メールアドレス</label> <p style="font-size:.8em;color:#999;">※配信可能なメールアドレスを入力してください. 自動返信メールがエラーとなる場合はサイト管理人へも配信されません.</p> <input type="email" name="entry.94116415" value="" required pattern="^(([-\w\d]+)(\.[-\w\d]+)*@([-\w\d]+)(\.[-\w\d]+)*(\.([a-zA-Z]{2,5}|[\d]{1,3})){1,2})quot; /> <label>お問い合わせ内容</label> <textarea required name="entry.1106124689"></textarea> <div class="g-recaptcha" data-sitekey="6LcZdtgUAAAAAIAhLVgmFuc97NQfRmrsILG9daWw"></div> <div style="margin-top:10px; color:red;" id="recaptcha-error"></div> <input style="margin-top:10px;" type="submit" value="送信"> <iframe name="dummyIframe" style="display:none;" onload="showThxMessage();"></iframe> </form> </div> <div id="thxMessage" style="display:none;"> お問い合わせありがとうございました。<br /> <span style="color:red;"></span> 様あてのメールでお答えいたします。<br /><br /> また自動返信メールをお送りいたしましたのでご確認ください。<br /> メールが届いていない場合はお答えメールも届きませんので、迷惑メールとなっていないかなどご確認ください。<br /><br /> --<br /> IMUZA.com </div>
05サーバー側(Google Apps Script)
サーバー側での認証は次の記事にあります。