GitHubのIssues縛りから抜け出す方法【禁断のマルパ○リ編】

# えっ!? Issuesのエクスポートボタンがない
みなさんGitHubのIssuesの管理どうしてますか？？
チーム内では「ZenHub」でカンバンな感じで管理しています。
これはこれで非常に便利なのですが、~~おっさん~~Excel好きな人は
何かの課題をExcelで一覧にしないと禁断症状で手が震えてくるはずです。
※私がその~~おっさん~~Excel好きです。。

そこでGoogle先生に聞いて見たら以下のイカス記事を発見!!

## ExcelはあきらめてGoogleさんのシートに書き出し

[GoogleSpreadSheetにGitHub Issueの一覧を表示させる方法 - 連携の仕方](http://qiita.com/yoshimikeisui/items/277b06c58f50d530e5d1)

って事で、上のありがたい記事を見ながら、早速ソースをコピペし、ワクワクしながら実行!!。。。。。

んっ30件だけ？？

え～っと確かIssueは1000オーバーだったはずだよな。。
あー多分なんかGitHubでデータ渡す人が勘違いしたんだよな多分!!
って事でもう一度実行三角をポチッ。。。。

。。
とれてねーーーよ!!
GitHubが人力でデータ渡してるはずがねーーーよ!!
手の震えがとまんねええよ!!


って事で上記の記事を、もう一度熟読。。

>すっごく気が向いたら、適当に済ませている部分とかを直します。
>編集リクエストも大歓迎です。

そらそーだよな仮初にもプログラマーなんだし、自分でなんとか。。
。。助けてーーGoogle先生。。(泣)


## GitHubAPIでの取得はページ単位!?

で以下のまたまた偉大な記事にたどりつく

[githubのissueを抜き出す(GHE → gitlabへ移行したい)](http://qiita.com/abeyuya/items/7301d01a2906457bdb77)

記事を読むと以下を参考にしたとあるなーフムフム

>[こちらのコード参考にしました](https://gist.github.com/tkarpinski/2369729)

さらにフムフム。。。んっページ??
ページらしき変数がリンク先に。。
>page = page +1

これってあきらかに**ページ単位**でグリグリしてますって事だよね!?

って事で~~パクった~~流用させただいたコードを以下に改変

## Issuesエクスポートコード
使い方は以下を見てください。
[GoogleSpreadSheetにGitHub Issueの一覧を表示させる方法 - 連携の仕方](http://qiita.com/yoshimikeisui/items/277b06c58f50d530e5d1)

```js


function myFunction() {

  var GITHUB_OWNER = 'hoge'; // レポジトリのオーナー名を入れてください
  var GITHUB_ACCESS_TOKEN = 'hugahuga012345'; // 上記で発行したaccess tokenを入れてください
  var REPOSITORIES = ['hoge'] // 出したいレポジトリ名を入れてください
  var NEWEST_ISSUE_NUM = 1000; //issuesの最新の番号

  // APIからissueのjsonを取得
  var getIssues = function(repository){
    //ページ数算出
    var total = Math.ceil(NEWEST_ISSUE_NUM / 30);
    //全ページ分fetch
    var j_obj = [];
    for(i = 1; i <= total; i++) {
      var url = 'https://api.github.com/repos/' + GITHUB_OWNER + '/' + repository + '/issues?page=' + i +'&state=all&sort=created&direction=asc&access_token=' + GITHUB_ACCESS_TOKEN;
      var response = UrlFetchApp.fetch(url);

      var json = response.getContentText();
      Array.prototype.push.apply(j_obj,JSON.parse(json));
    }
    return j_obj;
  }

  // issueのjsonから中身を取得
  var getAttributesOfIssue = function(issue){
    var milestone = "";
    if(issue["milestone"]){
      milestone = issue["milestone"]["title"];
    }

    var labels = "";
    if(issue["labels"]){
      labels = issue["labels"].map(function(label){
        return label["name"]
      }).join(",");
    }

    var assignee = "";
    if(issue["assignee"]){
      assignee = issue["assignees"].map(function(assignee){
        return assignee["login"]
      }).join(",");
    }

    var due_on = "";
    if(issue["milestone"] && issue["milestone"]["due_on"]){
      due_on = issue["milestone"]["due_on"].substring(0, 10);
    }

    var opend_at = "";
    if(issue["created_at"]){
      opend_at = issue["created_at"].substring(0, 10);
    }

    var closed_at = "";
    if(issue["closed_at"]){
      closed_at = issue["closed_at"].substring(0, 10);
    }

    var url = '=HYPERLINK("' + issue["html_url"] + '","' + issue["number"] + '")';

    return [
      url,
      milestone,
      issue["title"],
      assignee,
      issue["state"],
      labels,
      due_on,
      opend_at,
      closed_at
    ]
  }

  var sortByValueOfIndex = function(ary, index){
    return ary.sort(function(a,b){
      if( a[index] < b[index] ) return -1;
      if( a[index] > b[index] ) return 1;
      return 0;
    });
  }

  // スプレッドシートを取得
  var ss = SpreadsheetApp.getActive()

  // 指定したレポジトリでシートに反映していく
  REPOSITORIES.forEach(function(repository){
    var issues = getIssues(repository).map(function(issue){
      return getAttributesOfIssue(issue);
    });

    // due on でソートしています
    //issues = sortByValueOfIndex(issues, 5);
    var titles = ["Issue URL","Milestone", "Title", "Assignee", "Status", "Labels", "due_on", "opened_at", "closed_at"];
    issues.unshift(titles);

    var sheet = ss.getSheetByName(repository);
    if(sheet == null) {
      ss.insertSheet(repository);
      sheet = ss.getSheetByName(repository);
    }
    sheet.getRange("A1:I" + (issues.length).toString()).setValues(issues);
  });
}
```

で三角ボタンをポチッと。。。
おーーーー取れた！！
Google先生ありがとう！！
[yoshimikeisui](http://qiita.com/yoshimikeisui)さんありがとう！！

これでやっと手の震えが。。。おさまらん。。

## 備考
[yoshimikeisui](http://qiita.com/yoshimikeisui)勝手にソースコード転載・改変させていただいてます。すいません。もし削除要求があった際には即刻削除いたしますので宜しくお願いいたします。

このソースでは、issues番号の最終(最新)を手動で設定していますが、実際はAPIに「length」などがあるかも知れませんが、その辺は事由に改変して使ってください。

## 2017'04'08 改訂内容
@omochiiiY さんのご協力で、”assignee”　が一人しか取得できなかったので複数assigneeを "," 区切りで取得するように、ソース改訂いたしました。
@omochiiiY　さん有難う御座います!!

改訂前:

```js
    if(issue["assignee"]){
      assignee = issue["assignee"]["login"];
    }
```

改訂後:

```js
    if(issue["assignee"]){
       assignee = issue["assignees"].map(function(assignee){
        return assignee["login"]
      }).join(",");
    }
```