Github PagesでGASを使ってデータを保存・取得する


# はじめに

Github Pages で公開したサイトにデータを保存したい場合，静的サイトなのでサーバー側でデータを保存することができません．そのため，Google Apps Script を使ってデータを保存・取得する方法を紹介します．

また，せっかく Github Pages で公開しているので，特に登録も必要なく，無料で使えるものを使いたいと思います．

# 今回の目標

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670528/a61a0d25-2eee-a30e-7e62-99ec949626e0.png)

# GAS とは

Google Apps Script（GAS）は，Google が提供するスクリプト言語で，Google のサービスを自動化することができます．例えば，Google スプレッドシートや Google ドキュメントなどの Google のサービスを自動化することができます．
そして，GAS をウェブアプリとすることで，API として使うことができます．

今回は，データベースとして Google スプレッドシートを使っていこうと思います．その気になれば，Google ドライブにファイルを保存することもできるので，より高度なこともできるかと思います．

# GAS の作成

まず，Google スプレッドシートを作成します．
そして，拡張機能から「Apps Script」を選択します．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670528/45efd6fc-cd3b-4bd5-23da-33520a52eec6.png)

:::note warn
たまに更新によって，Google スプレッドシートのメニューに「Apps Script」が表示されないことがあります．その場合は，別の記事を参考にしてください．
:::

すると，新しいウィンドウが開きます．ここで，GAS を作成します．

早速コードを書いていくんですが，注意点として，GAS は GET と POST しか受け付けないので，それに合わせてコードを書いていきます．

```javascript
function doPost(e) {
  const string = e.postData.getDataAsString();
  const JsonData = JSON.parse(string);
  const sheetName = JsonData.sheet;
  const cell = JsonData.cell;
  const value = JsonData.value;

  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName(sheetName);
  sheet.getRange(cell).setValue(value);
  var data = { valid: true };

  const response = ContentService.createTextOutput();
  response.setMimeType(ContentService.MimeType.JSON);
  response.setContent(JSON.stringify(data));

  return response;
}

function doGet(e) {
  const sheetName = e.parameter.sheetName;
  const cell = e.parameter.cell;

  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName(sheetName);
  var value = sheet.getRange(cell).getValue();
  var data = { value: value };

  const response = ContentService.createTextOutput();
  response.setMimeType(ContentService.MimeType.JSON);
  response.setContent(JSON.stringify(data));

  return response;
}
```

このコードは，POST でデータを受け取ると，そのデータをスプレッドシートに書き込みます．GET でデータを受け取ると，そのデータをスプレッドシートから読み込んで返します．
また，セルとシート名を指定してデータを読み書きしています．

リクエストデータは，以下のようにします．

### GET

```
https://script.google.com/macros/s/GASのデプロイID/exec?sheetName=シート名&cell=セル名
```

クエリパラメータ部分は`?sheetName=シート名&cell=セル名`です．

### POST

```json
{
  "sheet": "シート名",
  "cell": "セル名",
  "value": "値"
}
```

:::note warn
データをエンコードしたほうがいいかもしれませんが，今回は省略します．
そのため，日本語でデータを**value**を送ると，文字化けするかもしれません．
その場合は，エンコードするか，英語などで送るようにしてください．
:::

# GAS の公開

次に，GAS を公開します．
GAS のウィンドウで，左上の「デブロイ」をクリックします．
初めてであれば，新しいデプロイを選択します．
ウェブアプリとして公開します．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670528/a3445fc9-a38f-b757-bd75-4e82249dc145.png)

二回目以降であれば，デプロイを管理->編集->バージョンを新バージョンに変更します．
これによって，URL が変更されずに更新ができます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670528/0ffba9b4-d179-e6d8-6a90-3f94b9b6de3b.png)

これによって，GAS の URL が発行されます．この URL を使って，データを保存・取得します．

# Github Pages で使う

最後に，Github Pages で使うために，fetch を使ってデータを送受信します．

### fetch の使い方

```javascript
async function fetchData(url, options) {
  try {
    const response = await fetch(url, options);
    const data = await response.json();
  } catch (error) {
    console.error("Error:", error);
  }
}
```

### GET

```javascript
// GASのurlにクエリパラメータ（?sheetName=シート名&cell=セル名）を付ける
const url =
  "https://script.google.com/macros/s/GASのデプロイID/exec?sheetName=シート名&cell=セル名";
const options = {
  method: "GET",
  headers: {
    "Content-Type": "application/json",
  },
};
fetchData(url, options);
```

### POST

```javascript
// GASのurl
const url = "https://script.google.com/macros/s/GASのデプロイID/exec";
const options = {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    sheet: "シート名",
    cell: "セル名",
    value: "値",
  }),
};
fetchData(url, options);
```

# まとめ

GAS を使って，Github Pages サイトでのデータを保存・取得する方法を紹介しました．
Github Pages も GAS も無料で使えるので，無料でデータベースを使うことができます．

# 次回

今回は，GET や POST でスプレッドシートのデータを読み書きしましたが，これだけでは spreadsheet の API を使用すればいいだけです．

https://developers.google.com/sheets/api/guides/concepts?hl=ja

ただし，それでは spreadsheet の API 情報が漏れてしまうこともあり，セキュリティ上あまりよろしくないです．（特に GithubPages では）
つまり，次回は，GAS でリクエストを処理することで，キーワード認証を行えるようにしたいと思います．