PR

[GASでWEBアプリ] doPostでHTML+Bootstrapフォームからスプレッドシートへ自動書き込み

こんにちは。イカPOです。GASで作ったWEBアプリからスプレッドシートに書き込む、シンプルな方法を紹介します。オリジナルの入力画面を作ってスプレッドシートに書き込むことができるようになるので、仕事が楽なります。もっとリッチなコードにすれば、スマホ一台で在庫の確認と数の更新ができるようになったり…そんな話の基礎を今回は紹介します。


HTML フォームを作ろう

フォームの画面。Bootstrapを使っているのでそれっぽい画面に
実際の画面。Bootstrapをしたシンプルなフォームの画面です。

まずは form.html をプロジェクトに追加し、下記のようなシンプルな問い合わせフォームを用意します。Bootstrap 5 を読み込んでいるので、ほぼ手を加えなくても見栄え良く整います。

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <!-- Bootstrap 5 -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
  </head>

  <body class="container py-5">
    <h1 class="h4 mb-4">お問い合せ</h1>

    <!-- ★ ここがポイント -->
    <form method="POST" action="<?!= deployURL ?>">
      <div class="mb-3">
        <label for="name" class="form-label">お名前</label>
        <input type="text" id="name" name="name" class="form-control" required>
      </div>

      <div class="mb-3">
        <label for="email" class="form-label">メールアドレス</label>
        <input type="email" id="email" name="email" class="form-control" required>
      </div>

      <div class="mb-4">
        <label for="msg" class="form-label">メッセージ</label>
        <textarea id="msg" name="msg" rows="4" class="form-control" required></textarea>
      </div>

      <button type="submit" class="btn btn-primary">送信</button>
    </form>
  </body>
</html>

ここだけは押さえよう — フォームの核心ポイント

  • <form method="POST" …>
    フォーム送信時に HTTP POST を使う指定です。
    doPost(e) が受け取るのは POST データなので、ここを GET にしてしまうと doGet(e) が呼ばれ、パラメータが URL に丸見えになります(セキュリティ面・文字数制限の両方で不利)。
  • action="<?!= deployURL ?>"
    deployURL はサーバー側(Code.gs のテンプレート)で差し込むウェブアプリの公開 URL。
    ウェブアプリは再デプロイのたびに URL が変わるため、アドレスを直書きするとすぐ動かなくなるのが落とし穴。テンプレートに埋め込んでおけば、コードをいじらずに常に最新の URL へ自動追従できます。
  • input / textarea 各フィールド
    name="name", name="email", name="msg"キー となり、GAS 側では e.parameter.name / e.parameter.email / e.parameter.msg として受け取れます。
  • required
    ブラウザレベルの簡易バリデーション。空欄で送信ボタンを押すと警告を出してくれるので、スクリプト側のチェックを減らせます。
  • Bootstrap の読み込み
    CDN を 1 行書くだけでフォームが即“それっぽく”整います。GAS の HTMLService は外部 CSS の読み込みも OK なので、今回は最小構成として CDN を採用しています。

doGet でフォームを表示する

まずは Code.gs に次の関数を用意します。これで先ほど作った form.html をブラウザに表示できるようになります。

function doGet(e) {
  // ① テンプレート(form.html)を読み込む
  const template = HtmlService.createTemplateFromFile('form');

  // ② デプロイ URL をテンプレートに渡す
  template.deployURL = ScriptApp.getService().getUrl();

  // ③ テンプレートを評価して HTMLOutput を生成
  const htmlOutput = template.evaluate();

  // ④ スマホ対応&タイトル設定(お好みで)
  htmlOutput.addMetaTag('viewport', 'width=device-width, initial-scale=1');
  htmlOutput.setTitle('フォームだよ');

  // ⑤ ブラウザへ返却
  return htmlOutput;
}

