HTML手打ちのWebサイト(!)に、
手作りPHPのお問い合わせフォーム(!)を載っけた状態で
何年も使っていたんだけど
Recaptcha v2ではスパムが防ぎきれておらず、
Recaptcha v3に変えてみたら、挙動が不安定になってしまった。
そこで手作りPHPフォームを卒業することにしたのだが、
フォーム乗り換え先の第一候補であるGoogleフォームは安定性に優れているけど、
そのまま埋め込むと、見た目がダサい。
Googleフォームの仕組みだけを使って、見た目は自作フォームのままに出来たらな…
そんな都合の良いやり方が、ありました。
目次
自作HTMLフォームをGoogleフォームで動かす
Googleフォームの埋め込み方法2つ!サンプルも紹介 | formLab
↑この記事の「自作のフォームと連携してデザインを変える方法」を参考に。
- HTMLフォームを作成
- それと同じ項目を持つGoogleフォームを作成
- フォーム編集画面の「送信」ボタンからGoogleフォームの共有用リンクを取得し、そのURLのページを表示
- Chromeのデベロッパーツールでコードを検索し、form action=”XXXX/formResponse“ の"〜"内をコピーする
- 自作フォームの form action="〜" にペーストする
- 再びGoogleフォームのコードをデベロッパーツールで検索、name=”entry.数字“ が複数並んでいる箇所を見つける
- 上から順にコピーして、自作フォームの input name="〜" やtextarea name="〜"にペーストしていく
- 自作フォームの見た目をCSSで整えて、完成
この段階では、こういう感じ
<form id="mailform" role="form" action="https://docs.google〜〜〜〜/formResponse" method="post">
<div class="form-group">
<label>お名前 Your name</label>
<input type="text" class="form-control" placeholder="Your name" name="entry.〜数字1〜" required>
<label>メールアドレス Email</label>
<input type="email" class="form-control" placeholder="Email" name="entry.〜数字2〜" required>
<label>メッセージ Message</label>
<textarea class="form-control" rows="8" name="entry.〜数字3〜" required></textarea>
</div>
<input type="submit" value="送信">
</form>
メール通知を良い感じにする
Googleフォームは、入力された時にメールで通知する機能はあるものの
その通知というのが「フォームに回答がありました」というだけで、
回答の中身をメール本文に載せてくれる機能は無い。
なので、Google Apps Scriptを使う。
参考:
Google フォームの回答送信を通知するいろんな方法|Teeda
ASCII.jp:Googleフォームで自動返信システムをサクッとつくる (3/4)
- まず、フォームの回答をスプレッドシートで表示させるよう設定する
- スプレッドシートの画面で、拡張機能 > Apps Script
- 以下のような感じでScriptを書き、保存
function onFormSubmit(e) {
let TimeStamp = e.namedValues["タイムスタンプ"][0];
let YourName = e.namedValues["お名前 Your Name"][0];
let Email = e.namedValues["メールアドレス Email"][0];
let Message = e.namedValues["メッセージ Message"][0];
let Subject ="【Webサイトからのお問い合わせ】" + YourName;
var options =
{
replyTo:Email,
name:YourName
}
let Body = TimeStamp + "\n" +
"From: " + YourName + "\n" +
"Email: " + Email + "\n" +
"Message: " + "\n" + Message + "\n" ;
GmailApp.sendEmail("〜〜自分のメールアドレス〜〜", Subject, Body, options);
}
※「お名前 Your Name」とか「メールアドレス Email」とかは、スプレッドシートの見出し行に表示されている文字列をコピペする。
※「〜〜自分のメールアドレス〜〜」のところに、自分のメールアドレス(通知の宛先)を入れる。
そしてトリガーの設定を「フォーム送信時」に設定するが、
ポップアップで「安全ではありません」みたいなやつが出て、先に進めなくなる場合がある。
そうなったら、小さい文字の「安全ではないサイトにアクセスする」みたいな選択肢を選んで進んでいく。
参考:
GAS実行時に「このアプリはGoogleで確認されていません」と出る原因と対処法 - bestcloud
これで、フォームへの入力内容が無事にメールで通知されるようになった。
送信完了画面をGoogleフォームから別のページに変更する
送信ボタンを押すと、
Googleフォームの「回答が記録されました。」のページに飛んでしまうので
せっかく隠していたGoogleフォーム感が丸出しになってしまう。
それでは残念すぎるので、送信後の遷移先を無理やり設定する。
参考:
無料で使えるGoogleフォームでお問合わせフォームを設置(設定方法とメリット) | 32Web(サニウェブ)
上記の参考記事では index.html に戻る仕様になっているが、
なんか上手くいかなかった(戻ってからもフォームにフォーカスがされたままで「必須項目を入力してください!」みたいな注意が出てしまってダサかった)ので、
thanks.html を新たに作成し、そちらに移るようにした。
indexに戻るより、そっち方がわかりやすくていい気もする。
formタグを
<form id="mailform" role="form" action="https://docs.google.com/forms/〜〜〜〜/formResponse" method="post" target="hidden_iframe" onsubmit="submitted=true;">
という感じにして、
form閉じタグの直後に
<script type="text/javascript">var submitted = false;</script>
<iframe name="hidden_iframe" id="hidden_iframe" style="display:none;" onload="if(submitted){window.location='https://〜〜/thanks.html';}"></iframe>
というものを付け加える。
あとは thanks.html にお礼と「ホームに戻る」ボタンなどを設置して、
無事すべてが良い感じになった。
thanksページに飛ばす参考:
Google FormをHTML/CSSでデザインしたフォームで運用する方法
追記:Google reCAPTCHA v3をつける
上記のやり方だと、
迷惑メール(スパム)は普通に来た。
とはいえ2~3日に1通とかなので、無視かな…と思っていたが、
やっぱり気になるので、がんばって recaptcha v3を実装することにした。
めっちゃ参考:
Googleフォームをカスタマイズ+reCAPTCHAv3導入 | BLOG | フロントエンド・コーディングの受託/請負制作専門フリーランス JWS
ちょっと参考:
Google フォームを reCaptcha 付でブログに埋め込む – IMUZA.com
1. まず、Googleフォームの質問項目に「recaptcha」という項目を追加する
recaptcha って綴りが覚えられなくて、何度も間違えた。
気をつけよう、ではなくコピペしよう。
入力欄の種類は普通の短文テキストでOK。
2. HTMLの送信ボタンの後ろにrecaptcha用の input を追加
<input
id="recap"
name="entry.0000000"
type="hidden"
value=""
data-sitekey="yyyyyyyyyyyyyyyyyyyyyy"
/>
name="entry.0000000" ← 他の項目と同じようにGoogleフォームをデベロッパツールで見て数字コピペする
yyyyyyyyyyyyyyyyyyyyyyにはreCAPTCHAのサイトキーを入れる
3. HTMLのヘッダーでreCAPTCHAを読み込む
<script src="https://www.google.com/recaptcha/api.js?render=xxxxxxxxxxxx"></script>
xxxxxxxxxxxxにはreCAPTCHAのサイトキーを入れる
4. submitの挙動をJavascriptで制御する
<script>
const key = $('#recap').attr('data-sitekey');
$('#mailform').on('submit', function (e) {
e.preventDefault();
grecaptcha.ready(function () {
grecaptcha.execute(key, { action: 'submit' }).then(function (token) {
$('#recap').val(token);
$('#mailform').unbind('submit').submit();
$('.bl_form_message').show();
});
});
});
</script>
これは参考サイトをまるまるコピペさせていただいたのだが、
送信後の挙動が「thanksページに遷移」ではなく「お礼メッセージ表示」になっている。
そっちの方が良さそうと思ったので、そこも変更する。
寄り道 : thanksページ遷移ではなくお礼メッセージ表示に変更
送信ボタンの下をこうする
<iframe name="dummyIframe" style="display:none"></iframe>
<div class="bl_form_message">
<p>ありがとうございました。メッセージは送信されました。</p>
<p>数日以内に返信しますので、しばらくお待ちください。</p>
</div>
お礼メッセージは非表示にしておく
.bl_form_message{
display: none;
}
formのtargetも "dummyIframe" に直しておく
<form id="mailform" role="form" action="https://docs.google.com/forms/u/0/d/e/~~~~~formResponse" method="post" target="dummyIframe">
5. GASでrecaptchaを確認、OKだったらメール送るようにする
参考サイトのGASは、Google Formに対して書かれている。
Google Formと、スプレッドシートでは、スクリプトの書き方が異なる。
参考サイトのコードをできるだけ丸写ししたかったので、
スプレッドシートのGASをやめにして、
Google Formの縦3点メニューにある「スクリプトエディタ」から新規にスクリプトを作成した。
const secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx';
function verifyCaptcha(arg) {
const payload = { secret, response: arg };
const url = 'https://www.google.com/recaptcha/api/siteverify';
const resp = UrlFetchApp.fetch(url, {
payload,
method: 'POST',
}).getContentText();
return JSON.parse(resp).success;
}
function submitForm(e) {
const itemResponses = e.response.getItemResponses();
let userMail;
let userName;
let userMessage;
let recaptcha;
let body;
let subject;
for (let i = 0; i < itemResponses.length; i++) {
const question = itemResponses[i].getItem().getTitle();
const answer = itemResponses[i].getResponse();
if (question === 'メールアドレス Email') userMail = answer;
if (question === 'お名前 Your Name') userName = answer;
if (question === 'メッセージ Message') userMessage = answer;
if (question === 'recaptcha') recaptcha = answer;
}
const resp = verifyCaptcha(recaptcha);
if (resp) {
subject = '【Webサイトからのお問い合わせ】';
body =
'サイトからお問い合わせがありました。\n' +
'受付内容' +
'\n メールアドレス: ' +
userMail +
'\n お名前:' +
userName +
'\n メッセージ:\n' +
userMessage;
GmailApp.sendEmail('メールアドレス', subject, body, {
replyTo:userMail,
name:userName,
});
}
}
メールの細かな設定以外は、
ほとんど参考サイトを丸写しさせてもらった。
あとはトリガーを「フォーム送信時」に設定して、完了!
reCAPTCHAがOKな時だけメールが届き、
NGの時はスプレッドシートに記録されるだけ、という感じになり、快適になった。
6. reCAPTCHAバッジを非表示にする
Google公式にやり方が書いてあるので、それに従う。
よくある質問 | reCAPTCHA | Google for Developers
できた〜〜〜〜