「これからのための気持ちの整理。 」

これからのことを考えています。本当に、本当にめんどうくさい、めんどくさい人間です。これからのために、気持ちの整理をします。

(gas) 公開SpreadSheetをdatabaseにした簡易APIのApps Script

SpreadSheetを簡易databaseにできないか

SpreadSheetManagerを実装

const DEFAULT_SHEET_NAME = 'シート1';


/**
 * スプレッドシート管理
 */
function SpreadSheetManager(targetSheetName) {
  const _this = this;

  // 初期化
  const book = SpreadsheetApp.getActive();
  const sheet = book.getSheets().find(sheet => sheet.getName() === targetSheetName);
  if(!sheet){
    throw new Error('シートが存在しません');
  }

  // 1行目はカラムキー行
  _this.columnKeys = function () {
    return allRows().splice(0, 1)[0];
  };

  // 2行目以降はレコード行
  _this.allRecords = function () {
    const records = allRows();
    return records.slice(1, records.length);
  };

  // 全行取得
  function allRows() {
    return sheet.getDataRange().getValues();
  };

  // 行の挿入
  _this.insertRow = function(row) {
    if(!Array.isArray(row)){
      return;
    }
    return sheet.appendRow(row);
  };
}

最終的な実装

const DEFAULT_SHEET_NAME = 'シート1';

/**
 * Apps Script 向けの utilities
 */
const AsUtils = {

  parseGetParams(getE) {
    return getE.parameter;
  },
  parsePostData(postE) {
    return JSON.parse(postE.postData.getDataAsString());
  },
  convertPostDataToRow(postData, keys) {
    return keys.map(key=>{
      const value = postData[key];
      if (value instanceof Date) {
        return Utilities.formatDate(value, 'Asia/Tokyo', 'yyyy/MM/dd HH:mm:ss');
      }
      if (typeof value === 'object') {
        return JSON.stringify(value);
      }
      return value;
    });
  },
  convertRowsToAPIResult(rows, keys) {
    const result = rows.map(row => {
      const obj = {};
      row.map((item, index) => {
        obj[String(keys[index])] = String(item);
      });
      return obj;
    });
    return ContentService.createTextOutput(JSON.stringify(result, null, 2))
            .setMimeType(ContentService.MimeType.JSON);
  },
  abort(error, etc) {
    error.etc = etc;
    return ContentService.createTextOutput(JSON.stringify(error))
            .setMimeType(ContentService.MimeType.JSON);
  }
}

/**
 * スプレッドシート管理
 */
function SpreadSheetManager(targetSheetName) {
  const _this = this;

  // 初期化
  const book = SpreadsheetApp.getActive();
  const found = book.getSheets().find(sheet => sheet.getName() === targetSheetName);
  if(!found){
    throw new Error('シートが存在しません');
  }
  const sheet = book.getSheetByName(targetSheetName);

  // 1行目はカラムキー行
  _this.columnKeys = function () {
    return allRows().splice(0, 1)[0];
  };

  // 2行目以降はレコード行
  _this.allRecords = function () {
    const records = allRows();
    return records.slice(1, records.length);
  };

  // 全行取得
  function allRows() {
    return sheet.getDataRange().getValues();
  };

  // 行の挿入
  _this.insertRow = function(row) {
    if(!Array.isArray(row)){
      return;
    }
    return sheet.appendRow(row);
  };
}

/**
 * APIコントローラー
 */
function SpreadSheetAPIController() {
  const _this = this;
  let manager, 
      columnKeys;

  /**
   * 初期化
   * @param e:request変数
   * @param method:string
   */
  function init(e, method = 'GET') {
    // 指定スプレッドシートの管理インスタンスを生成
    manager = makeTargetSpreadSheetManager(
      parseTargetSheetName(e, method)
    );
    // ヘッダ行を設定
    columnKeys = manager.columnKeys();
  }

  /**
   * @method GET
   */
  _this.handleGet = function (e) {
    init(e, 'get');
    return AsUtils.convertRowsToAPIResult(
      manager.allRecords(),
      columnKeys
    );
  }
  /**
   * @method POST
   */
  _this.handlePost = function(e) {
    init(e, 'post');
    return manager.insertRow(
      AsUtils.convertPostDataToRow(
        AsUtils.parsePostData(e),
        columnKeys
      )
    );
  }

  /**
   * 指定したスプレッドシートの管理インスタンスを作成
   * @return spreadSheetManager:SpreadSheetManager
   */
  function makeTargetSpreadSheetManager(sheet) {
    return new SpreadSheetManager(sheet);
  }

  /**
   * 指定されたシート名を取得
   * @param e:request変数
   * @param method:string
   * @return sheet:string
   */
  function parseTargetSheetName(e, method = 'GET') {
    let data;
    if(method.toLowerCase() == 'get') {
      data = AsUtils.parseGetParams(e);
    }
    if(method.toLowerCase() == 'post') {
      data = AsUtils.parsePostData(e);
    }
    return (data && data.sheet) ? data.sheet : DEFAULT_SHEET_NAME;
  }
}

const contoller = new SpreadSheetAPIController();

function doGet(e) {
  return contoller.handleGet(e);
}

function doPost(e) {
  return contoller.handlePost(e);
}

参照

最初デプロイできなくて

www.yukibnb.com

Node.jsでGoogleスプレッドシートを操作する

techblog.lclco.com

Google Sheets にデータを追加、更新、削除する Web API をサクッと作る

qiita.com

【GAS】スプレッドシート内の全シートへのリンク一覧を作る

qiita.com