Google Apps Scriptでカンバンボードを作成する【GAS】

業務でタスク管理が非常に重要視されてきています。と言っても、これまでのようにタスクをただ並べて、消化したら消すだけでは芸がない上に、効率的で且つ合理的な管理が出来てるとは言えません。そこで使われているのがKanban BoardMicrosoft365のPlannerであったり、Backlogであったり、AsanaTrello等が利用されるようになりました。

しかし、Google WorkspaceにはアドオンとしてはKanbanchi Taskのような外部サービス連携はあったりしますが、タスク管理といえるのはGmail付属のToDoリストやKeepしかありません(しかも、KeepはGoogle Apps Scriptから操作するAPIが用意されておらず、REST APIであるGoogle Keep APIはEnterpriseでしか利用できない)、

そこで今回スプレッドシートをベースにしつつも、kanban方式のタスク管理を作ってみようと考えました。但し、機能は順次追加中の過程なので、ベータ版です。

図:こんな感じのアプリを作ります

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

今回は、Vue-Draggableと呼ばれるVue.jsに対応したプラグインを用いて構築してみたいと思います。VueやVuetifyについては以下のエントリーを参考にしてみてください。今回のサンプルはKanban Boardのアプリですが、様々なGASアプリのノウハウを詰め込んであるので、学習用資材として活用してもらえたらと思います。

尚、現時点でのサンプルアプリはこちらをクリックすると操作する事が可能です。

Google Apps ScriptでVue.jsを使ってみる

Google Apps ScriptでVuetifyを使ってUIを作る

仕組みと使い方

仕組み

概要

今回のアプリはGASでウェブアプリを構築する極めて標準的なテクニックと、応用テクニックが含まれています。主に列挙すると

  • Googleスプレッドシートをデータの入出力の土台として作成
  • 複数名同時に書き込みへ対処する為の排他処理
  • ウェブアプリケーションとして構築
  • VueおよびVuetifyの2つのフレームワークといくつかのプラグインで構成
  • 書き込み時のタスクの並び順を記録する為のロジック(sort列)
  • ドメイン内のユーザのプロファイルからアイコンURLをAdmin SDKを利用して取得(アサイン先ユーザのアイコンとして使用予定)
  • ウィンドウサイズにフィットするようにサイズ自動調整
  • 3分置きにGoogleスプレッドシートのデータを自動取得するポーリング機能
  • Vue.jsを利用して動的にclass指定を変動させるテクニック
  • Draggableで移動時に移動先情報のマージ、自分向けのタスクの背景色変更、期日オーバーの場合の日付色変更など細かなユーザビリティ
  • Google Calendarへのイベント登録を行う

ここに順次、新規・編集追加ダイアログの装備やGoogle Calendar連携、アサイン時にメールで通知、トリガーで締め切り前にメールで一括通知などを装備して行こうかなと思います。もちろん、タスク管理のアプリなので、Google Formからの依頼をこのシートに書き出すようにする使い方も非常に良い選択肢だと思います。

Google Apps ScriptのAdmin SDKでユーザ作成フォームを作る

queryシート

メインのkanbanとusersにシートを分けて、Query関数で結合したシートをデータ取得元として利用しています。kanbanシートの担当者列の値とusersのメール列の値を連結し、kanbanの全データ + usersの氏名とアイコンURLを1枚にしたテーブルとして表示させています。

数式としては以下のようなものが、A2に入っていますがこのシートは変更禁止です。

使い方

セットアップ

スプレッドシートを開くと、「▶設定」というメニューが開かられるので

  1. 初期化を実行して、スプレッドシートのIDをスクリプトプロパティに格納する
  2. Usersシートにドメイン内限定ですが、ユーザを登録し、アイコン取得を実行すると管理者権限があれば、各ユーザのアイコンへのURLを取得して来ます。
  3. 通知トリガーをクリックすると、3日前〜終了日超過したタスクについてまとめて、毎日朝の5時に対象者にメール通知を送るトリガーが設置されます。
  4. Google Cloud Consoleで作成しておいたPicker API用のAPIキーをセットする為に、APIキー登録をクリックして、入力して保存する(タスク追加編集時にドライブのファイルを選択する為に利用します)
  5. アップ先フォルダIDを指定しておくと、添付ファイル選択時にPickerでファイルを直接アップすることが可能になります。
  6. カレンダーID登録をしておくと、対象のGoogle Calendarにもイベントが登録されるようになります。(タスク名と開始日付、終了日付のみ今は対応)
  7. ウェブアプリケーションとしてデプロイする

あとは、サンプルにあるようにタスクを登録してゆくことで、Drag可能なTrello風のカンバンボードが表示されるようになります。セクションを移動させる事で、各レコードのステータスおよびそのセクション内に於けるソート順を書き換えてくれるようになっています。

条件付き書式設定にて、完了済みは背景色を黄色、終了のものは灰色となり、終了のデータはカンバンボードには出てこない仕組みになっています。また、担当者のメアドがアクセスしてるユーザと同じメアドの場合、カードの背景は青色になる仕組みになっていますので、ウェブアプリケーションとして公開する場合(デプロイ時)には、「次のユーザとして実行」については、ウェブアプリケーションにアクセスしてるユーザにするのが望ましいでしょう。

特に今回Picker APIを追加したのですが、自分の権限でデプロイしてしまうと、他の人のPickerでも自分のフォルダ構成が表示されてしまうので要注意です。

