GASでAPIを作成してみた

GASでAPIを作成してみました。手軽にAPIを作成できると聞いています。 すごい今更感があるのですが、今まで一度もやってなかったのでやってみました。

Google Apps Script (GAS) とは

Google Apps Script (GAS) は、Googleが提供するサーバーレスなスクリプト実行環境です。JavaScriptをベースとした言語で、Googleスプレッドシート、Googleドキュメント、Gmail、Googleドライブなど、様々なGoogleサービスを操作したり、連携させたりすることができます。

GASでAPIを作成する

GASでAPIを作成するには、主に以下の手順で進めます。

  1. GASプロジェクトの作成:Googleドライブから新しいGASプロジェクトを作成します。
  2. コードの記述
  3. ウェブアプリとしてデプロイ
  4. APIの実行

GETメソッドを作成

ファイルを作って以下のコードを書きます。

/**
 * HTTP GETリクエストを処理する関数です。
 * ウェブアプリとしてデプロイされた際に、GETリクエストがあると実行されます。
 * @param {object} e - イベントオブジェクト。クエリパラメータなどが含まれます(今回はこの例では使用しません)。
 * @return {object} TextOutput - レスポンスとして返すテキストデータ。
 */
function doGet(e) {
  // レスポンスとして返すテキストを作成するためのオブジェクトを生成します。
  var output = ContentService.createTextOutput();

  // APIからの応答として返す内容を設定します。
  output.setContent("これはGASで作成した簡単なAPIからの応答です!");

  // レスポンスのデータ形式(MIMEタイプ)をプレーンテキストに設定します。
  output.setMimeType(ContentService.MimeType.TEXT);

  // 作成したレスポンスオブジェクトを返します。
  return output;
}

その後、デプロイを実行します。 デプロイは以下のように選択しました。

  • 「次のユーザーとして実行」:「自分」
  • 「アクセスできるユーザー」:「全員」

GETメソッドを試す

ウェブアプリのURLをコピーします。 リダイレクトがあるので、-L オプションを付与してcurlコマンドでたたきます。

curl -L https://script.google.com/macros/s/XXXXXXXXXXXXXXXXXXXXXXXXX/exec

POSTメソッドを作成

せっかくなのでスプレッドシートに書き込む形で作成しました。

/**
 * HTTP POSTリクエストを処理する関数です。
 * ウェブアプリとしてデプロイされた際に、POSTリクエストがあると実行され、
 * リクエストボディのJSONデータをスプレッドシートに追記します。
 *
 * @param {object} e - イベントオブジェクト。リクエストに関する情報が含まれます。
 * @return {object} TextOutput - レスポンスとして返すJSONデータ。
 */
function doPost(e) {
  // スプレッドシートIDとシート名をここに設定してください。
  // スプレッドシートのURLにある `/d/` と `/edit` の間の文字列がIDです。
  var SPREADSHEET_ID = "スプレッドシートID"; // 例: "1AbCdEfGhiJklMnOpQrStUvWxYz1234567"
  var SHEET_NAME = "シート1"; // 例: "データ入力"

  var response = {
    status: "エラー",
    message: "不明なエラーが発生しました。"
  };

  try {
    // リクエストボディの内容(通常はJSON文字列)を取得します。
    var postData = e.postData.contents;

    // リクエストボディが空でないか確認します。
    if (!postData) {
      response.message = "リクエストボディが空です。データを送信してください。";
      return ContentService.createTextOutput(JSON.stringify(response))
        .setMimeType(ContentService.MimeType.JSON);
    }

    // JSON文字列をJavaScriptのオブジェクト/配列にパースします。
    var data;
    try {
      data = JSON.parse(postData);
    } catch (jsonError) {
      response.message = "送信されたデータが不正なJSON形式です: " + jsonError.message;
      return ContentService.createTextOutput(JSON.stringify(response))
        .setMimeType(ContentService.MimeType.JSON);
    }

    // スプレッドシートを開きます。
    var spreadsheet = SpreadsheetApp.openById(SPREADSHEET_ID);
    var sheet = spreadsheet.getSheetByName(SHEET_NAME);

    // シートが見つからなかった場合のエラー処理
    if (!sheet) {
      response.message = "指定されたシート '" + SHEET_NAME + "' が見つかりません。";
      return ContentService.createTextOutput(JSON.stringify(response))
        .setMimeType(ContentService.MimeType.JSON);
    }

    // 追記するデータが配列形式であることを期待します。
    // もし単一のオブジェクトの場合は、必要に応じて配列に変換するなどの処理が必要です。
    if (!Array.isArray(data)) {
       // 例: オブジェクトの場合は値を配列に変換して追記するなどの処理
       // data = [data.field1, data.field2]; // 例
       response.message = "送信されたデータは配列形式である必要があります。";
       return ContentService.createTextOutput(JSON.stringify(response))
        .setMimeType(ContentService.MimeType.JSON);
    }


    // データをシートの最終行に追記します。
    sheet.appendRow(data);

    // 成功時の応答を設定します。
    response.status = "成功";
    response.message = "データがシートに正常に追記されました。";

  } catch (e) {
    // 処理中にエラーが発生した場合
    response.message = "サーバー側でエラーが発生しました: " + e.toString();
    Logger.log("エラー: " + e.toString()); // GASのログにもエラーを出力
  }

  // 応答をJSON形式で返します。
  return ContentService.createTextOutput(JSON.stringify(response))
    .setMimeType(ContentService.MimeType.JSON);
}

その後、デプロイを実行します。 デプロイは以下のように選択しました。

  • 「次のユーザーとして実行」:「自分」
  • 「アクセスできるユーザー」:「全員」

デプロイ時に以下のようなダイアログが表示されます。

Google hasn’t verified this app

The app is requesting access to sensitive info in your Google Account. Until the developer (xxxx@gmail.com) verifies this app with Google, you shouldn’t use it.

この警告はGoogleアカウントの機密情報にアクセスするために表示されています。テスト目的であれば問題無いので、下の方のリンクから先に進みます。

POSTメソッドを試す

curl -H "Content-Type: application/json" -d '["a", "b2", "c3"]' -L "https://script.google.com/macros/s/XXXXXXXXXXXXXXXXXXXXXXXXX/exec"

これでスプレッドシートに追記されます。

-X オプションを設定していると、411 Length Requiredエラーとなります。

POST requests require a Content-length header.  That’s all we know.

かなり悩んだのですが、GASのdoPost関数をcurlでテストする時リダイレクトが必要なら-Xオプションを使わない #GAS - Qiita に助けられました。

要約

通常、ウェブブラウザは302リダイレクトを受け取ると、リダイレクト先のURLに対してGETメソッドで再度アクセスします。GASも同様に、リダイレクト後はGETメソッドでのアクセスを期待しています。

curlコマンドでリダイレクトを自動的に追跡するために-Lオプションを使用しますが、-X POSTオプションを一緒に使用すると、curlはリダイレクト後も強制的にPOSTメソッドを使用しようとします。このため、リダイレクト先のGASがPOSTメソッドを許可していない場合に、405 Method Not Allowedエラーが発生してしまいます。

感想

非常に簡単にAPIを作成することができました。ちょっとしたツールであれば、これで充分なのかなと思いました。Googleのデータとも連携できるので、個人理由にぴったりだと思いました。一方で一日のアクセス数の制限があったりと一般公開するには向いてないと思います。

次は以下の点を確認したいと思います。

  • APIキーをつけることができるか
  • HTMLを作って画面を公開できるか

補足:コードや説明はAIに書いてもらいました。

投稿日 2025年05月06日