[Google Apps Script]Backlogのマイプロジェクトの課題Issues群を、BacklogのAPIを使ってGoogle Spreadsheetに書き出す

##Backlog側の設定
####1.Backlog画面で「課題(Issues)」をいくつか登録する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91974/557f4951-9328-3742-e4a5-678401b48308.png)

・個人向けの無料枠IDがある。https://apps.nulab.com/signup
・上記ではサンプルとして、５件ほど登録。
・状態(statusId)は「完了」と「未対応」と「処理中」などと複数ある模様。
・状態(statusId)にある「処理済み」と「完了」の違いがよく分からん...(担当者が処理を終わらせたのが「処理済み」で、それを上司もしくはPMがヨシ！と判断したら「完了」なのかも？使い分けがよくわからん...)
・優先度も「高」とか「低」なども複数の状態を用意（「デフォルトは「中」）
・期限日も何件かセット
・登録者はデフォルトで登録者ユーザがセットされるが、担当者は「NULL」の状態もありうる(後述)
・上図サンプルで件名や概要に入力した文章(引用文/警句)は、[ここ](https://immigrantofthe150thyears.hatenablog.com/entry/2019/02/03/150107)を参考にした

#### 2.BacklogのAPIを利用する
・BacklogのAPIを実行するのに必要な項目は、space名とprojectIdとAPIキーの３つ。
・space名は、Backlogにログインした際のURL「https://<font color=blue>XXXX</font>.backlog.com/」の「XXXX」の部分、また「projectId」は、Backlogの管理画面の「課題」のページのURLのGet要求の項目にある<font color=blue>project_Id=XXXXXX</font>の記述の部分で番号が確認できる。

・BacklogのAPIキーを確認するには、「個人設定」のAPIの欄で**API認証キー**の設定画面があるので、そちらでAPIキーをメモしておく(Google Apps Script実行時で、キーを利用する)

![スクリーンショット 2020-12-13 16.01.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91974/57204491-69ab-2421-74ea-c227c3856616.png)


![スクリーンショット 2020-12-13 14.39.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91974/a2856d91-92a9-6306-6e13-14afa37ee247.png)

##  Google apps Script側の設定
#### 1.script(GAS)
```js:test.gs
var space_id   = 'hogehoge';
var api_key    = "abcdefghijklmn1234567890opqrstuvwxyz"
var project_id = "20201213";

function exec_api() {
  //BacklogのAPIを実行(issuesを検索)
  var url = "https://"+space_id+".backlog.com/api/v2/issues?apiKey="+api_key+"&projectId[]="+project_id
  var url = url + "&statusId[0]=1&statusId[1]=2&statusId[2]=3"  //★重要！:「完了」以外を検索するべし
  var res = UrlFetchApp.fetch(url);

  if (res.getResponseCode() != 200) {
    return false;
  }
  return res
}

function myFunction() {

  //API実行してIssuesを取得  
  res = exec_api()
  var issuelist = JSON.parse(res.getContentText());
  
  // スプレットシートの設定
  var sheet_id   = 'hogehogefugafuga1234567890';
  var sheet_name = 'test20201211'
  var MySheet = SpreadsheetApp.openById(sheet_id);
  var range = MySheet.getSheetByName(sheet_name).getRange(3, 1);
  
  // 一旦、シートをクリアにする [注:初回実行時は不要]
  MySheet.getSheetByName(sheet_name).getRange("A2:I"+MySheet.getLastRow()+"").clearContent();
  
  // 現在時刻を書き込む
  var date = new Date();
  var gdate = Utilities.formatDate(date, 'Asia/Tokyo', 'yyyy/MM/dd/HH:mm:ss');
  MySheet.getRange("A1").setValue('実行日時：' + gdate);
  
  // ヘッダーの編集
  MySheet.getRange("A2").setValue("issueKey");
  MySheet.getRange("B2").setValue("summary");
  MySheet.getRange("C2").setValue("description")
  MySheet.getRange("D2").setValue("createdUser");
  MySheet.getRange("E2").setValue("assignee");
  MySheet.getRange("F2").setValue("priority");
  MySheet.getRange("G2").setValue("status");
  MySheet.getRange("H2").setValue("dueDate");
  MySheet.getRange("I2").setValue("created");
  
  MySheet.getRange("A2:I2").setBackground('#696969'); //背景色
  MySheet.getRange("A2:I2").setFontColor('#FFFFFF');  //文字色
  
  //Logger.log("length: " + issuelist.length);
  
  // 各Issueを書き込み
  for(var i=0; i<issuelist.length; i++) {
        // スプレッドシートに１件ずつ書き込み
        var issue_url = "https://" + space_id  + ".backlog.com/view/" + issuelist[i]["issueKey"]
        range.offset(i, 0).setValue('=HYPERLINK(\"' + issue_url + '\",\"' + issuelist[i]["issueKey"] + '\")')
        range.offset(i, 1).setValue(issuelist[i]["summary"]);
        range.offset(i, 2).setValue(issuelist[i]["description"]);
        range.offset(i, 3).setValue(issuelist[i]["createdUser"]["name"]);
    
        //担当者：NULL判定をして、担当者が決まっていたら担当者名を格納(未定の場合は「--」をセット)
        //Logger.log(issuelist[i]["assignee"] );
        if( issuelist[i]["assignee"] == null ){
             range.offset(i, 4).setValue("--");
        } else {
             range.offset(i, 4).setValue(issuelist[i]["assignee"]["name"]);        
        }
        range.offset(i, 5).setValue(issuelist[i]["priority"]["name"]);
    
        //優先順位
        if( issuelist[i]["priority"]["name"] == '高' ){
          var clr =  '#ff0000'
        }else if(issuelist[i]["priority"]["name"] == '低'){
          var clr =  '#0000ff'
        } else {
          var clr =  '#000000'
        }
        range.offset(i, 5).setFontColor(clr);  //文字色
    
        range.offset(i, 6).setValue(issuelist[i]["status"]["name"]);
        //range.offset(i, 6).setValue(issuelist[i]["startDate"]);
        range.offset(i, 7).setValue(issuelist[i]["dueDate"]);
        range.offset(i, 8).setValue(issuelist[i]["created"]);
        //var list = SpreadsheetApp.newDataValidation().requireValueInList(['未対応','処理中', '処理済み', '完了'], true).build();
        //range.offset(i, 6).setDataValidation(list).setValue(issuelist[i]["status"]["name"]);
    }

  //終了の合図
  Browser.msgBox("finish!");
}
```
・上記でやっていることは、至ってシンプルで、BacklogのAPIを実行(APIで課題一覧を取得するには、IssuesでHttpRequestをGetで実行)して、取得した課題一覧を１件ずつループ文でスプレッドシートの各セルに値を格納していくというもの。簡単！
・APIキーは、Backlogの「個人設定」の画面で、確認可能。
・やっていることはBacklogのAPIを実行して、レスポンス結果を手ごろなspreadsheetに書き出すことなので、APIの実行は、Google apps scriptである必要はない。PythonでもRubyでもなんでも良いかと。(今回は、取得結果をspreadsheetに書き出すので、spreadsheet内のGoogle apps scriptを手っ取り早く利用)


#### 2.Spreadsheet
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91974/2f9ec7ea-6eed-5070-96ca-9c4be0a4f796.png)

