Google Apps Scriptはライブラリを活用すべし【GAS】

Google Apps Scriptで開発をしていると、だんだん似たようなコードや同じ仕組みを同じプロジェクトに何度も書く事が出てきます。しかし、そのままでは他のプロジェクトで使い回しをしたり、コードを簡潔に書くにはちょっと不都合です。また、1つのスプレッドシートに複数のプロジェクトファイルを追加した場合、プロジェクトプロパティなどはそのプロジェクト内のものしか参照出来ないので、複数のプロジェクトで参照させたい場合、これでは困った事になります。

そこで活用したいのが、ライブラリ機能。なるべくなるべく小さな関数や決まった処理をするルーチンはライブラリにまとめて、足りない部分だけをコードで記述するようにすると、開発がとっても早くなります。但し、公式サイトにも掲載されていますが、ライブラリは使用するとプログラムの実行速度は遅くなりますので、注意が必要です。5分の壁問題が生じる場合には、あえて使わない事も考慮すべきでしょう。

※2020/12月リリースの新IDEよりプロジェクトキーは利用不可能になり、スクリプトIDで統一されました

今回使用するスプレッドシート

スクリプトID:
18ZTA1QAjtpJuhtn4Uka0Yo-VIKodP8zVVR71uJPg1qgr4vUkiGtt7lXS

ライブラリの作り方

コードを記述する

様々な処理を行う関数をまずプロジェクト内に記述しましょう。この時、他のプログラムから呼び出される事を意識してコードは書かなければなりません。あくまでも別々のプロジェクトなので、スプレッドシート操作などでgetActiveSpreadsheetなど使っても、ライブラリ側からはアクティブなスプレッドシートがどれなのかわかりませんから。

また、変わった使い方としては、ライブラリ側によく使うCSSやJavaScriptの塊をhtmlファイルとして用意しておき、HTML ServiceのgetContent()で取得し返して上げる。ライブラリ呼び出し側は、HtmlService.createTemplateFromFileにて表示したウェブアプリのコード内に、スクリプトレットとしてライブラリ側のCSSを呼び出してあげると、cssやjavascriptを使いまわしする事が出来るようになります。

スクリプトプロパティを共用してみた

ワークフローな仕組みを作る時に、例えば読み書きするスプレッドシートのIDなどや送信先メアドなどをプロパティサービスを使って保存し、プログラムで利用することがあります。しかし、申請用フォームと承認用フォームで共用の2つで共用したくとも、スクリプトプロパティはそのプロジェクト内しか参照できません。

そこでライブラリ機能を使って1箇所で読み書き出来るようにして使ってたりします。この場合そのスプレッドシートには申請用、承認用に加えてスクリプトプロパティ用の3つ目のプロジェクトを追加しておく必要があります。この3つ目がライブラリとなります。

読み書きコード
//プロパティを取得する
function getProp(value) {
  var Properties = PropertiesService.getScriptProperties();  
  var temp = Properties.getProperty(value);
  
  return temp;
}

//プロパティをセットする
function setProp(key,value){
  var Properties = PropertiesService.getScriptProperties();
  
  Properties.setProperty(key,value);
}

呼び出し側は、例えばlibrary.getPropでプロパティを取得します。library.setPropでプロパティを保存します。呼び出し側でPropertiesServiceをいちいち記述する必要もないので楽ちんです。共通設定用のプロジェクトとしてこれを版保存し呼び出し側のライブラリに追加してあげましょう。

CSSをライブラリとしてみた

GASのコード
//CSSを取得して返す
function getcss(cssname){
  var css = HtmlService.createHtmlOutputFromFile(cssname)
          .setSandboxMode(HtmlService.SandboxMode.IFRAME).getContent();

  return css;
}
css.htmlのコード
<style>
table {
    border-collapse: collapse;
    width:100%;
}
th.t_top {
    border-top: #be1309 4px solid;
}
th {
    border-bottom: #e3e3e3 1px dotted;
    text-align: left;
    padding: 10px;
    font-weight: normal;
}
td.t_top {
    border-top: #b3b3b3 4px solid;
}
td {
    border-bottom: #e3e3e3 1px dotted;
    text-align: left;
    padding: 10px;
}
tr:hover {
    background: #3D80DF;
    color: #FFFFFF;
}
</style>

