📋

Asana APIとGASで各タスクの課題や進行状況を素早く把握する

2023/08/30に公開

どもども、かずおです。
Asanaで管理しているタスクをGoogleスプレッドシートに出力する方法を共有したいと思います。

まずは、以下の手順に従って設定を行ってください。

Asana APIのトークンの発行

下記のURLからAsana APIのトークンを発行します。
https://app.asana.com/0/my-apps
(※Google Apps Script(GAS)で使用します)

Googleスプレッドシートの作成とGoogle Apps Script(GAS)の作成

Googleスプレッドシートのメニューから「拡張機能:Apps Script」を選択し、GASを作成します。
以下の画像を参考にしてください。

GASの作成

*下記の項目は適宜変更。
- シート名
- APIトークン
- プロジェクトID(https://app.asana.com/0/プロジェクトID/ の部分)

以下のソースコードをGASに貼り付けてください。

/**
 * Asanaからタスクを取得する
 */
function getAsanaData() {
  // 出力先シートを指定
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('変更箇所:シート名');

  // シートをクリア
  sheet.clear();

  // スプレッドシートのヘッダー名を指定
  sheet.getRange(1,1).setValue("Section Name");
  sheet.getRange(1,2).setValue("Task Name");
  sheet.getRange(1,3).setValue("asana URL");

  // リクエストオプションを作成
  var options = {
    // GETメソッド
    'method': 'get',
    // JSON形式
    'contentType': 'application/json',
    // ヘッダ
    'headers': { 
      // 認証情報 アクセストークン
      'Authorization': 'Bearer ' + '変更箇所:APIトークン'
    }
  }  
  // Asana APIを実行しタスクを取得する
  var projectGid = '変更箇所:プロジェクトID'; //プロジェクトのID
  // セクション一覧を取得
  asanaApiSectionUrl = `https://app.asana.com/api/1.0/projects/` + projectGid +`/sections`
  var response_section = UrlFetchApp.fetch(asanaApiSectionUrl, options);
  // 取得結果をJSONパース
  var result_section = JSON.parse(response_section);
  var task_no = 1 //行番号
  if(result_section.data){
    for(var i_s = 0; i_s < result_section.data.length; i_s++){
      //セクション単位でタスク取得
      asanaApiUrl = `https://app.asana.com/api/1.0/sections/` + result_section.data[i_s].gid + `/tasks?opt_fields=name,permalink_url`
      var response = UrlFetchApp.fetch(asanaApiUrl, options);
      var section_name = result_section.data[i_s].name
      // 取得結果をJSONパース
      var result = JSON.parse(response);
        // スプレッドシートにAsanaのデータを出力
      if(result.data){
        for(var i = 0; i < result.data.length; i++){
          task_no = task_no + 1
          // Section Name
          sheet.getRange(task_no,1).setValue(section_name);
          // Task Name
          task_name = result.data[i].name
          sheet.getRange(task_no,2).setValue(task_name);
          // asana URL
          sheet.getRange(task_no,3).setValue(result.data[i].permalink_url);
        }
      }
    }
  }
}

上記のソースコードは、セクション名、タスク名、AsanaのURLのみ設定していますが、
Asana APIのパラメータのopt_fieldsを追加することで取得できる項目を増やすことができます。
(詳細はasanaドキュメントを参照)

ソースコードでは、セクション一覧を取得した後にセクションIDを使用してタスク一覧を取得しています。
Asanaのドキュメントを見るとassignee_section.nameでセクション名が取得できるようですが、
実際のデータを確認するとgidとresource_typeのみ存在していたため、この方法で対応しました。

Asana

Googleスプレッドシート

活用事例

私たちのチームでは以下の最終的な目標を達成するために機能追加を行っています。

  • 各タスクの細かい課題や進行状況を一覧で管理
  • 完了したセクションは表示しない

これらの要件に合わせて、タスクの詳細な状況を管理するためにコメント機能を活用しています。最新のコメントを抽出し、コメントの先頭行が「=>」で始まる場合には、そのコメントをGoogleスプレッドシートに出力する方法を使用しています。

この方法を実現するために、以下の手順を踏んでいます。

  1. Asanaのタスクにコメントを追加します。
  • タスクの進捗、課題、更新情報などをコメントとして追加します。
  • コメントの先頭行を「=>」で始めることで、特定のコメントを抽出するためのマーカーとして使用します。
  1. Google Apps Script(GAS)を使用して最新のコメントを抽出します。
  • GASを使ってAsanaのAPIを呼び出し、タスクのコメントを取得します。
  • 取得したコメントの中から、先頭行が「=>」で始まるコメントを特定します。
  1. 抽出されたコメントをGoogleスプレッドシートに出力します。
  • GASを使って、抽出されたコメントをGoogleスプレッドシートの該当するセルに書き込みます。
  • セルの位置は、タスクに関連するセクションやタスク名の横に設定されるようにします。

この方法により、タスクの詳細な状況や進捗状況をコメントとして管理し、最新のコメントを自動的にGoogleスプレッドシートに反映させることができます。これにより、タスクの進捗や課題の把握が容易になり、チーム全体でタスク管理を効果的に行うことができます。

具体的な実装方法については、AsanaのAPIやGoogle Apps Scriptのドキュメントを参考にしながら、適切にカスタマイズしてください。また、コメントの書式やマーカーの使用方法は、チームのニーズやタスク管理のスタイルに合わせて調整することができます。

以下にソースコードと結果の例を示します。

/**
 * Asanaからタスクを取得する
 */
function getAsanaData() {
  // 出力先シートを指定
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('変更箇所:シート名');

  // シートをクリア
  sheet.clear();

  // スプレッドシートのヘッダー名を指定
  sheet.getRange(1,1).setValue("Section Name");
  sheet.getRange(1,2).setValue("Task Name");
  sheet.getRange(1,3).setValue("asana URL");
  sheet.getRange(1,4).setValue("comment");

  // リクエストオプションを作成
  var options = {
    // GETメソッド
    'method': 'get',
    // JSON形式
    'contentType': 'application/json',
    // ヘッダ
    'headers': { 
      // 認証情報 アクセストークン
      'Authorization': 'Bearer ' + '変更箇所:APIトークン'
    }
  }  
  // Asana APIを実行しタスクを取得する
  var projectGid = '変更箇所:プロジェクトID'; //プロジェクトのID
  // セクション一覧を取得
  asanaApiSectionUrl = `https://app.asana.com/api/1.0/projects/` + projectGid +`/sections`
  var response_section = UrlFetchApp.fetch(asanaApiSectionUrl, options);
  // 取得結果をJSONパース
  var result_section = JSON.parse(response_section);
  var task_no = 1 //行番号
  if(result_section.data){
    for(var i_s = 0; i_s < result_section.data.length; i_s++){
      //セクション単位でタスク取得
      asanaApiUrl = `https://app.asana.com/api/1.0/sections/` + result_section.data[i_s].gid + `/tasks?opt_fields=name,permalink_url`
      var response = UrlFetchApp.fetch(asanaApiUrl, options);
      var section_name = result_section.data[i_s].name
      // 取得結果をJSONパース
      var result = JSON.parse(response);
        // スプレッドシートにAsanaのデータを出力
      if(result.data){
        for(var i = 0; i < result.data.length; i++){
          // comment:完了はスキップ(セクション名が変更になったら変更)
          if (result_section.data[i_s].name == '完了'){
            continue
          }
          task_no = task_no + 1
          // Section Name
          sheet.getRange(task_no,1).setValue(section_name);
          // Task Name
          task_name = result.data[i].name
          sheet.getRange(task_no,2).setValue(task_name);
          // asana URL
          sheet.getRange(task_no,3).setValue(result.data[i].permalink_url);
          // comment:完了以外のコメントを取得(セクション名が変更になったら変更)
          if (result_section.data[i_s].name != '完了'){
            asanaApiStoriesUrl = `https://app.asana.com/api/1.0/tasks/` + result.data[i].gid + `/stories`
            var stories_response = UrlFetchApp.fetch(asanaApiStoriesUrl, options);
            var result_stories = JSON.parse(stories_response);

            for(var i_stories = 0; i_stories < result_stories.data.length; i_stories++){
              if (result_stories.data[i_stories].type == "comment"){
                comment_text = result_stories.data[i_stories].text
                if (comment_text != null){
                  if (comment_text.startsWith('=>'))
                  sheet.getRange(task_no,4).setValue(comment_text.replace('=>', ''));
                }
              }
            }
          }
        }
      }
    }
  }
}

Asana

Googleスプレッドシート

おまけ:データの定期的な更新

GASのトリガー機能を設定することで、定期的にAsanaのデータを取得し、Googleスプレッドシートを最新の状態に保つことができます。

  • トリガー追加

  • 定期的に実行したいタイミングを設定

参考サイト

https://zenn.dev/nekoniki/articles/3a1c0362db5e12
https://liginc.co.jp/570311
https://www.pre-practice.net/2018/02/asana-api_17.html

CareNet Engineers

Discussion