【GAS】バックログの課題情報を取得してスプレッドシートに展開！そして非エンジニアでも使えるように書いてみる！

# 概要
社内メンバーより、
「スプレッドシートでタスクの管理をしているけど、APIとか使ってもう少し楽にしたい！」
という要望を受けたので、四苦八苦しながらも頑張って作ってみました。

自分自身も今回、はじめてGASを触ったということあり、
非エンジニアの方にも使ってもらえるように、なるべく分かりやすく書いていこうと思います。
（この手の記事は非エンジニアに優しくないことが多いので…苦笑）

※ただし、「GAS（Google Apps Script）とは」みたいな話はすっ飛ばすので、その辺りはググっていただけるとm(__)m

# 更新履歴
- 共通部分の関数化
- 存在しない課題番号がある場合に処理が止まってしまう問題を解決

# 必要となるもの
まずは、バックログから情報を取得するために、**APIキー**というものが必要になります。
APIキーの発行は以下の手順で行ってください。

1. バックログの「個人設定」を開く
2. 「API」タブを開く
3. 「メモ」に適当なテキストを入れ、登録ボタンをクリック

すると、何やら長ったらしい文字列が表示されたかと思いますが、そちらがAPIキーになります。

# GASコード
さて、以下は実際のGASコードとなりますが、捕捉説明は後述するとしてまずは完成版から。
とりあえず、スプレッドシートの「ツール」タブから「スクリプト エディタ」を開き、コードを貼り付けてください。

```
// 編集時に発動
function task_action() {

  // 編集したセルを取得
  var range = SpreadsheetApp.getActiveRange();

  // 編集したセルの値を取得
  var rangeID = range.getValue();

  // 課題情報をセット
  set_task(rangeID,range)
}

// 一定時間に発動
function task_time() {

  // 現在のスプレッドシートを取得
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();

  // 現在のシートを取得
  var sheet = spreadsheet.getActiveSheet();

  for(var i=1; i<100; i++) {
    // B列を取得
    var range = sheet.getRange(i, 2);

    // B列の値を取得
    var rangeID = range.getValue();
    
    // 課題情報をセット
    set_task(rangeID,range)
  }
}

// 共通の処理
function set_task(rangeID,range){

  // rangeIDに値が入っている場合
  if(rangeID){

    try { // 通常時の処理
      // Backlogの課題を取得
      var issue = UrlFetchApp.fetch("https://***.backlog.jp/api/v2/issues/"+rangeID+"?apiKey=***");
      var issuelist = JSON.parse(issue.getContentText());
      
      // 課題情報をセット
      range.offset(0, 1).setValue(issuelist["issueType"]["name"]);　　// 種別
      range.offset(0, 2).setValue(issuelist["summary"]);　　　　　　　// 件名
      range.offset(0, 3).setValue(issuelist["assignee"]["name"]);　　 // 担当者
      range.offset(0, 4).setValue(issuelist["status"]["name"]);　　　 // 状態
      range.offset(0, 5).setValue(issuelist["priority"]["name"]);　　 // 優先度
      range.offset(0, 6).setValue(issuelist["created"]);　　　　　　　// 登録日
      range.offset(0, 7).setValue(issuelist["dueDate"]);　　　　　　　// 期限日
      range.offset(0, 8).setValue(issuelist["updated"]);　　　　　　　// 更新日
      range.offset(0, 9).setValue(issuelist["createdUser"]["name"]);　// 登録者
    } catch(e) { // エラー時の処理
      range.offset(0, 1).setValue("エラー");
    }
  }
}
```

# 実行タイミングの設定
吹き出しの時計のようなマークを選択すると、「現在のプロジェクトのトリガー」が開きます。
これは何かというと、記述したGASを**いつ実行させるか**の設定画面になります。

今回は、**「編集時」「一定時間ごと」**の二種類の実行タイミングを設定しているため、
以下のような形でトリガーを追加して設定してください。

## 一定時間ごと
- 実行：**tast_time**
- イベント：時間主導型、〇タイマーなどの時間設定は任意

## 編集時
- 実行：**task_action**
- イベント：スプレッドシートから、編集時

