Webサイトを静的HTMLで運用していると、WordPressの問い合わせフォームプラグインのような動的機能をそのまま使えないことがあります。
そんなときは、HTMLフォームからGoogle Apps Scriptへ送信し、Googleスプレッドシートに内容を保存する方法が手軽です。このサイトの contact/ でも、フォームの送信先としてApps Scriptを使っています。
この記事では、できるだけ簡単にするため、Vueなどのフレームワークは使わず、HTMLと少しのJavaScriptだけで説明します。
作るもの
今回作るのは、次のようなシンプルな問い合わせフォームです。
- Webページ側にHTMLフォームを置く
- 送信ボタンを押すとApps ScriptのURLへ送信する
- Apps ScriptがGoogleスプレッドシートに1行追加する
- 必要ならメール通知も送る
Googleフォームそのものをiframeで埋め込む方法もありますが、今回はサイトのデザインに合わせやすい「自分で作ったHTMLフォーム」を使います。
全体の流れ
- Googleスプレッドシートを作る
- Apps Scriptを書く
- Apps ScriptをWebアプリとして公開する
- HTMLフォームからApps Scriptへ送信する
先にスプレッドシートとApps Scriptを用意して、最後にHTML側へ送信先URLを設定します。
1. スプレッドシートを用意する
まず、Googleスプレッドシートで新しいファイルを作成します。シート名は例として お問い合わせ にします。
1行目には、次の見出しを入れておきます。
| 日時 | お名前 | メールアドレス | 相談内容 | お問い合わせ内容 | 送信元 |
|---|---|---|---|---|---|
| timestamp | name | category | message | source |
見出しの日本語は自由に変えて構いません。Apps Script側で、同じ順番にデータを追加していきます。
2. Apps Scriptを書く
スプレッドシート上部のメニューから「拡張機能」→「Apps Script」を開きます。
開いたエディタに、次のコードを貼り付けます。
const SHEET_NAME = 'お問い合わせ';
const NOTICE_EMAIL = 'your@example.com'; // 通知が不要なら空文字にする
function doPost(e) {
const lock = LockService.getScriptLock();
lock.waitLock(10000);
try {
const sheet = SpreadsheetApp
.getActiveSpreadsheet()
.getSheetByName(SHEET_NAME);
const params = e.parameter;
// 空の項目は空文字として扱う
const name = params.name || '';
const email = params.email || '';
const category = params.category || '';
const message = params.message || '';
const source = params.source || '';
// 簡単なスパム対策。HTML側の隠し項目に入力があれば保存しない
if (params.website) {
return createResponse({ result: 'ok' });
}
sheet.appendRow([
new Date(),
name,
email,
category,
message,
source,
]);
if (NOTICE_EMAIL) {
MailApp.sendEmail({
to: NOTICE_EMAIL,
subject: 'Webサイトからお問い合わせがありました',
body: [
`お名前: ${name}`,
`メールアドレス: ${email}`,
`相談内容: ${category}`,
'',
message,
].join('n'),
});
}
return createResponse({ result: 'ok' });
} catch (error) {
return createResponse({ result: 'error', message: error.message });
} finally {
lock.releaseLock();
}
}
function createResponse(data) {
return ContentService
.createTextOutput(JSON.stringify(data))
.setMimeType(ContentService.MimeType.JSON);
}SHEET_NAME は、実際に作ったシート名に合わせてください。メール通知が不要な場合は、NOTICE_EMAIL を空文字にします。
appendRow の順番が、スプレッドシートの列の順番になります。フォーム項目を増やしたい場合は、HTML側の name 属性とApps Script側の params.xxx を同じ名前で増やします。
3. Apps ScriptをWebアプリとして公開する
コードを保存したら、Apps ScriptをWebアプリとしてデプロイします。
- 右上の「デプロイ」を押す
- 「新しいデプロイ」を選ぶ
- 種類で「ウェブアプリ」を選ぶ
- 実行するユーザーは「自分」を選ぶ
- アクセスできるユーザーは「全員」を選ぶ
- デプロイして、表示されたWebアプリURLをコピーする
ここでコピーしたURLを、HTML側の送信先として使います。
「全員」にするとURLを知っている人は送信できる状態になります。問い合わせフォームとして公開する以上必要な設定ですが、スパム対策や入力チェックは最低限入れておくのがおすすめです。
4. HTMLフォームを作る
次に、Webページ側のHTMLを作ります。以下の YOUR_APPS_SCRIPT_WEB_APP_URL を、先ほどコピーしたWebアプリURLに置き換えてください。
<form id="contact-form" class="contact-form">
<label>
お名前
<input type="text" name="name" autocomplete="name" required>
</label>
<label>
メールアドレス
<input type="email" name="email" autocomplete="email" required>
</label>
<label>
相談内容
<select name="category" required>
<option value="">選択してください</option>
<option value="Webサイト制作">Webサイト制作</option>
<option value="WordPress構築・改修">WordPress構築・改修</option>
<option value="サイト運用・保守">サイト運用・保守</option>
<option value="その他">その他</option>
</select>
</label>
<label>
お問い合わせ内容
<textarea name="message" rows="8" required></textarea>
</label>
<!-- スパム対策用。通常のユーザーには見せない -->
<label class="form-trap">
Webサイト
<input type="text" name="website" tabindex="-1" autocomplete="off">
</label>
<input type="hidden" name="source" value="example.com/contact">
<button type="submit">送信する</button>
<p id="form-status" role="status"></p>
</form>
<script>
const endpoint = 'YOUR_APPS_SCRIPT_WEB_APP_URL';
const form = document.getElementById('contact-form');
const statusText = document.getElementById('form-status');
form.addEventListener('submit', async (event) => {
event.preventDefault();
statusText.textContent = '送信中です';
try {
const formData = new FormData(form);
await fetch(endpoint, {
method: 'POST',
body: formData,
mode: 'no-cors',
});
form.reset();
statusText.textContent = '送信しました。お問い合わせありがとうございます。';
} catch (error) {
statusText.textContent = '送信できませんでした。時間をおいて再度お試しください。';
}
});
</script>mode: 'no-cors' を指定しているのは、静的サイトからApps Scriptへ送信するときにCORSエラーを避けるためです。
この指定を使うと、JavaScript側ではApps Scriptから返ってきたJSONの中身を読めません。そのため、「fetchが完了したら送信完了として表示する」というシンプルな扱いにしています。
5. 最低限のCSS
見た目を少し整えるなら、次のようなCSSを追加します。
.contact-form {
display: grid;
gap: 16px;
max-width: 640px;
}
.contact-form label {
display: grid;
gap: 6px;
font-weight: 700;
}
.contact-form input,
.contact-form select,
.contact-form textarea {
width: 100%;
padding: 12px;
border: 1px solid #ccc;
border-radius: 4px;
font: inherit;
}
.contact-form button {
width: fit-content;
padding: 12px 24px;
border: 0;
border-radius: 4px;
background: #111;
color: #fff;
font: inherit;
cursor: pointer;
}
.form-trap {
position: absolute;
left: -9999px;
}フォーム項目を増やす場合
たとえば電話番号を追加したい場合は、HTMLに name="tel" の入力欄を追加します。
<label>
電話番号
<input type="tel" name="tel" autocomplete="tel">
</label>Apps Script側にも params.tel を追加し、appendRow に入れます。
const tel = params.tel || '';
sheet.appendRow([
new Date(),
name,
email,
tel,
category,
message,
source,
]);あわせて、スプレッドシート側にも「電話番号」の列を追加しておきます。
注意点
- Apps ScriptのWebアプリURLは、フォーム送信用のURLとしてHTMLに設定します。
- スプレッドシートの共有設定を一般公開にする必要はありません。
- メール通知を使う場合、初回実行時にGoogleアカウントの許可が必要です。
no-corsではレスポンス本文を読めないため、細かいエラー表示には向きません。- 本格的なフォームでは、reCAPTCHAやサーバー側の入力検証も検討してください。
まとめ
HTMLフォーム、Googleスプレッドシート、Apps Scriptを組み合わせると、静的なWebページにも問い合わせフォームを追加できます。
WordPressのフォームプラグインを使わずに済むため、静的サイトやヘッドレスCMS構成でも扱いやすい方法です。
まずは、お名前・メールアドレス・お問い合わせ内容だけの小さなフォームから作ると理解しやすいです。必要になったら項目を増やし、通知メールやスパム対策を追加していくとよいと思います。


