【GAS】プロパティサービスについてまとめる

# はじめに
最近GASを使い始め、プロパティサービスを覚えたので忘備録として記録します。
GASでアクセストークンやAPIキーを使用する際、はじめは以下のようにハードコーディングを行っていました。

```javascript:ダメな例
const apiKey = 'xxxxxxxxxxx';
const accessToken = 'yyyyyyyyyyyy';
```
しかし、セキュリティ的にまずいなと思い調べたところ、GASにはプロパティサービスという機能がありました。
これを使用することでハードコーディングを避けてセキュリティ性やメンテナンス性の高いコードが書けるようになります。

# プロパティサービスとは
プロパティサービスとは、スクリプト内で使用する値を、キーと値をペアとして保存できるサービスです。
キーと値はいずれも**文字列に変換**されます。
**プロジェクト内ならグローバルに読み書きが可能ですが、複数のプロジェクト間での共有はできません。**

# プロパティサービスの種類
プロパティサービスには以下の3種類のサービスが存在します。
1. スクリプトプロパティ
2. ユーザープロパティ
3. ドキュメントプロパティ

それぞれの違いをみていきます。
## スクリプトプロパティ
プロジェクト内の全てのユーザーが、読み書き可能。
**アプリケーション全体の設定値**を格納するのに適している。

## ユーザープロパティ
そのユーザーのみ読み書き可能。
**ユーザー固有の設定値**を格納するのに適している。

## ドキュメントプロパティ
開いているドキュメントのアドオンのユーザーが、読み書き可能。
**ドキュメント固有の設定値**を格納するのに適している。


# スクリプトプロパティを使ってみる
スクリプトプロパティの読み書きの方法についてみていきます。

少し話がずれるのですが、GASは2020年12月にエディタがアップデートされました。
このアップデートにより、旧エディタで可能であったGUI上でスクリプトプロパティの読み書きが、新エディタではできなくなりました。
セキュリティ上、GUIで設定値が見れるのはよくないと考えているので、
GUIでの読み書きの方法に関しては今回省略し、スクリプトでの読み書きの方法についてのみ記述します。

## プロパティの追加
以下のように、各プロパティサービスの`setProperty()`を使用することで値を格納できます

```javascript:プロパティの追加
// スクリプトプロパティ
var scriptProperties = PropertiesService.getScriptProperties();
scriptProperties.setProperty('SERVER_URL', 'http://www.example.com/');

// ユーザープロパティ
var userProperties = PropertiesService.getUserProperties();
userProperties.setProperty('EMAIL', 'hoge@test.com');

// ドキュメントプロパティ
var documentProperties = PropertiesService.getDocumentProperties();
documentProperties.setProperty('SOURCE_DATA_ID', '1234567890abcdefghijklmnopqrstuvwxyz');

```

`setProperties()`を使用すると一気に複数のプロパティを追加することも可能です。

```javascript
var scriptProperties = PropertiesService.getScriptProperties();
scriptProperties.setProperties({
  'cow': 'moo',
  'sheep': 'baa',
  'chicken': 'cluck'
});
```

## プロパティの取得
以下のように、各プロパティサービスの`getProperty()`を使用することで値を取得できます。

```javascript:プロパティの追加
// スクリプトプロパティ
var scriptProperties = PropertiesService.getScriptProperties();
scriptProperties.getProperty('SERVER_URL');

// ユーザープロパティ
var userProperties = PropertiesService.getUserProperties();
userProperties.setProperty('EMAIL');

// ドキュメントプロパティ
var documentProperties = PropertiesService.getDocumentProperties();
documentProperties.setProperty('SOURCE_DATA_ID');

```


`getProperties()`を使用すると複数の値を一気に取得できます。

```javascript:プロパティの取得
var scriptProperties = PropertiesService.getScriptProperties();
var data = scriptProperties.getProperties();
for (var key in data) {
  Logger.log('Key: %s, Value: %s', key, data[key]);
}
```

## プロパティの修正
プロパティの修正をしたい場合は再度`serProperty()`を行うと、値が上書きされます。

```javascript:プロパティの修正
var userProperties = PropertiesService.getUserProperties();
var units = userProperties.getProperty('DISPLAY_UNITS');
units = 'imperial';
userProperties.setProperty('DISPLAY_UNITS', units);
```

## プロパティの削除
プロパティを削除したい場合、`deleteProperty()`を使用すると削除できます。

```javascript:プロパティの削除
var userProperties = PropertiesService.getUserProperties();
userProperties.deleteProperty('DISPLAY_UNITS');
```

`deleteAllProperties()`を使用すると全てのプロパティを削除できます。

```javascript
var userProperties = PropertiesService.getUserProperties();
userProperties.deleteAllProperties();
```

# 機密情報を取り扱う
最後に、スクリプトプロパティでの機密情報の取り扱い方についてのメモ。
スクリプトプロパティは上述した通り、プロジェクト内のユーザーで編集権限があれば誰でも編集することができます。
そのため、機密情報を使用する際はスプレッドシートに値を記述し、そのスプレッドシートの編集権限（閲覧権限）とスクリプトの実行権限は特定のユーザーのみに限定することで、セキュリティを担保することができます。
やってみた記事をまた別で書こうと思います。

# 参考サイト
[Class PropertiesService](https://developers.google.com/apps-script/reference/properties/properties-service)
[Properties Service](https://developers.google.com/apps-script/guides/properties)
[Google Apps Scriptで使う情報はプロパティを利用しよう](https://officeforest.org/wp/2019/04/30/google-apps-script%E3%81%A7%E4%BD%BF%E3%81%86%E6%83%85%E5%A0%B1%E3%81%AF%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%82%88%E3%81%86/)