PowerShellからREST APIを使ってTrelloのボード作成をもっと便利に

[Google Apps Scriptを使ってBacklogのプロジェクト作成をもっと便利に［REST API / スプレッドシート操作］ - Qiita](https://qiita.com/zaki-lknr/items/17d731955edfc19dcf8b) のTrello編

---

[タスク管理のTrello](https://trello.com/)のUI/UXが面白くて、これも業務で試せないかなと思って、他のツールのAPIと並行していくつか調べてみました。

で、REST APIの実行という点では、[Backlogのときはスプレッドシート+GAS](https://qiita.com/zaki-lknr/items/17d731955edfc19dcf8b)で試して、過去には[Googleフォトのときはcurl](https://qiita.com/zaki-lknr/items/97c363c12ede4c1f25d2)、[チャットワークのときはPython(ただし2.7)](https://qiita.com/zaki-lknr/items/2df218938e1462ed710a)だったので、今回はPowerShellで試してみました。

(ちなみにGoogleフォトは最終的にPowerShellでツール化して、今回のTrelloについては結局スプレッドシート＋GASでツール化しました:innocent:)

PowerShellのバージョンは5.1(Windows 10 home)

ちなみに、PowerShellでHTTPアクセスするためのInvoke-WebRequestについては以下にもまとめてるので、ご参考
[curl/PowerShellでHTTPアクセスいろいろ - Qiita](https://qiita.com/zaki-lknr/items/8950f6acea20961a8afc)

# API Document

[Trello Developers](https://developers.trello.com/)から。

"Get Started In Under 5 Minutes"(5分ではじめよっ！)ってあるけど、これはREST APIじゃなくてPower-Upっぽい。

上部の[API Docs]のリンクを開けばAPIの一覧が見れる。

# 準備

## API Keyの作成

APIキーはスクリプトに紐づくキー

[API Key](https://trello.com/app-key)のリンクを開く。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/d7a3c606-8b76-5b26-d442-af2ea9a74a2d.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/8697399c-8600-ac0c-6e05-390fc776c1b0.png)

開発者契約(英語)を確認し、チェックを入れて「APIキーを表示」を押下すると、生成されたAPI Keyが表示される。

## API Tokenの作成

APIトークンは、スクリプトを使用するユーザ毎に取得するトークン。
API実行時はこのトークンを取得したユーザ権限で動作する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/3d47e2ee-68f9-e2a8-931e-453f729c92d7.png)

ローカルテスティング用の手動トークン作成のリンク

https://trello.com/1/authorize?expiration=never&scope=read,write,account&response_type=token&name=Server%20Token&key=$API_KEY

となってるので、`account`権限を外して

https://trello.com/1/authorize?expiration=never&scope=read,write&response_type=token&name=Script%20Sample&key=$API_KEY

こんな感じのURLで、Trelloにログインしている状態でブラウザでアクセスする。(`$API_KEY`のとこは取得したAPIキーの文字列)
`name`のところは、トークンを取得するユーザが「見たときにわかりやすいもの」を設定すればよい。

するとこのAPIキーを使用したアプリケーションを使用してもよいかの確認が表示されるので「許可」する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/e04470ff-c451-21a4-aabf-9e14e2195b72.png)

すると、トークンが表示されるので、このテキストをメモする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/8672fa29-d149-202f-5ff5-da42e919fee0.png)

これでAPIの実行に必要なAPI KeyとAPI Tokenが取得できた。

# APIの実行

API Docsの[API Key & Tokens](https://developers.trello.com/reference#api-key-tokens)から。

## 自分のユーザIDを取得するには？？？

「自分のユーザIDを取得するAPI」はない。替わりに`me`を指定すればよい。
(REST API的によくある設定パターンなのかな？確か[Mattermost](https://api.mattermost.com/)もこういう仕様だったような)

## ボード一覧の取得(curl編)

APIは[Membersのboards](https://developers.trello.com/reference#membersidboards)を使用。
日本語のエンコード状態がどうなってるか見るには、勝手にエンコードされたりしないcurlが結局一番かもしれない笑

```json
zaki@mascarpone% curl -sS "https://api.trello.com/1/members/me/boards?key=${API_KEY}&token=${API_TOKEN}&fields=name" | python -m json.tool 
[
    {
        "id": "5cc3933dda8c9901496f1aec",
        "name": "zaki\u30bf\u30b9\u30af"
    },
    :
    :
]
```

日本語はUnicodeのコードポイント方式でGoogleフォトと一緒かな？

ユーザIDを指定する場合は、`me`のところにユーザIDを指定

```json
zaki@mascarpone% curl -sS "https://api.trello.com/1/members/${USER_ID}/boards?key=${API_KEY}&token=${API_TOKEN}&fields=name" | python -m json.tool 
[
    {
        "id": "5cc3933dda8c9901496f1aec",
        "name": "zaki\u30bf\u30b9\u30af"
    },
    :
    :
]
```

# APIの実行(PowerShell編)

ここから本題

## 参照系

### ボード一覧の取得

上記のcurlと同等の処理をPowerShellから実行するには、`Invoke-RestMethod`を使ってこんな感じ

```powershell
$base_url = "https://api.trello.com/1"
$api_key = "********"
$api_token = "********"

$boads_url = $base_url + "/members/me/boards?key=" + $api_key + "&token=" + $api_token
$resp = Invoke-RestMethod $boads_url
```

これで`$resp`に、JSON形式のレスポンスがオブジェクト化(連想配列)されてセットされる。
`$resp | ConvertTo-Json`すればJSONの構造がわかりやすい。

取得できるボード情報については、リンクが見当たらなくてちょっとあれ？って思ったけど、[Board Object](https://developers.trello.com/reference#board-object)に載ってる

### 指定ボードのリスト一覧の取得

[BoardsのAPIの"lists"機能](https://developers.trello.com/reference#boardsboardidlists)から。
指定のボードは前述のボード一覧取得などからあらかじめ特定しておく。

```powershell
$base_url = "https://api.trello.com/1"
$api_key = "********"
$api_token = "********"
$board_id = ****

$lists_url = $base_url + "/boards/" + $board_id + "/lists?key=" + $api_key + "&token=" + $api_token
$list_resp = Invoke-RestMethod $lists_url
```

これで`$list_resp`にJSON形式でリスト一覧がセットされる。
リストの形式は[List Object](https://developers.trello.com/reference#list-object)から。

`ConvertTo-Json`するとこんな感じ。

```json
PS C:\Users\zaki\src\trello\ps1> $list_resp | ConvertTo-Json
[
    {
        "id":  "5cd428573041d96b6e9670d2",
        "name":  "◆pickup◆",
        "closed":  false,
        "idBoard":  "5cc3933dda8c9901496f1aec",
        "pos":  0.5,
        "subscribed":  false,
        "softLimit":  null
    },
    {
        "id":  "5cc3933d59e30b084e1c2d72",
        "name":  "するべきこと",
        "closed":  false,
        "idBoard":  "5cc3933dda8c9901496f1aec",
        "pos":  1,
        "subscribed":  false,
        "softLimit":  null
    },
    :
    :
]
```

### 指定ボードの全カード取得

ボード上の全カードを取得するのであれば、[BoardsのAPIの"cards"機能]から。
リスト一覧取得同様、指定のボードIDはあらかじめ取得しておく。

```powershell
$base_url = "https://api.trello.com/1"
$api_key = "********"
$api_token = "********"

$cards_url = $base_url + "/boards/" + $board_id + "/cards?key=" + $api_key + "&token=" + $api_token
$cards_resp = Invoke-RestMethod $cards_url
```

リスト一覧同様、`$cards_resp`にJSON形式のカード一覧がセットされる。
カードの形式は[Card Object](https://developers.trello.com/reference#card-object)参照。

### 指定リストのカード一覧

リスト一覧取得で取得したリストのIDがあれば、そのリスト内のカード一覧だけ取得することもできる。

```powershell
$base_url = "https://api.trello.com/1"
$api_key = "********"
$api_token = "********"
$list_id = ********

$card_in_list_url = $base_url + "/lists/" + $list_id + "/cards?key=" + $api_key + "&token=" + $api_token
$card_in_list_resp = Invoke-RestMethod $card_in_list_url
```

## 登録系

先に日本語のエンコードについて書いておくと、前述のcurlのレスポンス的にはUTF-16のコードポイントで指定するように見えるけど、2019年5月の時点ではUTF-8の文字列をただURLエスケープしただけでPOSTして大丈夫だった。

で、PowerShellの`Invoke-RestMethod`と`Invoke-WebRequest`は(全バージョンを調べたわけじゃないけど、少なくともwin10標準のPowerShell5.1では)ソースコードのエンコードがShift_JISでもHTTPリクエスト時にはUTF-8でURLエスケープしてくれるので、特に何も考えずに日本語の引数を指定すればTrello的には問題ない。

### 新規ボードの作成

ボードを新しく作成するには、[Boardsの/boards/のPOST](https://developers.trello.com/reference#boardsid)を使う。

Query Paramsがいろいろあるが、ボードを作成するのに最低限必要なのは

```powershell
$base_url = "https://api.trello.com/1"
$api_key = "********"
$api_token = "********"

$board_name = "サンプルボード"

$create_board_url = $base_url + "/boards?name=" + $board_name + "&key=" + $api_key + "&token=" + $api_token
$create_board_resp = Invoke-RestMethod $create_board_url -Method Post
```

レスポンスは

```powershell
PS C:\Users\zaki\src\trello\ps1> $create_board_resp


id             : 5ce11e359ce2422ed908369f
name           : サンプルボード
desc           : 
descData       : 
closed         : False
idOrganization : 
pinned         : False
url            : https://trello.com/b/79K4qbRR/%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%83%9C%E3%83%BC%E3%83%89
shortUrl       : https://trello.com/b/79K4qbRR
prefs          : @{permissionLevel=private; voting=disabled; comments=members; invitations=members; selfJoin=True; cardCovers=True; isTemplate=False; cardAging=regul
                 ar; calendarFeedEnabled=False; background=blue; backgroundImage=; backgroundImageScaled=; backgroundTile=False; backgroundBrightness=dark; backgroun
                 dColor=#0079BF; backgroundBottomColor=#0079BF; backgroundTopColor=#0079BF; canBePublic=True; canBeEnterprise=True; canBeOrg=True; canBePrivate=True;
                  canInvite=True}
labelNames     : @{green=; yellow=; orange=; red=; purple=; blue=; sky=; lime=; pink=; black=}
limits         : 
```

Trelloで見るとこんな感じ。作成できてる。というか、「デフォルトのリスト」も作成されてる。(これどこに設定あるかわからなかった…)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/2cca2861-8ade-9b30-eb3c-6f8fdd6d1e73.png)

#### 主要なパラメタ

- デフォルトのリストを作成しない
    - Query Paramsに`defaultLists=false`を追加
- 背景色を指定したい
    - `prefs_background=***`を追加。指定できる背景色は

        > The id of a custom background or one of: `blue`, `orange`, `green`, `red`, `purple`, `pink`, `lime`, `sky`, `grey`.

        とあるが、それ以外に背景画像IDの指定もできた。  
        背景画像IDの取得は…わからん。。どこかにあるかもしれないけど、背景設定済みボードのボード情報を取得すれば、`prefs.background`にセットされてるのでそれ参照
- 「このボードについて」のテキストを設定
    - `desc=********`を追加。ここに指定したテキストがそのまま「このボードについて」に設定される

### 新規リストの作成

リスト作成のボードIDを指定して、[Listsの"/lists"のPOST](https://developers.trello.com/reference#lists-1)を使う。

```powershell
$base_url = "https://api.trello.com/1"
$api_key = "********"
$api_token = "********"

$board_id = ******
$list_name = "優先タスク"

$create_list_url = $base_url + "/lists?name=" + $list_name + "&idBoard=" + $board_id + "&pos=bottom&key=" + $api_key + "&token=" + $api_token
$create_list_resp = Invoke-RestMethod $create_list_url -Method Post
```

前述の「ボード作成」の例であれば、レスポンスのボードIDは`5ce11e359ce2422ed908369f`になっているので、これを指定すればこんな感じ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/e8f4ccee-63b8-02d6-345f-f268e5c3a347.png)

レスポンスは以下の通り。

```powershell
PS C:\Users\zaki\src\trello\ps1> $create_list_resp


id      : 5ce1276eb20290533b2c888e
name    : 優先タスク
closed  : False
idBoard : 5ce11e359ce2422ed908369f
pos     : 65536
limits  : 
```

`pos`については

> `top`, `bottom`, or a positive floating point number

とあるが、`top`を指定すれば左端、`bottom`で右端になる。
リストの作成は1個ずつしかできないので、ボード作成時に複数のリストをまとめてドンと作りたい場合は、ループで処理すればまぁ問題ないかと。

### メンバーの招待

チーム機能を使おう！
ということなんだろうけど、いろんな事情でユーザ指定で招待して共有したい場合。

[Boardsの/boards/{id}/membersにPUT](https://developers.trello.com/reference#boardsidlabelnamesmembers)を使って、これもAPIで実行できる。

```powershell
$base_url = "https://api.trello.com/1"
$api_key = "********"
$api_token = "********"

$board_id = ******
$email_addr = "zaki-lknr@example.org"

$url = $base_url + "/boards/" + $board_id + "/members?email=" + $email_addr + "&key=" + $api_key + "&token=" + $api_token
$resp = Invoke-RestMethod $url -Method Put -Headers @{type = "normal"}
```

ポイントは
- メソッドはPUT
- 招待するユーザのアドレスはQuery Stirngに指定
- 対象ユーザの権限はHTTPヘッダで指定(`type`に`normal`か`admin`を指定)
- 招待済みのユーザに対する再実行は問題ない(権限が更新されると思えばいい)
- ボードのオーナーのアドレスを指定すると403エラー("Not enough admins"と出力される)になるので注意

実行すると、処理対象のボードIDと、`members`のリストと、`memberships`のリストが返る。
[membersはこちら](https://developers.trello.com/reference#member-object)
membershipsはどこにドキュメントあるかわからん。。

---

PowerShell単体だと使う人(非技術者を想定)にはまだちょっと不親切なので、Excelで作った作成対象ボード一覧とかリスト一覧とか招待するユーザ一覧とかを用意して、PowerShellのCOMからExcel操作してファイル読み込んでスクリプト実行、みたいにすれば便利になると思う。
[PowerShell で Excel をどうのこうのすることに興味を持ってくれると嬉しい - Qiita](https://qiita.com/miyamiya/items/161372111b68bad0744a)