引数にcssnameを取っています。cssnameで使うcssファイルを切り替えられます。

呼び出し側コード

GAS側のコード
//メイン画面呼び出し
function doGet(e) {
  var output = HtmlService.createTemplateFromFile('index2');
  var html = output.evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME);
 
  return html;
}

//ライブラリ側にあるCSSファイルを呼び出す
function retcss(){
  var css = library.getcss("css");
  return css;
}
HTML側のコード
<head>

  <?!= retcss(); ?>

</head>
<body>
  <!-- 基本情報入力部分 -->
  <table summary="ウェブサイト紹介">
    <tr>
      <th class="t_top" width="100">サイト名</th>
      <td class="t_top">officeの杜</td>
    </tr>
    <tr>
      <th>サイトのジャンル</th>
      <td>G SuiteやMicrosoft365</td>
    </tr>
    <tr>
      <th>URL</th>
      <td>https://officeforest.org/</td>
    </tr>
    <tr>
      <th>趣味</th>
      <td>パッションフルーツの栽培</td>
    </tr>
    <tr>
      <th>メールアドレス</th>
      <td>hogehoge@hogehoge.com</td>
    </tr>
  </table>
</body>
サンプルページ

注意事項

ライブラリを記述する時に注意しなければならないポイントがいくつかあります。

  1. もし同じプロジェクト内に同じ関数やクラスなどがある場合、オーバーライドされてしまいます
  2. ライブラリ内でだけ使ってるプライベートな関数は、参照させたくないので、関数名の後にアンダーバー(_)を入力する。例えば、getkinoko()という関数ならば、getkinoko_()でプライベート関数になります。セキュリティホールになるので注意。
  3. ライブラリへのアクセス権限がなければ、ライブラリを追加しても使えません。必ずそのライブラリが属するドキュメントに公開権限を付けるようにしましょう。
  4. ライブラリは最低でも1個は版として保存しなければ使えないので、必ず版を保存しましょう。また、版として保存しないと、反映もされないので、記述したのに出てこない時には注意。
  5. ライブラリを呼び出す側も版(バージョン)指定によって使える関数などが変わってくるので注意が必要です。提供する側も古い版は捨てるようにしましょう。
  6. ライブラリの関数をGoogleスプレッドシート上では直接呼び出せません。スプレッドシートのプロジェクト上で呼び出す関数を用意してあげましょう。

Google Apps Scriptの関数は誰でも実行できちゃうので注意【GAS】

JSDocを記述しておく

JSDocとは、関数を記述する時に関数のリストや候補として出て来る文字列を用意しておくもので、利用者がどんな関数なのか?入力中にわかるようにしておく為のリストです。独特の記述方法があります。この記述を関数の前に記述しておく事で、その関数の使い方や引数の取り方などがわかるようになり、また、JSDocを記述することでライブラリのリファレンスも自動的に作成されます。

例えばとある関数のJSDocとしては以下のように記述してあります。

/**
* これ、Admin SDK有効にしておかないと使えないよ★
*
* var pass = ore.addUser("メールアドレス","名","姓");
* @param {string} mail 作りたいメールアドレスを入れる
* @param {string} firstname 文字通りファーストネームを入れます。
* @param {string} familyname ファミリーネームを入れます。姓ですな。
* @return {string} pass 自動生成したパスワードを返します。
*/ 
function addUser(mail, firstname, familyname) {
  var pass = String("_" + Math.random().toString(36).slice(-11));
  var user = {
    primaryEmail: mail,
    name: {
      givenName: firstname,
      familyName: familyname
    },
    // Generate a random password string.
    password: pass,
    changePasswordAtNextLogin: true
  };
  user = AdminDirectory.Users.insert(user);
  return pass;
}

この関数を入力しようとするとオートコンプリートの候補として以下のように表示されます。

図:addUserの入力候補が出てきました

公開する