・２行目のヘッダーの項目名のセットや、背景色や文字色を変更するなどはおまけ。
・１列目のissueKeyは、backlogの各課題ページへのURLリンクをセットしている
・assignee(担当者)は、まだ割り振っていない状態というのは普通にありうる、NULLということも十分ありえるので、IF文でassigneeのnameがNULLか否かを判定して、担当者名をセットしている。NULLの値を取得しようとすると、Google apps script上でプログラムエラーが表示されるので、NULL判定は必須。
・priority(優先順位)は、デフォルトが「中」でセットされるので、NULLというのは無いのでIF文のNULL判定は割愛している。ただ優先順位の色は、「高」と「低」は、目立つように色を変更している。
・上図の左から３列目のdescriptionの文章は長くなると思うので、スプレッドシートのセルの収まりを考えると、割愛したほうがいいかもしれない。１列目のissueKeyは、Backlogの各課題ページへのURLリンクをセットしているので、課題の詳細文章はBacklogのWeb画面を参照して確認してもらうのがよいかも。(そこは実際の業務でのBacklogの利用に応じて調整を！)

・上記のgoogle apps scriptをタイマーで定期実行する事を想定して、上記では、A1のセルに現在時刻をセットするようにしてみた。
![スクリーンショット 2020-12-13 15.53.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91974/1c350e7e-c14d-0051-c806-af9965b60837.png)

なおGoogle apps scriptをタイマー実行するには、Google apps scriptのスクリプトエディタにタイマー実行の設定があるので、そちらで定期実行のセットをされたし！

#### 3.その他
・BackLogのAPIは、逆にGoogle Spreadsheetに登録したタスク一覧を、まとめてAPIを使ってBacklogに課題として一括登録するみたいなことも可能だが、今回は割愛。あくまでもBacklogのweb画面で管理するのが本筋であり、今回は、それを１方向にブロードキャスト的に、読み取り専用的な扱いで、Google Spreadsheetにて一覧を参照するような使用用途を想定している。

・今回のイシューを調べた際に、どこかのブログに書かれていたことですが。自分の業務で、複数のプロジェクトに参加していて、Backlog上で複数のプロジェクトの進捗および各タスク、課題イシューを一括で閲覧するのに、Backlog上で複数プロジェクトをいちいち一個ずつ閲覧していくのが超煩雑というユーザーのペインがあって、それを解消するために、今回のようなスプレッドシートに複数のプロジェクトの課題イシューをまとめて書き出すというのが、今回のイシューの一番の使いどころというか、便益なのかなと推測。
(なので、そもそも単一のプロジェクトにしか参加していないのだったら、今回のイシューはぶっちゃけ不要で、普通にBacklogの管理画面で閲覧してねという話でございます)

## 参考ページ：
1.ヌーラボのBacklog API「課題一覧の取得」
https://developer.nulab.com/ja/docs/backlog/api/2/get-issue-list/#
・レスポンスの項目は上記で紹介した以外にも色々あるので、ここを参考にされたし！

2.inokappa/my_issues.gs[github]
https://gist.github.com/inokappa/a52298dbf4695ca4f2498cf2ae3d9149
・色々Googleで検索してみて、githubのinokappaさんの一番このページが、一番役に立ちました。