Google Apps Script から Amazon API Gateway にリクエストを送る

Google スプレッドシートをインターフェイスにして、Google Apps Script 経由で AWS 環境にリクエストを送信する処理を clasp と TypeScript を使って実装しました。
2023.01.16

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

こんにちは、筧( @TakaakiKakei )です。

Google スプレッドシートをインターフェイスにして、 Google Apps Script 経由で AWS 環境にリクエストを送信する、 社内向けツールを開発する機会がありました。

今後も繰り返し使えそうな処理だったので、開発したコードを汎化してご紹介します。

前提

紹介するコードは、下記処理を行います。

  1. Google スプレッドシートにインプット情報を記載
  2. メニューバーからツール実行ボタンを押下
  3. Google Apps Script が起動
  4. Google Apps Script から Amazon API Gateway にリクエストを投げる
  5. Google Apps Script がインプット情報を削除&別シートに履歴を記録

また、開発には Google Apps Script のコマンドラインツールである google/clasp を利用します。 言語は TypeScript で書きます。

コード

clasp/dev/src/invoke.ts

type Item = {
  requester: string;
  target_accountid: string;
  before_payer_name: string;
  after_payer_name: string;
  skip_supportcase: string;
};
type Items = Item[];

const exec = () => {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const inputSheet = ss.getSheetByName('シート1');

  if (!inputSheet) {
    throw new Error('Not found inputSheet');
  }

  // 環境変数(ステージによって変更する)
  const props = PropertiesService.getScriptProperties();
  const APIKEY = props.getProperty('APIKEY');
  const URL = props.getProperty('URL');

  if (!APIKEY) {
    throw new Error('Not found APIKEY of property');
  }
  if (!URL) {
    throw new Error('Not found URL of property');
  }

  // データ入力シートのデータ取得
  const inputSheetDataRange = inputSheet.getDataRange();
  const arrays = inputSheetDataRange.getValues();
  const arraysLen = arrays.length;

  // 処理対象の行がなければ終了
  if (arraysLen <= 1) {
    Logger.log('None');
    return;
  }

  // 二次元配列のデータをJSON形式に変換
  const [header, ...rows] = arrays;
  const _json = rows.map((row) =>
    row.reduce((acc, cell, i) => ({ ...acc, [header[i]]: String(cell) }), {})
  );

  // APIGW へのリクエスト
  const payload = JSON.stringify(_json);
  Logger.log(`payload:\n${payload}`);

  const response = UrlFetchApp.fetch(URL, {
    method: 'post',
    contentType: 'application/json',
    payload: payload,
    headers: {
      'x-api-key': APIKEY,
    },
  });
  Logger.log(`response:\n${response}`);

  // 実行履歴シートの存在有無を確認して、なければ作成
  const today = new Date();
  const year = today.getFullYear();
  const historySheetName = `履歴${year}`;
  let historySheet = ss.getSheetByName(historySheetName);

  if (!historySheet) {
    // 実行履歴シートの作成
    let newSheet = ss.insertSheet();
    newSheet.setName(historySheetName);
    if (!newSheet) {
      throw new Error('Not found and Create historySheet');
    }
    historySheet = newSheet;
  }

  // 実行履歴シートに処理データを転記
  const historySheetLastRow = historySheet.getLastRow();
  inputSheetDataRange.copyTo(
    historySheet.getRange(historySheetLastRow + 1, 1),
    { contentsOnly: true }
  );

  // データ入力用シートのデータ削除
  inputSheet.deleteRows(2, arraysLen - 1);

  return;
};

// スプレッドシートにツール実行ボタン表示
const onOpen = () => {
  const ui = SpreadsheetApp.getUi();

  //メニュー名を決定
  const menu = ui.createMenu('実行メニュー');

  //メニューに実行ボタン名と関数を割り当て: その1
  menu.addItem('Payer移動自動化ツール実行', 'exec');

  //スプレッドシートに反映
  menu.addToUi();
};

デプロイ方法

API の有効化

デプロイ先の Google アカウントにログインします。 下記から Google Apps Script API を有効化します。

clasp のインストール

cd {プロジェクトフォルダ}
npm i @google/clasp
npm install @types/google-apps-script

プロジェクトの作成

mkdir {ステージ}
cd {ステージ}

clasp login
clasp create --type sheets

ファイルの編集

tsconfig.json を下記の通り作成します。

{
  "compilerOptions": {
    "lib": ["esnext"],
    "experimentalDecorators": true,
    "strict": true
  }
}

appsscrript.json を下記の通り編集します。

{
  "timeZone": "Asia/Tokyo",
  "dependencies": {},
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8"
}

src/invoke.ts を作成して、前述の TypeScript のコードを貼り付けます。

コードの push

clasp push

プロパティの設定

clasp open

Google Apps Script の画面が開いたら、設定画面のスクリプトプロパティにプロパティを追加します。

  • APIKEY: {Amazon API Gateway の API キー}
  • URL: {Amazon API Gateway のエンドポイント}

動かしてみる

clasp で作成したスプレッドシートを開きます。 データ入力シート用の"シート 1"を編集します。 下図のように、1 行目にヘッダーを、2 行目以降に値を追加します。

メニューバーの"実行メニュー"から"ツール実行"を選択します。

"シート 1"から入力したデータが削除され、"履歴 YYYY シート"に実行履歴が追加で記録されます。

Amazon API Gateway には以下のようなリクエストボディが送信されます。

[
  {
    "requester": "kakei",
    "target_accountid": "0123456789014",
    "before_payer_name": "Hoge",
    "after_payer_name": "Fuga",
    "skip_supportcase": ""
  },
  {
    "requester": "kakei",
    "target_accountid": "0123456789015",
    "before_payer_name": "Hoge",
    "after_payer_name": "Piyo",
    "skip_supportcase": ""
  },
  {
    "requester": "kakei",
    "target_accountid": "0123456789016",
    "before_payer_name": "Fuga",
    "after_payer_name": "Hoge",
    "skip_supportcase": ""
  }
]

おわりに

最後まで読んでいただきありがとうございます。

本コードが皆さんの役に立つと幸いです。 デプロイで躓くことがあれば、後述の参考ブログをご覧ください。

それではまた!

参考