WordPressのお問い合わせフォームは、スパムの対象になりやすいです。
それに加え、お問い合わせフォーム用のプラグインには脆弱性がしばしば見つかります。
実際、プラグインの脆弱性を突かれたハッキングもよく発生します。
個人的には、スパムが嫌ですぐにお問い合わせフォームを閉じました。
そのため、X(旧Twitter)を経由して問い合わせが来ることがあります。
ただ、DMは解放していません。
よって、投稿へのリプという形で問い合わせが来るという感じです。
このこと自体、非常にハードルが上がっています。
だから、お問い合わせを復活させたいとはずっと思っていました。
お問い合わせフォームの復活
この度、約3年振りぐらいにお問い合わせフォームを復活させました。
それは、スパム問題は大丈夫と判断したからです。
自作のフォームなら、そうそう簡単にスパムに侵略されないはずなので。
侵略されたら、その都度対応はしていくつもりです。
自作のため、何とでもできますからね。
あとは、SMTPを利用しないで済む方法が見つかったのも大きいです。
GASを使えば、個人でSMTPを用意しないで済みます。
SMTPによるメール送信は、今後ますます厳しくなっていくはずです。
また、求められるセキュリティレベルもどんどんと高くなります。
それなら、メール送信はGoogleさんに任せようということです。
お問い合わせフォームの構成
WordPressの固定ページを利用しています。
WordPressのソースは、できる限りで触りたくありません。
固定ページにHTMLタグを入力しています。
そして、カスタムCSSとカスタムJavaScriptを利用する形になります。
ここまではWordPressの管理画面だけで済みます。
ただ、ここから先がハードルが少しあがります。
JavaScriptから非同期でPHPにアクセスしています。
そのPHP上でGASにアクセスとなります。
セキュリティに問題なければ、JavaScriptからGASへ直接もありなんですけどね。
それはマズイので、PHPを間に入れているということです。
HTML
<form id="contact-form" method="post"> <div> <label for="name">名前:</label> <input type="text" id="name" name="name" required> </div> <div> <label for="email">メールアドレス:</label> <input type="email" id="email" name="email" required> </div> <div> <label for="message">メッセージ:</label> <textarea id="message" name="message" required></textarea> </div> <div> <button type="submit">送 信</button> </div> </form> <!-- 確認画面のモーダル(初期状態では非表示) --> <div id="confirmModal" style="display:none;"> <p><strong>名前:</strong> <span id="confirmName"></span></p> <p><strong>メールアドレス:</strong> <span id="confirmEmail"></span></p> <p><strong>メッセージ:</strong></p> <p style="white-space: pre-line;" id="confirmMessage"></p> <button id="confirmSubmit">確 定</button> <div id="loadingSpinner" class="spinner"></div> <button id="goBack">戻 る</button> </div> <!-- 成功メッセージ表示用の要素 --> <div id="successMessage" style="display: none; padding: 20px; background-color: #4CAF50; color: white; text-align: center; border-radius: 5px;"> お問い合わせを受け付けました。 </div>
カスタムCSS
/* ボタンのスタイル */ button { background-color: #4CAF50; /* 緑色の背景 */ color: white; /* 白色のテキスト */ padding: 15px 32px; /* 上下15px、左右32pxのパディング */ text-align: center; /* テキストを中央揃え */ text-decoration: none; /* テキストの装飾をなしに */ display: inline-block; /* インラインブロック要素として表示 */ font-size: 16px; /* フォントサイズ */ margin: 4px 2px; /* 上下4px、左右2pxのマージン */ cursor: pointer; /* カーソルをポインターに */ border: none; /* 境界線なし */ border-radius: 5px; /* 角を丸くする */ } /* ボタンのホバー時のスタイル */ button:hover { background-color: #45a049; /* ホバー時の背景色を少し暗く */ } /* フェードインエフェクト */ .fade-in { animation: fadeIn 1s; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } /* 確認画面モーダルのスタイル */ #confirmModal { background-color: #f5f5f5; border: 1px solid #ccc; padding: 20px; max-width: 90%; margin: 0 auto; } #confirmModal p { margin: 10px 0; } #confirmModal strong { font-weight: bold; } #confirmModal button { background-color: #007bff; color: white; border: none; padding: 10px 20px; cursor: pointer; } #confirmModal button:hover { background-color: #0056b3; } /* 名前とメールアドレス入力フィールドのスタイル */ #name, #email { width: 100%; padding: 10px; margin-bottom: 10px; font-size: 1rem; } /* ローディングスピナーのスタイル */ .spinner { border: 4px solid rgba(0, 0, 0, 0.3); border-radius: 50%; border-top: 4px solid #007bff; width: 40px; height: 40px; animation: spin 2s linear infinite; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); display: none; /* 初期状態では非表示 */ } @keyframes spin { 0% { transform: translate(-50%, -50%) rotate(0deg); } 100% { transform: translate(-50%, -50%) rotate(360deg); } }
カスタムJavaScript
document.getElementById('contact-form').addEventListener('submit', handleFormSubmit); function handleFormSubmit(event) { event.preventDefault(); // 通常の送信を阻止 const name = document.getElementById('name').value; const email = document.getElementById('email').value; const message = document.getElementById('message').value; if (!validateFormData(name, email, message)) { return; } setConfirmationData(name, email, message); toggleDisplay('contact-form', false); toggleDisplay('confirmModal', true); document.getElementById('confirmSubmit').onclick = handleConfirmSubmit; document.getElementById('goBack').onclick = handleGoBack; } function validateFormData(name, email, message) { if (name === '') { alert('名前を入力してください。'); return false; } if (!email.match(/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/)) { alert('有効なメールアドレスを入力してください。'); return false; } if (message === '') { alert('メッセージを入力してください。'); return false; } return true; } function setConfirmationData(name, email, message) { document.getElementById('confirmName').textContent = name; document.getElementById('confirmEmail').textContent = email; document.getElementById('confirmMessage').textContent = message; } function toggleDisplay(elementId, show) { document.getElementById(elementId).style.display = show ? 'block' : 'none'; } function handleConfirmSubmit() { const submitButton = document.getElementById('confirmSubmit'); submitButton.disabled = true; submitButton.textContent = '送信中...'; toggleDisplay('loadingSpinner', true); const formData = { name: document.getElementById('confirmName').textContent, email: document.getElementById('confirmEmail').textContent, message: document.getElementById('confirmMessage').textContent }; sendFormData(formData) .then(response => { if (response.success) { toggleDisplay('successMessage', true); toggleDisplay('confirmModal', false); window.scrollTo(0, 0); } else { alert('エラーが発生しました。\n' + response.error); } }) .catch(() => alert('メールの送信に失敗しました。')) .finally(() => { submitButton.disabled = false; submitButton.textContent = '確定'; toggleDisplay('loadingSpinner', false); }); } function handleGoBack() { toggleDisplay('contact-form', true); toggleDisplay('confirmModal', false); } function sendFormData(formData) { return fetch('/sv/api/send_mail.php', { method: 'POST', headers: {'Content-Type': 'application/json;charset=UTF-8'}, body: JSON.stringify(formData) }) .then(response => { if (!response.ok) { throw new Error('ネットワークレスポンスが不正です。'); } return response.json(); }) .catch(error => { throw new Error('リクエスト中にエラーが発生しました: ' + error.message); }); }
PHP(send_mail.php)に関しては、非公開としておきます。
さすがに手の内を晒すのは、マズイと思いますので。
でも、60行前後のソースのため複雑なことはありません。
このPHPから、GASのプログラムにアクセスしています。
GASのプログラムは、上記記事内で紹介したそのままです。
そして、アクセスと言っても単なるHTTPリクエストです。
curlも使っていません。
それでも、send_mail.phpの中身を知りたい場合は下記から問い合わせてください。
メールで情報を返信します。
なお、この自作のお問い合わせフォームは2時間で制作しました。
コードは、ほぼChatGPTに書かせました。
要件入力、検証、レビューを繰り返しただけです。
それだけでお問い合わせフォームが、簡単に作れます。
なお、嘘のような本当の話ですが、早速問い合わせがありました。
復活から24時間も経っていないのに、仕事の依頼です。
復活させた甲斐があると言うもんです。