公開する時に必要なのは、スクリプトIDです。以前はプロジェクトキーを使っていたのですが現在は推奨されていません。公開するにはまずは現在の版を保存します。保存手順は以下のとおりです。

  1. スクリプトエディタに於いてメニューより「ファイル」⇒「版を管理」をクリック
  2. テキストボックスにバージョンの説明文を入れて、「新しいバージョンを保存」をクリック
  3. 改めてメニューより「ファイル」⇒「プロジェクトのプロパティ」をクリック
  4. 情報タブの中にある「スクリプトID」の文字列をコピー
  5. スクリプトIDを使ってもらいたい人に教える

図:スクリプトIDが重要なのです

V8エンジン対応

2020年2月6日よりV8エンジンが利用可能になったことに関連して、ライブラリでの要注意事項です。

GASのライブラリを使う場合、呼び出し元のプロジェクトがRhinoで、呼び出し先のライブラリ側がV8の場合、呼び出し元でそのライブラリを使った場合、V8でなければ使えないメソッド等の場合エラーとなります(逆にV8では使えないメソッドをライブラリ側で使っていた場合も同じ)。

呼び出された側のエンジンで動く事になるので、ライブラリ運用してる人は要注意事項です。必ず、両方のエンジンは同じにする事。ライブラリ側でうまく動いてるから問題なしと思ったら、それを使っていたプロジェクト側がV8ではなくエラーがバンバン出ることになります。

図:安易にライブラリ側はV8にすると厄介な事に

ライブラリの使い方

自分が作成したライブラリや他人が公開されてるライブラリは、公開されてるプロジェクトキーやスクリプトIDを追加する事で可能になります。尚現在、プロジェクトキーは使用は推奨されていませんので、公開する時はスクリプトIDを公開するようにしましょう。

さてこのキーやIDを追加し使えるようにしましょう。以下の手順で追加します。

追加手順

  1. スクリプトエディタのメニューより「リソース」⇒「ライブラリ」を開きます。
  2. ライブラリを追加のテキストボックスにプロジェクトキーやスクリプトIDを入れて、追加ボタンを押す
  3. ライブラリ一覧に追加されます。公開バージョンを選び、識別子を設定します。
  4. 識別子は関数を使う時に頭に付けるもので、ドット区切りでそのライブラリの関数を呼ぶので、例えばmomentと付けると、moment.hogehogeといった形でhogehoge関数呼び出します。日本語は使えません。
  5. 保存を押すと使えるようになります。

図:ライブラリ追加画面

ライブラリの関数を使う

追加すると、識別子にドットを付ければ、ライブラリの関数を呼び出す事が可能になります。自分のプロジェクトに作った関数と同じように使えるようになります。例えば、moment.jsを取り込み、識別子にmomentと指定した事例として

例えばある日付データがある日付データの属してる週と同じかどうかを検証する場合には

var hantei = moment.moment('2018/4/9').isSame('2018/4/13','week');

この時変数hanteiに、同じ週ならば、trueが入ります。違う週ならばfalseが入ります。識別子は大文字小文字区別するので注意して下さい。

開発者モード

自作のライブラリの場合、開発者モードと呼ばれるバージョンがあり、このバージョンの場合デプロイせずとも常に最新のコードが実行される状態になります。ライブラリを登録した状態ではこの版が表示されてるはずです。

ただしこのモードは、自分しか利用できない為、第三者にこのライブラリを含めたスクリプトを渡しても動作しません。第三者に渡すもしくは公開、またアドオン等に含めてGoogleにレビューを受ける場合には、必ずデプロイして指定の版にて設定しておかなければ動作しませんので要注意です。

図:あくまで開発中だけ使用する事

外部JSライブラリを使う手法

これまでの手法はあくまでもGASで作成されたライブラリを利用する手法です。しかし、次項で紹介するような一部のライブラリは既にメンテされてなかったり古かったり、本家とはバージョンがだいぶ乖離してるものや、そもそもGASで用意されていないものも多いです。

