WebアプリとしてのGAS(doGet/doPost)

20260308_WebアプリとしてのGAS(doGet_doPost)を解説している女性
目次

サーバーレスアーキテクチャの第一歩としてのGAS

これまでの章では、Google Apps Script(GAS)を主に「Google Workspace内の自動化ツール」として扱ってきました。スプレッドシートの操作や定期的なメール送信は、あくまでGoogleのエコシステム内で完結する処理でした。しかし、GASのポテンシャルはそれだけに留まりません。GASは、HTTPリクエストを受け取り、レスポンスを返す「簡易的なWebサーバー」として機能させることが可能です。これをサーバーレスアーキテクチャの一種として捉えることで、開発の幅は劇的に広がります。

例えば、社内用の簡易的な業務ポータルサイトを構築したり、外部のSaaS(SlackやLINEなど)からの通知を受け取って処理を走らせたりするWebhookの受け口として利用できます。本章では、GASをWebアプリケーションとして公開するための技術仕様、特にdoGetおよびdoPost関数の役割と実装方法、そしてデプロイ時の重要な権限設定について、エンジニアリングの観点から詳細に解説します。

Webアプリ化の核となるシンプルトリガー:doGetとdoPost

GASをWebアプリケーションとして動作させるためには、特定のルールに従った関数を定義する必要があります。それがdoGetdoPostです。これらは「シンプルトリガー」と呼ばれる特別な関数の一種であり、外部からそのスクリプトの公開URLに対してHTTPリクエストが送信された際に自動的に発火します。doGet(e)はHTTP GETリクエスト(主にブラウザでのアクセス)を受け取った際に実行され、doPost(e)はHTTP POSTリクエスト(フォーム送信や外部システムからのデータ通信)を受け取った際に実行されます。

開発者は、これらの関数内にロジックを記述し、最終的に何らかの出力を「return」することで、クライアント(ブラウザや外部サーバー)にレスポンスを返します。引数のe(イベントオブジェクト)には、リクエストに伴うパラメータやPOSTデータが格納されており、これを解析することで動的な処理が可能になります。通常の関数実行とは異なり、エントリーポイントが明確に規定されている点がWebアプリ化の大きな特徴です。

HtmlServiceによるHTMLコンテンツの生成と配信

Webブラウザからのアクセスに対して、人間が閲覧可能なWebページを表示する場合、HtmlServiceクラスを使用します。doGet関数の中でHtmlService.createHtmlOutput('HTML文字列')HtmlService.createTemplateFromFile('ファイル名')を実行し、生成されたHtmlOutputオブジェクトをreturnすることで、ブラウザ上にページがレンダリングされます。

単純な文字列を返すだけでなく、GASのプロジェクト内に拡張子.htmlのファイルを作成し、それを読み込んで表示するのが一般的な開発手法です。これにより、HTML、CSS、クライアントサイドJavaScriptを記述した本格的なフロントエンドを構築できます。また、GAS特有の機能として「スクリプトレット」があります。HTMLファイル内に<? var data = ... ?>のようなタグを記述することで、サーバーサイド(GAS側)の変数をHTML生成時に埋め込むことが可能です。これはPHPやJSPなどのサーバーサイドレンダリング(SSR)に近い挙動であり、スプレッドシートのデータを動的に反映したレポート画面などを構築する際に威力を発揮します。

doGet関数の実装:クエリパラメータの処理とルーティング

doGet(e)関数は、Webアプリの「顔」となる部分です。ブラウザのアドレスバーにURLを入力してEnterキーを押す行為はGETリクエストに相当するため、Webページを表示する場合は必ずこの関数を使用します。開発において重要なのは、イベントオブジェクトeに含まれるe.parameterの活用です。

例えば、公開URLの末尾に?page=report&id=123のようなクエリパラメータを付与してアクセスした場合、e.parameter.pageで”report”を、e.parameter.idで”123″を取得できます。これを利用して、1つのGAS Webアプリ内で表示する内容を切り替える「ルーティング」のような仕組みを実装できます。if文やswitch文を用いて、pageパラメータの値に応じて異なるHTMLテンプレートを読み込んで返却することで、擬似的な多階層サイトを構築することが可能です。AIにコードを生成させる際も、「クエリパラメータに応じて表示するHTMLファイルを切り替えるdoGet関数を書いて」と指示することで、構造的なWebアプリの基盤を作成させることができます。

Webアプリのデプロイメント:バージョン管理とURLの発行

コードを書いただけではWebアプリとして外部からアクセスすることはできません。「デプロイ」という公開手続きが必要です。GASのエディタ画面右上の「デプロイ」ボタンから「新しいデプロイ」を選択し、種類の選択で「ウェブアプリ」を選びます。ここで発行されるURL(…/execで終わるもの)が、本番環境のアクセスポイントとなります。

開発者が特に注意すべき点は、GASのWebアプリには「バージョン」の概念があることです。「新しいデプロイ」を行うたびにバージョンが固定され、その時点のコードが公開されます。その後コードを修正しても、再度デプロイ情報を更新(デプロイを管理 -> 編集 -> 新しいバージョンを選択)しない限り、公開されているWebアプリには反映されません。一方で、開発確認用として「テストデプロイ」のURL(…/devで終わるもの)も用意されており、こちらは最新のコードが即座に反映されます。開発中はテストURLを使用し、動作確認が取れたら本番デプロイを更新する、というサイクルを徹底することが、バグの混入を防ぐための鉄則です

