Trelloに日付リストを自動で生成する【Trello API】

# ✏️ 概要
Trelloをカレンダーレイアウトにしたら 日付リストの生成を自動化したくなってしまったので、
今回はPHPを用いてTrelloのAPIを叩いてリストを自動生成してみます。

こんな感じでスクリプトを叩くと自動でTrelloのボード上にリストが生成されます 📆

![Sep-01-2022 19-37-55.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468787/c904943b-c470-8ade-70f3-3af4c10dbc60.gif)

# 📁 準備をする

### 開発者向けAPIキーの取得

まずは以下のURLにアクセスして**開発者向けAPIキー**を取得します

[🔗 開発者向けAPIキー取得ページ](https://trello.com/1/appKey/generate)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468787/97e58655-bf46-a9ca-1d2f-fb60ce29a89c.png)


### トークンの取得

次に書き込みと読み込み権限のあるトークンを取得します。

以下のリンクにアクセスをして許可をクリックして次に進みます

```
https://trello.com/1/authorize?key={1で取得したキー}&name=&expiration=never&response_type=token&scope=read,write
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468787/3505ceaa-a9ff-4836-fa99-d3ffb8a09201.png)

すると、以下のようにトークンを取得することが出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468787/e696959c-7432-3bf1-644d-7722bb7282b4.png)

準備は以上で完了です！

# 🛠 APIを実際に叩いてみる

リストを生成するスクリプトを書く前にまずは実際にTrelloのAPIを叩いてみましょう！まずは、ボードの取得をしてみます。

`{ユーザーネーム}` `{取得したキー}` `{取得したトークン}` を自分のものに書き換えてターミナル等で叩いてみてみましょう

```shell
curl "https://trello.com/1/members/{ユーザーネーム}/boards?key={取得したキー}&token={取得したトークン}&fields=name"
```

以下のようなjsonが返ってくれば上手くいってます。

```
...
{"name":"xxxxx","id":"xxxxx"},
...
```

準備の時に取得した キー や トークン が使えてる事が確認できました👏


# 👩‍💻 スクリプトを書いてみる

やっと本題ですw

今回は特定のボードを指定してリストとしてカレンダーを生成するスクリプトを書いてみます。
まずは完成版のコードを見てみましょう！解説は後述します。

任意の場所にファイルを作成して以下のスクリプトを記述します。

```php
<?php

// 固定値
$key = '{取得したキー}';
$token = '{取得したトークン}';

// ____ １：ボード情報の取得 ____
$bords_url = 'https://trello.com/1/members/{ユーザーネーム}/boards?key=' . $key . '&token=' . $token . '&fields=name';

// cURLセッションを初期化
$ch = curl_init();

//オプション
curl_setopt($ch, CURLOPT_URL, $bords_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// URLの情報を取得
$bord_list =  curl_exec($ch);

// 取得結果を表示
echo json_encode(json_decode($bord_list), JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);

// セッションを終了
curl_close($ch);

// ____ ２：カレンダーを生成するボードを選択（ボードを間違えるとめんどくさいから標準入力から都度受け取る事にした） ____
echo 'カレンダーを生成したいボードのIDはどれですか: ';
$bord_id = trim(fgets(STDIN));

// ____ ３：カレンダー情報の生成 ____
// １ヶ月分の日付の取得
$period_object = new DatePeriod(
    // 来月の月始まりだよと宣言
    new DateTime('first day of +1 month'),
    // 1日毎の日付データを取得
    new DateInterval('P1D'),
    // ２ヶ月後までの日付を取得(２ヶ月後の表示はされない)
    new DateTime('first day of +2 month')
);

// 曜日を日本語に変換するための要素
$week = ['日', '月', '火', '水', '木', '金', '土'];

// １ヶ月分の日付を配列に格納（reverseさせたいので一旦ここで配列にした）
$period_map = [];
foreach ($period_object as $day) {
    $period_map[] = $day->format('m/d') . '（' . $week[$day->format('w')] . '）';
}

// POSTされる時に最終日からPOSTして欲しいのでreverse
$period_post_data = array_reverse($period_map);

// ____ ４：POST用データ作成, POST ____
// POSTするURL
$url = 'https://trello.com/1/lists';

foreach ($period_post_data as $date_name) {
    $post_data = [
        'key'     => $key,
        'token'   => $token,
        'name'    => $date_name,
        'idBoard' => $bord_id
    ];

    // cURLセッションを初期化
    $ch = curl_init();

    // オプションを設定
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);

    // URLの情報を取得
    $response =  curl_exec($ch);

    // 取得結果を表示
    echo json_encode(json_decode($response), JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);

    // セッションを終了
    curl_close($ch);
}
```

### スクリプトの解説


#### 固定値

```php
// 固定値
 $key = '{取得したキー}';
 $token = '{取得したトークン}';
```

後ほどのコードで使いやすくする為に、各自で取得したキーとトークンを変数に入れおきましょう

#### ボード情報の取得

```php

// ____ １：ボード情報の取得 ____
$bords_url = 'https://trello.com/1/members/{ユーザーネーム}/boards?key=' . $key . '&token=' . $token . '&fields=name';

// cURLセッションを初期化
$ch = curl_init();

//オプション
curl_setopt($ch, CURLOPT_URL, $bords_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// ボードの情報を取得
$bord_list =  curl_exec($ch);

// 取得結果を表示
echo json_encode(json_decode($bord_list), JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);

// セッションを終了
curl_close($ch);
```

先ほどターミナルで叩いたのと同じようにcurlを使用してAPIを叩きます
こちらのステップではボードの一覧を取得し表示しています。

#### カレンダーを生成するボードを選択

```php
// ____ ２：カレンダーを生成するボードを選択（ボードを間違えるとめんどくさいから標準入力から都度受け取る事にした） ____
echo 'カレンダーを生成したいボードIDはどれですか: ';
$bord_id = trim(fgets(STDIN));
```

スクリプトの中にボードIDを直接書き込んでもいいですが、変更漏れがあったり間違えたりした際に 容赦無くリストが生成されてしまい後から削除するのが面倒くさいので（経験済み）、ボードIDを実行する度に都度標準入力から受け取るようにしました。



#### カレンダー情報の生成


```php
// ____ ３：カレンダー情報の生成 ____
// １ヶ月分の日付の取得
$period_object = new DatePeriod(
    // 来月の月始まりだよと宣言
    new DateTime('first day of +1 month'),
    // 1日毎の日付データを取得
    new DateInterval('P1D'),
    // ２ヶ月後までの日付を取得(２ヶ月後の表示はされない)
    new DateTime('first day of +2 month')
);

// 曜日を日本語に変換するための要素
$week = ['日', '月', '火', '水', '木', '金', '土'];

// １ヶ月分の日付を配列に格納（reverseさせたいので一旦ここで配列にした）
$period_map = [];
foreach ($period_object as $day) {
    $period_map[] = $day->format('m/d') . '（' . $week[$day->format('w')] . '）';
}

// POSTされる時に最終日からPOSTして欲しいのでreverse
$period_post_data = array_reverse($period_map);
```

DatePeriod()を使用して日付のデータを配列に格納します。第一引数に 取得したい日付けデータの開始日、第二引数に日付の間隔、第三引数に取得したい日付けデータの終了日を指定します。

DatePeriod()で生成されたオブジェクトの曜日の部分は[0-6]の数値で返ってくる為、整形をする処理の中で 日本語表記に変換します。

また、最終的に月の最終日からPOSTしたいのでreverseします。

#### POST用データ作成とPOST

```php
// ____ ４：POST用データ作成, POST ____
// POSTするURL
$url = 'https://trello.com/1/lists';

foreach ($period_post_data as $date_name) {
    $post_data = [
        'key'     => $key,
        'token'   => $token,
        'name'    => $date_name,
        'idBoard' => $bord_id
    ];

    // cURLセッションを初期化
    $ch = curl_init();

    // オプションを設定
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);

    // URLの情報を取得
    $response =  curl_exec($ch);

    // 取得結果を表示
    echo json_encode(json_decode($response), JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);

    // セッションを終了
    curl_close($ch);
}
```

配列に入っている日付データを順にPOSTしています。１つ前のSTEPで配列をreverseさせているので 月の最終日から順にPOSTされ、最終的には月の頭から始まるカレンダーが完成します🌟

# 実際にスクリプトを動かしてみる

それでは実際に先ほどのスクリプトを動かしてみます。
先ほど作成したファイルをターミナルなどで実行してみましょう。

```shell
php {作成したファイルの名前}.php
```

すると自分のアカウントのボード一覧が返されるのでカレンダーを生成したいボードのIDを入力しましょう。

```shell
[
    {
        "name": "ボード１",
        "id": "hogehoge"
    },
    {
        "name": "ボード２",
        "id": "hogehoge"
    },
    {
        "name": "ボード３",
        "id": "hogehoge"
    }
]
カレンダーを生成したいボードのIDはどれですか: {ここでIDを入力する}
```

Enterを押して以下のように日付リストが生成されたら成功です🎉

![](https://storage.googleapis.com/zenn-user-upload/9e4f856c8bd1-20220813.png)

お疲れ様でした✨