ですが、以下の手法を利用することで、GAS用ではないもののJS用のライブラリを使える可能性があります。

  1. GAS内でeval関数を使って以下のように外部JSを呼び出す
    //moment.jsを呼び出して使う
    eval(UrlFetchApp.fetch('https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js').getContentText());

    evalで括った中で対象のライブラリをurlfetchappで呼び出し、中身をgetContentTextで取得すると、GAS内で使えるようになります。

  2. GAS内ではSleep関数は使えないので、ライブラリ内で使ってる場合は以下のようにメソッドを置き換えてしまいます。
    //setTimeoutをUtilities.sleepに置き換えてしまう
    setTimeout = (func, sleep) => (Utilities.sleep(sleep),func())

    GASのUtilities.sleepに置き換えてしまうことで、ライブラリの実行エラーを回避出来ます。

以下のエントリーではJS用のPDF操作ライブラリを使う手法を紹介しています。

Google Apps ScriptでPDFフォームを操作する【GAS】

公開してるライブラリ

Moment.js

※本プロジェクトは2020年9月に大元のプロジェクトが終了してしまいました。ただV8が使えるようになったGASならば、days.jsなどのソースを取り込んで使えるかもしれません。

もともとはJavaScriptで日付関係の処理をより簡単に扱う為に作られたMoment.jsをGoogle Apps Scriptでも使えるようにリファインしたライブラリ。自分でも簡単に用意出来るので、自分でソースコードをまるごとコピペして、ライブラリ化しても良いでしょう。公式リファレンスを見ながらそのまま使えます。

※但し、前述のeval関数を使った手法を使うことで本家Moment.jsのCDNのライブラリを呼び出せば最新のものが使えるので、JSライブラリを使う手法をオススメします。

プロジェクトキー:MHMchiX6c1bwSqGM1PZiW_PxhMjh3Sh48

最新のIDEではプロジェクトキーが使えない為、どうしても使いたい人はこちらにあるのが大元のようなので、コピーして自分でスクリプトIDをコピーすると良いかと思います(V8でも動くかどうかは未検証)。一応自分がコピーしておいたものは、スプレッドシートにしてあります。

Underscore.js

もともとはJavaScriptで配列やオブジェクト、各種関数などをもっと便利に使えるようにと用意されてるUnderscore.jsをGoogle Apps Scriptでも使えるようにしたライブラリです。Githubにてメンテナンスされています。100種類にもおよぶ数々の関数を使えるようになります。

こちらは7年前で開発が止まっていますが、大元のスクリプトはこちらのようで、コピーして自分でスクリプトIDをコピーすると良いかと思います(V8でも動くかどうかは未検証)。一応自分がコピーしておいたものは、スプレッドシートにしてあります。

プロジェクトキー:M3i7wmUA_5n0NSEaa6NnNqOBao7QLBR4j

Cheeriogs

Google Apps ScriptもUrlfetchAppを利用してスクレイピングできると言えばできるのですが、正直最も単純なタイプのスクレイピングしかできない点と、スクレイピングしたあとの処理がちょっと大変。そこで使うのがこのライブラリで、Node.jsなどでは結構おなじみのjQueryライクにスクレイピングした内容を処理できるという非常に便利なライブラリです。
※後述のXML Parserが以前は使われていましたが、扱いにくいののでCheerio.gsがオススメです。

 

自分もPuppeteerでのスクレイピング後の処理で利用させてもらってるもののGoogle Apps Script版となります。例えば、$('tomato').text()といったような構文でIDがtomatoのテキストデータを取り出せたりします。

 

ただ、ディープで高度なスクレイピングとなると、Google Cloud FunctionsでPuppeteerを動かして、Node.jsのCheerioで処理させるほうが苦労しなくて済むかと思います(特に動的サイトでは)。

Google Apps Scriptでスクレイピングを極める【GAS】

スクリプトID:1ReeQ6WO8kKNxoaA_O0XEQ589cIrRvEBA9qcWpNqdOP17i47u6N9M5Xh0

HTML/XML Parser for Google Apps Script

Google Apps ScriptにてHTMLのスクレイピングやXMLファイルのパースを簡単に行えるようにと作られたライブラリで、Githubにてメンテナンスされています。使い方の説明は製作者のページに記載されています。

スクリプトID:1Jrnqmfa6dNvBTzIgTeilzdo6zk0aUUhcXwLlQEbtkhaRR-fi5eAf4tBJ

BetterLog