権限設定の落とし穴:実行ユーザーとアクセスユーザーの重要性

デプロイ設定において、最もトラブルが起きやすく、かつ重要なのが「次のユーザーとして実行(Execute as)」と「アクセスできるユーザー(Who has access)」の設定です。これらを誤ると、意図した通りに動かないばかりか、セキュリティリスクにもなり得ます。

「次のユーザーとして実行」には、「自分(Me)」と「ウェブアプリケーションにアクセスしているユーザー」の2択があります。基本的には「自分」を選択することを推奨します。これを選ぶと、誰がアクセスしても、スクリプトオーナー(開発者)の権限でGASが実行されます。つまり、閲覧者が閲覧権限を持っていないスプレッドシートのデータでも、開発者が権限を持っていればWebアプリ上に表示できることになります。一方、「アクセスしているユーザー」を選ぶと、アクセスした人自身のGoogleアカウント権限で動作するため、社内ツールなどで厳密な権限管理が必要な場合に利用されますが、外部公開には向きません。

「アクセスできるユーザー」は、「自分のみ」「Googleアカウントを持つ全員」「全員(匿名ユーザーを含む)」から選択します。Webhookとして外部システムからの通知を受け取る場合は、Googleアカウント認証を挟めないため、必ず「全員(anyone)」を選択する必要があります。

doPost関数の実装:JSONデータの受け取りとパース

外部システム(Slack、LINE、決済サービスなど)からのWebhookを受け取る場合は、doPost(e)関数を使用します。これらのサービスは通常、データをJSON形式でPOSTリクエストとして送信してきます。GAS側でこのデータを受け取るには、e.postData.contentsを参照します。

e.postData.contentsには、リクエストボディの生データ(文字列)が格納されています。JSON形式で送られてきた場合、そのままでは扱いにくいため、JSON.parse(e.postData.contents)を実行してJavaScriptのオブジェクトに変換(パース)する必要があります。これにより、data.userIddata.messageのようにプロパティとして値を取り出せるようになります。AIにWebhookの処理コードを書かせる際は、「受け取ったJSONデータをパースし、特定のキーの値を取り出す処理を含めて」と指示することで、確実な実装が可能になります。

ContentServiceによるレスポンス返却:MIMEタイプの設定

Web APIとして機能させる場合、doGetdoPostの最後で、リクエスト元に対して適切なレスポンスを返す必要があります。HTMLを返す場合はHtmlServiceを使いましたが、JSONデータやプレーンテキストを返す場合はContentServiceを使用します。

特にWebhookの処理において、送信元のサービスによっては「正しく受信した」ことを示すために、特定のレスポンス(ステータスコード200や特定のJSON)を要求する場合があります。その際、return ContentService.createTextOutput(JSON.stringify(responseObj)).setMimeType(ContentService.MimeType.JSON);のように記述し、MIMEタイプを明示的にJSONに設定して返すことが作法です。これを怠ると、GASはデフォルトでHTMLとしてレスポンスを返そうとし、送信元システムが「エラー」や「不正なレスポンス」と判定してリトライを繰り返してしまう(無限ループに陥る)リスクがあります。

セキュリティ対策:不正なアクセスの遮断と検証

「アクセスできるユーザー」を「全員(anyone)」に設定してWebアプリを公開するということは、世界中の誰でも(URLさえ知っていれば)そのスクリプトを実行できる状態にあることを意味します。したがって、アプリケーション側でのセキュリティ対策が必須となります。

Webhookを受け取る場合、送信元が正当なサービスであるかを検証するロジックをdoPostの冒頭に組み込む必要があります。多くのAPIサービスは、リクエストヘッダーに署名(Signature)や検証用トークンを含めて送信してきます。GAS側でこのトークンを確認し、想定している値と一致しない場合は処理を中断(return)するというガード処理を実装します。また、URL自体が漏洩した場合に備え、Webアプリを廃止してURLを再発行する手順も想定しておくべきです。AIにコード生成を依頼する際も、「リクエストに含まれる検証トークンをチェックする認証ロジックを追加して」と明示することで、セキュアなコードベースを構築できます。

外部連携の実践:Webhookを活用した双方向通信

doPostの実装により、GASは「自分から情報を取得しに行く(Pull型)」だけでなく、「外部から情報が送られてくるのを待つ(Push型)」処理が可能になります。これにより、リアルタイム性の高いシステムが構築できます。

例えば、SlackのSlash CommandやEvent APIと連携し、Slack上で特定の発言があった瞬間にGASを起動してスプレッドシートを更新したり、決済サービスStripeからの「支払い完了」通知をWebhookで受け取り、即座に顧客へサンクスメールを送信したりといったフローが実現します。前章までのトリガー(時間主導など)と、本章のWebhook(イベント主導)を組み合わせることで、GASは単なるスクリプトツールを超え、業務システムのハブとして機能するようになります。WebアプリとしてのGASを理解することは、SaaS同士を繋ぐ「グルー(糊)コード」としての真価を引き出すための最終ステップです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次