## 末尾の「通知」について
何かしらの原因により上手く動作しなかった際にメールによる通知を行ってくれるものですので、任意で設定しておいてください。

# コードの説明
さて、ここから実際のコードの補足説明を書いていきます。

## 2行目、15行目　【編集時】【一定時間ごと】
```
function task_action() {
```
```
function task_time() {
```
前述した「編集時」「一定時間ごと」の実行タイミングによって記述を分けています。

## 5行目、8行目　【編集時】
```
var range = SpreadsheetApp.getActiveRange();
var rangeID = range.getValue();
```
セルに課題番号を記述した際に、その値を取得して保存しています。

## 23行目　【一定時間ごと】
```
for(var i=1; i<***; i++) {
```
複数行を監視する設定をしています。
「***」には何行目まで見るか数字を入れてください。
※本当は「記述されている分」みたいな書き方をしたい…

## 25行目　【一定時間ごと】
```
var range = sheet.getRange(i, 2);
```
今回の場合、B列の値を取得する設定をしています。
なので、C列を監視する場合は (i, 3) 、D列を監視する場合は (i, 4) …という風に設定を変更してください。

## 43行目　【編集時】【一定時間ごと】
```
var issue = UrlFetchApp.fetch("https://***.backlog.jp/api/v2/issues/"+rangeID+"?apiKey=***");
```
バックログの課題情報を取得しています。

「https://***.backlog.jp」
こちらに対象バックログのURLを記述。

「apiKey=***」
こちらに先ほど発行したAPIキーを記述。

## 47行目～55行目　【編集時】【一定時間ごと】
```
range.offset(0, 1).setValue(issuelist["issueType"]["name"]);　　// 種別
range.offset(0, 2).setValue(issuelist["summary"]);　　　　　　　 // 件名
range.offset(0, 3).setValue(issuelist["assignee"]["name"]);　　 // 担当者
range.offset(0, 4).setValue(issuelist["status"]["name"]);　　   // 状態
range.offset(0, 5).setValue(issuelist["priority"]["name"]);　　 // 優先度
range.offset(0, 6).setValue(issuelist["created"]);　　　　　　　 // 登録日
range.offset(0, 7).setValue(issuelist["dueDate"]);　　　　　　　 // 期限日
range.offset(0, 8).setValue(issuelist["updated"]);　　　　　　　 // 更新日
range.offset(0, 9).setValue(issuelist["createdUser"]["name"]);　// 登録者
```
「どの課題情報」を「どこに展開」するかの指定をしています。

ちなみに、offset(0, 1) は右隣りを意味していて、
そのまた右隣りが (0, 2) 、そのまたさらに右隣りが (0, 3) …という風になっています。
なので、縦方向に展開したい際には、offset(1, 0) と記述してください。

また、["summary"] などで展開する課題情報の指定をしていますが、
上記に記載されていない情報を取得したいといった場合には、以下のページの「レスポンスボディ」を参考にしてください。
http://developer.nulab-inc.com/ja/docs/backlog/api/2/get-issue

## 41行目、56行目　【編集時】【一定時間ごと】
```
try { // 通常時の処理
```
```
} catch(e) { // エラー時の処理
```
何かしらのエラーにより処理が中断してしまう際に、処理を止めずにまた別の処理に移るというものです。
今回の場合、課題情報が存在しない場合にエラーが返ってきて処理が中断してしまっため、その対処として入れています。

## 57行目　【編集時】【一定時間ごと】
```
range.offset(0, 1).setValue("エラー");
```
catch(e) の処理に移った際に、右隣りのセルに「エラー」と表記させる指定をしています。
表記させる文言は適宜変更してください。

# まとめ
GASに関する記事がそこまでネットに転がっていなかったのと、
自分自身が超絶プログラミングを得意としているわけでもないので、少々苦戦しました…（笑）
だからこそ、ちょっとでも**分かりやすく**を心がけて書いてみましたので、みなさんに役立てていただければ幸いです。

また、今回はバックログのAPIを使用しましたが、
基本的には同じようなやり方で色々な情報を取得して展開することが可能だと思います。

夢が広がりますね☆