Google Apps ScriptはLogger.logにて各種ログを取得することができますが、ちょっと使いにくい。再度スクリプトを実行すると前のログは消えてしまいますし。そこでこのlogをスプレッドシートに書き出してくれるライブラリがこのライブラリ。Githubにてメンテナンスされています。

4年前からストップしているので、コピーして自分でスクリプトIDをコピーすると良いかと思います(V8でも動くかどうかは未検証)。一応自分がコピーしておいたものは、スプレッドシートにしてあります。

プロジェクトキー:MYB7yzedMbnJaMKECt6Sm7FLDhaBgl_dE

ChatWorkClient for GAS

チャットサービスである「ChatWork」のAPIをGoogle Apps Scriptから扱えるようにする為のライブラリです。公式サイトでメンテナンスされています(Githubはこちら)。Google Apps Scriptからチャットを投げる事が可能になったりします。

スクリプトID:1nf253qsOnZ-RcdcFu1Y2v4pGwTuuDxN5EbuvKEZprBWg764tjwA5fLav

SlackApp for Google Apps Script

ビジネス向けとしてプッシュしてるチャットサービス「Slack」にGoogle Apps Scriptから投稿できるようにしてくれるライブラリです。作者のサイトでメンテナンスされています。ITのスタートアップ企業などでよくみかけますね。

スクリプトID:1on93YOYfSmV92R5q59NpKmsyWIQD8qnoLYk-gkQBI92C58SPyA2x1-bq

 

OAuth2 library for Google Apps Script

Google Apps Scriptにて外部のサービス認証で用いられてるOAuth2認証を手軽に出来るようにする為のライブラリです。これを用いることで、例えばFacebookなどのサービスにOAuth2認証して連携などが出来るようになります。Githubにてメンテナンスされています。各種サンプルも用意されているので、おすすめです。

スクリプトID:1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF

Google Service Account Library for Apps Script

Googleのプロジェクトに於いてサービスアカウントを容易に扱えるようにするためのライブラリです。Githubにてメンテナンスされています。あまり一般の人は使うことがないかもしれませんが、Google開発者としては利用する価値があるかもしれませんよ。

プロジェクトキー:MJ5317VIFJyKpi9HCkXOfS0MLm9v2IJHf

CryptoJS libraries for Google Apps Script

JavaScriptで用いられてる文字や画像類などをAES暗号化する為のライブラリです。こちらのサイトで詳細を見ることが出来ます。ソースコードはこちらから閲覧できます。

プロジェクトキー:MSJnPeIon6nzdLewGV60xWqi_d-phDA33

spreadsheets-sql

Googleスプレッドシート上のデータを更新や変更、削除をするのは結構手間が掛かります。この更新作業をSQLっぽい感じのコードで手軽に扱えるようにしてくれるライブラリです。Githubにてメンテナンスされています。公式サイトでドキュメントを見ることが可能です。

スクリプトID:17p1ghyOkbWOhdE4bdBFhOXL079I-yt5xd0LAi00Zs5N-bUzpQtN7iT1a

NCMB for Google Apps Script

Niftyが提供してるスマフォ向けのモバイルバックエンドサービスであるmBaaSをGoogle Apps Scriptから操作出来るようにしてくれるライブラリです。プッシュ通知に代表されるAPIが使えるのはとても便利ですね。公式サイトでメンテナンスされています。V8版は別ライブラリになってるので注意。

プロジェクトキー(旧版):1yWnb7GfYsBCR-MZvi6r-TOYv_y-AV4le5P7kaG5B3iZ5VNnSk9Q55pSJ
スクリプトID(V8版):1Z8Lezd0OS6qm9W0EVQxBGx1gztqD14kXPfQxycr_rc2atOfKujiWZe7I

SORACOM API ライブラリ

IoTプラットフォーム「SORACOM」をGoogle Apps Scriptで扱うためのライブラリです。主にセンシングデバイスでSIMを使ってのデータ通信を管理するためのもので、農業などでは活用ができそうですね。ライブラリはこちらのページで公開されています。使い方含めて詳細に記述されているので、IoTに興味のある人の助けになるでしょう。

