AsanaとGoogleスプレッドシートを連携して、バーンダウンチャートを自動生成する
この記事は、前回投稿したバーンダウンチャートに関する記事の応用編です。
前回は、工数を手動で計算し、Googleスプレッドシートに入力してチャートを作成する方法を紹介しました。ここでは、AsanaとGoogleスプレッドシートを連携して、バーンダウンチャートを自動的に生成する方法を紹介します。
はじめに
こんにちは。株式会社Mobility Technologiesで、タクシーアプリ『GO』の法人向けサービス『GO BUSINESS』のプロダクトマネージャー(PdM)を担当しております。Tannyです。
Asanaの認定アンバサダーでもあり、Asanaの便利な使い方を日々探求しております。
Asanaではダッシュボード機能の中に「バーンアップチャート」を表示する機能があります。が、これだと少しカスタマイズ性が足りないので、私の開発チームでは、Googleスプレッドシートでバーンダウンチャートを作成していました。この方法の場合、残工数をシートに毎日転記する手間が発生します。そこで、Google Apps Script (GAS) を利用して、Asanaの残工数を自動的に連携できるようにしました。
この記事では、連携方法の概要を紹介します。作成する連携フローは以下のようになります。
はじめに、GASを利用してAsanaからタスク一覧を取得する方法を説明します。次に、取得したタスク一覧からバーンダウンチャートを作成する方法を説明します。
Asanaからタスク一覧を取得する
AsanaではREST APIを提供していて、これを使うことで外部のサービスからタスクのデータを取得したり、タスクの新規作成したりできるようになります。今回はこのAPIをGASで呼び出すことで、Asanaのタスク一覧を取得します。
Asanaのプロジェクトを作成する
まずは、バーンダウンチャートの生成元となるAsanaプロジェクトを作成します。今回は、以下のようなサンプルプロジェクトを用意しました。
カスタムフィールドとして「ストーリーポイント(数値)」を作成し、これをバーンダウンチャートに記載する工数としました。
プロジェクトを作成したら、プロジェクトのURLを取得します。URLには以下のような形式でプロジェクトのIDが含まれているので、このIDをメモしておきます。
projectUrl = "https://app.asana.com/0/[project_id]/[project_id]"
アクセストークンを取得する
Asana APIを利用するためのアクセストークンを取得します。Asanaにログインした状態で、以下のURLから開発者コンソールにアクセスします。
画面の指示にしたがって「個人アクセストークン」を取得し、メモしておきます。
GASの新規プロジェクトを作成する
次に、GASのプロジェクトを作成します。バーンダウンチャートを作成するためのGoogleスプレッドシートのファイルを作成し、「拡張機能」>「Apps Script」をクリックします。
プロジェクトが作成できたら、「プロジェクトの設定」>「スクリプト プロパティ」をひらき、先ほど取得したトークンをプロパティとして保存しておきます。
これで事前準備は完了です。
Asana APIでタスク一覧を取得する
ここからは、Asana APIを使ってタスク一覧を取得します。GASの「エディタ」メニューを開いて、コードを書いていきます。
Asana APIの「…/projects/{project_gid}/tasks」を利用すると、プロジェクトに含まれるタスクを全て取得できます。公式ドキュメントを参照して、以下のようなコードを作成しました。
[project_id]の箇所には、最初に取得したプロジェクトのIDを記載します。スクリプトプロパティに記載したトークンは「getProperty('ASANA_API_KEY') 」メソッドで取得しています。
function getAsanaTasks() {
// AsanaプロジェクトのIDを指定
const projectGid = "[project_id]"
var options = {
'method': 'get',
'contentType': 'application/json',
'headers': {
'Authorization': 'Bearer ' + PropertiesService.getScriptProperties().getProperty('ASANA_API_KEY')
}
}
// Asana APIを実行し、タスクを取得する
var response = UrlFetchApp.fetch(`https://app.asana.com/api/1.0/projects/` + projectGid + `/tasks?opt_fields=name,completed_at,created_at,custom_fields`,options);
var result = JSON.parse(response);
Logger.log(result)
//省略
}
以下のようにオプションを指定することで、「タスク名」「完了日時」「作成日時」「カスタムフィールド(ストーリーポイント)」を取得しています。
`/tasks?opt_fields=name,completed_at,created_at,custom_fields`
結果はJSON形式で取得します。このコードを実行すると、以下のようにプロジェクトの全てのタスクを取得できます。
取得したデータを加工する
Googleスプレッドシートで扱いやすいように、取得したデータを加工します。ここでは、日付の形式をGoogleスプレッドシートに認識される形式に変更しています。タイムゾーンもUTC→JSTに変更しています。
//「Asana APIでタスク一覧を取得する」のコード部分
if(result.data){
//スプレッドシートに表示するためのデータに加工する
var filteredTasks = result.data
.map( task => {
let completedDateTimeYMD = ""
let createdDateTimeYMD = ""
if (task.completed_at != null) {
let completedDateTime = new Date(task.completed_at)
completedDateTimeYMD = Utilities.formatDate(completedDateTime, 'JST', 'yyyy-MM-dd HH:mm:ss')
}
if (task.created_at != null) {
let createdDateTime = new Date(task.created_at)
createdDateTimeYMD = Utilities.formatDate(createdDateTime, 'JST', 'yyyy-MM-dd HH:mm:ss')
}
return{
name : task.name,
completedAt : completedDateTimeYMD,
createdAt : createdDateTimeYMD,
storyPoint : Number(task.custom_fields[0].display_value)
}
})
Logger.log(filteredTasks)
//省略
}
データをGoogleスプレッドシートに出力する
加工したデータをGoogleスプレッドシートに出力します。ここでは「sample」というシートの、「2行目・10列目(J2)」からデータを出力しています。
if(result.data){
//「取得したデータを加工する」のコード部分
// 出力先シートを指定
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("sample")
//タスクをスプレッドシートに出力する
filteredTasks.forEach( (tasks, i) => {
let line = i+2 //ヘッダ1行分の次の行
let row = 9 // 10列目
sheet.getRange(line, row+0).setValue(tasks.createdAt)
sheet.getRange(line, row+1).setValue(tasks.completedAt)
sheet.getRange(line, row+2).setValue(tasks.name)
sheet.getRange(line, row+3).setValue(tasks.storyPoint)
})
}
これでスクリプトを実行すると、sampleシートにタスクの一覧が表示されます。
Asanaの連携部分のコーディングは、これでひとまず完了です。このデータを利用して、Googleスプレットシード側でバーンダウンチャートを作成します。
関数の定期実行を設定する
今回作成した関数を定期的に実行するように設定して、最新のタスクをGoogleスプレッドシートに同期するようにします。
「トリガー」メニュー > 「トリガーを追加」から、定期実行のトリガーを設定できます。バーンダウンチャートは1日に1回更新するので、データの取得も1日1回に設定しています。
これで、毎朝9時ごろにはAsanaプロジェクトの最新のタスク状況がGoogleスプレッドシートに自動的に同期されるようになりました。
バーンダウンチャートを作成する
自動的に同期されたデータを利用して、バーンダウンチャートを作成します。Googleスプレッドシートを用いたチャートの作成方法は、前回のnote記事に記載していますので、詳しい仕組みは「表計算ソフトを用いたチャートの作り方」の章を参照してください。
上記で紹介した方法では、「残工数」を手入力していましたが、今回はGoogleスプレッドシートのSUMIFS関数を利用して、自動で入力できるようにします。
ベースの表を作る
まずは、ベースとなる表を作ります。以下の例のように、灰色セルの箇所は手入力で記載し、黄色セルの箇所は数式を書いて埋めます。青セルの残工数部分は、これから数式を作ります。
この例では、締めタイミングを当日の23:59に設定しています。この日時は集計したいタイミングによって変更してください。
残工数を計算する
残工数の部分は、以下のような考え方で数式を作ります。
この計算式を、以下のようにSUMIFS関数で表現しました。「締めタイミング」の日時を基準にして、毎日の残工数を計算します。(この例では、完了日時を後から手動で変更しています。)
バーンダウンチャートを作成する
必要なデータがそろったので、あとはグラフを挿入してバーンダウンチャートを作成するだけです。
この例では、プロジェクトの期間が全て終了した後の状態を出力しています。プロジェクトの途中では、Asanaのタスクの状態を変更し、GASの関数が定期実行されるたびに、バーンダウンチャートが更新されます。
なお、今回は「作成日時」の項目を利用しませんでした。プロジェクトの途中でタスクが新しく追加される場合は、この項目を利用することで、累積工数の増加をチャートに表現できます。
おわりに
今回は、GASでAsanaからタスク一覧を取得して、自動的にバーンダウンチャートを作成しました。毎日のちょっと面倒な単純作業を自動化することができます。
この記事ではもっともシンプルな方法だけを紹介しましたが、GASとAsana APIを活用すれば色々な機能をチャートに追加することができます。例えば以下のような機能です。
累積工数も表記したバーンダウンチャートを作成する
担当ユーザー別の完了工数を計算して表示する
Slack APIを利用して、チャートの更新内容をSlackに通知する
今回の作業で初めてGASを利用してみましたが、非常に簡単にシステム間の連携を実装することができました。まだまだ改良の余地はありそうなので、上記のような機能拡張も試してみたいと思っています。