GitHubのProjects用API(試験運用中)を使ってみた

# 更新履歴
・[2016/09/26] 記事公開
・[2017/04/17] APIに変更があったので一通りチェックして更新
2016/10/28にリポジトリ単位だけでなくOrganization単位でプロジェクトを作ることができるようになっていました。
[Introducing Projects for Organizations](https://github.com/blog/2272-introducing-projects-for-organizations)
(実はこの記事書いたもののまだ実用はしていなかったので知らなかったです。)
それに伴ってプロジェクトの取得方法などが変わっています。
どこがどう変わったかについては[編集履歴](http://qiita.com/KanaSakaguchi/items/fbd244af006dd746ef7e/revisions)を参照してください。

# はじめに
2016/9/15にGitHubで[大型アップデート](https://github.com/blog/2256-a-whole-new-github-universe-announcing-new-tools-forums-and-features)がありましたね。
早速その中の[Projects](https://help.github.com/articles/about-projects/)を使ってみました。
プルリクをカード化してカラムに並べて置けるので、例えばプルリクの進捗を管理するのに良さそうです。
(もともとラベルで進捗を管理していますが、全体を見通すことはできていませんでした。)
ですが、例えばカードを移動させた時に通知してくれるような機能は今の所ないようなので、アクセスしないことには状況がわかりません。

そこで、とりあえず[GitHub API](https://developer.github.com/v3/)にProject用のAPIがないか探してみたらありました。
(ただし2017/4/17現在も試験運用中のため、今後も機能追加・変更の可能性があります。)
[Preview the new Projects API | GitHub Developer Guide](https://developer.github.com/changes/2016-09-14-projects-api/)
[Projects | GitHub Developer Guide](https://developer.github.com/v3/repos/projects/)
今までGitHub APIを使ったことない私ですが、Projects APIを使って何ができるか試してみます。

# 使用言語
Google Apps Scriptを使って試してみようと思います。
(GASのサーバーレスで自動実行可能なところ好きです。)

# GitHub APIを使うための準備
[Personal Access Tokens](https://github.com/settings/tokens)にアクセスしてトークンを取得します。
(なんかすでに4か月前に`Help example`のトークンを取得済みのようですが、心当たりがありません・・・；)
とりあえず`Generate new token`を押します。
<img width="750" alt="Personal_access_tokens.png" src="https://qiita-image-store.s3.amazonaws.com/0/76523/dbba247b-259a-5812-2933-3eb310fe7ef8.png">
トークンの説明を入力してスコープを選択したら、最後にある`Generate token`を押します。
(私は今後他のことにも使うかもしれないと思ったので、とりあえず全てにチェックを入れておきました。)
<img width="755" alt="New_personal_access_token.png" src="https://qiita-image-store.s3.amazonaws.com/0/76523/5a462ec4-0a54-4606-9ca0-67c3aa23c729.png">
するとトークンが表示されます。
クリップボードのアイコンを押すとコピーされます。
<img width="754" alt="GitHub_API_トークン取得.png" src="https://qiita-image-store.s3.amazonaws.com/0/76523/eafb336b-ff56-a0a4-9728-698e54778da7.png">

これで準備完了です。
次から早速使ってみたいと思います。

# プロジェクトのCRUD

一部OrganizaitonのものかリポジトリのものかによってAPIパスや取得内容が異なる。

## 実行コード例

### リポジトリプロジェクト一覧取得
[List repository projects](https://developer.github.com/v3/projects/#list-repository-projects)
リポジトリプロジェクト一覧を取得できる。

```js:リポジトリプロジェクト一覧取得.gs
function getProjectList() {
  var header = {
    "Accept" : "application/vnd.github.inertia-preview+json"
  };
  var options = {
    "headers" : headers
  }
  var url = "https://api.github.com/repos/オーナー名/リポジトリ名/projects?access_token=取得したトークン";
  return JSON.parse(UrlFetchApp.fetch(url, options));
}
```

### Organizationプロジェクト一覧取得
[List organization projects](https://developer.github.com/v3/projects/#list-organization-projects)
Organizationプロジェクト一覧を取得できる。

```js:Organizationプロジェクト一覧取得.gs
function getProjectList() {
  var header = {
    "Accept" : "application/vnd.github.inertia-preview+json"
  };
  var options = {
    "headers" : headers
  }
  var url = "https://api.github.com/orgs/Organization名/projects?access_token=取得したトークン";
  return JSON.parse(UrlFetchApp.fetch(url, options));
}
```

### プロジェクト取得
[List a project](https://developer.github.com/v3/repos/projects/#list-a-project)
Organizaiton/リポジトリ問わず指定したプロジェクトIDのプロジェクトを取得できる。
存在しないIDを指定すると404が返ってくる。
参加していない団体のものも同様？

```js:プロジェクト取得.gs
function getProject() {
  var headers = {
    "Accept" : "application/vnd.github.inertia-preview+json"
  };
  var options = {
    "headers" : headers
  }
  var url = "https://api.github.com/projects/プロジェクトID?access_token=取得したトークン";
  return JSON.parse(UrlFetchApp.fetch(url, options));
}
```

### リポジトリプロジェクト作成
[Create a repository projectt](https://developer.github.com/v3/projects/#create-a-repository-project)
payloadでJSONを渡せばプロジェクトの作成ができる。
nameは必須だがbodyはなくても良い。
(これはブラウザで作成する時も同様。)

```js:リポジトリプロジェクト作成.gs
function createProject() {
  var headers = {
    "Accept" : "application/vnd.github.inertia-preview+json"
  };
  var payload = JSON.stringify({
    "name": "プロジェクトタイトル",
    "body": "説明" 
  });
  var options = {
    "method" : "POST",
    "headers" : headers,
    "payload" : payload
  }
  var url = "https://api.github.com/repos/オーナー名/リポジトリ名/projects?access_token=取得したトークン";
  return JSON.parse(UrlFetchApp.fetch(url, options));
}
```

### Organizationプロジェクト作成
[Create a organization projectt](https://developer.github.com/v3/projects/#create-a-organization-project)
payloadでJSONを渡せばプロジェクトの作成ができる。
nameは必須だがbodyはなくても良い。
(これはブラウザで作成する時も同様。)

```js:Organizationプロジェクト作成.gs
function createProject() {
  var headers = {
    "Accept" : "application/vnd.github.inertia-preview+json"
  };
  var payload = JSON.stringify({
    "name": "プロジェクトタイトル",
    "body": "説明" 
  });
  var options = {
    "method" : "POST",
    "headers" : headers,
    "payload" : payload
  }
  var url = "https://api.github.com/orgs/Organization名/projects?access_token=取得したトークン";
  return JSON.parse(UrlFetchApp.fetch(url, options));
}
```

### プロジェクト更新(タイトル・説明変更/close/open)
[Update a project](https://developer.github.com/v3/projects/#update-a-project)
Organizaiton/リポジトリ問わずpayloadでJSONを渡せばプロジェクトの更新ができる。
作成は`POST`だったが更新は`PATCH`。
キーは全て任意。(キーがないJSONや存在しないキーを含むJSONでもOK)
存在しないIDを指定すると404が返ってくる。
参加していない団体のものも同様？
close済みプロジェクトを再度closeしようとしてもエラーにはならない。
(openも同様)
ちなみにclose済みプロジェクトに対する操作はWeb・API共に可能。

|キー|値|
|:--:|:--:|
|name|プロジェクトタイトル|
|body|説明|
|state|プロジェクトのステータス<br>open もしくは closed<br>それ以外を指定すると422になる|

```js:プロジェクト更新(タイトル・説明変更/close/open).gs
function createProject() {
  var headers = {
    "Accept" : "application/vnd.github.inertia-preview+json"
  };
  var payload = JSON.stringify({
    "name": "プロジェクトタイトル",
    "body": "説明",
    "status": "ステータス"
  });
  var options = {
    "method" : "POST",
    "headers" : headers,
    "payload" : payload
  }
  var url = "https://api.github.com/projects/プロジェクトID?access_token=取得したトークン";
  return JSON.parse(UrlFetchApp.fetch(url, options));
}
```

#### 指定例と実行結果

|name|body|state|実行結果|
|:--:|:--:|:--:|:--:|
|同じ|同じ|同じ|何も変わらず|
|違う|違う|違う|全て変わる|
|同じ|違う|同じ|説明だけ変わる|
|同じ|違う|なし|説明だけ変わる|
|なし|違う|なし|説明だけ変わる|
|なし|違う|同じ|説明だけ変わる|
|違う|なし|なし|タイトルだけ変わる|
|なし|なし|違う|ステータスだけ変わる|
|なし|違う|違う|説明とステータスが変わる|
|違う|なし|違う|タイトルとステータスが変わる|

### プロジェクト削除
[Delete a project](https://developer.github.com/v3/projects/#delete-a-project)
Organizaiton/リポジトリ問わずIDを指定してDELETEで実行するとプロジェクトを削除できる。
削除したIDとOrganizationもしくはリポジトリでの番号は永久欠番になり、そのプロジェクトへアクセスしようとすると404になる。
また、APIで存在しないIDなどを指定しても404が返ってくる。
参加していない団体のものも同様？

```js:リポジトリのプロジェクト削除.gs
function deleteProject() {
  var headers = {
    "Accept" : "application/vnd.github.inertia-preview+json"
  };
  var options = {
    "method" : "DELETE",
    "headers" : headers
  }
  var url = "https://api.github.com/projects/プロジェクトID?access_token=取得したトークン";
  UrlFetchApp.fetch(url, options);
}
```

## 取得できるリポジトリプロジェクトの内容
リポジトリプロジェクトの情報、下記JSON。
一覧の場合はそれの配列で削除の場合は何もなし。
リポジトリのプロジェクトを作成した人の情報豊富。
(ただしほぼAPIのURL)
最終更新日時はタイトルや説明の更新だけでなく、そのプロジェクト内のカラムやカードに対してCRUDを実行した場合も含む。

```json:リポジトリプロジェクトのJSON
{
  "owner_url":"https://api.github.com/repos/オーナー名/リポジトリ名",
  "url":"https://api.github.com/repos/sen-corporation/オーナー名/projects/リポジトリ内でのプロジェクト番号",
  "id":プロジェクトID,
  "name":"プロジェクトタイトル",
  "body":"説明",
  "number":リポジトリ内でのプロジェクト番号,
  "creator":{
    "login":"作成者のアカウント名",
    "id":作成者のID,
    "avatar_url":"https://avatars1.githubusercontent.com/u/作成者のID?v=3",
    "gravatar_id":"",
    "url":"https://api.github.com/users/作成者のアカウント名",
    "html_url":"https://github.com/作成者のアカウント名",
    "followers_url":"https://api.github.com/users/作成者のアカウント名/followers",
    "following_url":"https://api.github.com/users/作成者のアカウント名/following{/other_user}",
    "gists_url":"https://api.github.com/users/作成者のアカウント名/gists{/gist_id}",
    "starred_url":"https://api.github.com/users/作成者のアカウント名/starred{/owner}{/repo}",
    "subscriptions_url":"https://api.github.com/users/作成者のアカウント名/subscriptions",
    "organizations_url":"https://api.github.com/users/作成者のアカウント名/orgs",
    "repos_url":"https://api.github.com/users/作成者のアカウント名/repos",
    "events_url":"https://api.github.com/users/作成者のアカウント名/events{/privacy}",
    "received_events_url":"https://api.github.com/users/作成者のアカウント名/received_events",
    "type":"User",
    "site_admin":サイト管理者かどうか
  },
  "created_at":"作成日時(ISO 8601形式 UTC)",
  "updated_at":"更新日時(ISO 8601形式 UTC)"
}
```

## 取得できる Organizationプロジェクトの内容
Organizationプロジェクトの情報、下記JSON。
一覧の場合はそれの配列で削除の場合は何もなし。
リポジトリのプロジェクトを作成した人の情報豊富。
(ただしほぼAPIのURL)
最終更新日時はタイトルや説明の更新だけでなく、そのプロジェクト内のカラムやカードに対してCRUDを実行した場合も含む。

```json:OrganizationプロジェクトのJSON
{
  "owner_url":"https://api.github.com/orgs/Organization名",
  "url":"https://api.github.com/projects/プロジェクトID",
  "html_url":"https://github.com/orgs/Organization名/projects/Organization内でのプロジェクト番号",
  "columns_url":"https://api.github.com/projects/プロジェクトID/columns",
  "id":プロジェクトID,
  "name":"プロジェクトタイトル",
  "body":"説明",
  "number":Organization内でのプロジェクト番号,
  "creator":{
    "login":"作成者のアカウント名",
    "id":作成者のID,
    "avatar_url":"https://avatars1.githubusercontent.com/u/作成者のID?v=3",
    "gravatar_id":"",
    "url":"https://api.github.com/users/作成者のアカウント名",
    "html_url":"https://github.com/作成者のアカウント名",
    "followers_url":"https://api.github.com/users/作成者のアカウント名/followers",
    "following_url":"https://api.github.com/users/作成者のアカウント名/following{/other_user}",
    "gists_url":"https://api.github.com/users/作成者のアカウント名/gists{/gist_id}",
    "starred_url":"https://api.github.com/users/作成者のアカウント名/starred{/owner}{/repo}",
    "subscriptions_url":"https://api.github.com/users/作成者のアカウント名/subscriptions",
    "organizations_url":"https://api.github.com/users/作成者のアカウント名/orgs",
    "repos_url":"https://api.github.com/users/作成者のアカウント名/repos",
    "events_url":"https://api.github.com/users/作成者のアカウント名/events{/privacy}",
    "received_events_url":"https://api.github.com/users/作成者のアカウント名/received_events",
    "type":"User",
    "site_admin":サイト管理者かどうか
  },
  "created_at":"作成日時(ISO 8601形式 UTC)",
  "updated_at":"更新日時(ISO 8601形式 UTC)"
}
```

# カラムのCRUD

Organizaiton/リポジトリ問わず同じ方法で実行できる。

## 実行コード例

### カラム一覧取得
[List project columns](https://developer.github.com/v3/projects/columns/#list-project-columns)
プロジェクトIDを指定してカラム一覧を取得できる。

```js:カラム一覧取得.gs
function getColmunList() {
  var headers = {
    "Accept" : "application/vnd.github.inertia-preview+json"
  };
  var options = {
    "headers" : headers
  }
  var url = "https://api.github.com/projects/プロジェクトID/columns?access_token=取得したトークン";
  return JSON.parse(UrlFetchApp.fetch(url, options));
}
```

### カラム取得
[Get a project column](https://developer.github.com/v3/projects/columns/#get-a-project-column)
カラムIDを指定してカラムを取得できる。
プロジェクト番号等の指定は不要。
IDはカラム一覧から取得できる。
IDはGitHub全体でユニークな値が設定されている。

```js:カラム取得.gs
function getColumn() {
  var headers = {
    "Accept" : "application/vnd.github.inertia-preview+json"
  };
  var options = {
    "headers" : headers
  }
  var url = "https://api.github.com/projects/columns/カラムID?access_token=取得したトークン";
  return JSON.parse(UrlFetchApp.fetch(url, options));
}
```

### カラム作成
[Create a column](https://developer.github.com/v3/projects/columns/#create-a-project-column)
payloadでJSONを渡せばカラムの作成ができる。

```js:カラム作成.gs
function createColumn() {
  var headers = {
    "Accept" : "application/vnd.github.inertia-preview+json"
  };
  var payload = JSON.stringify({
    "name": "カラム名"
  });
  var options = {
    "method" : "POST",
    "headers" : headers,
    "payload" : payload
  }
  var url = "https://api.github.com/projects/プロジェクトID/columns?access_token=取得したトークン";
  return JSON.parse(UrlFetchApp.fetch(url, options));
}
```

### カラム更新
[Update a column](https://developer.github.com/v3/repos/projects/#update-a-column)
payloadでJSONを渡せばカラムの更新ができる。
作成はPOSTだったが更新はPATCH。
存在しないIDを指定すると404が返ってくる。
参加していない団体のものも同様？

```js:カラム更新.gs
function updateColumn() {
  var headers = {
    "Accept" : "application/vnd.github.inertia-preview+json"
  };
  var payload = JSON.stringify({
    "name": "新しいカラム名"
  });
  var options = {
    "method" : "PATCH",
    "headers" : headers,
    "payload" : payload
  }
  var url = "https://api.github.com/projects/columns/カラムID?access_token=取得したトークン";
  return JSON.parse(UrlFetchApp.fetch(url, options));
}
```

### カラム削除
[Delete a column](https://developer.github.com/v3/repos/projects/#delete-a-column)
カラムIDを指定してDELETEで実行するとカラムを削除できる。
存在しないIDを指定すると404が返ってくる。
参加していない団体のものも同様？

```js:カラム削除.gs
function deleteColumn() {
  var headers = {
    "Accept" : "application/vnd.github.inertia-preview+json"
  };
  var options = {
    "method" : "DELETE",
    "headers" : headers
  }
  var url = "https://api.github.com/projects/columns/カラムID?access_token=取得したトークン";
  UrlFetchApp.fetch(url, options);
}
```

### カラム移動
[Move a column](https://developer.github.com/v3/repos/projects/#move-a-column)
positionを指定してカラムを移動できる。
afterに指定するカラムIDは当然同じプロジェクトのものでないといけない。

指定できる値|概要
:--:|:--:
first|先頭に移動
last|最後に移動
after:カラムID|カラムIDの後に移動

```js:カラム移動.gs
function moveColumns() {
  var headers = {
    "Accept" : "application/vnd.github.inertia-preview+json"
  };
  var payload = JSON.stringify({
    "position": "after:カラムID"
  });
  var options = {
    "method" : "POST",
    "headers" : headers,
    "payload" : payload
  }
  var url = "https://api.github.com/projects/columns/カラムID?access_token=取得したトークン";
  return JSON.parse(UrlFetchApp.fetch(url, options));
}
```

## 取得できるデータ
カラムの情報、下記JSON。
一覧の場合はそれの配列で削除の場合は何もなし、移動の場合は空JSON。
カラムを作成した人の情報は入っていない。
最終更新日時はnameの更新だけでなく、そのカラム内のカードに対してCRUDを実行した場合も含む。

```json:カラムのJSON
{
  "url":"https://api.github.com/projects/columns/カラムID",
  "project_url":"https://api.github.com/projects/プロジェクトID",
  "cards_url":"https://api.github.com/projects/columns/プロジェクトID/cards",
  "id":カラムID,
  "name":"カラム名",
  "created_at":"作成日時(ISO 8601形式 UTC)",
  "updated_at":"最終更新日時(ISO 8601形式 UTC)"
}
```

# カードのCRUD

Organizaiton/リポジトリ問わず同じ方法で実行できる。

## 実行コード

### カード一覧取得
[List project cards](https://developer.github.com/v3/projects/cards/#list-project-cards)
指定したカラムIDにあるカード一覧を取得できる。

```js:カード一覧取得.gs
function getCardList() {
  var headers = {
    "Accept" : "application/vnd.github.inertia-preview+json"
  };
  var options = {
    "headers" : headers
  }
  var url = "https://api.github.com/projects/columns/カラムID/cards?access_token=取得したトークン";
  return JSON.parse(UrlFetchApp.fetch(url, options));
}
```

### カード取得
[List a project card](https://developer.github.com/v3/repos/projects/#list-a-project-card)
指定したカードIDの情報を取得できる。
プロジェクトIDやカラムID等の指定は不要。
IDは一覧から取得できる。
IDはGitHub全体でユニークな値が設定されている。

```js:カード取得.gs
function getCard() {
  var headers = {
    "Accept" : "application/vnd.github.inertia-preview+json"
  };
  var options = {
    "headers" : headers
  }
  var url = "https://api.github.com/projects/columns/cards/カードID?access_token=取得したトークン";
  return JSON.parse(UrlFetchApp.fetch(url, options));
}
```

### カード作成
[Create a project card](https://developer.github.com/v3/projects/cards/#create-a-project-card)
payloadでJSONを渡せばプロジェクトの作成ができる。
キーはnoteもしくはcontent_idとcontent_typeを指定する。
issueやプルリクのIDはそれぞれのAPIより取得できる。
[Pull Requests | GitHub Developer Guide](https://developer.github.com/v3/pulls/)
[Issues | GitHub Developer Guide](https://developer.github.com/v3/issues/)
キーの指定を間違えると422が返ってくる。
noteとcontent_*を同時に指定することはできない。
誤ったcontent_idを指定しているとnoteを指定しないことはできないと言われる。
(私は番号を指定してしてエラーになって悩んでしまった。)

キー|値
:--:|:--:
note|ノートやタイトル
content_id|issueID もしくは プルリクID
content_type|"Issue" もしくは "PullRequest"


```js:カード作成.gs
function createCard() {
  var headers = {
    "Accept" : "application/vnd.github.inertia-preview+json"
  };
  var payload = JSON.stringify({
    "note": "ノートやタイトル"
  });
  var options = {
    "method" : "POST",
    "headers" : headers,
    "payload" : payload
  }
  var url = "https://api.github.com/projects/columns/カラムID/cards?access_token=取得したトークン";
  return JSON.parse(UrlFetchApp.fetch(url, options));
}
```

### カード更新
[Update a project card](https://developer.github.com/v3/projects/cards/#update-a-project-card)
指定したカードIDのnoteを書き換えることができる。
一応issueやプルリクのカードのnoteも書き換えることができる、
IDは一覧から取得できる。

```js:カード更新.gs
function updateCard() {
  var headers = {
    "Accept" : "application/vnd.github.inertia-preview+json"
  };
  var payload = JSON.stringify({
    "note" : "新しいノートやタイトル"
  });
  var options = {
    "method" : "PATCH",
    "headers" : headers,
    "payload" : payload
  }
  var url = "https://api.github.com/projects/columns/cards/カードID?access_token=取得したトークン";
  var project = JSON.parse(UrlFetchApp.fetch(url, options));
  Logger.log(JSON.stringify(project));
}
```

### カード削除
[Delete a project card](https://developer.github.com/v3/projects/cards/#delete-a-project-card)
カードIDを指定してDELETEで実行するとカードを削除できる。
issueやプルリクのカードを削除しても、プロジェクトに載らなくなるだけでそれ自体が削除されるわけではない。
存在しない番号やリポジトリに関係ない番号を指定しても404が返ってくる。

```js:カード削除.gs
function deleteCard() {
  var headers = {
    "Accept" : "application/vnd.github.inertia-preview+json"
  };
  var options = {
    "method" : "DELETE",
    "headers" : headers
  }
  var url = "https://api.github.com/projects/columns/cards/カードID?access_token=取得したトークン";
  UrlFetchApp.fetch(url, options);
}
```

### カード移動
[Move a project card](https://developer.github.com/v3/projects/cards/#move-a-project-card)
positionやcolmun_idを指定してカラムを移動できる。
afterに指定するカードIDは当然同じプロジェクトのものでないといけない。
positionは必須だがcolmun_idはなくても良い。

キー|値
:--:|:--:
position|top, buttom, after:カードID
colmun_id|移動先のカラムID

```js:カード移動.gs
function moveColumns() {
  var headers = {
    "Accept" : "application/vnd.github.inertia-preview+json"
  };
  var payload = JSON.stringify({
    "position" : "top",
    "column_id" : カラムID
  });
  var options = {
    "method" : "POST",
    "headers" : headers,
    "payload" : payload
  }
  var url = "https://api.github.com/projects/columns/cards/カードID/moves?access_token=取得したトークン";
  UrlFetchApp.fetch(url, options);
}
```

## 取得できるデータ
カードの情報、下記JSON。
一覧の場合はそれの配列で削除の場合は何もなし、移動の場合は空JSON。
カードを作成した人の情報豊富。
(ただしほぼAPIのURL)

```json:noteカードのJSON
{
  "url":"https://api.github.com/projects/columns/cards/カードID",
  "column_url":"https://api.github.com/projects/columns/カラムID",
  "id":カードID,
  "note":"ノートやタイトル",
  "creator":{
    "login":"作成者のアカウント名",
    "id":作成者のID,
    "avatar_url":"https://avatars1.githubusercontent.com/u/作成者のID?v=3",
    "gravatar_id":"",
    "url":"https://api.github.com/users/作成者のアカウント名",
    "html_url":"https://github.com/作成者のアカウント名",
    "followers_url":"https://api.github.com/users/作成者のアカウント名/followers",
    "following_url":"https://api.github.com/users/作成者のアカウント名/following{/other_user}",
    "gists_url":"https://api.github.com/users/作成者のアカウント名/gists{/gist_id}",
    "starred_url":"https://api.github.com/users/作成者のアカウント名/starred{/owner}{/repo}",
    "subscriptions_url":"https://api.github.com/users/作成者のアカウント名/subscriptions",
    "organizations_url":"https://api.github.com/users/作成者のアカウント名/orgs",
    "repos_url":"https://api.github.com/users/作成者のアカウント名/repos",
    "events_url":"https://api.github.com/users/作成者のアカウント名/events{/privacy}",
    "received_events_url":"https://api.github.com/users/作成者のアカウント名/received_events",
    "type":"User",
    "site_admin":サイト管理者かどうか
  },
  "created_at":"作成日時(ISO 8601形式 UTC)",
  "updated_at":"最終更新日時(ISO 8601形式 UTC)"
}
```

```json:issueやプルリクカードのJSON
{
  "url":"https://api.github.com/projects/columns/cards/カードID",
  "column_url":"https://api.github.com/projects/columns/カラムID",
  "id":カードID,
  "note":null,
  "creator":{
    "login":"作成者のアカウント名",
    "id":作成者のID,
    "avatar_url":"https://avatars1.githubusercontent.com/u/作成者のID?v=3",
    "gravatar_id":"",
    "url":"https://api.github.com/users/作成者のアカウント名",
    "html_url":"https://github.com/作成者のアカウント名",
    "followers_url":"https://api.github.com/users/作成者のアカウント名/followers",
    "following_url":"https://api.github.com/users/作成者のアカウント名/following{/other_user}",
    "gists_url":"https://api.github.com/users/作成者のアカウント名/gists{/gist_id}",
    "starred_url":"https://api.github.com/users/作成者のアカウント名/starred{/owner}{/repo}",
    "subscriptions_url":"https://api.github.com/users/作成者のアカウント名/subscriptions",
    "organizations_url":"https://api.github.com/users/作成者のアカウント名/orgs",
    "repos_url":"https://api.github.com/users/作成者のアカウント名/repos",
    "events_url":"https://api.github.com/users/作成者のアカウント名/events{/privacy}",
    "received_events_url":"https://api.github.com/users/作成者のアカウント名/received_events",
    "type":"User",
    "site_admin":サイト管理者かどうか
  },
  "created_at":"作成日時(ISO 8601形式 UTC)",
  "updated_at":"最終更新日時(ISO 8601形式 UTC)",
  "content_url":"https://api.github.com/repos/オーナー名/リポジトリ名/issues/issueIDもしくはプルリクID"
}
```

# まとめ
ProjectsのAPIを使えばProjectをプログラムで操作することができるが、カードからissueを作ることはできないようだ。
だが、まだ試験運用中のようなので、今後もシステム含めこれからやれることが増えるかもしれない。

- プロジェクト
    - [x] 一覧取得
    - [x] 取得
    - [x] 作成
    - [x] 更新(タイトル・説明変更/close/open)
    - [x] 削除
- カラム
    - [x] 一覧取得
    - [x] 取得
    - [x] 作成
    - [x] 更新
    - [x] 削除
    - [x] 移動
- カード
    - [x] 一覧取得
    - [x] 取得
    - [x] 作成
    - [x] 既にあるプルリクやissueからカード作成
    - [x] 更新
    - [x] 削除
    - [x] 移動
    - [ ] カードをissue化

ちなみに、カラムやカードの操作を行なった場合はページリロードしなくても反映される。
(プルリクのブランチにpushした場合と同様。)

# あとがき
GitHubをあれこれ見ている間に[Webhooks](https://developer.github.com/webhooks/)を見つけました。
更新を受け取るならそれだなと思いましたが、
Project操作に関するものは今の所ありませんでした。
ただ、こうしてAPIで一通りの動作ができることはわかったので、定期的に状態をチェックして変更があったかどうか調べるくらいはできるなと思いました。

あとは、Webhooksでプルリクにラベルが貼られたことなどを検知してカードを自動移動させるのもできそうです。
(2017/7/17追記)確認したところProject関連のWebhooksができていたので、いつか試して記事にします。

## 参考資料
[Projects | GitHub Developer Guide](https://developer.github.com/v3/projects/)
公式ページ。
成功時のステータスコードなど本記事では扱っていない内容もあります。

[GitHub APIでユーザー情報を取得する - Qiita](http://qiita.com/kz800/items/68648b0b4612fa6ef270)
この記事のおかげでGitHub APIの使い方がわかりました。<br>[kz800](http://qiita.com/kz800)さんありがとうございました。