プロジェクトキー:MJlievwjcIu8-7grDZqGf-FSucpP_quDO

TwitterApp for Google Apps Script

言わずとしれたツイッターへGoogle Apps Scriptでアクセスを容易にするためのライブラリです。GitHubにてメンテされています.ツイートを投稿したりデータを取得したり、このライブラリがあれば自前で構築する必要がありません。

※現在のXでも使えるかどうかは不明です。

スクリプトID:1CIaZhVF8e8d_RVv5T1GGJrkVZjZhv4Cg-Nsylwv1OUa8x7nxeQjNdll3

Google Apps Script Kintone Library

小規模な業務改善プラットフォームとして利用されているサイボウズのKintone。Google Apps Scriptがあると正直利用するのかな?と思うところではあるけれど、GASからKintoneへアクセスする為の一連のAPIをまとめたライブラリ。Githubにてメンテされています。レコードの取得、更新、削除など一通りの作業を簡単に実現できます。

スクリプトID:1-Dlw6bRJOH65e2XwrimFwwFn9vHMa5m1PS6E_2_kMcC99Hxm1Nm7nFkt

GASUnit ライブラリ

Google Apps Script用のテスト実行ライブラリです。Githubにてメンテされています。Google Apps Scriptにはテスト実行用環境などは用意されておらず、QUnitベースのライブラリはこちらにあります(Key : MxL38OxqIK-B73jyDTvCe-OBao7QLBR4j)。

プロジェクトキー:MSnMmw8hLWgjUG6uKSTQBEzVZgzu5bsVr

Google Apps Script Drive API v3 ライブラリ

Google Apps ScriptのDriveAppはDrive API v2に従ったもので、またその機能の全てを実装しているわけではありません。その為、Google Driveのファイル操作に於いて、GASでもDrive APIを別途呼び出して使う必要があるシーンがあります。そんなDrive APIをGASで使いやすくするためのライブラリ。但しこちらはプロジェクトキーで公開されてるわけではなく、Githubでソースが公開されてるだけなので、自分でスクリプトファイルにコピペして使う必要があります。使えるのかどうかも不明・・・
また、Drive APIを有効にする必要があるため、Cloud Consoleとの紐付け作業等も必要になります。

 

QualityForwardライブラリ

QualityForwardと呼ばれるクラウドベースのテスト管理サービスをGASから使うライブラリ。Qiitaのページにて開発中のようです。ソフトウェアのテストを行う為のもので、Redmineとも連携してるとか。大規模開発のデバッグ作業などを行うのに人力じゃちょっとね・・・というケースで活躍するサービスですね。

 

スクリプトID:1ppRPLjuClG0MhtnXYbskdZ8uYGbyCFHv7MFhr0GYa-3IAKEh8B7lmTMb

Firestore for Google Apps Scripts

Googleのモバイル向けプラットフォームであるFirestore Databaseにアクセスしやすくする為のライブラリです。認証関係やデータのやり取りなどができますが、事前セットアップとしてプライベートキーの取得などが必要になります。コードは、Githubにてメンテされています。

スクリプトID:1VUSl4b1r1eoNcRWotZM3e87ygkxvXltOgyDZhixqncz9lQ3MjfT1iKFw

 

RunAllライブラリ

Google Apps Scriptは基本的には並列処理が出来ません。そのためマルチスレッドなプログラミングで速度をあげようとおもっても、其のための仕組みがないので、基本一個ずつ実行になります。しかしいくつか例外があって、UrlfetchApp.fetchAll()は非同期に実行されるので、これを利用して擬似的に並列処理をさせることが可能です。こちらでメンテされています。

 

ただし、UrlfetchAppのQuotaの制限や10秒間に実行できる最大数は3個までなので、実装するにはSleepなどの処理を考慮する必要があります。今回のこのライブラリはUrlfetchApp.fetchAll()をより簡単に使えるようにするためのライブラリです。ただし、GASの命令実行は最大で30の制約もあるので、メソッドの実行は最大で30まで。

 

スクリプトID:1FWYhQFhL7UIAZJn-FR3TlcHvXwHPJc2HwI4vtmNUAQv2OybGe-S97Lal

関連リンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)