【GAS】パスワードやトークンをコードに直書きしない方法

こんにちは、しきゆらです。
最近はGASをよく書いています。

そんな中、GASを書いていて困るのは「コードにパスワードとかを直書きしたくない」ということ。
環境変数のようなものがあればいいのに・・・と思っていました。

探してみると、一応それっぽいものは用意されていました。
それが、PropertiesServiceというもの。
ドキュメント:https://developers.google.com/apps-script/reference/properties/properties

こいつを使えば、コードに書きたくない隠しておきたいものを置いておくことができます。

ということで、今回はPropertiesServiceの設定方法や使い方をメモしておきます。


PropertiesServiceとは

PropertiesService自体は、シンプルなkey / value形式でデータを保持できる仕組みです。
スクリプトが紐づいているドキュメントを対象にデータを持たせることができます。
基本的な使い方は以下の通り。

const documentProperties = PropertiesService.getDocumentProperties();
documentProperties.setProperty("key", "value");
documentProperties.getProperty("key"); // => value

// 複数の値を一気に設定も可能
const config = {username: "hoge", age: "20"};
documentProperties.setProperties(config);

名前が長いですが、基本的にはPropertiesServiceからインスタンスを取得して、データをセットしたり取得したりできます。

なお、ドキュメントにはScriptPropertyUserPropertyも紹介されていますが、これらは非推奨のようです。
特に、前者のScriptPropertyに関しては、GASの古いエディタにあった「スクリプトプロパティ」のようですが、
新しくなったエディタでは、そもそも項目がなくなっているので使わないほうがよいでしょう。

GUI上で設定することはできません。
スクリプト内でデータの設定・取得・削除を行うことになるので、何の値を入れていたっけ?とならないようにきちんと管理したいです。

PropertiesServiceに追加できる値

PropertiesServiceは、基本的に文字列を設定することになります。
例えば、配列を設定すること自体は可能ですが、内部的には文字列として保存されます。

const array = [1,2,3];
array[0] // => 1

documentProperties.setProperty("array", array);
_array = documentProperties.getProperty("array");
_array[0] // => [

上記は何が起こっているかというと、arrayの値を文字列として保存しているので
文字列に対して[0]でアクセスして1文字目の「[」を取得している、という感じです。
どんな値も保持することができますが、あくまで文字列として保持されるので注意が必要です。

特に注意なのは、大きな数値を数値のまま設定すると値が変わることです。
コード上で大きな値を変数に突っ込んで、これを設定しようとするとおかしな値を取得してしまいます。
この辺はJSの仕様っぽいですが、xxxxxxxxe+23のような形になってしまって意図しない値になってしまうことがあります。
なので、基本的には数値は文字列で設定するのがよさそうです。

任意の値を保持させたい

さて、基本的には文字列として保存されるPropertiesServiceですが、やはり文字列だけでは物足りないですよね。
いくつかの値をひとまとめにして保持したいとか思いますよね。
例えば、ログイン情報をサイトごとに保存しておきたいとか。

どうすればよいか、というと文字列として保存されるということで、保存したいものを文字列でも問題ない形で保存してしまえばよいのです。
JSで任意のオブジェクトを文字列として保持するもの、ありますよね。
そう、JSONです。

先ほどの配列の例でもそうですが、配列をJSONにして保持すればきちんと元に戻して中身を取得することも可能です。
実際に見てみましょう。

const array = [1,2,3];
array[0] // => 1

const arrayJson = JSON.stringify(array); // JSONに変換
documentProperties.setProperty("array", arrayJson);


const _arrayJson = documentProperties.getProperty("array"); 
const _array = JSON.parse(_arrayJson); // JSON形式で保存しているのでパースする
_array[0] // => 1

はい、きちんと値を取得できていますね。
これで、任意のオブジェクトを保持することができるようになりました。

まとめ

今回はGASで環境変数のように使えるPropertiesServiceを紹介しました。
GASは、個人的には微妙に使いにくい印象があったんですが、
ほぼJSとして書けるのとSpreadSheetやメールなどGoogleサービスを利用したスクリプトを気軽に書けるので最近はちょこちょこ各頻度が上がっています。

また、TypeScriptも良しなに変換してくれるようなので、JSなんて型がない世界で生きていけるか!という方も安心です。
好きな言語でAPIをたたくのもよいですが、そこまで準備するのも面倒だなぁというときに気軽に書けるGAS、おすすめです。

ということで、今回はここまで。
おわり