dely Tech Blog

クラシル・TRILLを運営するdely株式会社の開発ブログです

GASで作ったBotを負債化させないようにやってきた管理の仕方

f:id:rnitame:20200814180020p:plain

こんにちは。androidエンジニアと兼任でスクラムマスターをしているkenzoです。
スクラムマスターの業務において、メンバーや自分へのリマインド、バックログ整理の自動化、タスク状況の可視化などをGAS(Google Apps Script)を使って実施しています。
また、それ以外にもプロジェクトの進行管理やいろいろなことをGASでやってきました。(自分の健康管理とかも

GASを使うとちょっとしたスクリプトを書くだけで簡単にG Suiteのサービス(ドキュメント、スプレッドシート、カレンダー等)と連携することができます。
HTTP通信もできるので、APIを通じて他のサービスと連携させることも可能です。
そのため、うまく使えばかなりの業務を効率化させることができます。

簡単なことをやらせているうちは良いのですが、次第にいろんなことをさせたくなり、スクリプトは複雑化していきます。
永遠に自分だけで管理するのならそのままでも良いでしょう。
しかし、会社で業務としてやる以上は役割が変わったり退職したりと他の人がそのbotの面倒を見るようになることが考えられます。
その後任の方に辛い思いをさせないよう、きちんと整理しておく必要があります。

本記事では筆者が初めてGASを触ってから今まで作ってきたbotの管理方法の変遷について書いています。
コードの中身の話はありません。

GASのコードエディタ直書き + トリガーで定期実行

初めはスプレッドシートからGASのコードエディタを開き、そこにスプレッドシートの内容の操作やSlack等の外部サービスと連携するコードを直に書いていました。
そして、その処理を定期実行させるために作成した関数をトリガーに設定して運用していました。

f:id:kenzo_aiue:20200527181417p:plain

おそらく誰しも初めはここから始めたことと思います。

Chromeの拡張機能を使いGitHubでコードを管理

運用を続け、コードが増えてくるとGitHub等で管理したい気持ちが強くなってきます。
初めのうちはGASのコードエディタに書いたコードをローカルのファイルにコピペし、それをGitHubに上げていました。
なにか良い方法はないかと思い、見つけたのがChromeの拡張機能「Google Apps Script GitHub アシスタント」でした。

これを使うとコードエディタ上にGitHubでのコード管理に使うボタンが表示されるようになり、その場でpushやpullをすることができるようになります。

f:id:kenzo_aiue:20200618114812p:plain

当時はこれでずいぶん楽になったのを覚えています。

claspを使ったローカル開発

コード管理は楽になりましたが、当時は依然としてGASのコードエディタ上でコードを書いていました。
また、コードをコピペしてきてIDE上で変更してそれをまたコードエディタに戻したりというきつい運用をしていたこともありました。
その頃知ったのがGoogleが作ったCLIツール「clasp」でした。

このツールを使うとコードエディタのコードをコマンドでローカルに持ってきて開発することができます。
そして、ローカルで開発したコードは別のコマンドでコードエディタにアップロードして動かすことができます。(他にもできることはあります)
これを使うことで泥臭くやっていたローカル開発を手軽に行えるようになりました。

そして、いつからかTypeScriptに対応していたので、ローカルではTypeScriptで書けるようになりました。

トリガーをコードとスプレッドシートで管理

これまで多くのトリガーを作成して運用してきましたが、トリガーには若干扱いづらい部分もいくつかありました。

  • トリガーが作成したユーザーに紐付くため他のメンバーから見られない
  • 定期的に走るトリガーは○時〜○時の間としか指定できず、その間のいつ発火するかわからない
  • どのトリガーがいつ発火するのものなのか、コンソールで一つずつ開いてみなければわからない

GASにはトリガーを作る関数もあるのでそれを使うことにしました。
スプレッドシートにこのように実行したい関数と曜日、時間を指定します。

f:id:kenzo_aiue:20200618084818p:plain
(イメージです)

毎日0時を過ぎたくらいにこのスプレッドシートを元にトリガーを作成する処理を走らせることで、上記の問題も下記のように解決できました。
ちなみにこの処理のトリガーだけはコンソールで管理していました。*1

  • スプレッドシート(+コードも)の権限さえ付与すれば誰でもトリガーを管理できる
  • 指定した曜日、時間にトリガーを発火させられる
  • スプレッドシートを見ればどのトリガーいつ発火するのかひと目で分かる

Slackに送るメッセージをスプレッドシートで管理

リマインドすべきものが増えてくると、中には毎度同じメッセージを送っているものもあることに気が付きました。
そこで、上記のトリガーと同様にスプレッドシートで送りたいメッセージを送信タイミングを指定して管理することにしました。

f:id:kenzo_aiue:20200618111643p:plain (イメージです)

SlackのユーザーやグループのIDを用意しておけば、メンション付きのメッセージを送ることもできます。
こちらも毎朝早い時間にその日のメッセージを送るトリガーを作成して*2指定した時間に実行しています。

ちなみにこれはslackのremindでもそこそこ近いことができます。

スクリプト毎にclaspの設定を持たせて管理

スクラムに関するBotが多くの機能を持つようになってきて下記の理由のためにスクリプトエディタを分ける必要が出てきました。

  • 1日にトリガーの最大設定数20を超える処理を実行する場合がある
  • シートに設置したオブジェクトのクリックで処理の実行をさせるためそのシートのスクリプトエディタ上に処理を書く必要がある
  • それぞれが異なる役割を持っている(リマインド機能、タスクの可視化機能など、、)

スクリプトを分けてもスクラムに関するBotとして共通の処理もあるため、GitHub上では1つのリポジトリで扱い、ディレクトリ毎にclaspの設定ファイルを置いてアップロード先を分けて運用する形にしました。

各スクリプト共通で使う処理の括り出し

上記でスクリプト毎にアップロードする単位を分けましたが、Slackへの投稿をする機能のようにそれぞれのスクリプトで同じ機能を使う箇所があります。
分けた当初はその機能をファイルとして切り出してはいたものの、それを各ディレクトリにコピペして置いていました。
そのため、処理に変更を加えたければそれぞれのディレクトリ以下にあるファイル同じファイルに同様の変更を加える必要がある状態でした。

こちらへの対応としては、共通処理を書いたファイルをディレクトリに括り出し、アップロードの直前でそれらを移動して対象のファイルと一緒にするかたちをとりました。

|--common
|  |--slack.ts
|  |--github.ts
|--script1
|  |--.clasp.json
|  |--src
|  |  |--script1.ts
|--script2
|  |--.clasp.json
|  |--src
|  |  |--script2.ts
|--script1アップロード用(スクリプトで作成)
|  |--.clasp.json
|  |--common
|  |  |--slack.ts
|  |  |--github.ts
|  |--script1
|  |  |--src
|  |  |  |--script1.ts

package.jsonにファイル移動・アップロードをするスクリプトを作成し、それを使って運用しています。 (webpackでまとめてからアップロードすることもできそうでしたが、こちらの方法に比べて学習・作業コストが高そうだったため一旦見送っています。いずれ時間のあるときに試してみようと思います。)

まとめ

以上が今日に至るまでに実施してきたGASで作ったBotの管理の仕方でした。
どこまで管理してどのような運用をすべきかはBotを使う環境や扱う方の職種等によって様々かと思います。
こちらはあくまで一例ですが、Botの管理や運用の仕方で困っている方の一助になれば幸いです。


delyはエンジニア大募集中です。クラシルのエンジニアとざっくばらんに話をするお茶会・ランチ会なども実施していますので、興味のある方は是非ご応募ください!

*1:V8ランタイムで実行する際にバグっぽい挙動があったので注意してください(コンソールで作成したトリガーで実行する関数でさらにトリガーを作成するとそのトリガーが無効になる?ような挙動でした。あんまりやらないとは思いますが。)

*2:トリガー毎にメッセージを渡すことができなかったので、別シートに送信予定のメッセージを置いています。