template.deployURL の役割

  • 何をしている?
    template.deployURL = ScriptApp.getService().getUrl(); で取得しているのは、ウェブアプリをデプロイしたときに発行される 公開 URL(例:https://script.google.com/macros/s/AKfycb.../exec)。
  • なぜ必要?
    ウェブアプリは再デプロイのたびに URL が変わるため、HTML 側に URL を直書きするとすぐ動かなくなります。
    deployURL をテンプレート変数として渡しておけば、form.html<form method="POST" action="<?!= deployURL ?>"> がテンプレート評価時に 最新の URL に自動置換 され、フォームは常に正しいエンドポイントへ POST できます。
  • ポイントまとめ
    1. サーバー側(doGet)で URL を取得 → テンプレート変数に格納
    2. クライアント側(form.html)でその変数を展開し action に埋め込む
    3. 再デプロイしてもコード修正ゼロで動き続ける

これでフォームの表示は完成です。続いて doPost を実装し、入力内容をスプレッドシートへ保存しましょう!

HTMLの表示方法については以下の記事でも紹介しています。


スクリプトをウェブアプリとしてデプロイする

  1. エディタ右上[デプロイ ▸ 新しいデプロイ]をクリック
  2. 「説明」はメモ程度で OK(例:初回公開)
  3. 種類を選択 ▸ ウェブアプリ
  4. 実行するユーザー:自分
    • 自分の権限でスプレッドシートに書き込むため
  5. アクセス権:全員(匿名可)
    • 社外に公開しない場合は「組織内のみ」でも可
  6. [デプロイ]→ 表示された 公開 URL をコピー
    • これが ScriptApp.getService().getUrl() で取得できる URL
  7. 完了! この URL にアクセスすると doGet() のフォームが開きます。

ポイント
再デプロイ(コード更新→バージョンアップ)のたびに URL が変わるため、フォームの action を固定文字列にしないのが鉄則です。


doPost でスプレッドシートに書き込む

フォーム入力後、送信ボタンを押すと、スプレッドシートに書き込まれる

Code.gs に次の関数を追記します。

function doPost(e) {
  // 1 受信パラメータを取得
  const name    = e.parameter.name  || '';
  const email   = e.parameter.email || '';
  const message = e.parameter.msg   || '';

  // 2 シートに追記
  const sheet   = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const nextRow = sheet.getLastRow() + 1;          // 最下行の 1 つ下
  sheet.getRange(nextRow, 1, 1, 3)                 // A〜C 列 1 行
       .setValues([[name, email, message]]);

  // 3 応答を返す
  return HtmlService.createHtmlOutput('保存しました!');
}

① 受信パラメータを取得

  • e.parameter.<name属性> でフォームの値を取り出します。
  • || '' は「値が空または undefined のときは空文字を入れる」保険です。

② シートに追記

  1. シート取得 const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  2. 書き込み行決定 const nextRow = sheet.getLastRow() + 1;
  3. 範囲指定 & 書き込み sheet .getRange(nextRow, 1, 1, 3) // A〜C列の 1 行 .setValues([[name, email, message]]); // まとめて書き込む [[name, email, message]] という 2 重配列 を渡すことで、
    name → A 列, email → B 列, message → C 列 が一発で書き込まれます。

③ 応答を返す

成功時に表示される画面。保存しました!とブラウザに表示されていればOKです。
  • HtmlService.createHtmlOutput('保存しました!') を返して、送信後のブラウザに完了メッセージを表示します。
  • 複数行の HTML を返してサンクスページを作っても OK です。

このページも参考にしてください。


doGet と doPost の違いを理解しよう

  • doGet(e)
    ブラウザが HTTP GET でアクセスしたときに呼ばれ、パラメータは URL の末尾に付く。主に 表示専用 の処理に使います。
  • doPost(e)
    フォームが HTTP POST で送信したときに呼ばれ、パラメータはリクエストボディに入る。データの 追加・更新・削除 などサーバー処理に最適です。

フォーム入力 → 保存 という典型的な “書き込み処理” では GET で表示/POST で保存 のペアが王道パターンです。


まとめ

これで HTML フォーム → doPost → スプレッドシート保存 という最小構成が完成しました。流れをもう一度振り返ると──

  1. フォームを用意
    method="POST"action="<?!= deployURL ?>" を忘れずに。
  2. doGet でフォームを表示
    ScriptApp.getService().getUrl() で最新の公開 URL をテンプレートに渡す。
  3. ウェブアプリとしてデプロイ
    実行ユーザー:自分/アクセス権:用途に合わせて設定。
  4. doPost で受信 & 追記
    e.parameter で値を取り出し、sheet.setValues() で A〜C 列に一括書き込み。

⚠️ 公開範囲に注意: フォームをインターネット公開すると、URL を知っている誰でも書き込み可能になるので、公開範囲には注意してください。

この基礎が動けば、スマホで在庫管理・社内アンケートなど応用は無限大。まずは試しにフォームを送信し、スプレッドシートにデータが増える様子を確認してみてください!

タイトルとURLをコピーしました