尚、カレンダーIDですが以下の手順で取得出来ます(xxxxx@group.calendar.google.comというのがIDになります)

  1. 適当にカレンダーを作る
  2. カレンダーの「︙」をクリックし、設定と共有を開く
  3. カレンダーの統合を開く
  4. カレンダーIDが表示されてるので、これをアプリの設定に登録する

図:カレンダーIDの取得方法

図:イベントがカレンダーに登録された

Pickerでファイルやフォルダを選択する画面を装備する

Google Apps Scriptでレスポンシブメールを送ってみた

図:デプロイしないと使えません

図:締切日超過メール

アプリの使い方

現時点で実装済みの内容についてだけとりあえず記載しています。

タスクカードの色

青いタスクカードは自分にアサインされているタスクになります。それ以外は誰かにアサインされているか?アサインされていないタスクとなります。また、赤字の日付は、今日の時点で終了日を超過してるタスクとなります。

図:ひと目で状態を把握する事が可能

タスクカードを移動

タスクカードを掴んで、未着手⇔進行中⇔完了済みの3つのセクションを自由に移動できます。移動が完了すると対象のタスクカードの詳細を開けるようになります(移動中はロックしています)。

複数名同時に同じカードを掴んで移動した場合、最後の人の処理が反映します(排他処理をしている為バッティングはしません)。

タスクカード編集・新規追加

タスクカードをクリックすると編集画面が出ます。また右上の新規追加からは空の状態のタスクカード作成画面が出ます。また、添付ファイルの隣にあるボタンをクリックすると、Google Pickerを利用してGoogle Drive上のファイルを選択して、URLを取得する事が可能です。アップロードで指定する事も可能です。

アップロードの場合はセットアップで指定したフォルダにファイルがアップされ、そのファイルへのURLが取得されるようになっています。このURLがカードのリンクボタンとなります。

保存を実行すると対象のレコードの内容が書き換わります。新規追加の場合には、appendRowにて新規にシートにレコードが追加されます。

図:タスク編集画面

図:Google Pickerを使ったファイル選択

ソースコード

全体のコードのうち、一部分主要な部分のみを掲示しています。

GAS側コード

GAS側はHTML側からの命令にしたがって、シートへの読み書きを中心に装備しています。また、Admin SDKを利用しているのでユーザのアイコンURLを一括で取ってくる関数等も含まれています。

主に、起動時・アイコンURL取得時・タスク移動時のイベント毎の関数を記述しています。

  • スプレッドシートのデータに基づいて、その全データと加えて自分向けタスクかどうか?等を加えています
  • Vueで利用するため、データはこれまでと違い連想配列の形式で構築してから返しています。
  • AdminDirectory.Users.getにて、サムネイルアイコンのURLを取得させています。故に、サービスとしてAdminDirectoryを追加しています
  • タスク移動時にはそのセクションの全データを渡し、該当タスクのステータス変更だけでなく並び順を保存する為、sort列の値も毎回順番になるよう書き直しています。
  • LockServiceによって、同時書き込み等の対応の為、30秒間のロックを実施し排他処理を実現しています。
  • 但し、リアルタイム処理はGASではできないので、書き込み前に誰かが書き換えていた場合にはそのレコードは上書きとなるので要注意です。これはGoogle Apps Scriptの仕様なので仕方ないです。
  • 移動後はHTML側で最新情報を取得し直してるので、注意すべきはセクション移動対象のレコードだけになります。

HTML側コード

今回のコードはそこそこの量があるため、主要な部分のコードと解説を記載しています。主なポイントは

HTML部分

  • Vueのデザインやスクロールバーの位置などの調整の為のCSSが多数含まれています。
  • 未着手、進行中、完了済みの3つの配列をもって、それぞれにDraggableを割り当てています。
  • v-ifにてlimitの値が無い場合には、日付は表示されません
  • Vue-Draggable自身にはUIを構築する機能を持っていない為、UIやデザインは自身で構築する必要があります(故に今回はVuetifyを利用して各UIを構築しています)
  • box_scrollbarを追加し、タスクが枠以上になるとスクロールバー表示が追加されます。
  • 今日の日付よりもlimitの値が過去の場合には、日付の文字色は赤色になるようにVueで条件判定させてclassの切り替えをしています。
  • v-on:click.stopにて各ボタンアクションを設定。親のカードのイベントが発火しないように分けています

JS部分

外部のCDNとして、以下のURLをBody以下で読み込ます必要があります。

VueおよびVuetifyの各関数等は以下の通り。また、ウィンドウサイズ変更時にbox_scrollbarの高さの自動調整用の関数などをリサイズイベント時に発動するようにしてあります。

  • 起動時に、setInterval("onRefresh()", waitmil)をセットして3分毎にGAS側の最新データを自動で取得するようにしてあります。
  • itemsにはgetKanbanDataから取得したデータをステータス列の値に応じて、それぞれの配列に連想配列の形で追加するようにしてあります。
  • 移動開始時イベントはonStart、終了時イベントはonEndとしてそれぞれ定義しています。
  • Draggableの対象となるタグはv-colタグとしています。
  • src.getAttributeにて移動元、移動先のセクションのIDを取得させています。
  • 移動時にエラーが出た場合には、元の位置に戻すように仕組みを追加しています。
  • 一番重要なのは、onEnd関数。移動が終わった後にGAS側にその結果を伝えて、スプレッドシートのデータを書き換えています。
  • 移動したデータだけでなく、移動先セクションに於けるタスクの並び順も変えるchangelog関数を実行する必要があるため、そのためのデータの塊で渡しています。
  • 移動と書き換え後にスプレッドシートから最新の全データを再取得しています。他の人の更新内容もリフレッシュする為に。

関連リンク

コメントを残す

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

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